From ac4be62c592886447c91e2689bb919b20eb05385 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dj8yf0=CE=BCl?= Date: Fri, 21 Apr 2023 23:19:52 +0300 Subject: [PATCH 01/11] feat(evm-utils/evm-state): connect to fast_rlp tag/feature of triedb --- Cargo.lock | 150 +++++++++++------ evm-utils/evm-state/Cargo.toml | 6 +- evm-utils/evm-state/src/lib.rs | 2 + .../evm-state/src/rlp_roundtrip_tests.rs | 140 ++++++++++++++++ evm-utils/evm-state/src/storage/inspectors.rs | 10 +- evm-utils/evm-state/src/storage/mod.rs | 9 +- evm-utils/evm-state/src/storage/walker.rs | 5 +- evm-utils/evm-state/src/transactions.rs | 57 +++++-- evm-utils/evm-state/src/types.rs | 153 +++++++++++++++--- ledger-tool/Cargo.toml | 2 +- 10 files changed, 434 insertions(+), 100 deletions(-) create mode 100644 evm-utils/evm-state/src/rlp_roundtrip_tests.rs diff --git a/Cargo.lock b/Cargo.lock index 4a1f57bc37..de8cf9e099 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -47,6 +47,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "aho-corasick" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" +dependencies = [ + "memchr", +] + [[package]] name = "aliasable" version = "0.1.3" @@ -224,6 +233,18 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "auto_impl" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a8c1df849285fbacd587de7818cc7d13be6cd2cbcd47a04fb1801b0e2706e33" +dependencies = [ + "proc-macro-error", + "proc-macro2 1.0.56", + "quote 1.0.26", + "syn 1.0.109", +] + [[package]] name = "autocfg" version = "0.1.8" @@ -241,9 +262,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "axum" -version = "0.6.15" +version = "0.6.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b32c5ea3aabaf4deb5f5ced2d688ec0844c881c9e6c696a8b769a05fc691e62" +checksum = "113713495a32dd0ab52baf5c10044725aa3aec00b31beda84218e469029b72a3" dependencies = [ "async-trait", "axum-core", @@ -577,9 +598,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.12.0" +version = "3.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" +checksum = "9b1ce199063694f33ffb7dd4e0ee620741495c32833cde5aa08f02a0bf96f0c8" [[package]] name = "bv" @@ -655,12 +676,6 @@ dependencies = [ "iovec", ] -[[package]] -name = "bytes" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0dcbc35f504eb6fc275a6d20e4ebcda18cf50d40ba6fabff8c711fa16cb3b16" - [[package]] name = "bytes" version = "1.4.0" @@ -1097,9 +1112,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181" +checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" dependencies = [ "libc", ] @@ -1876,7 +1891,7 @@ name = "evm" version = "0.35.0" source = "git+https://github.com/velas/evm?tag=v0.35-with-traces#90a980bb9d7ccbb21b2897e71b889847f7beeade" dependencies = [ - "auto_impl", + "auto_impl 0.5.0", "environmental", "ethereum", "evm-core", @@ -1967,7 +1982,7 @@ dependencies = [ "tracing", "tracing-attributes", "tracing-opentelemetry 0.16.0", - "tracing-subscriber 0.3.16", + "tracing-subscriber 0.3.17", "txpool", ] @@ -2023,7 +2038,7 @@ name = "evm-runtime" version = "0.35.0" source = "git+https://github.com/velas/evm?tag=v0.35-with-traces#90a980bb9d7ccbb21b2897e71b889847f7beeade" dependencies = [ - "auto_impl", + "auto_impl 0.5.0", "environmental", "evm-core", "primitive-types", @@ -2038,14 +2053,16 @@ dependencies = [ "auto_enums", "bincode", "borsh", - "bytes 0.6.0", + "bytes 1.4.0", "criterion", "dashmap 4.0.2", "derivative", "derive_more", + "etcommon-hexutil", "ethabi", "ethbloom 0.11.1", "evm", + "fastrlp", "fixed-hash 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex", "impl-rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2119,6 +2136,32 @@ dependencies = [ "instant", ] +[[package]] +name = "fastrlp" +version = "0.3.0" +source = "git+https://github.com/velas/fastrlp?tag=second_release_candidate#f4e921c54f7669e157b2e7e8f5385eed54e105cc" +dependencies = [ + "arrayvec", + "auto_impl 1.0.1", + "bytes 1.4.0", + "ethbloom 0.11.1", + "ethereum", + "fastrlp-derive", + "primitive-types", + "thiserror", +] + +[[package]] +name = "fastrlp-derive" +version = "0.2.0" +source = "git+https://github.com/velas/fastrlp?tag=second_release_candidate#f4e921c54f7669e157b2e7e8f5385eed54e105cc" +dependencies = [ + "bytes 1.4.0", + "proc-macro2 1.0.56", + "quote 1.0.26", + "syn 2.0.15", +] + [[package]] name = "fd-lock" version = "3.0.6" @@ -2457,7 +2500,7 @@ version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "029d74589adefde59de1a0c4f4732695c32805624aec7b68d91503d4dba79afc" dependencies = [ - "aho-corasick", + "aho-corasick 0.7.20", "bstr", "fnv", "log 0.4.17", @@ -2496,9 +2539,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66b91535aa35fea1523ad1b86cb6b53c28e0ae566ba4a460f4457e936cad7c6f" +checksum = "17f8a914c2987b688368b5138aa05321db91f4090cf26118185672ad588bce21" dependencies = [ "bytes 1.4.0", "fnv", @@ -3037,7 +3080,7 @@ checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" dependencies = [ "hermit-abi 0.3.1", "io-lifetimes 1.0.10", - "rustix 0.37.11", + "rustix 0.37.14", "windows-sys 0.48.0", ] @@ -3300,9 +3343,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.141" +version = "0.2.142" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" +checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" [[package]] name = "libloading" @@ -3415,9 +3458,9 @@ checksum = "d4d2456c373231a208ad294c33dc5bff30051eafd954cd4caae83a712b12854d" [[package]] name = "linux-raw-sys" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f" +checksum = "36eb31c1778188ae1e64398743890d0877fef36d11521ac60406b42016e8c2cf" [[package]] name = "lock_api" @@ -3864,9 +3907,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.50" +version = "0.10.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e30d8bc91859781f0a943411186324d580f2bbeb71b452fe91ae344806af3f1" +checksum = "97ea2d98598bf9ada7ea6ee8a30fb74f9156b63bbe495d64ec2b87c269d2dda3" dependencies = [ "bitflags", "cfg-if 1.0.0", @@ -3896,18 +3939,18 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-src" -version = "111.25.2+1.1.1t" +version = "111.25.3+1.1.1t" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320708a054ad9b3bf314688b5db87cf4d6683d64cfc835e2337924ae62bf4431" +checksum = "924757a6a226bf60da5f7dd0311a34d2b52283dd82ddeb103208ddc66362f80c" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.85" +version = "0.9.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d3d193fb1488ad46ffe3aaabc912cc931d02ee8518fe2959aea8ef52718b0c0" +checksum = "992bac49bdbab4423199c654a5515bd2a6c6a23bf03f2dd3bdb7e5ae6259bc69" dependencies = [ "cc", "libc", @@ -4506,7 +4549,7 @@ dependencies = [ "rand 0.8.5", "rand_chacha 0.3.1", "rand_xorshift 0.3.0", - "regex-syntax", + "regex-syntax 0.6.29", "rusty-fork", "tempfile", "unarray", @@ -5070,13 +5113,13 @@ dependencies = [ [[package]] name = "regex" -version = "1.7.3" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d" +checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" dependencies = [ - "aho-corasick", + "aho-corasick 1.0.1", "memchr", - "regex-syntax", + "regex-syntax 0.7.1", ] [[package]] @@ -5091,6 +5134,12 @@ version = "0.6.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" +[[package]] +name = "regex-syntax" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" + [[package]] name = "repair-check" version = "0.1.0" @@ -5223,9 +5272,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4a36c42d1873f9a77c53bde094f9664d9891bc604a45b4798fd2c389ed12e5b" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustc-hash" @@ -5279,15 +5328,15 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.11" +version = "0.37.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85597d61f83914ddeba6a47b3b8ffe7365107221c2e557ed94426489fefb5f77" +checksum = "d9b864d3c18a5785a05953adeed93e2dca37ed30f18e69bba9f30079d51f363f" dependencies = [ "bitflags", "errno 0.3.1", "io-lifetimes 1.0.10", "libc", - "linux-raw-sys 0.3.1", + "linux-raw-sys 0.3.4", "windows-sys 0.48.0", ] @@ -7376,7 +7425,7 @@ dependencies = [ "tracing", "tracing-attributes", "tracing-opentelemetry 0.16.0", - "tracing-subscriber 0.3.16", + "tracing-subscriber 0.3.17", "velas-account-program", "velas-relying-party-program", ] @@ -8246,7 +8295,7 @@ dependencies = [ "cfg-if 1.0.0", "fastrand", "redox_syscall 0.3.5", - "rustix 0.37.11", + "rustix 0.37.14", "windows-sys 0.45.0", ] @@ -8899,13 +8948,13 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" dependencies = [ "proc-macro2 1.0.56", "quote 1.0.26", - "syn 1.0.109", + "syn 2.0.15", ] [[package]] @@ -8961,7 +9010,7 @@ dependencies = [ "tracing", "tracing-core", "tracing-log", - "tracing-subscriber 0.3.16", + "tracing-subscriber 0.3.17", ] [[package]] @@ -8977,9 +9026,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" +checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" dependencies = [ "nu-ansi-term", "sharded-slab", @@ -9003,13 +9052,16 @@ checksum = "0de5f738ceab88e2491a94ddc33c3feeadfa95fedc60363ef110845df12f3878" [[package]] name = "triedb" version = "0.5.0" -source = "git+https://github.com/velas/triedb?tag=optimal_children#16643d9ee244b0ff4e9e69281a39a7e79df3c4f1" +source = "git+https://github.com/velas/triedb?tag=fast_rlp#4897a7febd6808523879aa4b41e87aa3a091c8ec" dependencies = [ "anyhow", + "backtrace", "bincode", + "bytes 1.4.0", "dashmap 4.0.2", "derivative", "etcommon-hexutil", + "fastrlp", "log 0.4.17", "primitive-types", "rayon", diff --git a/evm-utils/evm-state/Cargo.toml b/evm-utils/evm-state/Cargo.toml index aafbff7e83..7ce1e710b9 100644 --- a/evm-utils/evm-state/Cargo.toml +++ b/evm-utils/evm-state/Cargo.toml @@ -11,7 +11,7 @@ secp256k1 = { version = "0.19.0", features = ["recovery", "global-context"] } rand2 = { version = "=0.6.1", package = "rand" } rocksdb = { git = "https://github.com/velas/rust-rocksdb", version = "0.19.0", default-features = false } # rocksdb = { version = "0.16.0", default-features = false } -triedb = { git = "https://github.com/velas/triedb", tag = "optimal_children", features = ["rocksdb"] } +triedb = { git = "https://github.com/velas/triedb", tag = "fast_rlp", features = ["rocksdb"] } # triedb = { path = "../../../triedb", features = ["rocksdb"] } primitive-types = { version = "0.11.0", features = ["borsh"] } @@ -19,16 +19,18 @@ keccak-hash = "0.9.0" log = "0.4.11" simple_logger = "2.2" hex = "0.4.2" +etcommon-hexutil = "0.2.4" serde = "1.0" sha3 = "0.9.1" rand = "0.8.3" rlp = "0.5.0" +fastrlp = { git = "https://github.com/velas/fastrlp", tag="second_release_candidate", features = ["derive", "handle-thiserror"] } thiserror = "1.0.22" anyhow = "1.0.34" bincode = "1.3.1" borsh = "0.9.3" lazy_static = "1.4.0" -bytes = "0.6.0" +bytes = "1" snafu = "0.7" derive_more = "0.99.11" tempfile = "3.1.0" diff --git a/evm-utils/evm-state/src/lib.rs b/evm-utils/evm-state/src/lib.rs index 6e9dbc1539..65d4e6658f 100644 --- a/evm-utils/evm-state/src/lib.rs +++ b/evm-utils/evm-state/src/lib.rs @@ -18,6 +18,8 @@ pub use ethbloom::Bloom; pub use traces::*; pub use transactions::*; pub use types::*; +#[cfg(test)] +mod rlp_roundtrip_tests; pub use { context::{ChainContext, EvmConfig}, diff --git a/evm-utils/evm-state/src/rlp_roundtrip_tests.rs b/evm-utils/evm-state/src/rlp_roundtrip_tests.rs new file mode 100644 index 0000000000..c28cba2dc7 --- /dev/null +++ b/evm-utils/evm-state/src/rlp_roundtrip_tests.rs @@ -0,0 +1,140 @@ +use crate::transaction_roots::EthereumReceipt; + +use super::types::Account; + +use ethbloom::Bloom; +use evm::backend::Log; +use keccak_hash::H256; +use primitive_types::{U256, H160}; +use rlp::{Decodable as DecodableOld, DecoderError as OldDecoderError, Rlp}; + +use triedb::rlp::{Encodable, Decodable, DecoderError}; + +fn decode_old(bytes: &[u8]) -> Result { + + ::decode(&Rlp::new(bytes)) +} + + pub fn decode<'a, T: Decodable<'a>>(mut val: &'a [u8]) -> Result { + Decodable::decode(&mut val) +} + +pub use rlp::encode as encode_old; + +pub fn encode(val: &V) -> Vec { + let mut vec_buffer = Vec::with_capacity(val.length()); + val.encode(&mut vec_buffer); + vec_buffer +} + +macro_rules! check_roundtrip { + ($v: expr => $type: ty) => {{ + let old_rlp_raw: Vec; + let rlp_raw; + { + old_rlp_raw = encode_old(&$v).to_vec(); + dbg!(hexutil::to_hex(&old_rlp_raw)); + let decoded_node: $type = decode_old(&old_rlp_raw).unwrap(); + assert_eq!(decoded_node, $v); + } + { + rlp_raw = encode(&$v); + dbg!(hexutil::to_hex(&rlp_raw)); + let decoded_node: $type = decode(&rlp_raw).unwrap(); + assert_eq!(decoded_node, $v); + } + + { + assert_eq!(old_rlp_raw, rlp_raw); + } + }}; +} + +#[test] +fn test_check_account_roundtrip() { + let acc = Account { + nonce: U256([27;4]), + balance: U256([24;4]), + storage_root: H256([7; 32]), + code_hash: H256([2; 32]), + + }; + + check_roundtrip!(acc => Account); + let acc = Account { + nonce: U256([21;4]), + balance: U256([23;4]), + storage_root: H256([8; 32]), + code_hash: H256([123; 32]), + + }; + + check_roundtrip!(acc => Account); + +} + +#[test] +fn test_check_log_roundtrip() { + let acc = Log { + address: H160([23; 20]), + topics: vec![H256([37; 32]), H256([173;32]), H256([21; 32])], + data: vec![0, 123, 12, 17, 19, 244], + + }; + + check_roundtrip!(acc => Log); + let acc = Log { + address: H160([23; 20]), + topics: vec![], + data: vec![], + + }; + + check_roundtrip!(acc => Log); + +} +#[test] +fn test_check_bloom_roundtrip() { + let mut acc = [10; 256]; + for i in 0..256 { + acc[i] = i as u8; + } + let bloomy = Bloom(acc); + + check_roundtrip!(bloomy => Bloom); +} + +#[test] +fn test_check_ethereum_receipt_roundtrip() { + let mut acc = [10; 256]; + for i in 0..256 { + acc[i] = i as u8; + } + let bloomy = Bloom(acc); + let mut h160_special = [0; 20]; + for i in 0..20 { + h160_special[i] = i as u8; + } + let log1 = Log { + address: H160(h160_special), + topics: vec![H256([37; 32]), H256([173;32]), H256([21; 32])], + data: vec![0, 123, 12, 17, 19, 244], + + }; + let log2 = Log { + address: H160([38; 20]), + topics: vec![H256([27; 32]), H256([173;32]), H256([24; 32])], + data: vec![0, 123, 12, 17, 111, 244], + + }; + + let receipt = EthereumReceipt { + log_bloom: bloomy, + logs: vec![log1, log2], + status: 7, + gas_used: U256([23;4]), + + }; + + check_roundtrip!(receipt => EthereumReceipt); +} \ No newline at end of file diff --git a/evm-utils/evm-state/src/storage/inspectors.rs b/evm-utils/evm-state/src/storage/inspectors.rs index 3ae01711e1..48f583d39f 100644 --- a/evm-utils/evm-state/src/storage/inspectors.rs +++ b/evm-utils/evm-state/src/storage/inspectors.rs @@ -49,7 +49,7 @@ pub mod encoding { where T: DataInspector, K: TryFromSlice, - V: rlp::Decodable, + V: for<'r> triedb::rlp::Decodable<'r>, { fn inspect_data_raw>(&self, key: Vec, value: Data) -> Result<()> { let key = TryFromSlice::try_from_slice(&key)?; @@ -93,11 +93,11 @@ pub mod encoding { fn data_from_bytes, Value>(data: Data) -> Result where - Value: rlp::Decodable, + Value: for<'r> triedb::rlp::Decodable<'r>, { - let rlp = rlp::Rlp::new(data.as_ref()); - trace!("rlp: {:?}", rlp); - let t = Value::decode(&rlp)?; + trace!("rlp: {:?}", hexutil::to_hex(data.as_ref())); + + let t = triedb::rlp::decode(data.as_ref())?; Ok(t) } } diff --git a/evm-utils/evm-state/src/storage/mod.rs b/evm-utils/evm-state/src/storage/mod.rs index 8ac02fb0df..7375e63ea2 100644 --- a/evm-utils/evm-state/src/storage/mod.rs +++ b/evm-utils/evm-state/src/storage/mod.rs @@ -13,7 +13,7 @@ use bincode::config::{BigEndian, DefaultOptions, Options as _, WithOtherEndian}; use derive_more::{AsRef, Deref}; use lazy_static::lazy_static; use log::*; -use rlp::{Decodable, Encodable}; +use rlp::{Decodable as DecodableOld, Encodable as EncodableOld}; use rocksdb::{ backup::{BackupEngine, BackupEngineOptions, RestoreOptions}, db::{DBInner, DBWithThreadModeInner}, @@ -32,6 +32,7 @@ use triedb::{ gc::{DatabaseTrieMut, DbCounter, TrieCollection}, rocksdb::{RocksDatabaseHandleGC, RocksHandle}, FixedSecureTrieMut, + rlp::{Encodable, Decodable}, }; pub mod inspectors; @@ -371,7 +372,7 @@ impl Storage { } } - pub fn typed_for, V: Encodable + Decodable>( + pub fn typed_for, V: Encodable + for<'r> Decodable<'r>>( &self, root: H256, ) -> FixedSecureTrieMut>, K, V> { @@ -633,7 +634,7 @@ impl Storage { static SECONDARY_MODE_PATH_SUFFIX: &str = "velas-secondary"; fn account_extractor(data: &[u8]) -> Vec { - if let Ok(account) = rlp::decode::(data) { + if let Ok(account) = triedb::rlp::decode::(data) { vec![account.storage_root] } else { vec![] // this trie is mixed collection, and can contain storage values among with accounts @@ -730,7 +731,7 @@ impl std::fmt::Debug for DbWithClose { } pub trait SubStorage { const COLUMN_NAME: &'static str; - type Key: Encodable + Decodable; + type Key: EncodableOld + DecodableOld; type Value: Serialize + DeserializeOwned; } diff --git a/evm-utils/evm-state/src/storage/walker.rs b/evm-utils/evm-state/src/storage/walker.rs index 90887e1b94..2f01ba2024 100644 --- a/evm-utils/evm-state/src/storage/walker.rs +++ b/evm-utils/evm-state/src/storage/walker.rs @@ -1,7 +1,6 @@ use std::{borrow::Borrow, sync::Arc}; use primitive_types::H256; -use rlp::Rlp; use triedb::merkle::{MerkleNode, MerkleValue, Leaf, Extension, Branch}; use anyhow::{anyhow, Result}; @@ -58,9 +57,7 @@ where .ok_or_else(|| anyhow!("hash {:?} not found in database", hash))?; trace!("raw bytes: {:?}", bytes); - let rlp = Rlp::new(bytes.as_slice()); - trace!("rlp: {:?}", rlp); - let node = MerkleNode::decode(&rlp)?; + let node = triedb::rlp::decode(&bytes)?; debug!("node: {:?}", node); self.process_node(nibble, &node)?; diff --git a/evm-utils/evm-state/src/transactions.rs b/evm-utils/evm-state/src/transactions.rs index 8158777a8a..0e22a307d7 100644 --- a/evm-utils/evm-state/src/transactions.rs +++ b/evm-utils/evm-state/src/transactions.rs @@ -1,10 +1,12 @@ use borsh::{BorshDeserialize, BorshSchema, BorshSerialize}; +use bytes::BufMut; use evm::{backend::Log, ExitReason, ExitRevert}; use primitive_types::{H160, H256, U256}; -use rlp::{Decodable, DecoderError, Encodable, Rlp, RlpStream}; +use rlp::{Decodable as DecodableOld, DecoderError, Encodable as EncodableOld, Rlp, RlpStream}; use serde::{Deserialize, Serialize}; use sha3::{Digest, Keccak256}; use std::str::FromStr; +use triedb::rlp::{Encodable, Decodable}; use crate::error::*; use secp256k1::{ @@ -137,7 +139,8 @@ pub struct UnsignedTransaction { } impl UnsignedTransaction { - fn signing_rlp_append(&self, s: &mut RlpStream, chain_id: Option) { + #[cfg(test)] + fn signing_rlp_append_old(&self, s: &mut RlpStream, chain_id: Option) { s.begin_list(if chain_id.is_some() { 9 } else { 6 }); s.append(&self.nonce); s.append(&self.gas_price); @@ -152,13 +155,21 @@ impl UnsignedTransaction { s.append(&0u8); } } - - pub fn signing_hash(&self, chain_id: Option) -> H256 { + fn signing_rlp_append(&self, chain_id: Option) { + unimplemented!(); + } + + #[cfg(test)] + pub fn signing_hash_old(&self, chain_id: Option) -> H256 { let mut stream = RlpStream::new(); - self.signing_rlp_append(&mut stream, chain_id); + self.signing_rlp_append_old(&mut stream, chain_id); H256::from_slice(Keccak256::digest(stream.as_raw()).as_slice()) } + pub fn signing_hash(&self, chain_id: Option) -> H256 { + unimplemented!(); + } + pub fn sign(self, key: &SecretKey, chain_id: Option) -> Transaction { let hash = self.signing_hash(chain_id); // hash is always MESSAGE_SIZE bytes. @@ -296,7 +307,7 @@ impl TransactionSignature { } } -impl Encodable for TransactionAction { +impl EncodableOld for TransactionAction { fn rlp_append(&self, s: &mut RlpStream) { match self { TransactionAction::Call(address) => { @@ -309,7 +320,7 @@ impl Encodable for TransactionAction { } } -impl Decodable for TransactionAction { +impl DecodableOld for TransactionAction { fn decode(rlp: &Rlp<'_>) -> Result { Ok(if rlp.is_empty() { if rlp.is_data() { @@ -323,7 +334,7 @@ impl Decodable for TransactionAction { } } -impl Encodable for Transaction { +impl EncodableOld for Transaction { fn rlp_append(&self, s: &mut RlpStream) { s.begin_list(9); s.append(&self.nonce); @@ -338,7 +349,7 @@ impl Encodable for Transaction { } } -impl Decodable for Transaction { +impl DecodableOld for Transaction { fn decode(rlp: &Rlp<'_>) -> Result { Ok(Self { nonce: rlp.val_at(0)?, @@ -356,7 +367,7 @@ impl Decodable for Transaction { } } -impl Encodable for UnsignedTransaction { +impl EncodableOld for UnsignedTransaction { fn rlp_append(&self, s: &mut RlpStream) { s.begin_list(6); s.append(&self.nonce); @@ -368,7 +379,7 @@ impl Encodable for UnsignedTransaction { } } -impl Decodable for UnsignedTransaction { +impl DecodableOld for UnsignedTransaction { fn decode(rlp: &Rlp<'_>) -> Result { Ok(Self { nonce: rlp.val_at(0)?, @@ -410,6 +421,22 @@ impl TransactionInReceipt { } impl Encodable for TransactionInReceipt { + + fn encode(&self,out: &mut dyn BufMut) { + unimplemented!(); + } + fn length(&self) -> usize { + unimplemented!(); + + } +} + +impl<'de> Decodable<'de> for TransactionInReceipt { + fn decode(buf: &mut &'de [u8]) -> Result { + unimplemented!(); + } +} +impl EncodableOld for TransactionInReceipt { fn rlp_append(&self, s: &mut RlpStream) { match self { TransactionInReceipt::Signed(tx) => { @@ -434,7 +461,7 @@ impl From for TransactionInReceipt { } } -impl Decodable for TransactionInReceipt { +impl DecodableOld for TransactionInReceipt { fn decode(rlp: &Rlp<'_>) -> Result { let items = rlp.item_count()?; Ok(match items { @@ -463,7 +490,7 @@ pub struct UnsignedTransactionWithCaller { pub signed_compatible: bool, } -impl Encodable for UnsignedTransactionWithCaller { +impl EncodableOld for UnsignedTransactionWithCaller { fn rlp_append(&self, s: &mut RlpStream) { let chain_id = self.chain_id; if self.signed_compatible { @@ -646,9 +673,9 @@ mod test { let chain_id = 0x77; let mut stream = RlpStream::new(); - tx.signing_rlp_append(&mut stream, Some(chain_id)); + tx.signing_rlp_append_old(&mut stream, Some(chain_id)); println!("rlp = {}", hex::encode(stream.out())); - println!("hash = {:x}", tx.signing_hash(Some(chain_id))); + println!("hash = {:x}", tx.signing_hash_old(Some(chain_id))); let tx = tx.sign(&secret_key, Some(chain_id)); assert_eq!(tx.signature.chain_id(), Some(chain_id)); diff --git a/evm-utils/evm-state/src/types.rs b/evm-utils/evm-state/src/types.rs index 662dc54701..66b752e058 100644 --- a/evm-utils/evm-state/src/types.rs +++ b/evm-utils/evm-state/src/types.rs @@ -1,11 +1,13 @@ +use bytes::{BufMut, Buf}; use derive_more::{AsRef, From, Into}; use itertools::Itertools; -use rlp::{Decodable, DecoderError, Encodable, Rlp, RlpStream}; +use rlp::{Decodable as DecodableOld, DecoderError as OldDecoderError, Encodable as EncodableOld, Rlp, RlpStream}; use serde::{Deserialize, Serialize}; use sha3::{Digest, Keccak256}; use triedb::empty_trie_hash; +use triedb::rlp::{Encodable, Decodable}; use crate::TransactionReceipt; use auto_enums::auto_enum; @@ -93,7 +95,7 @@ impl AccountState { } } -impl Encodable for AccountState { +impl EncodableOld for AccountState { fn rlp_append(&self, s: &mut RlpStream) { s.begin_list(3) .append(&self.nonce) @@ -102,8 +104,8 @@ impl Encodable for AccountState { } } -impl Decodable for AccountState { - fn decode(rlp: &Rlp) -> Result { +impl DecodableOld for AccountState { + fn decode(rlp: &Rlp) -> Result { Ok(Self { nonce: rlp.val_at(0)?, balance: rlp.val_at(1)?, @@ -133,15 +135,15 @@ impl Code { } } -impl Encodable for Code { +impl EncodableOld for Code { fn rlp_append(&self, s: &mut RlpStream) { self.0.rlp_append(s) } } -impl Decodable for Code { - fn decode(rlp: &Rlp) -> Result { - <_>::decode(rlp).map(Self) +impl DecodableOld for Code { + fn decode(rlp: &Rlp) -> Result { + as rlp::Decodable>::decode(rlp).map(Self) } } @@ -154,6 +156,7 @@ pub struct Account { pub code_hash: H256, } + impl Account { pub fn is_empty(&self) -> bool { self.nonce == U256::zero() @@ -174,7 +177,8 @@ impl Default for Account { } } -impl Encodable for Account { +#[cfg(test)] +impl EncodableOld for Account { fn rlp_append(&self, s: &mut RlpStream) { s.begin_list(4) .append(&self.nonce) @@ -183,9 +187,61 @@ impl Encodable for Account { .append(&self.code_hash); } } +impl Encodable for Account { + fn encode(&self,out: &mut dyn BufMut) { + + let len = self.nonce.length() + self.balance.length() + self.storage_root.length() + self.code_hash.length(); + fastrlp::Header { + list: true, + payload_length: len, + }.encode(out); + self.nonce.encode(out); + self.balance.encode(out); + self.storage_root.encode(out); + self.code_hash.encode(out); + } + + fn length(&self) -> usize { + + let len = self.nonce.length() + self.balance.length() + self.storage_root.length() + self.code_hash.length(); + fastrlp::Header { + list: true, + payload_length: len, + } + .length() + + len + + } +} -impl Decodable for Account { - fn decode(rlp: &Rlp) -> Result { + +impl<'de> Decodable<'de> for Account { + fn decode(buf: &mut &'de [u8]) -> Result { + let h = fastrlp::Header::decode(buf)?; + if !h.list { + return Err(fastrlp::DecodeError::UnexpectedString); + } + let payload_view = &mut &buf[..h.payload_length]; + let cnt = fastrlp::count(*payload_view)?; + if cnt!= 4 { + return Err(fastrlp::DecodeError::ListLengthMismatch { expected: 4, got: cnt }); + } + + let nonce = fastrlp::Decodable::decode(payload_view)?; + let balance = fastrlp::Decodable::decode(payload_view)?; + let storage_root= fastrlp::Decodable::decode(payload_view)?; + let code_hash = fastrlp::Decodable::decode(payload_view)?; + buf.advance(h.payload_length); + Ok(Self { + nonce, balance, storage_root, code_hash, + }) + } +} + + +#[cfg(test)] +impl DecodableOld for Account { + fn decode(rlp: &Rlp) -> Result { Ok(Self { nonce: rlp.val_at(0)?, balance: rlp.val_at(1)?, @@ -453,7 +509,7 @@ pub struct Block { pub transactions: Vec<(crate::H256, TransactionReceipt)>, } -impl Encodable for BlockHeader { +impl EncodableOld for BlockHeader { fn rlp_append(&self, s: &mut RlpStream) { match self.version { BlockVersion::InitVersion => self.rlp_append_legacy(s), @@ -477,15 +533,19 @@ impl From> for Option { } } -mod transaction_roots { +pub(super) mod transaction_roots { use crate::{Log, TransactionReceipt, H256, U256}; + use bytes::{BufMut, Buf}; use ethbloom::Bloom; - use rlp::{Decodable, DecoderError, Encodable, Rlp, RlpStream}; + #[cfg(test)] + use rlp::{Decodable as DecodableOld, DecoderError as OldDecoderError, Encodable as EncodableOld, Rlp, RlpStream}; use triedb::gc::{MapWithCounterCached, TrieCollection}; use triedb::FixedTrieMut; + use triedb::rlp::{Encodable, Decodable}; + - #[derive(Clone, Debug)] + #[derive(Clone, Debug, PartialEq,)] pub struct EthereumReceipt { pub gas_used: U256, pub log_bloom: Bloom, @@ -504,7 +564,59 @@ mod transaction_roots { } } + impl Encodable for EthereumReceipt { + fn encode(&self,out: &mut dyn BufMut) { + let len = self.status.length() + self.gas_used.length() + self.log_bloom.length() + self.logs.length(); + fastrlp::Header { + list: true, + payload_length: len, + }.encode(out); + self.status.encode(out); + self.gas_used.encode(out); + self.log_bloom.encode(out); + self.logs.encode(out); + } + + fn length(&self) -> usize { + let len = self.status.length() + self.gas_used.length() + self.log_bloom.length() + self.logs.length(); + fastrlp::Header { + list: true, + payload_length: len, + } + .length() + + len + + } + } + + + + impl<'de> Decodable<'de> for EthereumReceipt { + fn decode(buf: &mut &'de [u8]) -> Result { + let h = fastrlp::Header::decode(buf)?; + if !h.list { + return Err(fastrlp::DecodeError::UnexpectedString); + } + let payload_view = &mut &buf[..h.payload_length]; + let cnt = fastrlp::count(*payload_view)?; + if cnt!= 4 { + return Err(fastrlp::DecodeError::ListLengthMismatch { expected: 4, got: cnt }); + } + + let status = fastrlp::Decodable::decode(payload_view)?; + let gas_used = fastrlp::Decodable::decode(payload_view)?; + let log_bloom= fastrlp::Decodable::decode(payload_view)?; + let logs = fastrlp::Decodable::decode(payload_view)?; + buf.advance(h.payload_length); + Ok(Self { + status, gas_used, log_bloom, logs, + }) + } + } + + #[cfg(test)] + impl EncodableOld for EthereumReceipt { fn rlp_append(&self, s: &mut RlpStream) { s.begin_list(4); s.append(&self.status); @@ -514,8 +626,9 @@ mod transaction_roots { } } - impl Decodable for EthereumReceipt { - fn decode(rlp: &Rlp<'_>) -> Result { + #[cfg(test)] + impl DecodableOld for EthereumReceipt { + fn decode(rlp: &Rlp<'_>) -> Result { Ok(EthereumReceipt { gas_used: rlp.val_at(1)?, log_bloom: rlp.val_at(2)?, @@ -637,7 +750,7 @@ mod tests { pub nonce: H64, } - impl Encodable for Header { + impl EncodableOld for Header { fn rlp_append(&self, s: &mut RlpStream) { s.begin_list(15); s.append(&self.parent_hash); @@ -658,8 +771,8 @@ mod tests { } } - impl Decodable for Header { - fn decode(rlp: &Rlp) -> Result { + impl DecodableOld for Header { + fn decode(rlp: &Rlp) -> Result { Ok(Self { parent_hash: rlp.val_at(0)?, ommers_hash: rlp.val_at(1)?, diff --git a/ledger-tool/Cargo.toml b/ledger-tool/Cargo.toml index 9cfc137e92..cf5691cd48 100644 --- a/ledger-tool/Cargo.toml +++ b/ledger-tool/Cargo.toml @@ -41,7 +41,7 @@ tokio = { version = "1.14.1", features = ["full"] } evm-state = { path = "../evm-utils/evm-state" } evm-rpc = { path = "../evm-utils/evm-rpc" } solana-evm-loader-program = { path = "../evm-utils/programs/evm_loader" } -triedb = { git = "https://github.com/velas/triedb", tag = "optimal_children", features = ["rocksdb"] } +triedb = { git = "https://github.com/velas/triedb", tag = "fast_rlp", features = ["rocksdb"] } rlp = "0.5.0" anyhow = "1.0.43" rayon = "1.5.0" From d6313a709e5e9ad1bc375c8d8ec977e031c2181e Mon Sep 17 00:00:00 2001 From: Maksim Vykhota Date: Tue, 25 Apr 2023 20:04:15 +0300 Subject: [PATCH 02/11] Feature: add `geth` dump parsing (#417) * Feature: add `geth` dump parsing * Fix: use raw `DatabaseTrieMut` * Chore: inline `flush_changes`, `set_account_state`, `ext_storage` into `set_initial` * Refactoring: extract state generation from `EvmBackend` into `Storage` * Refactor: renaming * Fix: few various panics * Feature: add optional `state_root` verification * Feature: dynamically determine importing accounts chunk size * Fix: properly calculate heap size, open evm_state after import * Fix: accounts counter (pointer), better naming, fmt * Fix: flushing storage by chunks * Fix: tests * Docs: add notes about deleting files * Fix: correctly handle state_root * Feature: extract evm dump functionality into separate trait * Fix: move tests to separate module * Fix: add `#[cfg(test)]` attributes to test modules * Fix: better public API * Fix: clippy * Feature: add tests for `GethAccountExtractor` * Fix: add sample dump * Adjust CLI * Fix: reduce code duplication * Fix: unwrap one time used functions * Fix: split account batching and storage writing procedures. * Fix: add missing `state_root` assert --- evm-utils/evm-state/src/lib.rs | 6 +- evm-utils/evm-state/src/state.rs | 11 + evm-utils/evm-state/src/storage/mod.rs | 109 ++- genesis/src/main.rs | 68 +- ledger-tool/src/main.rs | 3 +- ledger/src/blockstore.rs | 27 +- ledger/src/blockstore_processor.rs | 42 +- sdk/src/genesis_config.rs | 1037 +++++++++++++++--------- sdk/tests/geth-dump.txt | 204 +++++ test-validator/src/lib.rs | 3 +- 10 files changed, 1073 insertions(+), 437 deletions(-) create mode 100644 sdk/tests/geth-dump.txt diff --git a/evm-utils/evm-state/src/lib.rs b/evm-utils/evm-state/src/lib.rs index 65d4e6658f..b078b77bf9 100644 --- a/evm-utils/evm-state/src/lib.rs +++ b/evm-utils/evm-state/src/lib.rs @@ -25,9 +25,11 @@ pub use { context::{ChainContext, EvmConfig}, state::{ AccountProvider, ChangedState, Committed, EvmBackend, EvmPersistState, EvmState, Incomming, - BURN_GAS_PRICE, DEFAULT_GAS_LIMIT, MAX_IN_MEMORY_EVM_ACCOUNTS, + BURN_GAS_PRICE, DEFAULT_GAS_LIMIT, MAX_IN_HEAP_EVM_ACCOUNTS_BYTES, + MAX_IN_MEMORY_EVM_ACCOUNTS, }, - storage::Storage, storage::StorageSecondary + storage::Storage, + storage::StorageSecondary, }; pub use executor::{ diff --git a/evm-utils/evm-state/src/state.rs b/evm-utils/evm-state/src/state.rs index 3860f09521..99076fc0d2 100644 --- a/evm-utils/evm-state/src/state.rs +++ b/evm-utils/evm-state/src/state.rs @@ -24,6 +24,8 @@ pub const DEFAULT_GAS_LIMIT: u64 = 300_000_000; pub const BURN_GAS_PRICE: u64 = 2_000_000_000; // 2 lamports per gas. /// Dont load to many account to memory, to avoid OOM. pub const MAX_IN_MEMORY_EVM_ACCOUNTS: usize = 10000; +/// Approximate size, real size could be twice as much +pub const MAX_IN_HEAP_EVM_ACCOUNTS_BYTES: usize = 100_000_000; pub type ChangedState = HashMap, HashMap)>; @@ -66,6 +68,13 @@ pub struct Incomming { } impl Incomming { + pub fn genesis_from_state(state_root: H256) -> Self { + Self { + state_root, + ..Default::default() + } + } + fn new( block_number: BlockNum, state_root: H256, @@ -542,6 +551,7 @@ impl Default for EvmPersistState { } impl EvmState { + /// Clears content of `path` directory and creates new empty `EvmState` pub fn new>(path: P) -> Result { let evm_state = path.as_ref(); if evm_state.is_dir() && evm_state.exists() { @@ -553,6 +563,7 @@ impl EvmState { Self::load_from(evm_state, Incomming::default(), true) } + /// Clears content of `evm_state` directory and creates new `EvmState` from genesis pub fn new_from_genesis( evm_state: impl AsRef, evm_genesis: impl AsRef, diff --git a/evm-utils/evm-state/src/storage/mod.rs b/evm-utils/evm-state/src/storage/mod.rs index 7375e63ea2..b44a80f723 100644 --- a/evm-utils/evm-state/src/storage/mod.rs +++ b/evm-utils/evm-state/src/storage/mod.rs @@ -1,7 +1,7 @@ use std::{ array::TryFromSliceError, borrow::Borrow, - collections::BTreeSet, + collections::{BTreeSet, HashMap}, convert::TryInto, fs, io::Error as IoError, @@ -11,6 +11,7 @@ use std::{ use bincode::config::{BigEndian, DefaultOptions, Options as _, WithOtherEndian}; use derive_more::{AsRef, Deref}; +use itertools::Itertools; use lazy_static::lazy_static; use log::*; use rlp::{Decodable as DecodableOld, Encodable as EncodableOld}; @@ -44,6 +45,7 @@ pub use rocksdb; // avoid mess with dependencies for another crates type DB = OptimisticTransactionDB; type BincodeOpts = WithOtherEndian; +type ChangedState = HashMap, HashMap)>; lazy_static! { static ref CODER: BincodeOpts = DefaultOptions::new().with_big_endian(); } @@ -65,6 +67,7 @@ pub enum Error { const BACKUP_SUBDIR: &str = "backup"; const CUSTOM_LOCATION: &str = "tmp_inner_space"; +const NUM_ENTRIES_IN_STORAGES_CHUNK: usize = 10000; /// Marker-like wrapper for cleaning temporary directory. /// Temporary directory is only used in tests. @@ -194,7 +197,6 @@ impl Descriptors { } } - impl Storage where D: DBInner, @@ -257,7 +259,6 @@ type ReadOnlyDb = rocksdb::DBWithThreadMode; pub type StorageSecondary = Storage; impl StorageSecondary { - pub fn open_secondary_persistent>(path: P, gc_enabled: bool) -> Result { Self::open(Location::Persisent(path.as_ref().to_owned()), gc_enabled) } @@ -305,9 +306,11 @@ impl Storage { pub fn create_temporary() -> Result { Self::open(Location::Temporary(Arc::new(TempDir::new()?)), false) } + pub fn create_temporary_gc() -> Result { Self::open(Location::Temporary(Arc::new(TempDir::new()?)), true) } + fn open(location: Location, gc_enabled: bool) -> Result { log::warn!("gc_enabled {}", gc_enabled); log::info!("location is {:?}", location); @@ -381,6 +384,7 @@ impl Storage { FixedSecureTrieMut::new(DatabaseTrieMut::trie_for(handle, root)) } + // FIXME: flush_changes_hashed code duplication pub fn flush_changes(&self, state_root: H256, state_updates: crate::ChangedState) -> H256 { let r = self.rocksdb_trie_handle(); @@ -439,6 +443,65 @@ impl Storage { .leak_root() } + // FIXME: flush_changes code duplication + pub fn flush_changes_hashed(&self, state_root: H256, state_updates: ChangedState) -> H256 { + let r = self.rocksdb_trie_handle(); + + let db_trie = TrieCollection::new(r); + + use triedb::TrieMut; + let mut accounts = db_trie.trie_for(state_root); + + for (address, (state, storages)) in state_updates { + if let Maybe::Just(AccountState { + nonce, + balance, + code, + }) = state + { + let mut account: Account = accounts + .get(address.as_bytes()) + .and_then(|accounts| rlp::decode(&accounts).ok()) + .unwrap_or_default(); + + account.nonce = nonce; + account.balance = balance; + + if !code.is_empty() { + let code_hash = code.hash(); + self.set::(code_hash, code); + account.code_hash = code_hash; + } + + let storage_values = storages.into_iter().chunks(NUM_ENTRIES_IN_STORAGES_CHUNK); + for index_changes in storage_values.into_iter() { + let mut storage = db_trie.trie_for(account.storage_root); + for (index, value) in index_changes { + if value != H256::default() { + let value = U256::from_big_endian(&value[..]); + storage.insert(index.as_bytes(), &rlp::encode(&value)); + } else { + storage.delete(index.as_bytes()); + } + } + + let storage_patch = storage.into_patch(); + account.storage_root = db_trie + .apply_increase(storage_patch, |_| vec![]) + .leak_root() + } + accounts.insert(address.as_bytes(), &rlp::encode(&account)); + } else { + accounts.delete(address.as_bytes()); + } + } + + let accounts_patch = accounts.into_patch(); + db_trie + .apply_increase(accounts_patch, account_extractor) + .leak_root() + } + pub fn merge_from_db(&self, other_db: &Self) -> Result<()> { assert!(!self.gc_enabled, "Cannot merge to db with rc counters"); assert!( @@ -612,8 +675,7 @@ impl Storage { if !self.gc_enabled { return (vec![], vec![]); } - self - .rocksdb_trie_handle() + self.rocksdb_trie_handle() .gc_cleanup_layer(removes, account_extractor) } @@ -629,6 +691,43 @@ impl Storage { engine.create_new_backup_flush(self.db.as_ref(), true)?; Ok(backup_dir) } + + pub fn set_initial( + &mut self, + accounts: impl IntoIterator, + state_root: H256, + ) -> H256 { + let mut state_updates: ChangedState = HashMap::new(); + + for ( + address, + evm::backend::MemoryAccount { + nonce, + balance, + storage, + code, + }, + ) in accounts + { + let account_state = AccountState { + nonce, + balance, + code: code.into(), + }; + + state_updates + .entry(address) + .or_insert((Maybe::Nothing, HashMap::new())) + .0 = Maybe::Just(account_state); + + state_updates + .entry(address) + .or_insert_with(|| (Maybe::Just(AccountState::default()), HashMap::new())) + .1.extend(storage); + } + + self.flush_changes_hashed(state_root, state_updates) + } } static SECONDARY_MODE_PATH_SUFFIX: &str = "velas-secondary"; diff --git a/genesis/src/main.rs b/genesis/src/main.rs index 372598c586..e3e3e27faa 100644 --- a/genesis/src/main.rs +++ b/genesis/src/main.rs @@ -1,6 +1,8 @@ //! A command-line executable for generating the chain's genesis config. #![allow(clippy::integer_arithmetic)] +use solana_ledger::blockstore::EvmStateJson; + use { clap::{crate_description, crate_name, value_t, value_t_or_exit, App, Arg, ArgMatches}, evm_state::U256, @@ -22,7 +24,10 @@ use { clock, epoch_schedule::EpochSchedule, fee_calculator::FeeRateGovernor, - genesis_config::{self, ClusterType, GenesisConfig}, + genesis_config::{ + self, evm_genesis::{OpenEthereumAccountExtractor, GethAccountExtractor}, ClusterType, + GenesisConfig, + }, inflation::Inflation, native_token::sol_to_lamports, poh_config::PohConfig, @@ -397,6 +402,11 @@ fn main() -> Result<(), Box> { .long("evm-state-file") .takes_value(true) .help("Path to EVM state json file, can be retrived from `parity export state` command."), + ).arg( + Arg::with_name("evm-state-format") + .long("evm-state-format") + .takes_value(true) + .help("EVM state json file format [`open-ethereum` or `geth`]") ).arg( Arg::with_name("evm-chain-id") .required(false) @@ -558,7 +568,22 @@ fn main() -> Result<(), Box> { } } - let evm_state_json = matches.value_of("evm-state-file").map(PathBuf::from); + let evm_state_file = matches.value_of("evm-state-file"); + let evm_state_format = matches.value_of("evm-state-format"); + let evm_state_json = match (evm_state_file, evm_state_format) { + (Some(path), Some(format)) if format == "geth" => { + EvmStateJson::Geth(std::path::Path::new(path)) + }, + (Some(path), Some(format)) if format == "open-ethereum" => { + EvmStateJson::OpenEthereum(std::path::Path::new(path)) + }, + (None, _) => { + EvmStateJson::None + }, + _ => { + panic!("`evm-state-format` argument value must be `open-ethereum` or `geth`") + } + }; if let Ok(raw_inflation) = value_t!(matches, "inflation", String) { let inflation = match raw_inflation.as_str() { @@ -643,11 +668,38 @@ fn main() -> Result<(), Box> { let mut evm_state_balance = U256::zero(); - if let Some(evm_state_json) = &evm_state_json { - info!("Calculating evm state lamports"); - for account in genesis_config::evm_genesis::read_accounts(evm_state_json).unwrap() { - evm_state_balance += account.unwrap().1.balance; - } + match evm_state_json { + EvmStateJson::OpenEthereum(path) => { + info!("Calculating evm state lamports"); + let dump_extractor = OpenEthereumAccountExtractor::open_dump(path) + .unwrap_or_else(|_| { + panic!( + "Unable to open dump at path: `{}`", + path.display() + ) + }); + + for pair in dump_extractor { + evm_state_balance += pair.unwrap().account.balance; + } + }, + EvmStateJson::Geth(path) => { + info!("Calculating evm state lamports"); + let dump_extractor = GethAccountExtractor::open_dump(path) + .unwrap_or_else(|_| { + panic!( + "Unable to open dump at path: `{}`", + path.display() + ) + }); + + for pair in dump_extractor { + evm_state_balance += pair.unwrap().account.balance; + } + }, + EvmStateJson::None => { + info!("No evm state file provided"); + }, } let (mut evm_state_lamports, change) = @@ -715,7 +767,7 @@ fn main() -> Result<(), Box> { create_new_ledger( &ledger_path, - evm_state_json.as_ref().map(AsRef::as_ref), + evm_state_json, &genesis_config, max_genesis_archive_unpacked_size, AccessType::PrimaryOnly, diff --git a/ledger-tool/src/main.rs b/ledger-tool/src/main.rs index ac08eac7bf..dbdbf9412b 100644 --- a/ledger-tool/src/main.rs +++ b/ledger-tool/src/main.rs @@ -87,6 +87,7 @@ use ledger_path::*; mod evm_blockstore; use evm_blockstore::*; +use solana_ledger::blockstore::EvmStateJson; mod evm_state; use crate::evm_state::*; @@ -1746,7 +1747,7 @@ fn main() { create_new_ledger( &output_directory, - None, + EvmStateJson::None, &genesis_config, solana_runtime::hardened_unpack::MAX_GENESIS_ARCHIVE_UNPACKED_SIZE, AccessType::PrimaryOnly, diff --git a/ledger/src/blockstore.rs b/ledger/src/blockstore.rs index 8a38ff2363..e31df4f100 100644 --- a/ledger/src/blockstore.rs +++ b/ledger/src/blockstore.rs @@ -32,7 +32,9 @@ use { solana_runtime::hardened_unpack::{unpack_genesis_archive, MAX_GENESIS_ARCHIVE_UNPACKED_SIZE}, solana_sdk::{ clock::{Slot, UnixTimestamp, DEFAULT_TICKS_PER_SECOND, MS_PER_TICK}, - genesis_config::{GenesisConfig, DEFAULT_GENESIS_ARCHIVE, DEFAULT_GENESIS_FILE}, + genesis_config::{GenesisConfig, DEFAULT_GENESIS_ARCHIVE, DEFAULT_GENESIS_FILE, + evm_genesis::{OpenEthereumAccountExtractor, GethAccountExtractor} + }, hash::Hash, pubkey::Pubkey, sanitize::Sanitize, @@ -70,6 +72,7 @@ use { thiserror::Error, trees::{Tree, TreeWalk}, }; + pub use crate::blockstore_db::BlockstoreError; pub mod blockstore_purge; @@ -4042,19 +4045,35 @@ fn slot_has_updates(slot_meta: &SlotMeta, slot_meta_backup: &Option) - (slot_meta_backup.is_some() && slot_meta_backup.as_ref().unwrap().consumed != slot_meta.consumed)) } +pub enum EvmStateJson<'a> { + OpenEthereum(&'a Path), + Geth(&'a Path), + None +} + // Creates a new ledger with slot 0 full of ticks (and only ticks). // // Returns the blockhash that can be used to append entries with. pub fn create_new_ledger( ledger_path: &Path, - evm_state_json: Option<&Path>, + evm_state_json: EvmStateJson, genesis_config: &GenesisConfig, max_genesis_archive_unpacked_size: u64, access_type: AccessType, ) -> Result { Blockstore::destroy(ledger_path)?; - genesis_config.generate_evm_state(ledger_path, evm_state_json)?; + match evm_state_json { + EvmStateJson::OpenEthereum(path) => { + let extractor = OpenEthereumAccountExtractor::open_dump(path).unwrap(); + genesis_config.generate_evm_state_from_dump(ledger_path, extractor)?; + }, + EvmStateJson::Geth(path) => { + let extractor = GethAccountExtractor::open_dump(path).unwrap(); + genesis_config.generate_evm_state_from_dump(ledger_path, extractor)?; + }, + EvmStateJson::None => genesis_config.generate_evm_state_empty(ledger_path)?, + } genesis_config.write(ledger_path)?; // Fill slot 0 with ticks that link back to the genesis_config to bootstrap the ledger. @@ -4294,7 +4313,7 @@ pub fn create_new_ledger_from_name_auto_delete( solana_sdk::genesis_config::evm_genesis::generate_evm_state_json(&evm_state_json).unwrap(); let blockhash = create_new_ledger( ledger_path.path(), - Some(evm_state_json.as_ref()), + EvmStateJson::OpenEthereum(evm_state_json.as_ref()), genesis_config, MAX_GENESIS_ARCHIVE_UNPACKED_SIZE, access_type, diff --git a/ledger/src/blockstore_processor.rs b/ledger/src/blockstore_processor.rs index c36ba65c29..5a949dc0fe 100644 --- a/ledger/src/blockstore_processor.rs +++ b/ledger/src/blockstore_processor.rs @@ -1778,7 +1778,7 @@ pub mod tests { .path() .join(solana_sdk::genesis_config::EVM_GENESIS); genesis_config - .generate_evm_state(&ledger_path.path(), None) + .generate_evm_state_empty(&ledger_path.path()) .unwrap(); let (bank_forks, ..) = test_process_blockstore( @@ -1829,7 +1829,7 @@ pub mod tests { .path() .join(solana_sdk::genesis_config::EVM_GENESIS); genesis_config - .generate_evm_state(&ledger_path.path(), None) + .generate_evm_state_empty(&ledger_path.path()) .unwrap(); // Should return slot 0, the last slot on the fork that is valid @@ -1854,7 +1854,7 @@ pub mod tests { .path() .join(solana_sdk::genesis_config::EVM_GENESIS); genesis_config - .generate_evm_state(&ledger_path.path(), None) + .generate_evm_state_empty(&ledger_path.path()) .unwrap(); let (bank_forks, ..) = test_process_blockstore( @@ -1920,7 +1920,7 @@ pub mod tests { .path() .join(solana_sdk::genesis_config::EVM_GENESIS); genesis_config - .generate_evm_state(&ledger_path.path(), None) + .generate_evm_state_empty(&ledger_path.path()) .unwrap(); let opts = ProcessOptions { @@ -2005,7 +2005,7 @@ pub mod tests { .path() .join(solana_sdk::genesis_config::EVM_GENESIS); genesis_config - .generate_evm_state(&ledger_path.path(), None) + .generate_evm_state_empty(&ledger_path.path()) .unwrap(); let (bank_forks, ..) = test_process_blockstore( &genesis_config, @@ -2037,7 +2037,7 @@ pub mod tests { .path() .join(solana_sdk::genesis_config::EVM_GENESIS); genesis_config - .generate_evm_state(&ledger_path.path(), None) + .generate_evm_state_empty(&ledger_path.path()) .unwrap(); let (bank_forks, ..) = test_process_blockstore( &genesis_config, @@ -2117,7 +2117,7 @@ pub mod tests { .path() .join(solana_sdk::genesis_config::EVM_GENESIS); genesis_config - .generate_evm_state(&ledger_path.path(), None) + .generate_evm_state_empty(&ledger_path.path()) .unwrap(); let (bank_forks, ..) = test_process_blockstore( @@ -2210,7 +2210,7 @@ pub mod tests { .path() .join(solana_sdk::genesis_config::EVM_GENESIS); genesis_config - .generate_evm_state(&ledger_path.path(), None) + .generate_evm_state_empty(&ledger_path.path()) .unwrap(); let (bank_forks, ..) = test_process_blockstore( @@ -2279,7 +2279,7 @@ pub mod tests { .path() .join(solana_sdk::genesis_config::EVM_GENESIS); genesis_config - .generate_evm_state(&ledger_path.path(), None) + .generate_evm_state_empty(&ledger_path.path()) .unwrap(); let (bank_forks, ..) = test_process_blockstore( @@ -2336,7 +2336,7 @@ pub mod tests { .path() .join(solana_sdk::genesis_config::EVM_GENESIS); genesis_config - .generate_evm_state(&ledger_path.path(), None) + .generate_evm_state_empty(&ledger_path.path()) .unwrap(); let (bank_forks, ..) = test_process_blockstore( @@ -2397,7 +2397,7 @@ pub mod tests { .path() .join(solana_sdk::genesis_config::EVM_GENESIS); genesis_config - .generate_evm_state(&ledger_path.path(), None) + .generate_evm_state_empty(&ledger_path.path()) .unwrap(); let (bank_forks, ..) = test_process_blockstore( &genesis_config, @@ -2461,7 +2461,7 @@ pub mod tests { .path() .join(solana_sdk::genesis_config::EVM_GENESIS); genesis_config - .generate_evm_state(&ledger_path.path(), None) + .generate_evm_state_empty(&ledger_path.path()) .unwrap(); let (bank_forks, ..) = test_process_blockstore( @@ -2619,7 +2619,7 @@ pub mod tests { .path() .join(solana_sdk::genesis_config::EVM_GENESIS); genesis_config - .generate_evm_state(&ledger_path.path(), None) + .generate_evm_state_empty(&ledger_path.path()) .unwrap(); let (bank_forks, ..) = test_process_blockstore( @@ -2663,7 +2663,7 @@ pub mod tests { .path() .join(solana_sdk::genesis_config::EVM_GENESIS); genesis_config - .generate_evm_state(&ledger_path.path(), None) + .generate_evm_state_empty(&ledger_path.path()) .unwrap(); let (bank_forks, ..) = test_process_blockstore( @@ -2696,7 +2696,7 @@ pub mod tests { .path() .join(solana_sdk::genesis_config::EVM_GENESIS); genesis_config - .generate_evm_state(&ledger_path.path(), None) + .generate_evm_state_empty(&ledger_path.path()) .unwrap(); test_process_blockstore( &genesis_config, @@ -2727,7 +2727,7 @@ pub mod tests { .path() .join(solana_sdk::genesis_config::EVM_GENESIS); genesis_config - .generate_evm_state(&ledger_path.path(), None) + .generate_evm_state_empty(&ledger_path.path()) .unwrap(); let (_bank_forks, leader_schedule, _) = test_process_blockstore( @@ -2802,7 +2802,7 @@ pub mod tests { .path() .join(solana_sdk::genesis_config::EVM_GENESIS); genesis_config - .generate_evm_state(&ledger_path.path(), None) + .generate_evm_state_empty(&ledger_path.path()) .unwrap(); test_process_blockstore( &genesis_config, @@ -3470,7 +3470,7 @@ pub mod tests { .path() .join(solana_sdk::genesis_config::EVM_GENESIS); genesis_config - .generate_evm_state(&ledger_path.path(), None) + .generate_evm_state_empty(&ledger_path.path()) .unwrap(); let (bank_forks, ..) = test_process_blockstore( @@ -4106,7 +4106,7 @@ pub mod tests { .path() .join(solana_sdk::genesis_config::EVM_GENESIS); genesis_config - .generate_evm_state(&ledger_path.path(), None) + .generate_evm_state_empty(&ledger_path.path()) .unwrap(); let (bank_forks, ..) = test_process_blockstore( @@ -4151,7 +4151,7 @@ pub mod tests { .path() .join(solana_sdk::genesis_config::EVM_GENESIS); genesis_config - .generate_evm_state(&ledger_path.path(), None) + .generate_evm_state_empty(&ledger_path.path()) .unwrap(); let (bank_forks, ..) = test_process_blockstore( @@ -4219,7 +4219,7 @@ pub mod tests { .path() .join(solana_sdk::genesis_config::EVM_GENESIS); genesis_config - .generate_evm_state(&ledger_path.path(), None) + .generate_evm_state_empty(&ledger_path.path()) .unwrap(); let (bank_forks, ..) = test_process_blockstore( diff --git a/sdk/src/genesis_config.rs b/sdk/src/genesis_config.rs index 2494233f74..0a2b805eef 100644 --- a/sdk/src/genesis_config.rs +++ b/sdk/src/genesis_config.rs @@ -19,7 +19,6 @@ use { system_program, timing::years_as_slots, }, - bincode::{deserialize, serialize}, chrono::{TimeZone, Utc}, evm_state::H256, @@ -31,6 +30,7 @@ use { fmt, fs::{File, OpenOptions}, io::Write, + mem, path::{Path, PathBuf}, str::FromStr, time::{SystemTime, UNIX_EPOCH}, @@ -46,7 +46,10 @@ pub const UNUSED_DEFAULT: u64 = 1024; pub const EVM_GENESIS: &str = "evm-state-genesis"; // Dont load to memory accounts, more specified count -use evm_state::MAX_IN_MEMORY_EVM_ACCOUNTS; +use evm_state::{Storage, MAX_IN_HEAP_EVM_ACCOUNTS_BYTES}; + +use self::evm_genesis::{AccountPair, EvmAccountDumpExtractor}; + // The order can't align with release lifecycle only to remain ABI-compatible... #[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, AbiEnumVisitor, AbiExample)] pub enum ClusterType { @@ -220,29 +223,68 @@ impl GenesisConfig { file.write_all(&serialized) } - pub fn generate_evm_state( + pub fn generate_evm_state_empty(&self, ledger_path: &Path) -> Result<(), std::io::Error> { + self.generate_evm_state(ledger_path, None::) + } + + pub fn generate_evm_state_from_dump( &self, ledger_path: &Path, - evm_state_json: Option<&Path>, + dump_extractor: impl EvmAccountDumpExtractor, ) -> Result<(), std::io::Error> { - let evm_state_path = tempfile::TempDir::new()?; - let evm_state = evm_state::EvmState::new(evm_state_path.path()) - .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, format!("{}.", e)))?; - let mut evm_state = if let evm_state::EvmState::Incomming(evm_state) = evm_state { - evm_state - } else { - unreachable!("Expected new evm-state to be writable."); - }; + self.generate_evm_state(ledger_path, Some(dump_extractor)) + } + + fn generate_evm_state( + &self, + ledger_path: &Path, + dump_extractor: Option, + ) -> Result<(), std::io::Error> { + std::fs::create_dir_all(ledger_path)?; + if let Some(dump_extractor) = dump_extractor { + // Group accounts from iterator into chunks of `MAX_IN_HEAP_EVM_ACCOUNTS_BYTES` heap bytes + let chunks = dump_extractor.batching(|iter| { + let mut chunk = vec![]; + let mut chunk_heap_bytes: usize = 0; + + loop { + match iter.next() { + Some(Ok(AccountPair { encoded_key, account })) => { + // Heap size calculation is rough + chunk_heap_bytes += account.code.capacity() + account.storage.len() * 64; + chunk.push((encoded_key, account)); + if chunk_heap_bytes > MAX_IN_HEAP_EVM_ACCOUNTS_BYTES { + break; + } + }, + Some(Err(err)) => return Some(Err(err)), + None => break + } + } + + if chunk.is_empty() { + return None + } else { + return Some(Ok(chunk)) + } + }); - if let Some(evm_state_json) = evm_state_json { - let accounts = evm_genesis::read_accounts(evm_state_json)?; + let mut storage = Storage::open_persistent(ledger_path, true).unwrap(); + let mut state_root = evm_state::empty_trie_hash(); - for chunk in &accounts.chunks(MAX_IN_MEMORY_EVM_ACCOUNTS) { - let chunk: Result, _> = chunk.collect(); + let mut total_written = 0; + for chunk in chunks { let chunk = chunk?; - log::info!("Adding {} accounts to evm state.", chunk.len()); - evm_state.set_initial(chunk); + total_written += chunk.len(); + log::info!( + "Adding {} accounts to storage. Account pointer: {}", + chunk.len(), + total_written + 1 + ); + state_root = storage.set_initial(chunk, state_root); } + assert_eq!(state_root, self.evm_root_hash); + log::info!("Storage state root: {:?}", state_root); } else { warn!("Generating genesis with empty evm state"); match self.cluster_type { @@ -255,11 +297,21 @@ impl GenesisConfig { } } }; + + let evm_state = { + let incomming = evm_state::Incomming::genesis_from_state(self.evm_root_hash); + let evm_state = evm_state::EvmState::load_from(ledger_path, incomming, true) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, format!("{}.", e)))?; + + if let evm_state::EvmState::Incomming(evm_state) = evm_state { + evm_state + } else { + unreachable!("Expected new evm-state to be writable."); + } + }; + // create zero block let committed = evm_state.commit_block(0, H256::zero()); - let genesis_evm_block = &committed.state.block; - assert_eq!(genesis_evm_block.state_root, self.evm_root_hash); - // TOOD: assert block number, and parent block_hash let mut evm_backup = ledger_path.to_path_buf(); evm_backup.push(EVM_GENESIS); @@ -267,11 +319,9 @@ impl GenesisConfig { let tmp_backup = evm_state .make_backup() .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, format!("{}.", e)))?; - std::fs::create_dir_all(ledger_path)?; - // use copy instead of move, to work with cross device-links (backup makes hardlink and is immovable between devices). - evm_genesis::copy_dir(tmp_backup, evm_backup).unwrap(); - Ok(()) + // use copy instead of move, to work with cross device-links (backup makes hardlink and is immovable across devices). + evm_genesis::copy_dir(tmp_backup, evm_backup) } pub fn set_evm_root_hash(&mut self, root_hash: H256) { @@ -373,18 +423,67 @@ pub mod evm_genesis { use evm_state::{MemoryAccount, H160, H256, U256}; use serde::{de, Deserialize, Serialize}; + use serde_json::de::Read; use serde_json::{de::IoRead, Deserializer}; use sha3::{Digest, Keccak256}; use std::fs::File; use std::io::{BufRead, BufReader, Error, ErrorKind}; - use std::iter; use std::path::Path; use std::{collections::BTreeMap, io::Write}; use std::fs; use std::path::PathBuf; - pub fn copy_dir(from: impl AsRef, to: impl AsRef) -> Result<(), std::io::Error> { + pub use geth::GethAccountExtractor; + pub use open_ethereum::{generate_evm_state_json, OpenEthereumAccountExtractor}; + + #[derive(Debug)] + pub struct AccountPair { + /// Keccak image of H160 public ethereum key + pub encoded_key: H256, + /// Ethereum account data, associated with key + pub account: MemoryAccount, + } + + impl AccountPair { + fn new(encoded_key: H256, account: MemoryAccount) -> Self { + Self { + encoded_key, + account, + } + } + } + + pub trait EvmAccountDumpExtractor: Iterator> { + type Key: AsRef<[u8]>; + + fn encode_key(&self, key: Self::Key) -> H256; + fn read_account(&mut self) -> Result, Error>; + } + + pub struct NoDumpExtractor; + + impl EvmAccountDumpExtractor for NoDumpExtractor { + type Key = [u8; 1]; + + fn encode_key(&self, _key: Self::Key) -> H256 { + H256::zero() + } + + fn read_account(&mut self) -> Result, Error> { + Ok(None) + } + } + + impl Iterator for NoDumpExtractor { + type Item = Result; + + fn next(&mut self) -> Option { + None + } + } + + pub fn copy_dir(from: impl AsRef, to: impl AsRef) -> Result<(), Error> { let mut stack = vec![PathBuf::from(from.as_ref())]; let output_root = PathBuf::from(to.as_ref()); @@ -429,417 +528,565 @@ pub mod evm_genesis { Ok(()) } - #[derive(Debug, Serialize, Deserialize)] - struct ExtendedMemoryAccount { - /// Account nonce. - #[serde(deserialize_with = "deserialize_skip_hex_prefix")] - pub nonce: U256, - /// Account balance. - #[serde(deserialize_with = "deserialize_skip_hex_prefix")] - pub balance: U256, - /// Full account storage. - pub storage: Option, Hex>>, - /// Account code. - #[serde(deserialize_with = "deserialize_skip_hex_prefix_bytes")] - #[serde(default)] - pub code: Option, - pub code_hash: Option>, - pub storage_root: Option>, - } + mod open_ethereum { + use super::*; + + #[derive(Debug, Serialize, Deserialize)] + struct ExtendedMemoryAccount { + /// Account nonce. + #[serde(deserialize_with = "deserialize_skip_hex_prefix")] + pub nonce: U256, + /// Account balance. + #[serde(deserialize_with = "deserialize_skip_hex_prefix")] + pub balance: U256, + /// Full account storage. + pub storage: Option, Hex>>, + /// Account code. + #[serde(deserialize_with = "deserialize_skip_hex_prefix_bytes")] + #[serde(default)] + pub code: Option, + pub code_hash: Option>, + pub storage_root: Option>, + } - fn deserialize_skip_hex_prefix<'de, D>(deserializer: D) -> Result - where - D: de::Deserializer<'de>, - { - let data = String::deserialize(deserializer)?; - U256::from_str_radix(&data, 16).map_err(|e| de::Error::custom(format!("{}", e))) - } + fn deserialize_skip_hex_prefix<'de, D>(deserializer: D) -> Result + where + D: de::Deserializer<'de>, + { + let data = String::deserialize(deserializer)?; + U256::from_str_radix(&data, 16).map_err(|e| de::Error::custom(format!("{}", e))) + } - fn deserialize_skip_hex_prefix_bytes<'de, D>(deserializer: D) -> Result, D::Error> - where - D: de::Deserializer<'de>, - { - let data = Option::::deserialize(deserializer)?; - data.map(|data| { - hex::decode(data) - .map(Bytes) - .map_err(|e| de::Error::custom(format!("{}", e))) - }) - .transpose() - } + fn deserialize_skip_hex_prefix_bytes<'de, D>( + deserializer: D, + ) -> Result, D::Error> + where + D: de::Deserializer<'de>, + { + let data = Option::::deserialize(deserializer)?; + data.map(|data| { + hex::decode(data) + .map(Bytes) + .map_err(|e| de::Error::custom(format!("{}", e))) + }) + .transpose() + } - impl From for MemoryAccount { - fn from(extended: ExtendedMemoryAccount) -> MemoryAccount { - MemoryAccount { - nonce: extended.nonce, - balance: extended.balance, - storage: extended - .storage - .into_iter() - .flatten() - .map(|(k, v)| (k.0, v.0)) - .collect(), - code: extended.code.unwrap_or_else(|| Bytes(Vec::new())).0, + impl From for MemoryAccount { + fn from(extended: ExtendedMemoryAccount) -> MemoryAccount { + MemoryAccount { + nonce: extended.nonce, + balance: extended.balance, + storage: extended + .storage + .into_iter() + .flatten() + .map(|(k, v)| (k.0, v.0)) + .collect(), + code: extended.code.unwrap_or_else(|| Bytes(Vec::new())).0, + } } } - } - /// Streaming deserializer for key,value pair in json. - /// input format is following: - /// - /// line0: { "state": { - /// line1-N: "0x....": {...}, - /// lineN: }} - /// - /// serde_json StreamDeserializer can only work with valid json Value. '"key":{object}' - is not a valid json Value. - /// - pub struct StreamAccountReader { - reader: R, - } - - impl StreamAccountReader> { - pub fn new(mut reader: R) -> Result { - let mut buffer = String::new(); + /// Streaming deserializer for key,value pair in json. + /// input format is following: + /// + /// line0: { "state": { + /// line1-N: "0x....": {...}, + /// lineN: }} + /// + /// serde_json StreamDeserializer can only work with valid json Value. '"key":{object}' - is not a valid json Value. + /// + pub struct OpenEthereumAccountExtractor { + reader: IoRead>, + } - let _header_size = reader.read_line(&mut buffer)?; - if buffer.as_str() != "{ \"state\": {\n" { - return Err(Error::new( - ErrorKind::Other, - format!("Trying to read header of evm state json file, and it is invalid, should be '{{ \"state\": {{' got: {}", buffer), - )); + impl OpenEthereumAccountExtractor { + pub fn open_dump(dump: &Path) -> Result { + let file = File::open(dump)?; + Self::new_with_reader(file) } + } - Ok(Self { - reader: IoRead::new(reader), - }) + impl<'a> OpenEthereumAccountExtractor<&'a [u8]> { + pub fn from_json_text( + dump: &'a impl AsRef, + ) -> Result, Error> { + Self::new_with_reader(dump.as_ref().as_bytes()) + } } - } - impl<'a, R: serde_json::de::Read<'a>> StreamAccountReader { - /// Return true if end brackets found. - fn end_brackets(&mut self) -> Result { - self.skip_whitespaces()?; - let end_bracket = self - .reader - .peek() - .map_err(|e| Error::new(ErrorKind::Other, format!("Read buffer error {:?}", e)))?; - - if let Some(b'}') = end_bracket { - // json should close 'state' object, and main object: '{"state": { .. }}' - for _ in 0..2 { - // check that 3 brackets found - let end_bracket = self.reader.next().map_err(|e| { - Error::new(ErrorKind::Other, format!("Read buffer error {:?}", e)) - })?; - if end_bracket.is_none() { - return Err(Error::new( - ErrorKind::Other, - "No enough end brackets at end of file found.".to_string(), - )); + impl OpenEthereumAccountExtractor { + pub fn new_with_reader(reader: R) -> Result { + let mut buf_reader = BufReader::new(reader); + let mut buffer = String::new(); + + let _header_size = buf_reader.read_line(&mut buffer)?; + if buffer.as_str() != "{ \"state\": {\n" { + return Err(Error::new( + ErrorKind::Other, + format!("Trying to read header of evm state json file, and it is invalid, should be '{{ \"state\": {{' got: {}", buffer), + )); + } + + let reader = IoRead::new(buf_reader); + + Ok(Self { reader }) + } + + /// Return true if end brackets found. + fn end_brackets(&mut self) -> Result { + self.skip_whitespaces()?; + let end_bracket = self.reader.peek().map_err(|e| { + Error::new(ErrorKind::Other, format!("Read buffer error {:?}", e)) + })?; + + if let Some(b'}') = end_bracket { + // json should close 'state' object, and main object: '{"state": { .. }}' + for _ in 0..2 { + // check that 3 brackets found + let end_bracket = self.reader.next().map_err(|e| { + Error::new(ErrorKind::Other, format!("Read buffer error {:?}", e)) + })?; + if end_bracket.is_none() { + return Err(Error::new( + ErrorKind::Other, + "No enough end brackets at end of file found.".to_string(), + )); + } } + return Ok(true); } - return Ok(true); + Ok(false) } - Ok(false) - } - fn skip_trailing_comma(&mut self) -> Result<(), Error> { - if let Some(b',') = self.reader.peek()? { - self.reader.discard() + fn skip_trailing_comma(&mut self) -> Result<(), Error> { + if let Some(b',') = self.reader.peek()? { + self.reader.discard() + } + Ok(()) } - Ok(()) - } - fn skip_whitespaces(&mut self) -> Result<(), Error> { - while let Some(c) = self.reader.peek()? { - // Discard all whitespaces, return if other - if !char::from(c).is_whitespace() { - return Ok(()); + fn skip_whitespaces(&mut self) -> Result<(), Error> { + while let Some(c) = self.reader.peek()? { + // Discard all whitespaces, return if other + if !char::from(c).is_whitespace() { + return Ok(()); + } + + self.reader.discard() } + Ok(()) + } - self.reader.discard() + fn skip_colon(&mut self) -> Result<(), Error> { + match self.reader.next() { + Ok(Some(b':')) => Ok(()), + s => Err(Error::new( + ErrorKind::Other, + format!("cannot skip colon {:?}", s), + )), + } } - Ok(()) - } - fn skip_colon(&mut self) -> Result<(), Error> { - match self.reader.next() { - Ok(Some(b':')) => Ok(()), - s => Err(Error::new( - ErrorKind::Other, - format!("cannot skip colon {:?}", s), - )), + fn read_token(&mut self) -> Result { + let mut stream = Deserializer::new(&mut self.reader).into_iter::(); + + match stream.next() { + None => Err(Error::new( + ErrorKind::Other, + "Buffer ended unexpected".to_string(), + )), + Some(Err(e)) => Err(Error::new( + ErrorKind::Other, + format!("Deserialization error {:?}", e), + )), + Some(Ok(o)) => Ok(o), + } } } - fn read_token(&mut self) -> Result { - let mut stream = Deserializer::new(&mut self.reader).into_iter::(); + impl EvmAccountDumpExtractor for OpenEthereumAccountExtractor { + type Key = H160; - match stream.next() { - None => Err(Error::new( - ErrorKind::Other, - "Buffer ended unexpected".to_string(), - )), - Some(Err(e)) => Err(Error::new( - ErrorKind::Other, - format!("Deserialization error {:?}", e), - )), - Some(Ok(o)) => Ok(o), + fn encode_key(&self, key: Self::Key) -> H256 { + H256(Keccak256::digest(key.as_ref()).into()) } - } - /// Read account, try to validate code_hash and storage_root. - /// - /// Result> instead of Option>, to allow power of `Try` for error handling. - pub fn read_account(&mut self) -> Result, Error> { - if self.end_brackets()? { - return Ok(None); - } - let key: Hex = self.read_token()?; - self.skip_colon()?; - - let value: ExtendedMemoryAccount = self.read_token()?; - - self.skip_trailing_comma()?; - - match (&value.storage_root, &value.storage) { - (Some(expected_storage), Some(storage)) => { - let storage_root = - triehash::sec_trie_root::( - storage.iter().map(|(k, v)| { - (&k.0, rlp::encode(&U256::from_big_endian(&v.0[..]))) - }), - ); - let storage_root = H256::from_slice(&storage_root); - assert_eq!(storage_root, expected_storage.0, "Storage hash mismatched") + /// Read account, try to validate code_hash and storage_root. + /// + /// Result> instead of Option>, to allow power of `Try` for error handling. + fn read_account(&mut self) -> Result, Error> { + if self.end_brackets()? { + return Ok(None); } - (None, None) => {} - _ => panic!( - "Expected storage_root and storage properties to exist in account: {:?}.", - key - ), - } - match (&value.code_hash, &value.code) { - (Some(expected_code), Some(code)) => { - let code_hash = H256::from_slice(Keccak256::digest(&code.0).as_slice()); - assert_eq!(code_hash, expected_code.0, "Code hash mismatched") + let key: Hex = self.read_token()?; + self.skip_colon()?; + + let value: ExtendedMemoryAccount = self.read_token()?; + + self.skip_trailing_comma()?; + + match (&value.storage_root, &value.storage) { + (Some(expected_storage), Some(storage)) => { + let storage_root = + triehash::sec_trie_root::( + storage.iter().map(|(k, v)| { + (&k.0, rlp::encode(&U256::from_big_endian(&v.0[..]))) + }), + ); + let storage_root = H256::from_slice(&storage_root); + assert_eq!(storage_root, expected_storage.0, "Storage hash mismatched") + } + (None, None) => {} + _ => panic!( + "Expected storage_root and storage properties to exist in account: {:?}.", + key + ), } - (None, None) => {} - _ => panic!( - "Expected code_hash and code properties to exist in account: {:?}.", - key - ), + match (&value.code_hash, &value.code) { + (Some(expected_code), Some(code)) => { + let code_hash = H256::from_slice(Keccak256::digest(&code.0).as_slice()); + assert_eq!(code_hash, expected_code.0, "Code hash mismatched") + } + (None, None) => {} + _ => panic!( + "Expected code_hash and code properties to exist in account: {:?}.", + key + ), + } + + let account_pair = AccountPair::new(self.encode_key(key.0), value.into()); + Ok(Some(account_pair)) } + } - Ok(Some((key.0, value.into()))) + impl Iterator for OpenEthereumAccountExtractor { + type Item = Result; + + fn next(&mut self) -> Option { + self.read_account().transpose() + } } - } - pub fn read_accounts( - evm_state_snapshot: &Path, - ) -> Result>, Error> { - let evm_file = BufReader::new(File::open(evm_state_snapshot)?); + pub fn generate_evm_state_json(file: &Path) -> Result { + let json = b"{ \"state\": {\n}}"; + let mut file = std::fs::File::create(file)?; + file.write_all(json)?; + Ok(evm_state::empty_trie_hash()) + } - let mut reader = StreamAccountReader::new(evm_file)?; - Ok(iter::from_fn(move || reader.read_account().transpose())) - } + #[cfg(test)] + mod tests { + use solana_program::pubkey::Pubkey; + + use crate::{ + account::AccountSharedData, + genesis_config::{ + evm_genesis::{ + self, AccountPair, EvmAccountDumpExtractor, OpenEthereumAccountExtractor, + }, + GenesisConfig, + }, + }; - pub fn generate_evm_state_json(file: &Path) -> Result { - let json = b"{ \"state\": {\n}}"; - let mut file = std::fs::File::create(file)?; - file.write_all(json)?; - Ok(evm_state::empty_trie_hash()) - } -} + use { + crate::signature::{Keypair, Signer}, + std::path::PathBuf, + }; -#[cfg(test)] -mod tests { - use evm_state::{MemoryAccount, H160}; - use { - super::evm_genesis::*, - super::*, - crate::signature::{Keypair, Signer}, - std::path::PathBuf, - }; - - fn make_tmp_path(name: &str) -> PathBuf { - let out_dir = std::env::var("FARF_DIR").unwrap_or_else(|_| "farf".to_string()); - let keypair = Keypair::new(); - - let path = [ - out_dir, - "tmp".to_string(), - format!("{}-{}", name, keypair.pubkey()), - ] - .iter() - .collect(); - - // whack any possible collision - let _ignored = std::fs::remove_dir_all(&path); - // whack any possible collision - let _ignored = std::fs::remove_file(&path); - - path - } + fn make_tmp_path(name: &str) -> PathBuf { + let out_dir = std::env::var("FARF_DIR").unwrap_or_else(|_| "farf".to_string()); + let keypair = Keypair::new(); - #[test] - fn test_evm_genesis_config() { - let faucet_keypair = Keypair::new(); - let mut config = GenesisConfig::default(); - config.add_account( - faucet_keypair.pubkey(), - AccountSharedData::new(10_000, 0, &Pubkey::default()), - ); - config.add_account( - solana_sdk::pubkey::new_rand(), - AccountSharedData::new(1, 0, &Pubkey::default()), - ); - config.add_native_instruction_processor("hi".to_string(), solana_sdk::pubkey::new_rand()); - - assert_eq!(config.accounts.len(), 2); - assert!(config - .accounts - .iter() - .any(|(pubkey, account)| *pubkey == faucet_keypair.pubkey() - && account.lamports == 10_000)); - - let path = &make_tmp_path("genesis_config"); - let evm_state_path = &make_tmp_path("evm_state_path"); - std::fs::create_dir_all(&evm_state_path).unwrap(); - let evm_state_path = evm_state_path.join("file.json"); - let evm_state_root = evm_genesis::generate_evm_state_json(&evm_state_path).unwrap(); - config.evm_root_hash = evm_state_root; - config - .generate_evm_state(path, Some(&evm_state_path)) - .expect("generate_evm_state"); - config.write(path).expect("write"); - let loaded_config = GenesisConfig::load(path).expect("load"); - assert_eq!(config.hash(), loaded_config.hash()); - let _ignored = std::fs::remove_file(&evm_state_path); - let _ignored = std::fs::remove_file(&path); - } + let path = [ + out_dir, + "tmp".to_string(), + format!("{}-{}", name, keypair.pubkey()), + ] + .iter() + .collect(); - #[test] - fn test_genesis_config() { - let faucet_keypair = Keypair::new(); - let mut config = GenesisConfig::default(); - config.add_account( - faucet_keypair.pubkey(), - AccountSharedData::new(10_000, 0, &Pubkey::default()), - ); - config.add_account( - solana_sdk::pubkey::new_rand(), - AccountSharedData::new(1, 0, &Pubkey::default()), - ); - config.add_native_instruction_processor("hi".to_string(), solana_sdk::pubkey::new_rand()); - config.evm_chain_id = 0x42; - - assert_eq!(config.accounts.len(), 2); - assert!(config - .accounts - .iter() - .any(|(pubkey, account)| *pubkey == faucet_keypair.pubkey() - && account.lamports == 10_000)); - - let path = &make_tmp_path("genesis_config"); - config.write(path).expect("write"); - let loaded_config = GenesisConfig::load(path).expect("load"); - assert_eq!(config.hash(), loaded_config.hash()); - let _ignored = std::fs::remove_file(&path); - } + // whack any possible collision + let _ignored = std::fs::remove_dir_all(&path); + // whack any possible collision + let _ignored = std::fs::remove_file(&path); - fn check_evm_genesis_file(data: &str) -> Result, std::io::Error> { - let mut reader = StreamAccountReader::new(data.as_bytes())?; + path + } - std::iter::from_fn(move || reader.read_account().transpose()).collect() - } + #[test] + fn test_evm_genesis_config() { + let faucet_keypair = Keypair::new(); + let mut config = GenesisConfig::default(); + config.add_account( + faucet_keypair.pubkey(), + AccountSharedData::new(10_000, 0, &Pubkey::default()), + ); + config.add_account( + solana_sdk::pubkey::new_rand(), + AccountSharedData::new(1, 0, &Pubkey::default()), + ); + config.add_native_instruction_processor( + "hi".to_string(), + solana_sdk::pubkey::new_rand(), + ); + + assert_eq!(config.accounts.len(), 2); + assert!(config + .accounts + .iter() + .any(|(pubkey, account)| *pubkey == faucet_keypair.pubkey() + && account.lamports == 10_000)); + + let path = &make_tmp_path("genesis_config"); + let evm_state_path = &make_tmp_path("evm_state_path"); + std::fs::create_dir_all(&evm_state_path).unwrap(); + let evm_state_path = evm_state_path.join("file.json"); + let evm_state_root = evm_genesis::generate_evm_state_json(&evm_state_path).unwrap(); + config.evm_root_hash = evm_state_root; + let dump_extractor = + OpenEthereumAccountExtractor::open_dump(&evm_state_path).unwrap(); + config + .generate_evm_state(path, Some(dump_extractor)) + .expect("generate_evm_state"); + config.write(path).expect("write"); + let loaded_config = GenesisConfig::load(path).expect("load"); + assert_eq!(config.hash(), loaded_config.hash()); + let _ignored = std::fs::remove_file(&evm_state_path); + let _ignored = std::fs::remove_file(&path); + } - #[test] - fn test_invalid_evm_genesis() { - let no_header = r#" - "0xffbb13a995ddf6ad35cf533e69f38d38887e8f5c": {"balance": "2544faa778090e00000", "nonce": "0"} - }}"#; - assert!(dbg!(check_evm_genesis_file(no_header)).is_err()); - - let no_footer = r#"{ "state": { - "0xffbb13a995ddf6ad35cf533e69f38d38887e8f5c": {"balance": "2544faa778090e00000", "nonce": "0"} - "#; - assert!(dbg!(check_evm_genesis_file(no_footer)).is_err()); - - let no_colon = r#"{ "state": { - "0xffbb13a995ddf6ad35cf533e69f38d38887e8f5c", {"balance": "2544faa778090e00000", "nonce": "0"} - }}"#; - assert!(dbg!(check_evm_genesis_file(no_colon)).is_err()); - - let not_valid_key = r#"{ "state": { - "0xKKKKKKKKKKKKKKKKKKKKK": {"balance": "2544faa778090e00000", "nonce": "0"} - }}"#; - assert!(dbg!(check_evm_genesis_file(not_valid_key)).is_err()); - } + #[test] + fn test_genesis_config() { + let faucet_keypair = Keypair::new(); + let mut config = GenesisConfig::default(); + config.add_account( + faucet_keypair.pubkey(), + AccountSharedData::new(10_000, 0, &Pubkey::default()), + ); + config.add_account( + solana_sdk::pubkey::new_rand(), + AccountSharedData::new(1, 0, &Pubkey::default()), + ); + config.add_native_instruction_processor( + "hi".to_string(), + solana_sdk::pubkey::new_rand(), + ); + config.evm_chain_id = 0x42; + + assert_eq!(config.accounts.len(), 2); + assert!(config + .accounts + .iter() + .any(|(pubkey, account)| *pubkey == faucet_keypair.pubkey() + && account.lamports == 10_000)); + + let path = &make_tmp_path("genesis_config"); + config.write(path).expect("write"); + let loaded_config = GenesisConfig::load(path).expect("load"); + assert_eq!(config.hash(), loaded_config.hash()); + let _ignored = std::fs::remove_file(&path); + } - #[test] - #[should_panic] - fn invalid_code_hash() { - let invalid_code_hash = r#"{ "state": { - "0x984cf4e0001003d4ef5328d0fea9a3a430b78027": {"balance": "0", "nonce": "1", "code_hash": "0x11111111111111111111111110be7c0893f036ad196680a723a9665e3681e165", "code": "60102233" } - }}"#; - let _expect_panic = check_evm_genesis_file(invalid_code_hash); - } - #[test] - #[should_panic] - fn invalid_storage_hash() { - let invalid_storage_hash = r#"{ "state": { - "0x984cf4e0001003d4ef5328d0fea9a3a430b78037": {"balance": "0", "nonce": "1", "storage_root": "0x11111111111111111111111110be7c0893f036ad196680a723a9665e3681e165", "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000c47fa223c0b394a6bebb360603c9505dcebdcbe6", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x0000000000000000000000003a1a9a4f4167b8c55f13b7189f210cc7b989d52b" - }} - }}"#; - let _expect_panic = check_evm_genesis_file(invalid_storage_hash); + fn check_evm_genesis_file(data: &str) -> Result, std::io::Error> { + let mut reader = OpenEthereumAccountExtractor::from_json_text(&data)?; + + std::iter::from_fn(move || reader.read_account().transpose()).collect() + } + + #[test] + fn test_invalid_evm_genesis() { + let no_header = r#" + "0xffbb13a995ddf6ad35cf533e69f38d38887e8f5c": {"balance": "2544faa778090e00000", "nonce": "0"} + }}"#; + assert!(dbg!(check_evm_genesis_file(no_header)).is_err()); + + let no_footer = r#"{ "state": { + "0xffbb13a995ddf6ad35cf533e69f38d38887e8f5c": {"balance": "2544faa778090e00000", "nonce": "0"} + "#; + assert!(dbg!(check_evm_genesis_file(no_footer)).is_err()); + + let no_colon = r#"{ "state": { + "0xffbb13a995ddf6ad35cf533e69f38d38887e8f5c", {"balance": "2544faa778090e00000", "nonce": "0"} + }}"#; + assert!(dbg!(check_evm_genesis_file(no_colon)).is_err()); + + let not_valid_key = r#"{ "state": { + "0xKKKKKKKKKKKKKKKKKKKKK": {"balance": "2544faa778090e00000", "nonce": "0"} + }}"#; + assert!(dbg!(check_evm_genesis_file(not_valid_key)).is_err()); + } + + #[test] + #[should_panic] + fn invalid_code_hash() { + let invalid_code_hash = r#"{ "state": { + "0x984cf4e0001003d4ef5328d0fea9a3a430b78027": {"balance": "0", "nonce": "1", "code_hash": "0x11111111111111111111111110be7c0893f036ad196680a723a9665e3681e165", "code": "60102233" } + }}"#; + let _expect_panic = check_evm_genesis_file(invalid_code_hash); + } + #[test] + #[should_panic] + fn invalid_storage_hash() { + let invalid_storage_hash = r#"{ "state": { + "0x984cf4e0001003d4ef5328d0fea9a3a430b78037": {"balance": "0", "nonce": "1", "storage_root": "0x11111111111111111111111110be7c0893f036ad196680a723a9665e3681e165", "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000c47fa223c0b394a6bebb360603c9505dcebdcbe6", + "0x0000000000000000000000000000000000000000000000000000000000000003": "0x0000000000000000000000003a1a9a4f4167b8c55f13b7189f210cc7b989d52b" + }} + }}"#; + let _expect_panic = check_evm_genesis_file(invalid_storage_hash); + } + + #[test] + fn test_valid_evm_genesis() { + let json_one_account = r#"{ "state": { + "0xffbb13a995ddf6ad35cf533e69f38d38887e8f5c": {"balance": "2544faa778090e00000", "nonce": "0"} + }}"#; + assert_eq!(check_evm_genesis_file(json_one_account).unwrap().len(), 1); + + let json_two_accounts = r#"{ "state": { + "0xffbb13a995ddf6ad35cf533e69f38d38887e8f5c": {"balance": "2544faa778090e00000", "nonce": "0"}, + "0xffbb13a995ddf6ad35cf533e69f38d38887e8f5e": {"balance": "2544faa778090e00000", "nonce": "0"} + }}"#; + assert_eq!(check_evm_genesis_file(json_two_accounts).unwrap().len(), 2); + + let json_two_accounts_full = r#"{ "state": { + "0xffbb13a995ddf6ad35cf533e69f38d38887e8f5c": {"balance": "2544faa778090e00000", "nonce": "0"}, + "0x984cf4e0001003d4ef5328d0fea9a3a430b78027": {"balance": "0", "nonce": "1", "code_hash": "0x5304993ef62b8112c1e117e13d564987d722edb2588c485c7a074aac542ad710", "code": "60102233", "storage_root": "0xee496207d2c8ef7e41788519fc346ced8255be4850587f290b84d63bf405266a", "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000c47fa223c0b394a6bebb360603c9505dcebdcbe6", + "0x0000000000000000000000000000000000000000000000000000000000000003": "0x0000000000000000000000003a1a9a4f4167b8c55f13b7189f210cc7b989d52b" + }} + }}"#; + assert_eq!( + check_evm_genesis_file(json_two_accounts_full) + .unwrap() + .len(), + 2 + ); + + let json_two_accounts_full = r#"{ "state": { + "0x984cf4e0001003d4ef5328d0fea9a3a430b78027": {"balance": "0", "nonce": "1", "code_hash": "0x5304993ef62b8112c1e117e13d564987d722edb2588c485c7a074aac542ad710", "code": "60102233", "storage_root": "0xee496207d2c8ef7e41788519fc346ced8255be4850587f290b84d63bf405266a", "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000c47fa223c0b394a6bebb360603c9505dcebdcbe6", + "0x0000000000000000000000000000000000000000000000000000000000000003": "0x0000000000000000000000003a1a9a4f4167b8c55f13b7189f210cc7b989d52b" + }}, + "0xffbb13a995ddf6ad35cf533e69f38d38887e8f5c": {"balance": "2544faa778090e00000", "nonce": "0"}, + "0x984cf4e0001003d4ef5328d0fea9a3a430b78037": {"balance": "0", "nonce": "1", "storage_root": "0xee496207d2c8ef7e41788519fc346ced8255be4850587f290b84d63bf405266a", "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000c47fa223c0b394a6bebb360603c9505dcebdcbe6", + "0x0000000000000000000000000000000000000000000000000000000000000003": "0x0000000000000000000000003a1a9a4f4167b8c55f13b7189f210cc7b989d52b" + }} + }}"#; + assert_eq!( + check_evm_genesis_file(json_two_accounts_full) + .unwrap() + .len(), + 3 + ); + } + } } - #[test] - fn test_valid_evm_genesis() { - let json_one_account = r#"{ "state": { - "0xffbb13a995ddf6ad35cf533e69f38d38887e8f5c": {"balance": "2544faa778090e00000", "nonce": "0"} - }}"#; - assert_eq!(check_evm_genesis_file(json_one_account).unwrap().len(), 1); - - let json_two_accounts = r#"{ "state": { - "0xffbb13a995ddf6ad35cf533e69f38d38887e8f5c": {"balance": "2544faa778090e00000", "nonce": "0"}, - "0xffbb13a995ddf6ad35cf533e69f38d38887e8f5e": {"balance": "2544faa778090e00000", "nonce": "0"} - }}"#; - assert_eq!(check_evm_genesis_file(json_two_accounts).unwrap().len(), 2); - - let json_two_accounts_full = r#"{ "state": { - "0xffbb13a995ddf6ad35cf533e69f38d38887e8f5c": {"balance": "2544faa778090e00000", "nonce": "0"}, - "0x984cf4e0001003d4ef5328d0fea9a3a430b78027": {"balance": "0", "nonce": "1", "code_hash": "0x5304993ef62b8112c1e117e13d564987d722edb2588c485c7a074aac542ad710", "code": "60102233", "storage_root": "0xee496207d2c8ef7e41788519fc346ced8255be4850587f290b84d63bf405266a", "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000c47fa223c0b394a6bebb360603c9505dcebdcbe6", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x0000000000000000000000003a1a9a4f4167b8c55f13b7189f210cc7b989d52b" - }} - }}"#; - assert_eq!( - check_evm_genesis_file(json_two_accounts_full) - .unwrap() - .len(), - 2 - ); - - let json_two_accounts_full = r#"{ "state": { - "0x984cf4e0001003d4ef5328d0fea9a3a430b78027": {"balance": "0", "nonce": "1", "code_hash": "0x5304993ef62b8112c1e117e13d564987d722edb2588c485c7a074aac542ad710", "code": "60102233", "storage_root": "0xee496207d2c8ef7e41788519fc346ced8255be4850587f290b84d63bf405266a", "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000c47fa223c0b394a6bebb360603c9505dcebdcbe6", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x0000000000000000000000003a1a9a4f4167b8c55f13b7189f210cc7b989d52b" - }}, - "0xffbb13a995ddf6ad35cf533e69f38d38887e8f5c": {"balance": "2544faa778090e00000", "nonce": "0"}, - "0x984cf4e0001003d4ef5328d0fea9a3a430b78037": {"balance": "0", "nonce": "1", "storage_root": "0xee496207d2c8ef7e41788519fc346ced8255be4850587f290b84d63bf405266a", "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000c47fa223c0b394a6bebb360603c9505dcebdcbe6", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x0000000000000000000000003a1a9a4f4167b8c55f13b7189f210cc7b989d52b" - }} - }}"#; - assert_eq!( - check_evm_genesis_file(json_two_accounts_full) - .unwrap() - .len(), - 3 - ); + mod geth { + use super::*; + + pub struct GethAccountExtractor { + reader: BufReader, + } + + impl GethAccountExtractor { + pub fn open_dump(dump: &Path) -> Result { + let mut reader = BufReader::new(File::open(dump)?); + // Skip first line `{"root": "..."}` + reader.read_line(&mut String::new())?; + Ok(Self { reader }) + } + } + + impl<'a> GethAccountExtractor<&'a [u8]> { + pub fn from_text(dump: &'a impl AsRef) -> Result { + let mut reader = BufReader::new(dump.as_ref().as_bytes()); + // Skip first line `{"root": "..."}` + reader.read_line(&mut String::new())?; + Ok(Self { reader }) + } + } + + impl EvmAccountDumpExtractor for GethAccountExtractor { + type Key = H256; + + fn encode_key(&self, key: Self::Key) -> H256 { + key + } + + fn read_account(&mut self) -> Result, Error> { + use std::str::FromStr; + + let mut buf = String::new(); + let len = self.reader.read_line(&mut buf)?; + + if len == 0 { + return Ok(None); + } + + let account_json: serde_json::Value = serde_json::from_str(&buf).unwrap(); + + let address = H256::from_str(account_json["key"].as_str().unwrap()).unwrap(); + + let nonce = account_json["nonce"].as_u64().unwrap().into(); + let balance = + U256::from_str_radix(account_json["balance"].as_str().unwrap(), 10).unwrap(); + let code = account_json["code"] + .as_str() + .map(|code| hex::decode(&code[2..]).unwrap()) + .unwrap_or_default(); + let storage = account_json["storage"] + .as_object() + .map(|storage| { + storage + .into_iter() + .map(|(key, value)| { + let key = H256::from_str(key).unwrap(); + let value_u256 = U256::from_str(value.as_str().unwrap()).unwrap(); + let mut value = H256::default(); + value_u256.to_big_endian(value.as_bytes_mut()); + (key, value) + }) + .collect::>() + }) + .unwrap_or_else(BTreeMap::new); + + let memory_account = MemoryAccount { + nonce, + balance, + storage, + code, + }; + + let pair = AccountPair::new(address, memory_account); + + Ok(Some(pair)) + } + } + + impl Iterator for GethAccountExtractor { + type Item = Result; + + fn next(&mut self) -> Option { + self.read_account().transpose() + } + } + + #[cfg(test)] + mod tests { + use super::*; + + #[test] + fn parse_geth_dump() { + let test_geth_dump = include_str!("../tests/geth-dump.txt"); + let account_extractor = GethAccountExtractor::from_text(&test_geth_dump).unwrap(); + let accounts = account_extractor.collect::, _>>().unwrap(); + assert_eq!(accounts.len(), 203) + } + } } } diff --git a/sdk/tests/geth-dump.txt b/sdk/tests/geth-dump.txt new file mode 100644 index 0000000000..6a84cd818a --- /dev/null +++ b/sdk/tests/geth-dump.txt @@ -0,0 +1,204 @@ +{"root":"0x6e3b38830bcad692e5121c0f46cc5be7f803439cde7778e732f15010beb40bf3"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x000000f01ca66a2744bf06898eacfa95488199e214a465ab84f6954791d0acca"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xaf011dd0cace12e716c464ce5d9eccd08b8803661561a0d2de035d8e110a25e3","code":"0x73921ce616f54d25ab46811fae8e67012134787c5f30146080604052600436106100405760003560e01c8063c3525c2814610045578063e617042414610063575b600080fd5b61004d610083565b60405161005a9190610e2f565b60405180910390f35b610076610071366004610c58565b61008f565b60405161005a9190610d59565b670de0b6b3a764000081565b60006100a86100a336879003870187610cf0565b6102be565b15806100f057506001600160a01b0389166000908152602087905260409020600701546100ee90600160a01b900460ff166100e836889003880188610cf0565b906102e6565b155b156100fd575060016102b2565b610105610b69565b6001600160a01b038a16600090815260208890526040902061012690610348565b5084525060208301819052151590506101435760019150506102b2565b61015f8988610157368a90038a018a610cf0565b888888610373565b506080850152506060830181905260408301919091526101835760019150506102b2565b61021a8160000151600a0a6102148a866001600160a01b031663b3596f078f6040518263ffffffff1660e01b81526004016101be9190610d45565b60206040518083038186803b1580156101d657600080fd5b505afa1580156101ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061020e9190610d2d565b90610834565b90610875565b60a08201819052604082015161022f916108b7565b60c082018190526102445760009150506102b2565b6102838160c0015161021461026a84602001518560a0015161083490919063ffffffff16565b6080850151604086015161027d91610834565b906108b7565b60e0820181905260c082015160608301516000926102a29291906108f9565b670de0b6b3a76400001115925050505b98975050505050505050565b517f555555555555555555555555555555555555555555555555555555555555555516151590565b60006080821060405180604001604052806002815260200161373760f01b8152509061032e5760405162461bcd60e51b81526004016103259190610d64565b60405180910390fd5b5050815160016002830281019190911c1615155b92915050565b5461ffff80821692601083901c821692602081901c831692603082901c60ff169260409290921c1690565b6000806000806000610383610bbe565b61038c8a610925565b156103aa576000806000806000199550955095509550955050610826565b600060e08201525b878160e0015110156107855760e08101516103ce908b9061092a565b6103d757610775565b60e0810151600090815260208a81526040808320546001600160a01b03166101e085018190528352908d9052902061040e81610348565b506080860181905260c08601929092525060a0840191909152600a0a60208301526101e082015160405163b3596f0760e01b81526001600160a01b038a169163b3596f07916104609190600401610d45565b60206040518083038186803b15801561047857600080fd5b505afa15801561048c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b09190610d2d565b825260c0820151158015906104d0575060e08201516104d0908c906102e6565b156105ee578060040160009054906101000a90046001600160a01b03166001600160a01b03166370a082318e6040518263ffffffff1660e01b81526004016105189190610d45565b60206040518083038186803b15801561053057600080fd5b505afa158015610544573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105689190610d2d565b6040830181905260208301518351600092610587929161021491610834565b61012084015190915061059a908261097b565b61012084015260a08301516105c0906105b4908390610834565b6101608501519061097b565b61016084015260c08301516105e6906105da908390610834565b6101808501519061097b565b610180840152505b60e08201516105fe908c906109a0565b15610773578060050160009054906101000a90046001600160a01b03166001600160a01b03166370a082318e6040518263ffffffff1660e01b81526004016106469190610d45565b60206040518083038186803b15801561065e57600080fd5b505afa158015610672573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106969190610d2d565b8260600181815250506107408160060160009054906101000a90046001600160a01b03166001600160a01b03166370a082318f6040518263ffffffff1660e01b81526004016106e59190610d45565b60206040518083038186803b1580156106fd57600080fd5b505afa158015610711573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107359190610d2d565b60608401519061097b565b606083018190526020830151835161076c92610760929161021491610834565b6101408401519061097b565b6101408301525b505b60e08101805160010190526103b2565b6000816101200151116107995760006107ae565b6101208101516101608201516107ae91610875565b6101608201526101208101516107c55760006107da565b6101208101516101808201516107da91610875565b61018082018190526101208201516101408301516107f7926108f9565b610100820181905261012082015161014083015161016084015161018090940151919850965091945090925090505b965096509650965096915050565b60008261084357506000610342565b8282028284828161085057fe5b041461086e5760405162461bcd60e51b815260040161032590610dee565b9392505050565b600061086e83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506109f1565b600061086e83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610a28565b600082610909575060001961086e565b61091d836109178685610a54565b90610ac6565b949350505050565b511590565b60006080821060405180604001604052806002815260200161373760f01b815250906109695760405162461bcd60e51b81526004016103259190610d64565b50509051600360029092021c16151590565b60008282018381101561086e5760405162461bcd60e51b815260040161032590610db7565b60006080821060405180604001604052806002815260200161373760f01b815250906109df5760405162461bcd60e51b81526004016103259190610d64565b50509051600160029092021c16151590565b60008183610a125760405162461bcd60e51b81526004016103259190610d64565b506000838581610a1e57fe5b0495945050505050565b60008184841115610a4c5760405162461bcd60e51b81526004016103259190610d64565b505050900390565b6000821580610a61575081155b15610a6e57506000610342565b816113881981610a7a57fe5b0483111560405180604001604052806002815260200161068760f31b81525090610ab75760405162461bcd60e51b81526004016103259190610d64565b50506127109102611388010490565b604080518082019091526002815261035360f41b602082015260009082610b005760405162461bcd60e51b81526004016103259190610d64565b5060408051808201909152600280825261068760f31b6020830152830490670de0b6b3a7640000821904851115610b4a5760405162461bcd60e51b81526004016103259190610d64565b508281670de0b6b3a764000086020181610b6057fe5b04949350505050565b6040518061014001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000151581525090565b604051806102400160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160001515815260200160006001600160a01b031681526020016000151581526020016000151581525090565b600080600080600080600080888a03610100811215610c75578485fd5b8935610c8081610e38565b985060208a0135610c9081610e38565b975060408a0135965060608a013595506020607f1982011215610cb1578485fd5b5060808901935060a0890135925060c0890135915060e08901356001600160a01b0381168114610cdf578182fd5b809150509295985092959890939650565b600060208284031215610d01578081fd5b6040516020810181811067ffffffffffffffff82111715610d20578283fd5b6040529135825250919050565b600060208284031215610d3e578081fd5b5051919050565b6001600160a01b0391909116815260200190565b901515815260200190565b6000602080835283518082850152825b81811015610d9057858101830151858201604001528201610d74565b81811115610da15783604083870101525b50601f01601f1916929092016040019392505050565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b90815260200190565b6001600160a01b0381168114610e4d57600080fd5b5056fea264697066735822122047aa69503c94a30b23f780d1ed67a6c9e36db5ac7ebf61a7adec2bc53ea82e0b64736f6c634300060c0033","key":"0x000001066008bdcc51df22dc3f3d4822acbe903f166a5d3e4e23cf71c5931bb2"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x0000012820dc5b8808bc4e1ad1fe3a11121b8d4b9ef359af07faea3e27805a2a"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0x1d93f60f105899172f7255c030301c3af4564edd4a48577dbdc448aec7ddb0ac","code":"0x6d4946c0e9f43f4dee607b0ef1fa1c3318585733ff","key":"0x00000173d46c52fadd9715da45f62f94667167d2400a60c75f571a187b7abc92"} +{"balance":"0","nonce":4,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x0000019595fd8804287771d1f49fe98fc93c2befb1a12974083c5d293f509af0"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x00000345b3c30032bee0bedb27cceb0974161c0b787164c8745d0f3eb5efa94d"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x0000034ae4431f973ed81cfe3917b0c6c36c1ad114d7096cc65775d465dee3ce"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x00000380fb07d21933c9494cfd8db690711cec40658726d2b228ec3749e445bc"} +{"balance":"100000000000000","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x000003ac9119ae8462da89e57be5ba78ce0da4e5db862be3dfc688442180f226"} +{"balance":"1000000000000000000","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x0000041df164838b3ac0f7e40de0c8e410c6bcab124bee0ee0d22b1a542feeb3"} +{"balance":"100000000000000","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x000004528d36ff92fd7811b38ca29028e8c20d7c5aa9b2226eb1e05d7c9ae441"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x000004951c3174ae1b84fe90200a4b027658fbe72fe857884f9ea884603a1a82"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x0000049cdd3a32e657e2c4b31a4dd2fa14cc938614d3180abbfded58938f56d0"} +{"balance":"1957736367000000000","nonce":20,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x000004a4df1dce6c3c9f9761d45f07b8faf257218510e6e0be036130a6251aaf"} +{"balance":"1500000000000000000","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x000004b1c73d819fe523fe9cce0e637a50d71569a6a330e28e71c2472eed2eab"} +{"balance":"0","nonce":1,"root":"0x86bba11eee32342aa42ad2f8c2aa4043f18faef6b80b193ce6503a24d0feae15","codeHash":"0xaca66479084605216a005cb7e191c7ca85f3240008b6c755e71ac8b040258b49","code":"0x608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063445df0ac1461005c5780638da5cb5b14610087578063fdacd576146100de575b600080fd5b34801561006857600080fd5b5061007161010b565b6040518082815260200191505060405180910390f35b34801561009357600080fd5b5061009c610111565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156100ea57600080fd5b5061010960048036038101908080359060200190929190505050610136565b005b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561019357806001819055505b505600a165627a7a723058207060295f37ce0ae2873de3ffa37201aa5a26fd948af057b98a268d989ac287a50029","storage":{"0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563":"41825736928c58561c2e8a272cbdf34906fab1c1","0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6":"01"},"key":"0x000004bdb4aaa50bb9a3b78c47c0755402fc64b176fecb434487bcc7b45f5e23"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0x31e986bc2d017ba3b4c7fdab548b0fe17760b019bdd31f2772e31e443df46433","code":"0x7323881c673951ed46f82a81d6b90e83adcfeafdb930146080604052600080fdfea26469706673582212208367dac7385beaffd201c05973e58eb58114fac80f52f6773fefaa9c34fcd67f64736f6c63430008070033","key":"0x00000509935593ff1a75b9f8bce367171bca07ee9276b23203025010f63ef7df"} +{"balance":"4294967296","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x0000051225764eed3d75c614070b0fcdb10b7ae9d4e0e21ead16f7b23400eb1d"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00000520ea5fc35b275a592a4fd58adbb5b74096302ec556c7e5195d267a31ae"} +{"balance":"10000000000000000","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x0000053fca53692c1fe26401db52b84edae3c5ae90d2fe7084a4420e80a393b1"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x00000558e64bef6beee2c1b0dd441371ce3df414b53e4af6d29f37e6c3c91761"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x00000590f5bca6aae0f861877aaad988462852a8cee57c059bffe12c9d4d6898"} +{"balance":"4294967296","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00000781f06168610af37e75eca93d47b51f3cf4a5630184047b07b193965c3e"} +{"balance":"0","nonce":2,"root":"0xd120a1ed89bd7f51060101131aa4ac9c236cedbda01f8cd18ebc54875f60ea60","codeHash":"0x2ce80549ecb0bea5cae8826a157b43ee9a99f1a41e49d145440151791e7fb1d4","code":"0x608060405234801561001057600080fd5b50600436106100cf5760003560e01c806370a082311161008c578063a6c3e6b911610066578063a6c3e6b914610285578063a9059cbb146102a9578063dd62ed3e146102d5578063f3fef3a314610303576100cf565b806370a082311461022b57806395d89b4114610251578063a457c2d714610259576100cf565b806306fdde03146100d4578063095ea7b31461015157806318160ddd1461019157806323b872dd146101ab578063313ce567146101e157806339509351146101ff575b600080fd5b6100dc610331565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101165781810151838201526020016100fe565b50505050905090810190601f1680156101435780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61017d6004803603604081101561016757600080fd5b506001600160a01b0381351690602001356103c7565b604080519115158252519081900360200190f35b6101996103e5565b60408051918252519081900360200190f35b61017d600480360360608110156101c157600080fd5b506001600160a01b038135811691602081013590911690604001356103eb565b6101e9610478565b6040805160ff9092168252519081900360200190f35b61017d6004803603604081101561021557600080fd5b506001600160a01b038135169060200135610481565b6101996004803603602081101561024157600080fd5b50356001600160a01b03166104d5565b6100dc6104f0565b61017d6004803603604081101561026f57600080fd5b506001600160a01b038135169060200135610551565b61028d6105bf565b604080516001600160a01b039092168252519081900360200190f35b61017d600480360360408110156102bf57600080fd5b506001600160a01b0381351690602001356105ce565b610199600480360360408110156102eb57600080fd5b506001600160a01b038135811691602001351661077a565b61032f6004803603604081101561031957600080fd5b506001600160a01b0381351690602001356107a5565b005b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103bd5780601f10610392576101008083540402835291602001916103bd565b820191906000526020600020905b8154815290600101906020018083116103a057829003601f168201915b5050505050905090565b60006103db6103d4610983565b8484610987565b5060015b92915050565b60025490565b60006103f8848484610a73565b61046e84610404610983565b61046985604051806060016040528060288152602001610d56602891396001600160a01b038a16600090815260016020526040812090610442610983565b6001600160a01b03168152602081019190915260400160002054919063ffffffff610bcf16565b610987565b5060019392505050565b60055460ff1690565b60006103db61048e610983565b84610469856001600061049f610983565b6001600160a01b03908116825260208083019390935260409182016000908120918c16815292529020549063ffffffff610c6616565b6001600160a01b031660009081526020819052604090205490565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156103bd5780601f10610392576101008083540402835291602001916103bd565b60006103db61055e610983565b8461046985604051806060016040528060258152602001610dc76025913960016000610588610983565b6001600160a01b03908116825260208083019390935260409182016000908120918d1681529252902054919063ffffffff610bcf16565b6007546001600160a01b031681565b60006105d8610cc7565b6001600160a01b031663b292b549846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060006040518083038186803b15801561062d57600080fd5b505afa158015610641573d6000803e3d6000fd5b505050508160001415610694576040805162461bcd60e51b8152602060048201526016602482015275696c6c6567616c207472616e736665722076616c756560501b604482015290519081900360640190fd5b61069c610cd6565b6001600160a01b031663aa5dcecc6040518163ffffffff1660e01b815260040160206040518083038186803b1580156106d457600080fd5b505afa1580156106e8573d6000803e3d6000fd5b505050506040513d60208110156106fe57600080fd5b505160408051630224547360e11b81523060048201523360248201526001600160a01b03868116604483015291519190921691630448a8e691606480830192600092919082900301818387803b15801561075757600080fd5b505af115801561076b573d6000803e3d6000fd5b505050506103df338484610a73565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6107ad610cc7565b6001600160a01b03166349616d79336107c4610cd6565b6001600160a01b03166306490f476040518163ffffffff1660e01b815260040160206040518083038186803b1580156107fc57600080fd5b505afa158015610810573d6000803e3d6000fd5b505050506040513d602081101561082657600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b039384166004820152929091166024830152516044808301926000929190829003018186803b15801561087657600080fd5b505afa15801561088a573d6000803e3d6000fd5b505050506000610898610cd6565b6001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156108d057600080fd5b505afa1580156108e4573d6000803e3d6000fd5b505050506040513d60208110156108fa57600080fd5b50516040805163a9059cbb60e01b81526001600160a01b0386811660048301526024820186905291519293509083169163a9059cbb916044808201926020929091908290030181600087803b15801561095257600080fd5b505af1158015610966573d6000803e3d6000fd5b505050506040513d602081101561097c57600080fd5b5050505050565b3390565b6001600160a01b0383166109cc5760405162461bcd60e51b8152600401808060200182810382526024815260200180610da36024913960400191505060405180910390fd5b6001600160a01b038216610a115760405162461bcd60e51b8152600401808060200182810382526022815260200180610d0e6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b038316610ab85760405162461bcd60e51b8152600401808060200182810382526025815260200180610d7e6025913960400191505060405180910390fd5b6001600160a01b038216610afd5760405162461bcd60e51b8152600401808060200182810382526023815260200180610ceb6023913960400191505060405180910390fd5b610b4081604051806060016040528060268152602001610d30602691396001600160a01b038616600090815260208190526040902054919063ffffffff610bcf16565b6001600160a01b038085166000908152602081905260408082209390935590841681522054610b75908263ffffffff610c6616565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008184841115610c5e5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610c23578181015183820152602001610c0b565b50505050905090810190601f168015610c505780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600082820183811015610cc0576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6006546001600160a01b031690565b60055461010090046001600160a01b03169056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa265627a7a72315820ad4c6d3578929dda1d76a7c7cf3a4ee733f4f566f597e375bf339a668e53f91a64736f6c63430005100032","storage":{"0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0":"3e23ff7819358dfdd857aeb3fb3e903f00f8bc3512","0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace":"989680","0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b":"5445524d53495a45000000000000000000000000000000000000000000000010","0xa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688":"fb5c0e6400a95e4191d46196073d30a289abd15c","0xb3626e58ba4d8a5b9a25e46e751ad36055af19f388714f48c9ee99037cf823b7":"989680","0xc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b":"7465726d2d73697a650000000000000000000000000000000000000000000012","0xf652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f":"f58d45ce73283b469559989fbcf4cc40390e3fe1"},"key":"0x000007e7e929eb9f970c731c12afb2e4a695d638ff39eb95514c9baa21713d93"} +{"balance":"0","nonce":1,"root":"0x3b915e0ed4e44a4e02fdb993126abe4c258080ee418c65f65a4ce33b4d989984","codeHash":"0xb11f53b27784bfa24e5da0c730223b145eaf2b391e92f4c898904ae4e4a9e11a","code":"0x6080604052600436106100f35760003560e01c806376428c9b1161008a578063acbe180011610059578063acbe180014610390578063addf027c146103cd578063ca31d586146103f6578063f8fa73a114610433576100f3565b806376428c9b1461029a5780637e7166f3146102d95780638a33be0114610316578063a81e9f7914610353576100f3565b80633c7fe5e3116100c65780633c7fe5e3146101db57806350743bb9146101f757806352e41f99146102345780636e6be03f1461025d576100f3565b80630a631576146100f85780631d414cbd146101375780631decbf181461016057806332393f2b1461019e575b600080fd5b34801561010457600080fd5b5061011f600480360381019061011a91906120e5565b610470565b60405161012e939291906121fb565b60405180910390f35b34801561014357600080fd5b5061015e60048036038101906101599190612265565b610542565b005b34801561016c57600080fd5b5061018760048036038101906101829190612362565b610671565b60405161019592919061244c565b60405180910390f35b3480156101aa57600080fd5b506101c560048036038101906101c0919061247c565b61099c565b6040516101d291906124f0565b60405180910390f35b6101f560048036038101906101f0919061250b565b610b7a565b005b34801561020357600080fd5b5061021e600480360381019061021991906120e5565b610d2a565b60405161022b919061255e565b60405180910390f35b34801561024057600080fd5b5061025b600480360381019061025691906125cf565b610d4d565b005b34801561026957600080fd5b50610284600480360381019061027f9190612669565b610e3e565b60405161029191906124f0565b60405180910390f35b3480156102a657600080fd5b506102c160048036038101906102bc9190612781565b611171565b6040516102d093929190612a56565b60405180910390f35b3480156102e557600080fd5b5061030060048036038101906102fb9190612aa2565b6113ff565b60405161030d9190612ae8565b60405180910390f35b34801561032257600080fd5b5061033d60048036038101906103389190612b59565b611417565b60405161034a919061255e565b60405180910390f35b34801561035f57600080fd5b5061037a60048036038101906103759190612265565b61151c565b604051610387919061255e565b60405180910390f35b34801561039c57600080fd5b506103b760048036038101906103b29190612c08565b61154b565b6040516103c491906124f0565b60405180910390f35b3480156103d957600080fd5b506103f460048036038101906103ef9190612ce3565b6118b6565b005b34801561040257600080fd5b5061041d60048036038101906104189190612d23565b611a41565b60405161042a9190612f12565b60405180910390f35b34801561043f57600080fd5b5061045a60048036038101906104559190612aa2565b611be0565b6040516104679190612ae8565b60405180910390f35b60006020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010154908060020180546104bf90612f63565b80601f01602080910402602001604051908101604052809291908181526020018280546104eb90612f63565b80156105385780601f1061050d57610100808354040283529160200191610538565b820191906000526020600020905b81548152906001019060200180831161051b57829003601f168201915b5050505050905083565b6000463033600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815461059390612fc4565b9190508190556040516020016105ac9493929190613076565b6040516020818303038152906040528051906020012090508233836040516020016105d9939291906130c4565b604051602081830303815290604052805190602001206002600083815260200190815260200160002081905550803373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fd48d52c7c6d0c940f3f8d07591e1800ef3a70daf79929a97ccd80b4494769fc7856040516106649190613101565b60405180910390a4505050565b60006060600560008b81526020019081526020016000205489338a8a6040516020016106a0949392919061313d565b60405160208183030381529060405280519060200120146106f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106ed906131e8565b60405180910390fd5b8873ffffffffffffffffffffffffffffffffffffffff1661079685858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506107888d8a8a60405160200161076d93929190613268565b60405160208183030381529060405280519060200120611bf8565b611c2890919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff16146107ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107e3906132de565b60405180910390fd5b600560008b8152602001908152602001600020600090558773ffffffffffffffffffffffffffffffffffffffff16878b88886040516024016108309392919061332b565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161089a919061338e565b6000604051808303816000865af19150503d80600081146108d7576040519150601f19603f3d011682016040523d82523d6000602084013e6108dc565b606091505b508092508193505050811561094157898973ffffffffffffffffffffffffffffffffffffffff167fc0977dab79883641ece94bb6a932ca83049f561ffff8d8daaeafdbc1acce9e0a88886040516109349291906133a5565b60405180910390a361098f565b898973ffffffffffffffffffffffffffffffffffffffff167fc7143b2270cddda57e0087ca5e2a4325657dcab10d10f6b1f9d5ce6b41cb97fc60405161098690613415565b60405180910390a35b9850989650505050505050565b60008073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415610a0d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a0490613481565b60405180910390fd5b84848484604051602001610a2494939291906134a1565b60405160208183030381529060405280519060200120905060405180606001604052808673ffffffffffffffffffffffffffffffffffffffff16815260200185815260200184848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505081525060008083815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550602082015181600101556040820151816002019080519060200190610b30929190612002565b50905050807fba204bad31c4ec4b9b54164af94ae10c4e7312f22c0f9c065d6319c928ec9e7a86868686604051610b6a94939291906134dc565b60405180910390a2949350505050565b818133604051602001610b8f939291906130c4565b60405160208183030381529060405280519060200120600260008581526020019081526020016000205414610bf9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bf090613568565b60405180910390fd5b6002600084815260200190815260200160002060009055828173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fadb4840bbd5f924665ae7e0e0c83de5c0fb40a98c9b57dba53a6c978127a622e3334604051610c70929190613588565b60405180910390a460008173ffffffffffffffffffffffffffffffffffffffff1634604051610c9e906135d7565b60006040518083038185875af1925050503d8060008114610cdb576040519150601f19603f3d011682016040523d82523d6000602084013e610ce0565b606091505b5050905080610d24576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d1b90613638565b60405180910390fd5b50505050565b60008060001b600560008481526020019081526020016000205414159050919050565b600560008781526020019081526020016000205485338686604051602001610d78949392919061313d565b6040516020818303038152906040528051906020012014610dce576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dc5906131e8565b60405180910390fd5b6005600087815260200190815260200160002060009055858573ffffffffffffffffffffffffffffffffffffffff167fc7143b2270cddda57e0087ca5e2a4325657dcab10d10f6b1f9d5ce6b41cb97fc8484604051610e2e929190613685565b60405180910390a3505050505050565b60008073ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff161415610eaf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ea690613481565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415610f1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f15906136f5565b60405180910390fd5b600360008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610fe7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fde90613761565b60405180910390fd5b6000600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050463033838d8d8d8d8d8d8d8d6040516020016110529c9b9a99989796959493929190613781565b60405160208183030381529060405280519060200120915089878787604051602001611081949392919061313d565b604051602081830303815290604052805190602001206005600084815260200190815260200160002081905550600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154809291906110fe90612fc4565b9190505550818a73ffffffffffffffffffffffffffffffffffffffff167f3a52c462346de2e9436a3868970892956828a11b9c43da1ed43740b12e1125ae8346338e8e8e8e8e8e8e60405161115c9a99989796959493929190613853565b60405180910390a35098975050505050505050565b60608060608484905067ffffffffffffffff811115611193576111926138e9565b5b6040519080825280602002602001820160405280156111c15781602001602082028036833780820191505090505b5092508484905067ffffffffffffffff8111156111e1576111e06138e9565b5b60405190808252806020026020018201604052801561120f5781602001602082028036833780820191505090505b5091508484905067ffffffffffffffff81111561122f5761122e6138e9565b5b60405190808252806020026020018201604052801561126257816020015b606081526020019060019003908161124d5790505b50905060005b858590508110156113f757600080600088888581811061128b5761128a613918565b5b90506020020135815260200190815260200160002090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168583815181106112da576112d9613918565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050806001015484838151811061132c5761132b613918565b5b60200260200101818152505080600201805461134790612f63565b80601f016020809104026020016040519081016040528092919081815260200182805461137390612f63565b80156113c05780601f10611395576101008083540402835291602001916113c0565b820191906000526020600020905b8154815290600101906020018083116113a357829003601f168201915b50505050508383815181106113d8576113d7613918565b5b60200260200101819052505080806113ef90612fc4565b915050611268565b509250925092565b60046020528060005260406000206000915090505481565b600080600090505b8888905081101561150b57600089898381811061143f5761143e613918565b5b90506020020160208101906114549190612aa2565b90508073ffffffffffffffffffffffffffffffffffffffff16635d51dbdc888a8989896040518663ffffffff1660e01b8152600401611497959493929190613947565b60206040518083038186803b1580156114af57600080fd5b505afa1580156114c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114e791906139af565b156114f757600192505050611511565b50808061150390612fc4565b91505061141f565b50600090505b979650505050505050565b60036020528160005260406000206020528060005260406000206000915091509054906101000a900460ff1681565b6000806000808a815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156115f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115ed90613a28565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161415611665576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161165c906136f5565b60405180910390fd5b600360008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661172e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161172590613761565b60405180910390fd5b6000600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050463033838d8d8d8d8d8d8d6040516020016117979b9a99989796959493929190613a48565b604051602081830303815290604052805190602001209250818888886040516020016117c6949392919061313d565b604051602081830303815290604052805190602001206005600085815260200190815260200160002081905550600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081548092919061184390612fc4565b9190505550828273ffffffffffffffffffffffffffffffffffffffff167feb39930cdcbb560e6422558a2468b93a215af60063622e63cbb165eba14c32038346338f8f8f8f8f8f8f6040516118a19a99989796959493929190613853565b60405180910390a35050979650505050505050565b6000600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541415611944576001600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fc2e532a12bbcce2bfa2ef9e4bee80180e4e1b1f78618f0d20bc49a648b577c5683604051611a35919061255e565b60405180910390a35050565b60608686905089899050148015611a5d57508484905089899050145b8015611a6e57508282905089899050145b611aad576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611aa490613b46565b60405180910390fd5b8888905067ffffffffffffffff811115611aca57611ac96138e9565b5b604051908082528060200260200182016040528015611af85781602001602082028036833780820191505090505b50905060005b89899050811015611bd057611b988d8d8d8d8d86818110611b2257611b21613918565b5b905060200201358c8c87818110611b3c57611b3b613918565b5b905060200201358b8b88818110611b5657611b55613918565b5b9050602002016020810190611b6b9190612aa2565b8a8a89818110611b7e57611b7d613918565b5b9050602002016020810190611b939190612aa2565b611417565b828281518110611bab57611baa613918565b5b6020026020010190151590811515815250508080611bc890612fc4565b915050611afe565b509b9a5050505050505050505050565b60016020528060005260406000206000915090505481565b600081604051602001611c0b9190613bbd565b604051602081830303815290604052805190602001209050919050565b6000806000611c378585611c4f565b91509150611c4481611cd2565b819250505092915050565b600080604183511415611c915760008060006020860151925060408601519150606086015160001a9050611c8587828585611ea7565b94509450505050611ccb565b604083511415611cc2576000806020850151915060408501519050611cb7868383611fb4565b935093505050611ccb565b60006002915091505b9250929050565b60006004811115611ce657611ce5613be3565b5b816004811115611cf957611cf8613be3565b5b1415611d0457611ea4565b60016004811115611d1857611d17613be3565b5b816004811115611d2b57611d2a613be3565b5b1415611d6c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d6390613c5e565b60405180910390fd5b60026004811115611d8057611d7f613be3565b5b816004811115611d9357611d92613be3565b5b1415611dd4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dcb90613cca565b60405180910390fd5b60036004811115611de857611de7613be3565b5b816004811115611dfb57611dfa613be3565b5b1415611e3c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e3390613d5c565b60405180910390fd5b600480811115611e4f57611e4e613be3565b5b816004811115611e6257611e61613be3565b5b1415611ea3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e9a90613dee565b60405180910390fd5b5b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c1115611ee2576000600391509150611fab565b601b8560ff1614158015611efa5750601c8560ff1614155b15611f0c576000600491509150611fab565b600060018787878760405160008152602001604052604051611f319493929190613e2a565b6020604051602081039080840390855afa158015611f53573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611fa257600060019250925050611fab565b80600092509250505b94509492505050565b6000806000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff85169150601b8560ff1c019050611ff487828885611ea7565b935093505050935093915050565b82805461200e90612f63565b90600052602060002090601f0160209004810192826120305760008555612077565b82601f1061204957805160ff1916838001178555612077565b82800160010185558215612077579182015b8281111561207657825182559160200191906001019061205b565b5b5090506120849190612088565b5090565b5b808211156120a1576000816000905550600101612089565b5090565b600080fd5b600080fd5b6000819050919050565b6120c2816120af565b81146120cd57600080fd5b50565b6000813590506120df816120b9565b92915050565b6000602082840312156120fb576120fa6120a5565b5b6000612109848285016120d0565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061213d82612112565b9050919050565b61214d81612132565b82525050565b61215c816120af565b82525050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561219c578082015181840152602081019050612181565b838111156121ab576000848401525b50505050565b6000601f19601f8301169050919050565b60006121cd82612162565b6121d7818561216d565b93506121e781856020860161217e565b6121f0816121b1565b840191505092915050565b60006060820190506122106000830186612144565b61221d6020830185612153565b818103604083015261222f81846121c2565b9050949350505050565b61224281612132565b811461224d57600080fd5b50565b60008135905061225f81612239565b92915050565b6000806040838503121561227c5761227b6120a5565b5b600061228a85828601612250565b925050602061229b85828601612250565b9150509250929050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6122da816122a5565b81146122e557600080fd5b50565b6000813590506122f7816122d1565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112612322576123216122fd565b5b8235905067ffffffffffffffff81111561233f5761233e612302565b5b60208301915083600182028301111561235b5761235a612307565b5b9250929050565b60008060008060008060008060c0898b031215612382576123816120a5565b5b60006123908b828c016120d0565b98505060206123a18b828c01612250565b97505060406123b28b828c01612250565b96505060606123c38b828c016122e8565b955050608089013567ffffffffffffffff8111156123e4576123e36120aa565b5b6123f08b828c0161230c565b945094505060a089013567ffffffffffffffff811115612413576124126120aa565b5b61241f8b828c0161230c565b92509250509295985092959890939650565b60008115159050919050565b61244681612431565b82525050565b6000604082019050612461600083018561243d565b818103602083015261247381846121c2565b90509392505050565b60008060008060608587031215612496576124956120a5565b5b60006124a487828801612250565b94505060206124b5878288016120d0565b935050604085013567ffffffffffffffff8111156124d6576124d56120aa565b5b6124e28782880161230c565b925092505092959194509250565b60006020820190506125056000830184612153565b92915050565b600080600060608486031215612524576125236120a5565b5b6000612532868287016120d0565b935050602061254386828701612250565b925050604061255486828701612250565b9150509250925092565b6000602082019050612573600083018461243d565b92915050565b60008083601f84011261258f5761258e6122fd565b5b8235905067ffffffffffffffff8111156125ac576125ab612302565b5b6020830191508360018202830111156125c8576125c7612307565b5b9250929050565b60008060008060008060a087890312156125ec576125eb6120a5565b5b60006125fa89828a016120d0565b965050602061260b89828a01612250565b955050604061261c89828a01612250565b945050606061262d89828a016122e8565b935050608087013567ffffffffffffffff81111561264e5761264d6120aa565b5b61265a89828a01612579565b92509250509295509295509295565b60008060008060008060008060e0898b031215612689576126886120a5565b5b60006126978b828c01612250565b98505060206126a88b828c016120d0565b97505060406126b98b828c01612250565b96505060606126ca8b828c01612250565b95505060806126db8b828c01612250565b94505060a06126ec8b828c016122e8565b93505060c089013567ffffffffffffffff81111561270d5761270c6120aa565b5b6127198b828c0161230c565b92509250509295985092959890939650565b60008083601f840112612741576127406122fd565b5b8235905067ffffffffffffffff81111561275e5761275d612302565b5b60208301915083602082028301111561277a57612779612307565b5b9250929050565b60008060208385031215612798576127976120a5565b5b600083013567ffffffffffffffff8111156127b6576127b56120aa565b5b6127c28582860161272b565b92509250509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61280381612132565b82525050565b600061281583836127fa565b60208301905092915050565b6000602082019050919050565b6000612839826127ce565b61284381856127d9565b935061284e836127ea565b8060005b8381101561287f5781516128668882612809565b975061287183612821565b925050600181019050612852565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6128c1816120af565b82525050565b60006128d383836128b8565b60208301905092915050565b6000602082019050919050565b60006128f78261288c565b6129018185612897565b935061290c836128a8565b8060005b8381101561293d57815161292488826128c7565b975061292f836128df565b925050600181019050612910565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600082825260208201905092915050565b600061299282612162565b61299c8185612976565b93506129ac81856020860161217e565b6129b5816121b1565b840191505092915050565b60006129cc8383612987565b905092915050565b6000602082019050919050565b60006129ec8261294a565b6129f68185612955565b935083602082028501612a0885612966565b8060005b85811015612a445784840389528151612a2585826129c0565b9450612a30836129d4565b925060208a01995050600181019050612a0c565b50829750879550505050505092915050565b60006060820190508181036000830152612a70818661282e565b90508181036020830152612a8481856128ec565b90508181036040830152612a9881846129e1565b9050949350505050565b600060208284031215612ab857612ab76120a5565b5b6000612ac684828501612250565b91505092915050565b6000819050919050565b612ae281612acf565b82525050565b6000602082019050612afd6000830184612ad9565b92915050565b60008083601f840112612b1957612b186122fd565b5b8235905067ffffffffffffffff811115612b3657612b35612302565b5b602083019150836020820283011115612b5257612b51612307565b5b9250929050565b600080600080600080600060c0888a031215612b7857612b776120a5565b5b600088013567ffffffffffffffff811115612b9657612b956120aa565b5b612ba28a828b01612b03565b97509750506020612bb58a828b01612250565b9550506040612bc68a828b016120d0565b9450506060612bd78a828b016120d0565b9350506080612be88a828b01612250565b92505060a0612bf98a828b01612250565b91505092959891949750929550565b600080600080600080600060c0888a031215612c2757612c266120a5565b5b6000612c358a828b016120d0565b9750506020612c468a828b01612250565b9650506040612c578a828b01612250565b9550506060612c688a828b01612250565b9450506080612c798a828b016122e8565b93505060a088013567ffffffffffffffff811115612c9a57612c996120aa565b5b612ca68a828b0161230c565b925092505092959891949750929550565b612cc081612431565b8114612ccb57600080fd5b50565b600081359050612cdd81612cb7565b92915050565b60008060408385031215612cfa57612cf96120a5565b5b6000612d0885828601612250565b9250506020612d1985828601612cce565b9150509250929050565b600080600080600080600080600080600060c08c8e031215612d4857612d476120a5565b5b60008c013567ffffffffffffffff811115612d6657612d656120aa565b5b612d728e828f01612b03565b9b509b50506020612d858e828f01612250565b99505060408c013567ffffffffffffffff811115612da657612da56120aa565b5b612db28e828f0161272b565b985098505060608c013567ffffffffffffffff811115612dd557612dd46120aa565b5b612de18e828f0161272b565b965096505060808c013567ffffffffffffffff811115612e0457612e036120aa565b5b612e108e828f01612b03565b945094505060a08c013567ffffffffffffffff811115612e3357612e326120aa565b5b612e3f8e828f01612b03565b92509250509295989b509295989b9093969950565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b612e8981612431565b82525050565b6000612e9b8383612e80565b60208301905092915050565b6000602082019050919050565b6000612ebf82612e54565b612ec98185612e5f565b9350612ed483612e70565b8060005b83811015612f05578151612eec8882612e8f565b9750612ef783612ea7565b925050600181019050612ed8565b5085935050505092915050565b60006020820190508181036000830152612f2c8184612eb4565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680612f7b57607f821691505b60208210811415612f8f57612f8e612f34565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612fcf82612acf565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561300257613001612f95565b5b600182019050919050565b6000819050919050565b61302861302382612acf565b61300d565b82525050565b60008160601b9050919050565b60006130468261302e565b9050919050565b60006130588261303b565b9050919050565b61307061306b82612132565b61304d565b82525050565b60006130828287613017565b602082019150613092828661305f565b6014820191506130a2828561305f565b6014820191506130b28284613017565b60208201915081905095945050505050565b60006130d0828661305f565b6014820191506130e0828561305f565b6014820191506130f0828461305f565b601482019150819050949350505050565b60006020820190506131166000830184612144565b92915050565b6000819050919050565b613137613132826122a5565b61311c565b82525050565b6000613149828761305f565b601482019150613159828661305f565b601482019150613169828561305f565b6014820191506131798284613126565b60048201915081905095945050505050565b600082825260208201905092915050565b7f496e76616c696420726571756573742066756c66696c6c6d656e740000000000600082015250565b60006131d2601b8361318b565b91506131dd8261319c565b602082019050919050565b60006020820190508181036000830152613201816131c5565b9050919050565b6000819050919050565b61322361321e826120af565b613208565b82525050565b600081905092915050565b82818337600083830152505050565b600061324f8385613229565b935061325c838584613234565b82840190509392505050565b60006132748286613212565b602082019150613285828486613243565b9150819050949350505050565b7f496e76616c6964207369676e6174757265000000000000000000000000000000600082015250565b60006132c860118361318b565b91506132d382613292565b602082019050919050565b600060208201905081810360008301526132f7816132bb565b9050919050565b600061330a838561216d565b9350613317838584613234565b613320836121b1565b840190509392505050565b60006040820190506133406000830186612153565b81810360208301526133538184866132fe565b9050949350505050565b600061336882612162565b6133728185613229565b935061338281856020860161217e565b80840191505092915050565b600061339a828461335d565b915081905092915050565b600060208201905081810360008301526133c08184866132fe565b90509392505050565b7f46756c66696c6c6d656e74206661696c656420756e65787065637465646c7900600082015250565b60006133ff601f8361318b565b915061340a826133c9565b602082019050919050565b6000602082019050818103600083015261342e816133f2565b9050919050565b7f4169726e6f64652061646472657373207a65726f000000000000000000000000600082015250565b600061346b60148361318b565b915061347682613435565b602082019050919050565b6000602082019050818103600083015261349a8161345e565b9050919050565b60006134ad828761305f565b6014820191506134bd8286613212565b6020820191506134ce828486613243565b915081905095945050505050565b60006060820190506134f16000830187612144565b6134fe6020830186612153565b81810360408301526135118184866132fe565b905095945050505050565b7f496e76616c6964207769746864726177616c2066756c66696c6c6d656e740000600082015250565b6000613552601e8361318b565b915061355d8261351c565b602082019050919050565b6000602082019050818103600083015261358181613545565b9050919050565b600060408201905061359d6000830185612144565b6135aa6020830184612ad9565b9392505050565b50565b60006135c1600083613229565b91506135cc826135b1565b600082019050919050565b60006135e2826135b4565b9150819050919050565b7f5472616e73666572206661696c65640000000000000000000000000000000000600082015250565b6000613622600f8361318b565b915061362d826135ec565b602082019050919050565b6000602082019050818103600083015261365181613615565b9050919050565b6000613664838561318b565b9350613671838584613234565b61367a836121b1565b840190509392505050565b600060208201905081810360008301526136a0818486613658565b90509392505050565b7f46756c66696c6c2061646472657373204169726e6f6465527270000000000000600082015250565b60006136df601a8361318b565b91506136ea826136a9565b602082019050919050565b6000602082019050818103600083015261370e816136d2565b9050919050565b7f526571756573746572206e6f742073706f6e736f726564000000000000000000600082015250565b600061374b60178361318b565b915061375682613715565b602082019050919050565b6000602082019050818103600083015261377a8161373e565b9050919050565b600061378d828f613017565b60208201915061379d828e61305f565b6014820191506137ad828d61305f565b6014820191506137bd828c613017565b6020820191506137cd828b61305f565b6014820191506137dd828a613212565b6020820191506137ed828961305f565b6014820191506137fd828861305f565b60148201915061380d828761305f565b60148201915061381d8286613126565b60048201915061382e828486613243565b91508190509d9c50505050505050505050505050565b61384d816122a5565b82525050565b600061012082019050613869600083018d612ad9565b613876602083018c612ad9565b613883604083018b612144565b613890606083018a612153565b61389d6080830189612144565b6138aa60a0830188612144565b6138b760c0830187612144565b6138c460e0830186613844565b8181036101008301526138d88184866132fe565b90509b9a5050505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060a08201905061395c6000830188612153565b6139696020830187612144565b6139766040830186612153565b6139836060830185612144565b6139906080830184612144565b9695505050505050565b6000815190506139a981612cb7565b92915050565b6000602082840312156139c5576139c46120a5565b5b60006139d38482850161399a565b91505092915050565b7f54656d706c61746520646f6573206e6f74206578697374000000000000000000600082015250565b6000613a1260178361318b565b9150613a1d826139dc565b602082019050919050565b60006020820190508181036000830152613a4181613a05565b9050919050565b6000613a54828e613017565b602082019150613a64828d61305f565b601482019150613a74828c61305f565b601482019150613a84828b613017565b602082019150613a94828a613212565b602082019150613aa4828961305f565b601482019150613ab4828861305f565b601482019150613ac4828761305f565b601482019150613ad48286613126565b600482019150613ae5828486613243565b91508190509c9b505050505050505050505050565b7f556e657175616c20706172616d65746572206c656e6774687300000000000000600082015250565b6000613b3060198361318b565b9150613b3b82613afa565b602082019050919050565b60006020820190508181036000830152613b5f81613b23565b9050919050565b600081905092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b6000613ba7601c83613b66565b9150613bb282613b71565b601c82019050919050565b6000613bc882613b9a565b9150613bd48284613212565b60208201915081905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b6000613c4860188361318b565b9150613c5382613c12565b602082019050919050565b60006020820190508181036000830152613c7781613c3b565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b6000613cb4601f8361318b565b9150613cbf82613c7e565b602082019050919050565b60006020820190508181036000830152613ce381613ca7565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b6000613d4660228361318b565b9150613d5182613cea565b604082019050919050565b60006020820190508181036000830152613d7581613d39565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202776272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b6000613dd860228361318b565b9150613de382613d7c565b604082019050919050565b60006020820190508181036000830152613e0781613dcb565b9050919050565b600060ff82169050919050565b613e2481613e0e565b82525050565b6000608082019050613e3f6000830187612153565b613e4c6020830186613e1b565b613e596040830185612153565b613e666060830184612153565b9594505050505056fea2646970667358221220d352a72cc353a3ece9a6eb186d121909b8eb59de68badbe12851d5a9d07b878a64736f6c63430008090033","storage":{"0x0ecbe5501e54cb33f7294330d65a46c284f37634ef832d3841bf766aaf8f8c51":"01","0x1494d3b37901f15029d850d3c4115c72c0117452357ddf679604d379f11b8c13":"0b","0x439567d77236708d0569beb37f08678c9ef18e3bd9d8ab94fb30abc14e7f14eb":"01","0x482aed70bac81ec2c4475258de5e82028420baa606e503a97fe10319797a4dfb":"01","0x54a7672470073186752e22a9a809bba21dc7387b3e151cbf60d6f661b98f2b09":"01","0x5a4eed3b7b3fb6085e6ebf6bf3a4181812651878d080483a786fa8ab1a5ddfd3":"01","0x6b597eaf705ec642ba65f83afab6912d020b1c6f552dccb4ce68fbeaf2303601":"01","0x83adeb540ea0e6379665a83fc809035d7127dcb11a80bb0dc06b2f95791b2a28":"01","0x8a68a25dd19894ed7fbbe0bda4b79beee99979319074edf868bba105654d00a6":"01","0xc2f368d4fe97d563dcc445c6979432258965442232d5ae6ff8d28e0a2f2b2bd8":"01","0xc8d6cb9d0f8d4b6debc46d0e66bbd39fade510a38cbf9e269c3bcc0703d2a9b5":"01","0xdf49733068289fbd6e0f4719611c380bff8692f1accb832dd7b3e713a6e1c557":"01"},"key":"0x000008bd1b0754843a6441ad896a820d255b340fcdb05c60f7e3b1cacae25034"} +{"balance":"0","nonce":2,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0x70ce20ef6559062c915ebc1568a1990a42607820644eb99ab254558335e2fad4","code":"0x6080604052600080fdfea264697066735822122048cfd26d1401e85ae56852a934004ba9519da5f6d8e86d77ec6f5fa52b86a04964736f6c63430006090033","key":"0x000008c33633b6d82f2127af225eccfa3ad6ac68378bfc36bde4b949033b710f"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x0000090c682c405c8958719220b602a2e90ddac561f131f9d3f6a1043dca547e"} +{"balance":"10000000000000000","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00000963935a4877c8c17c37fd3be2304f42545b922cf598876e0dc797d1d60b"} +{"balance":"1000000000000000000","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x0000097f84ec3819d153a4b339aeca4718e11dca77983b1973a28e11a24ce433"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x0000097f90f2d322b978571df7d21da99523a95000d40467a8742f9824d146ec"} +{"balance":"1","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x0000098aeb5e89ca78276b2a502af3a45eb35b9fdcdf5291c0e17a2f1090bd78"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x000009e605954d7f5b6321853e150377a0fd622b482cad1ce7efe67c4809f83e"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x00000ada2a4e508fb4dc394cc461f6b11876d057c5296cddd41250f4e0f8968a"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00000bc988ebfabe8fc7a68ab34e56cd9b0331547503b4a07354662de55964d6"} +{"balance":"0","nonce":1,"root":"0x39f41fb88580aaa613a47cf442fd48709892a8cfca3d066cfe2bb41bfe3cc529","codeHash":"0xc77da73bc2118b542dc2f909fb3b428364b4c3cd39d7c5f0314426697ffaddd5","code":"0x608060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630900f01014610067578063445df0ac146100aa5780638da5cb5b146100d5578063fdacd5761461012c575b600080fd5b34801561007357600080fd5b506100a8600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610159565b005b3480156100b657600080fd5b506100bf610241565b6040518082815260200191505060405180910390f35b3480156100e157600080fd5b506100ea610247565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561013857600080fd5b506101576004803603810190808035906020019092919050505061026c565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561023d578190508073ffffffffffffffffffffffffffffffffffffffff1663fdacd5766001546040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b15801561022457600080fd5b505af1158015610238573d6000803e3d6000fd5b505050505b5050565b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102c957806001819055505b505600a165627a7a7230582011f6591d9e69c907645e27b87cb9c707554ac2f7f708fbc3995fe3b00ceebe3e0029","storage":{"0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563":"9eed88aece4e78b97f190956a75dd7e27f36ccd6","0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6":"01"},"key":"0x00000be487e4219fdda8ef2a7b7ad1edd0751d2663a1100a449036054258eaf1"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x00000c17e07e06d6808155348987826c1b3ebef5f9a33a64ac6d418ea826d728"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xd80cd839dd3957d572b90780ada202a13936fa2875daea94216263371e9ef1d2","code":"0x6eb3f879cb30fe243b4dfee438691c043318585733ff","key":"0x00000ce5e25983fe18d9f6a6328b1df1379121d6c8384a003afb57442fce71c3"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00000cea0c32b8eec5a91b56a17ff7e323dbac9a520968e37309b269580dd079"} +{"balance":"3000000000000000000","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00000df87bfabd19bd0d38456b775585e41f1041c73ed30f18a2c8a91ce8c641"} +{"balance":"631537500000000","nonce":4,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00000e181b058154547f0bbd7cf7839c8dd547d2b70d5b8991c69add69ef11db"} +{"balance":"0","nonce":1,"root":"0x346291b43455024566e331ef5c6d929ac1662188d706d343ec77b98e4bdd156d","codeHash":"0xc2b39ba2ec5bd48a17de1087d1dfbdced77c1676558133a74e8b248823d8d062","code":"0x60606040525b603c5b60006010603e565b9050593681016040523660008237602060003683856040603f5a0204f41560545760206000f35bfe5b50565b005b733203a215abce94ee15ca6cc25d757e6d8a08d4285b905600a165627a7a7230582024bff7790866f651effcaba111bbe0172d470725422945c849c6cd34cdd228360029","storage":{"0x3a8d35b0699dc8e9e9331427e48a2865fe1bff8ea565a17f770a2a52be3c12f3":"01","0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace":"46be25efb9a5aca3ad3c4fb3ca310f21341d3cda","0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6":"3390a00e4166e2bf63e91ec6c82f9a8d122912ca"},"key":"0x00000e2c520225af68c03284f4951e8a61981adcdc9b590e7b77ca5a5485f0bc"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00000e46e374f599fb45e412794aeeba08b5186edd6dd59b56c79fc977ef0462"} +{"balance":"932000000000000","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00000e4c1ec82709dfb1688952f6de1c5eb6d9b6e4581c167d91d54bc7195dd1"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x00000ebe7a005707a693e5b5035c4b734a1dd4a8a05bb38b196a2230a4c517f5"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x00000f7d0d83200c769667d8e55c823585c0897b50e6c70035440c302bf92d6c"} +{"balance":"280020000000777","nonce":1,"root":"0x0d577c02c841137fe1b7d7e2185cac83cc597cc1d00d4d77a0911fb1abc300b2","codeHash":"0x89ac567c4105cdec863ef0d43f5353fafac23ab3dd3f30a928ec0471817b5f3c","code":"0x600036818037808036817332b9095160b00a641b9dbe0ba3c2de83b052b4845af43d82803e15602c573d90f35b3d90fd","storage":{"0x0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9":"ecc9c5fff8937594c5592eb4fa2522a300000000","0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0":"eacc301fee591a459d572cf1c5daa423f4433785","0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563":"360d2b7d240ec0643b6d819ba81a09e40e5bcd","0x31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c68":"02","0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace":"02540be400","0x55f448fdea98c4d29eb340757ef0a66cd03dbb9538908a6a81d96026b71ec475":"012c","0x66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a090":"0bf4","0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b":"3b9aca00","0x8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac802":"03e7","0xa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688":"02540be400","0xbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec3444":"5bcfc169","0xc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b":"0186a0","0xc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c15":"01","0xc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a8":"0309","0xce6d7b5282bd9a3661ae061feed1dbda4e52ab073b1f9285be6e155d9c38d4ec":"b4","0xd833147d7dc355ba459fc788f669e58cfaf9dc25ddcd0702e87d69c7b5124289":"0e10","0xf652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f":"aba1c9637f79ae219a6aa0e93b47d5a6b91eb7de"},"key":"0x00000fb8adf4583845d25c8cd5e407235e69fa0ee31f3c680875e1817fa0d600"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0x4e81033b3019c30e0f56ca20bc8a59de5d8733bb1c3dbb17eb34d1d38257619d","code":"0x731dc109eeb0964bac8df40a3def3c3fcf66de172830146080604052600080fd00a165627a7a7230582064e1208d5efd0b1b8aa7126bd89b553f1fc7eb63865eb66153dc90488f36721f0029","key":"0x00000feebae88fa7e72792545613c00f0b294220b4a07fa6c0c4854b94b16618"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x00001049983d3cac934135fe21e124644ebed746cd2e76179605eff2cd0608fc"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xd80cd839dd3957d572b90780ada202a13936fa2875daea94216263371e9ef1d2","code":"0x6eb3f879cb30fe243b4dfee438691c043318585733ff","key":"0x0000113fc70779b850f7cd07cefba4ac0dc8d6e53537482475263b864ed3f4e8"} +{"balance":"0","nonce":1,"root":"0xb7630d04245228a3a6d5cc5390c830bd2eba125b783d3ddb5d2d77814f5294a6","codeHash":"0x5b83bdbcc56b2e630f2807bbadd2b0c21619108066b92a58de081261089e9ce5","code":"0x608060405234801561001057600080fd5b50600436106101b95760003560e01c80636a627842116100f9578063ba9a7a5611610097578063d21220a711610071578063d21220a7146105da578063d505accf146105e2578063dd62ed3e14610640578063fff6cae91461067b576101b9565b8063ba9a7a5614610597578063bc25cf771461059f578063c45a0155146105d2576101b9565b80637ecebe00116100d35780637ecebe00146104d757806389afcb441461050a57806395d89b4114610556578063a9059cbb1461055e576101b9565b80636a6278421461046957806370a082311461049c5780637464fc3d146104cf576101b9565b806323b872dd116101665780633644e515116101405780633644e51514610416578063485cc9551461041e5780635909c0d5146104595780635a3d549314610461576101b9565b806323b872dd146103ad57806330adf81f146103f0578063313ce567146103f8576101b9565b8063095ea7b311610197578063095ea7b3146103155780630dfe16811461036257806318160ddd14610393576101b9565b8063022c0d9f146101be57806306fdde03146102595780630902f1ac146102d6575b600080fd5b610257600480360360808110156101d457600080fd5b81359160208101359173ffffffffffffffffffffffffffffffffffffffff604083013516919081019060808101606082013564010000000081111561021857600080fd5b82018360208201111561022a57600080fd5b8035906020019184600183028401116401000000008311171561024c57600080fd5b509092509050610683565b005b610261610d57565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561029b578181015183820152602001610283565b50505050905090810190601f1680156102c85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102de610d90565b604080516dffffffffffffffffffffffffffff948516815292909316602083015263ffffffff168183015290519081900360600190f35b61034e6004803603604081101561032b57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610de5565b604080519115158252519081900360200190f35b61036a610dfc565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b61039b610e18565b60408051918252519081900360200190f35b61034e600480360360608110156103c357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135610e1e565b61039b610efd565b610400610f21565b6040805160ff9092168252519081900360200190f35b61039b610f26565b6102576004803603604081101561043457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516610f2c565b61039b611005565b61039b61100b565b61039b6004803603602081101561047f57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611011565b61039b600480360360208110156104b257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166113cb565b61039b6113dd565b61039b600480360360208110156104ed57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166113e3565b61053d6004803603602081101561052057600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166113f5565b6040805192835260208301919091528051918290030190f35b610261611892565b61034e6004803603604081101561057457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356118cb565b61039b6118d8565b610257600480360360208110156105b557600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166118de565b61036a611ad4565b61036a611af0565b610257600480360360e08110156105f857600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060408101359060608101359060ff6080820135169060a08101359060c00135611b0c565b61039b6004803603604081101561065657600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516611dd8565b610257611df5565b600c546001146106f457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f556e697377617056323a204c4f434b4544000000000000000000000000000000604482015290519081900360640190fd5b6000600c55841515806107075750600084115b61075c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180612b2f6025913960400191505060405180910390fd5b600080610767610d90565b5091509150816dffffffffffffffffffffffffffff168710801561079a5750806dffffffffffffffffffffffffffff1686105b6107ef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180612b786021913960400191505060405180910390fd5b600654600754600091829173ffffffffffffffffffffffffffffffffffffffff91821691908116908916821480159061085457508073ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff1614155b6108bf57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f556e697377617056323a20494e56414c49445f544f0000000000000000000000604482015290519081900360640190fd5b8a156108d0576108d0828a8d611fdb565b89156108e1576108e1818a8c611fdb565b86156109c3578873ffffffffffffffffffffffffffffffffffffffff166310d1e85c338d8d8c8c6040518663ffffffff1660e01b8152600401808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001858152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509650505050505050600060405180830381600087803b1580156109aa57600080fd5b505af11580156109be573d6000803e3d6000fd5b505050505b604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b158015610a2f57600080fd5b505afa158015610a43573d6000803e3d6000fd5b505050506040513d6020811015610a5957600080fd5b5051604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905191955073ffffffffffffffffffffffffffffffffffffffff8316916370a0823191602480820192602092909190829003018186803b158015610acb57600080fd5b505afa158015610adf573d6000803e3d6000fd5b505050506040513d6020811015610af557600080fd5b5051925060009150506dffffffffffffffffffffffffffff85168a90038311610b1f576000610b35565b89856dffffffffffffffffffffffffffff160383035b9050600089856dffffffffffffffffffffffffffff16038311610b59576000610b6f565b89856dffffffffffffffffffffffffffff160383035b90506000821180610b805750600081115b610bd5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180612b546024913960400191505060405180910390fd5b6000610c09610beb84600363ffffffff6121e816565b610bfd876103e863ffffffff6121e816565b9063ffffffff61226e16565b90506000610c21610beb84600363ffffffff6121e816565b9050610c59620f4240610c4d6dffffffffffffffffffffffffffff8b8116908b1663ffffffff6121e816565b9063ffffffff6121e816565b610c69838363ffffffff6121e816565b1015610cd657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f556e697377617056323a204b0000000000000000000000000000000000000000604482015290519081900360640190fd5b5050610ce4848488886122e0565b60408051838152602081018390528082018d9052606081018c9052905173ffffffffffffffffffffffffffffffffffffffff8b169133917fd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d8229181900360800190a350506001600c55505050505050505050565b6040518060400160405280600a81526020017f556e69737761702056320000000000000000000000000000000000000000000081525081565b6008546dffffffffffffffffffffffffffff808216926e0100000000000000000000000000008304909116917c0100000000000000000000000000000000000000000000000000000000900463ffffffff1690565b6000610df233848461259c565b5060015b92915050565b60065473ffffffffffffffffffffffffffffffffffffffff1681565b60005481565b73ffffffffffffffffffffffffffffffffffffffff831660009081526002602090815260408083203384529091528120547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14610ee85773ffffffffffffffffffffffffffffffffffffffff84166000908152600260209081526040808320338452909152902054610eb6908363ffffffff61226e16565b73ffffffffffffffffffffffffffffffffffffffff851660009081526002602090815260408083203384529091529020555b610ef384848461260b565b5060019392505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b601281565b60035481565b60055473ffffffffffffffffffffffffffffffffffffffff163314610fb257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f556e697377617056323a20464f5242494444454e000000000000000000000000604482015290519081900360640190fd5b6006805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560078054929093169116179055565b60095481565b600a5481565b6000600c5460011461108457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f556e697377617056323a204c4f434b4544000000000000000000000000000000604482015290519081900360640190fd5b6000600c81905580611094610d90565b50600654604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905193955091935060009273ffffffffffffffffffffffffffffffffffffffff909116916370a08231916024808301926020929190829003018186803b15801561110e57600080fd5b505afa158015611122573d6000803e3d6000fd5b505050506040513d602081101561113857600080fd5b5051600754604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905192935060009273ffffffffffffffffffffffffffffffffffffffff909216916370a0823191602480820192602092909190829003018186803b1580156111b157600080fd5b505afa1580156111c5573d6000803e3d6000fd5b505050506040513d60208110156111db57600080fd5b505190506000611201836dffffffffffffffffffffffffffff871663ffffffff61226e16565b90506000611225836dffffffffffffffffffffffffffff871663ffffffff61226e16565b9050600061123387876126ec565b600054909150806112705761125c6103e8610bfd611257878763ffffffff6121e816565b612878565b985061126b60006103e86128ca565b6112cd565b6112ca6dffffffffffffffffffffffffffff8916611294868463ffffffff6121e816565b8161129b57fe5b046dffffffffffffffffffffffffffff89166112bd868563ffffffff6121e816565b816112c457fe5b0461297a565b98505b60008911611326576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180612bc16028913960400191505060405180910390fd5b6113308a8a6128ca565b61133c86868a8a6122e0565b811561137e5760085461137a906dffffffffffffffffffffffffffff808216916e01000000000000000000000000000090041663ffffffff6121e816565b600b555b6040805185815260208101859052815133927f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f928290030190a250506001600c5550949695505050505050565b60016020526000908152604090205481565b600b5481565b60046020526000908152604090205481565b600080600c5460011461146957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f556e697377617056323a204c4f434b4544000000000000000000000000000000604482015290519081900360640190fd5b6000600c81905580611479610d90565b50600654600754604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905194965092945073ffffffffffffffffffffffffffffffffffffffff9182169391169160009184916370a08231916024808301926020929190829003018186803b1580156114fb57600080fd5b505afa15801561150f573d6000803e3d6000fd5b505050506040513d602081101561152557600080fd5b5051604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905191925060009173ffffffffffffffffffffffffffffffffffffffff8516916370a08231916024808301926020929190829003018186803b15801561159957600080fd5b505afa1580156115ad573d6000803e3d6000fd5b505050506040513d60208110156115c357600080fd5b5051306000908152600160205260408120549192506115e288886126ec565b600054909150806115f9848763ffffffff6121e816565b8161160057fe5b049a5080611614848663ffffffff6121e816565b8161161b57fe5b04995060008b11801561162e575060008a115b611683576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180612b996028913960400191505060405180910390fd5b61168d3084612992565b611698878d8d611fdb565b6116a3868d8c611fdb565b604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff8916916370a08231916024808301926020929190829003018186803b15801561170f57600080fd5b505afa158015611723573d6000803e3d6000fd5b505050506040513d602081101561173957600080fd5b5051604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905191965073ffffffffffffffffffffffffffffffffffffffff8816916370a0823191602480820192602092909190829003018186803b1580156117ab57600080fd5b505afa1580156117bf573d6000803e3d6000fd5b505050506040513d60208110156117d557600080fd5b505193506117e585858b8b6122e0565b811561182757600854611823906dffffffffffffffffffffffffffff808216916e01000000000000000000000000000090041663ffffffff6121e816565b600b555b604080518c8152602081018c9052815173ffffffffffffffffffffffffffffffffffffffff8f169233927fdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496929081900390910190a35050505050505050506001600c81905550915091565b6040518060400160405280600681526020017f554e492d5632000000000000000000000000000000000000000000000000000081525081565b6000610df233848461260b565b6103e881565b600c5460011461194f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f556e697377617056323a204c4f434b4544000000000000000000000000000000604482015290519081900360640190fd5b6000600c55600654600754600854604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff9485169490931692611a2b9285928792611a26926dffffffffffffffffffffffffffff169185916370a0823191602480820192602092909190829003018186803b1580156119ee57600080fd5b505afa158015611a02573d6000803e3d6000fd5b505050506040513d6020811015611a1857600080fd5b50519063ffffffff61226e16565b611fdb565b600854604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051611aca9284928792611a26926e01000000000000000000000000000090046dffffffffffffffffffffffffffff169173ffffffffffffffffffffffffffffffffffffffff8616916370a0823191602480820192602092909190829003018186803b1580156119ee57600080fd5b50506001600c5550565b60055473ffffffffffffffffffffffffffffffffffffffff1681565b60075473ffffffffffffffffffffffffffffffffffffffff1681565b42841015611b7b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f556e697377617056323a20455850495245440000000000000000000000000000604482015290519081900360640190fd5b60035473ffffffffffffffffffffffffffffffffffffffff80891660008181526004602090815260408083208054600180820190925582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98186015280840196909652958d166060860152608085018c905260a085019590955260c08085018b90528151808603909101815260e0850182528051908301207f19010000000000000000000000000000000000000000000000000000000000006101008601526101028501969096526101228085019690965280518085039096018652610142840180825286519683019690962095839052610162840180825286905260ff89166101828501526101a284018890526101c28401879052519193926101e2808201937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081019281900390910190855afa158015611cdc573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811615801590611d5757508873ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b611dc257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f556e697377617056323a20494e56414c49445f5349474e415455524500000000604482015290519081900360640190fd5b611dcd89898961259c565b505050505050505050565b600260209081526000928352604080842090915290825290205481565b600c54600114611e6657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f556e697377617056323a204c4f434b4544000000000000000000000000000000604482015290519081900360640190fd5b6000600c55600654604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051611fd49273ffffffffffffffffffffffffffffffffffffffff16916370a08231916024808301926020929190829003018186803b158015611edd57600080fd5b505afa158015611ef1573d6000803e3d6000fd5b505050506040513d6020811015611f0757600080fd5b5051600754604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff909216916370a0823191602480820192602092909190829003018186803b158015611f7a57600080fd5b505afa158015611f8e573d6000803e3d6000fd5b505050506040513d6020811015611fa457600080fd5b50516008546dffffffffffffffffffffffffffff808216916e0100000000000000000000000000009004166122e0565b6001600c55565b604080518082018252601981527f7472616e7366657228616464726573732c75696e743235362900000000000000602091820152815173ffffffffffffffffffffffffffffffffffffffff85811660248301526044808301869052845180840390910181526064909201845291810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001781529251815160009460609489169392918291908083835b602083106120e157805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016120a4565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612143576040519150601f19603f3d011682016040523d82523d6000602084013e612148565b606091505b5091509150818015612176575080511580612176575080806020019051602081101561217357600080fd5b50515b6121e157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f556e697377617056323a205452414e534645525f4641494c4544000000000000604482015290519081900360640190fd5b5050505050565b60008115806122035750508082028282828161220057fe5b04145b610df657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f64732d6d6174682d6d756c2d6f766572666c6f77000000000000000000000000604482015290519081900360640190fd5b80820382811115610df657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f64732d6d6174682d7375622d756e646572666c6f770000000000000000000000604482015290519081900360640190fd5b6dffffffffffffffffffffffffffff841180159061230c57506dffffffffffffffffffffffffffff8311155b61237757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f556e697377617056323a204f564552464c4f5700000000000000000000000000604482015290519081900360640190fd5b60085463ffffffff428116917c0100000000000000000000000000000000000000000000000000000000900481168203908116158015906123c757506dffffffffffffffffffffffffffff841615155b80156123e257506dffffffffffffffffffffffffffff831615155b15612492578063ffffffff16612425856123fb86612a57565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169063ffffffff612a7b16565b600980547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092169290920201905563ffffffff8116612465846123fb87612a57565b600a80547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff92909216929092020190555b600880547fffffffffffffffffffffffffffffffffffff0000000000000000000000000000166dffffffffffffffffffffffffffff888116919091177fffffffff0000000000000000000000000000ffffffffffffffffffffffffffff166e0100000000000000000000000000008883168102919091177bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167c010000000000000000000000000000000000000000000000000000000063ffffffff871602179283905560408051848416815291909304909116602082015281517f1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1929181900390910190a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff808416600081815260026020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260016020526040902054612641908263ffffffff61226e16565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152600160205260408082209390935590841681522054612683908263ffffffff612abc16565b73ffffffffffffffffffffffffffffffffffffffff80841660008181526001602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b600080600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663017e7e586040518163ffffffff1660e01b815260040160206040518083038186803b15801561275757600080fd5b505afa15801561276b573d6000803e3d6000fd5b505050506040513d602081101561278157600080fd5b5051600b5473ffffffffffffffffffffffffffffffffffffffff821615801594509192509061286457801561285f5760006127d86112576dffffffffffffffffffffffffffff88811690881663ffffffff6121e816565b905060006127e583612878565b90508082111561285c576000612813612804848463ffffffff61226e16565b6000549063ffffffff6121e816565b905060006128388361282c86600563ffffffff6121e816565b9063ffffffff612abc16565b9050600081838161284557fe5b04905080156128585761285887826128ca565b5050505b50505b612870565b8015612870576000600b555b505092915050565b600060038211156128bb575080600160028204015b818110156128b5578091506002818285816128a457fe5b0401816128ad57fe5b04905061288d565b506128c5565b81156128c5575060015b919050565b6000546128dd908263ffffffff612abc16565b600090815573ffffffffffffffffffffffffffffffffffffffff8316815260016020526040902054612915908263ffffffff612abc16565b73ffffffffffffffffffffffffffffffffffffffff831660008181526001602090815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b6000818310612989578161298b565b825b9392505050565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600160205260409020546129c8908263ffffffff61226e16565b73ffffffffffffffffffffffffffffffffffffffff831660009081526001602052604081209190915554612a02908263ffffffff61226e16565b600090815560408051838152905173ffffffffffffffffffffffffffffffffffffffff8516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef919081900360200190a35050565b6dffffffffffffffffffffffffffff166e0100000000000000000000000000000290565b60006dffffffffffffffffffffffffffff82167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff841681612ab457fe5b049392505050565b80820182811015610df657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f64732d6d6174682d6164642d6f766572666c6f77000000000000000000000000604482015290519081900360640190fdfe556e697377617056323a20494e53554646494349454e545f4f55545055545f414d4f554e54556e697377617056323a20494e53554646494349454e545f494e5055545f414d4f554e54556e697377617056323a20494e53554646494349454e545f4c4951554944495459556e697377617056323a20494e53554646494349454e545f4c49515549444954595f4255524e4544556e697377617056323a20494e53554646494349454e545f4c49515549444954595f4d494e544544a265627a7a723158207dca18479e58487606bf70c79e44d8dee62353c9ee6d01f9a9d70885b8765f2264736f6c63430005100032","storage":{"0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0":"5c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f","0xa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688":"c778417e063141139fce010982780140aa0cd5ab","0xc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b":"d26b905208da8d27f07dea61dcc075d1af2743dc282d5f68a721ac1a583ca384","0xdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7":"01","0xf652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f":"6e09b6bb59cbc3602cedb44c93b499c1a968563b"},"key":"0x000011bc5e0081e3324ec67ad41409aaf45928fb6c589daffbf5be8afc9e490b"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x000012c9647f3cf7b228a65a0b56eecf22ca614921fc3356143771361001dbfe"} +{"balance":"0","nonce":1,"root":"0x2d79dd673f30c305bd67f00cc8b17ea650fb5d9646a3b94f51f4c9ef5563b05a","codeHash":"0x2edb75a2af7975269233ba06fb4de4d1297f81e960efed9745f3ee9f67dd2b21","code":"0x6080604052600080fd00a165627a7a7230582018d3c779a147dceae300ccb1b2f6f184f0e7be90c4542279d695ee90c98c86170029","storage":{"0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563":"4082cc8839242ff5ee9c67f6d05c4e497f63361a"},"key":"0x000012cc952da47a775635cb85c67c8f12389000cb1e423038d794f190a82d3b"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x000014a715add39aea6c921dc7277a6513793cd9a76985406b2e3dd294e7ac95"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x000014ec3889fd592fc369c7dd88fbc0afcbb53d932a8de7ca9f108ed650fa2e"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x000014fa71e102dc34b77f0e9a776dd7aa3a305b1c43e50ea8092ff53c93d6c6"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x0000152a9f2eac64e33d93bf9d902df5c7e5de958efe40edf1aac7c16770cec2"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x00001537deb9fbb514264b4c99da8e858a7f38e4805000018a5a56d8da969439"} +{"balance":"591000000000000","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x000015807ce4d5f9a97453bf27ceb966c0c28c642a5460d2b679f694826fcdae"} +{"balance":"1500000000000000000","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00001599df69264970e8c053c161a58b7b2de4f4099a14d6743efbbc603034ea"} +{"balance":"1990460000000000","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x000015bfb175334582bbb3dac33ca3b7a945c9221cb8ea835db23aeccadf5647"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xaf55ae668efbfcb0a08b688da877f63e6d11bf3358a2c54d0f20fdd1cd0ad3c0","code":"0x606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680632e1a7d4d146041575b005b3415604b57600080fd5b605f60048080359060200190919050506061565b005b67016345785d8a00008111151515607757600080fd5b3373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151560b657600080fd5b505600a165627a7a723058204d96ff17b8d33a13614088cff2f849da2676aa4fc4b750bf7f6bb980b12cca920029","key":"0x00001619553b5d2f8634d0fab2684014494996bdaca05087b0244c8f970a03b8"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x000016b14095d87fc5d889aa71985051fd3ede22ea74d78879a93a0a4365a79c"} +{"balance":"0","nonce":1,"root":"0x0e8b87227755394b2d44a0766f4b00d4a3222b321c28b9e646076b0805456c7b","codeHash":"0xb276357793bc2449e3133ec60a6055f12334c694854d91456288476b39b7f24d","code":"0x608060405234801561001057600080fd5b506004361061009e5760003560e01c806379502c551161006657806379502c551461011c5780637af53532146101245780639f3708891461012c578063ec9be18d1461013f578063f887ea40146101525761009e565b806331fd5cbc146100a357806360b56932146100b8578063732c3297146100cb57806376aad605146100f457806378a9e99f14610107575b600080fd5b6100b66100b1366004612c58565b61015a565b005b6100b66100c6366004612cb7565b610d50565b6100de6100d9366004612c88565b61172a565b6040516100eb9190613182565b60405180910390f35b6100b6610102366004612b83565b611aa5565b61010f611b73565b6040516100eb9190612d54565b61010f611b82565b61010f611b91565b6100de61013a366004612c88565b611ba0565b6100b661014d366004612c88565b612596565b61010f612a10565b60008054604051633ed0aabf60e11b81526001600160a01b0390911690637da1557e9061018b908590600401613182565b60206040518083038186803b1580156101a357600080fd5b505afa1580156101b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506101db9190810190612b9f565b9050806001600160a01b031663801aab976040518163ffffffff1660e01b815260040160206040518083038186803b15801561021657600080fd5b505afa15801561022a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061024e9190810190612c70565b42116102755760405162461bcd60e51b815260040161026c90612fb2565b60405180910390fd5b6000816001600160a01b031663d7058e296040518163ffffffff1660e01b815260040160206040518083038186803b1580156102b057600080fd5b505afa1580156102c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506102e89190810190612c70565b90506001811461030a5760405162461bcd60e51b815260040161026c9061314b565b6000826001600160a01b031663926323d56040518163ffffffff1660e01b815260040160206040518083038186803b15801561034557600080fd5b505afa158015610359573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061037d9190810190612c70565b9050610387612b6c565b836001600160a01b0316631509c42a6040518163ffffffff1660e01b8152600401604080518083038186803b1580156103bf57600080fd5b505afa1580156103d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506103f79190810190612bdb565b9050600160009054906101000a90046001600160a01b03166001600160a01b031663ad8e29ef6040518163ffffffff1660e01b815260040160206040518083038186803b15801561044757600080fd5b505afa15801561045b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061047f9190810190612c70565b821015801561049a575060208101516001600160a01b031615155b15610b0a576000846001600160a01b031663fe6dcdba6040518163ffffffff1660e01b815260040160206040518083038186803b1580156104da57600080fd5b505afa1580156104ee573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506105129190810190612b9f565b90506000600160009054906101000a90046001600160a01b03166001600160a01b0316638b9462bd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561056457600080fd5b505afa158015610578573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061059c9190810190612c70565b90506000600160009054906101000a90046001600160a01b03166001600160a01b0316639dc7fdf26040518163ffffffff1660e01b815260040160206040518083038186803b1580156105ee57600080fd5b505afa158015610602573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506106269190810190612c70565b9050600061064a8261063e888663ffffffff612a1f16565b9063ffffffff612a6016565b905084602001516001600160a01b0316846001600160a01b0316146109be5760006106fb828a6001600160a01b031663a7cac84689602001516040518263ffffffff1660e01b815260040161069f9190612d54565b60206040518083038186803b1580156106b757600080fd5b505afa1580156106cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506106ef9190810190612c70565b9063ffffffff612aa216565b905080896001600160a01b031663a7cac846876040518263ffffffff1660e01b815260040161072a9190612d54565b60206040518083038186803b15801561074257600080fd5b505afa158015610756573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061077a9190810190612c70565b10156107e357602086015160405163c5899d8960e01b81526001600160a01b038b169163c5899d89916107b09190600401612d54565b600060405180830381600087803b1580156107ca57600080fd5b505af11580156107de573d6000803e3d6000fd5b505050505b6040516353e5642360e11b815281906001600160a01b038b169063a7cac84690610811908990600401612d54565b60206040518083038186803b15801561082957600080fd5b505afa15801561083d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506108619190810190612c70565b14156109bc57886001600160a01b031663c5899d8987602001516001600160a01b031663426a0c886040518163ffffffff1660e01b815260040160206040518083038186803b1580156108b357600080fd5b505afa1580156108c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506108eb9190810190612c70565b876001600160a01b031663426a0c886040518163ffffffff1660e01b815260040160206040518083038186803b15801561092457600080fd5b505afa158015610938573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061095c9190810190612c70565b1061096b57876020015161096d565b865b6040518263ffffffff1660e01b81526004016109899190612d54565b600060405180830381600087803b1580156109a357600080fd5b505af11580156109b7573d6000803e3d6000fd5b505050505b505b60405163caa1015360e01b81526001600160a01b0389169063caa10153906109ea906004908101613182565b600060405180830381600087803b158015610a0457600080fd5b505af1158015610a18573d6000803e3d6000fd5b50505050876001600160a01b0316637f19fef4600160009054906101000a90046001600160a01b03166001600160a01b031663188efdb36040518163ffffffff1660e01b815260040160206040518083038186803b158015610a7957600080fd5b505afa158015610a8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ab19190810190612c70565b42016040518263ffffffff1660e01b8152600401610acf9190613182565b600060405180830381600087803b158015610ae957600080fd5b505af1158015610afd573d6000803e3d6000fd5b5050505050505050610b6a565b60405163caa1015360e01b81526001600160a01b0385169063caa1015390610b3790600290600401613182565b600060405180830381600087803b158015610b5157600080fd5b505af1158015610b65573d6000803e3d6000fd5b505050505b836001600160a01b031663fe6dcdba6040518163ffffffff1660e01b815260040160206040518083038186803b158015610ba357600080fd5b505afa158015610bb7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610bdb9190810190612b9f565b6001600160a01b0316336001600160a01b03167ff45143f321d76ca6fb69367cfee9673aed6b3429bb95dfbc87d81728ed82e68f87876001600160a01b031663a7cac846896001600160a01b031663fe6dcdba6040518163ffffffff1660e01b815260040160206040518083038186803b158015610c5857600080fd5b505afa158015610c6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610c909190810190612b9f565b6040518263ffffffff1660e01b8152600401610cac9190612d54565b60206040518083038186803b158015610cc457600080fd5b505afa158015610cd8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610cfc9190810190612c70565b604051610d0a92919061318b565b60405180910390a3604051610d1e90612d30565b604051908190038120906001600160a01b0386169033906000805160206131d983398151915290600090a45050505050565b60025460405163a90ffc2760e01b81526001600160a01b039091169063a90ffc2790610d9090339030906001600160e01b03196000351690600401612d82565b60206040518083038186803b158015610da857600080fd5b505afa158015610dbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610de09190810190612bbb565b610dfc5760405162461bcd60e51b815260040161026c90613047565b60008054604051633ed0aabf60e11b81526001600160a01b0390911690637da1557e90610e2d908890600401613182565b60206040518083038186803b158015610e4557600080fd5b505afa158015610e59573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610e7d9190810190612b9f565b905042816001600160a01b031663801aab976040518163ffffffff1660e01b815260040160206040518083038186803b158015610eb957600080fd5b505afa158015610ecd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ef19190810190612c70565b11610f0e5760405162461bcd60e51b815260040161026c90612f1d565b600354604051632ba21f0960e21b81526001600160a01b039091169063ae887c2490610f3e908790600401612d54565b60206040518083038186803b158015610f5657600080fd5b505afa158015610f6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610f8e9190810190612bbb565b15610fab5760405162461bcd60e51b815260040161026c90612ee6565b836001600160a01b0316816001600160a01b0316631d1438486040518163ffffffff1660e01b815260040160206040518083038186803b158015610fee57600080fd5b505afa158015611002573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506110269190810190612b9f565b6001600160a01b0316141561104d5760405162461bcd60e51b815260040161026c90613114565b60015460405163ea55efd960e01b81526001600160a01b039091169063ea55efd99061107d908690600401612d54565b60206040518083038186803b15801561109557600080fd5b505afa1580156110a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506110cd9190810190612bbb565b6110e95760405162461bcd60e51b815260040161026c9061307e565b6110f1612b6c565b60405163d8bff5a560e01b81526001600160a01b0383169063d8bff5a59061111d908890600401612d54565b604080518083038186803b15801561113457600080fd5b505afa158015611148573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061116c9190810190612c1d565b80516020820151919250906001600160a01b038216158015906111a15750856001600160a01b0316826001600160a01b031614155b1561132157836001600160a01b031663d747d1528361124284886001600160a01b031663a7cac846886040518263ffffffff1660e01b81526004016111e69190612d54565b60206040518083038186803b1580156111fe57600080fd5b505afa158015611212573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506112369190810190612c70565b9063ffffffff612ac716565b6040518363ffffffff1660e01b815260040161125f929190612dd3565b600060405180830381600087803b15801561127957600080fd5b505af115801561128d573d6000803e3d6000fd5b50505050836001600160a01b031663d747d152876112d184886001600160a01b031663a7cac8468c6040518263ffffffff1660e01b815260040161069f9190612d54565b6040518363ffffffff1660e01b81526004016112ee929190612dd3565b600060405180830381600087803b15801561130857600080fd5b505af115801561131c573d6000803e3d6000fd5b505050505b6001600160a01b03841663832641008888611342858a63ffffffff612aa216565b6040518463ffffffff1660e01b815260040161136093929190612daf565b600060405180830381600087803b15801561137a57600080fd5b505af115801561138e573d6000803e3d6000fd5b50505050836001600160a01b031663d747d152876113d288886001600160a01b031663a7cac8468c6040518263ffffffff1660e01b815260040161069f9190612d54565b6040518363ffffffff1660e01b81526004016113ef929190612dd3565b600060405180830381600087803b15801561140957600080fd5b505af115801561141d573d6000803e3d6000fd5b50505050836001600160a01b031663c0a0395861146d87876001600160a01b031663926323d56040518163ffffffff1660e01b815260040160206040518083038186803b1580156106b757600080fd5b6040518263ffffffff1660e01b81526004016114899190613182565b600060405180830381600087803b1580156114a357600080fd5b505af11580156114b7573d6000803e3d6000fd5b50505050836001600160a01b031663a7cac846856001600160a01b031663fe6dcdba6040518163ffffffff1660e01b815260040160206040518083038186803b15801561150357600080fd5b505afa158015611517573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061153b9190810190612b9f565b6040518263ffffffff1660e01b81526004016115579190612d54565b60206040518083038186803b15801561156f57600080fd5b505afa158015611583573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506115a79190810190612c70565b6040516353e5642360e11b81526001600160a01b0386169063a7cac846906115d3908a90600401612d54565b60206040518083038186803b1580156115eb57600080fd5b505afa1580156115ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506116239190810190612c70565b106116875760405163c5899d8960e01b81526001600160a01b0385169063c5899d8990611654908990600401612d54565b600060405180830381600087803b15801561166e57600080fd5b505af1158015611682573d6000803e3d6000fd5b505050505b856001600160a01b0316876001600160a01b0316336001600160a01b03167f18b76b7b9a65accf6d72a52732549b127422e2857ea046090c0515473175c06c8b896040516116d692919061318b565b60405180910390a46040516116ea90612cfe565b6040518091039020846001600160a01b0316886001600160a01b03166000805160206131d983398151915260405160405180910390a45050505050505050565b60025460405163a90ffc2760e01b81526000916001600160a01b03169063a90ffc279061176a90339030906001600160e01b031987351690600401612d82565b60206040518083038186803b15801561178257600080fd5b505afa158015611796573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506117ba9190810190612bbb565b6117d65760405162461bcd60e51b815260040161026c90613047565b60008054604051633ed0aabf60e11b81526001600160a01b0390911690637da1557e90611807908790600401613182565b60206040518083038186803b15801561181f57600080fd5b505afa158015611833573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506118579190810190612b9f565b9050806001600160a01b031663801aab976040518163ffffffff1660e01b815260040160206040518083038186803b15801561189257600080fd5b505afa1580156118a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506118ca9190810190612c70565b42116118e85760405162461bcd60e51b815260040161026c90612f1d565b60006001600160a01b0316816001600160a01b031663fe6dcdba6040518163ffffffff1660e01b815260040160206040518083038186803b15801561192c57600080fd5b505afa158015611940573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506119649190810190612b9f565b6001600160a01b0316141561198b5760405162461bcd60e51b815260040161026c9061301b565b6040516301fff5ad60e51b81526000906001600160a01b03831690633ffeb5a0906119ba908790600401612d54565b60206040518083038186803b1580156119d257600080fd5b505afa1580156119e6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611a0a9190810190612c70565b9050836001600160a01b0316336001600160a01b03167f5d31a5d622097ca7d2840e477230e278c2309c72fc1bfa75a89bef90db9555808784604051611a5192919061318b565b60405180910390a3604051611a6590612d0e565b6040518091039020826001600160a01b0316856001600160a01b03166000805160206131d983398151915260405160405180910390a49150505b92915050565b60025460405163a90ffc2760e01b81526001600160a01b039091169063a90ffc2790611ae590339030906001600160e01b03196000351690600401612d82565b60206040518083038186803b158015611afd57600080fd5b505afa158015611b11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611b359190810190612bbb565b611b515760405162461bcd60e51b815260040161026c90613047565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6003546001600160a01b031681565b6001546001600160a01b031681565b6002546001600160a01b031681565b60025460405163a90ffc2760e01b81526000916001600160a01b03169063a90ffc2790611be090339030906001600160e01b031987351690600401612d82565b60206040518083038186803b158015611bf857600080fd5b505afa158015611c0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611c309190810190612bbb565b611c4c5760405162461bcd60e51b815260040161026c90613047565b60008054604051633ed0aabf60e11b81526001600160a01b0390911690637da1557e90611c7d908790600401613182565b60206040518083038186803b158015611c9557600080fd5b505afa158015611ca9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611ccd9190810190612b9f565b90506006816001600160a01b031663d7058e296040518163ffffffff1660e01b815260040160206040518083038186803b158015611d0a57600080fd5b505afa158015611d1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611d429190810190612c70565b14611d5f5760405162461bcd60e51b815260040161026c90612eb8565b6000816001600160a01b031663d7982e166040518163ffffffff1660e01b815260040160206040518083038186803b158015611d9a57600080fd5b505afa158015611dae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611dd29190810190612c70565b90506003811480611de35750600481145b80611dee5750600581145b80611df95750600681145b611e155760405162461bcd60e51b815260040161026c906130b5565b6040516301990be160e71b81526001600160a01b0383169063cc85f08090611e41908790600401612d54565b60206040518083038186803b158015611e5957600080fd5b505afa158015611e6d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611e919190810190612c70565b15611eae5760405162461bcd60e51b815260040161026c90612f7b565b611eb6612b6c565b60405163d8bff5a560e01b81526001600160a01b0384169063d8bff5a590611ee2903390600401612d54565b604080518083038186803b158015611ef957600080fd5b505afa158015611f0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611f319190810190612c1d565b90506000600160009054906101000a90046001600160a01b03166001600160a01b0316638b9462bd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611f8357600080fd5b505afa158015611f97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611fbb9190810190612c70565b90506000600160009054906101000a90046001600160a01b03166001600160a01b0316639dc7fdf26040518163ffffffff1660e01b815260040160206040518083038186803b15801561200d57600080fd5b505afa158015612021573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506120459190810190612c70565b600354604051632ba21f0960e21b81529192506000916001600160a01b039091169063ae887c249061207b908b90600401612d54565b60206040518083038186803b15801561209357600080fd5b505afa1580156120a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506120cb9190810190612bbb565b15612208576120d8612b6c565b866001600160a01b0316631509c42a6040518163ffffffff1660e01b8152600401604080518083038186803b15801561211057600080fd5b505afa158015612124573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506121489190810190612bdb565b9050886001600160a01b031681600001516001600160a01b03161461217f5760405162461bcd60e51b815260040161026c90612f46565b61220084886001600160a01b031663ddca3f436040518163ffffffff1660e01b815260040160206040518083038186803b1580156121bc57600080fd5b505afa1580156121d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506121f49190810190612c70565b9063ffffffff612a1f16565b9150506122c4565b6122c1866001600160a01b031663926323d56040518163ffffffff1660e01b815260040160206040518083038186803b15801561224457600080fd5b505afa158015612258573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061227c9190810190612c70565b61063e86602001516121f4868b6001600160a01b031663ddca3f436040518163ffffffff1660e01b815260040160206040518083038186803b1580156121bc57600080fd5b90505b6000866001600160a01b031663705727b56040518163ffffffff1660e01b815260040160206040518083038186803b1580156122ff57600080fd5b505afa158015612313573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506123379190810190612c70565b905080156123df576000876001600160a01b0316631aa5fe036040518163ffffffff1660e01b815260040160206040518083038186803b15801561237a57600080fd5b505afa15801561238e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506123b29190810190612c70565b90506123db600161063e83816123ce828863ffffffff612ac716565b889063ffffffff612a1f16565b9250505b60405163d01d3b4760e01b81526001600160a01b0388169063d01d3b479061240d908c908690600401612dd3565b602060405180830381600087803b15801561242757600080fd5b505af115801561243b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061245f9190810190612c70565b50866001600160a01b03166328e216f26124ac848a6001600160a01b031663bd998cb36040518163ffffffff1660e01b815260040160206040518083038186803b1580156106b757600080fd5b6040518263ffffffff1660e01b81526004016124c89190613182565b600060405180830381600087803b1580156124e257600080fd5b505af11580156124f6573d6000803e3d6000fd5b50505050886001600160a01b0316336001600160a01b03167f43ca82823e8203ac145337b3559feb5f4fea55be44de6c7c3255c7aa9c8d5d808c8560405161253f92919061318b565b60405180910390a360405161255390612d42565b6040518091039020876001600160a01b03168a6001600160a01b03166000805160206131d983398151915260405160405180910390a45098975050505050505050565b60008054604051633ed0aabf60e11b81526001600160a01b0390911690637da1557e906125c7908690600401613182565b60206040518083038186803b1580156125df57600080fd5b505afa1580156125f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506126179190810190612b9f565b905042816001600160a01b031663801aab976040518163ffffffff1660e01b815260040160206040518083038186803b15801561265357600080fd5b505afa158015612667573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061268b9190810190612c70565b116126a85760405162461bcd60e51b815260040161026c90612f1d565b600354604051632ba21f0960e21b81526001600160a01b039091169063ae887c24906126d8903390600401612d54565b60206040518083038186803b1580156126f057600080fd5b505afa158015612704573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506127289190810190612bbb565b6127445760405162461bcd60e51b815260040161026c90612e3f565b61274c612b6c565b816001600160a01b0316631509c42a6040518163ffffffff1660e01b8152600401604080518083038186803b15801561278457600080fd5b505afa158015612798573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506127bc9190810190612bdb565b60208101519091506001600160a01b0316156127ea5760405162461bcd60e51b815260040161026c906130dd565b336001600160a01b0316826001600160a01b0316631d1438486040518163ffffffff1660e01b815260040160206040518083038186803b15801561282d57600080fd5b505afa158015612841573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506128659190810190612b9f565b6001600160a01b0316141561288c5760405162461bcd60e51b815260040161026c90613114565b60015460405163ea55efd960e01b81526001600160a01b039091169063ea55efd9906128bc908690600401612d54565b60206040518083038186803b1580156128d457600080fd5b505afa1580156128e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061290c9190810190612bbb565b6129285760405162461bcd60e51b815260040161026c9061307e565b60405163178241fb60e31b81526001600160a01b0383169063bc120fd8906129569033908790600401612d68565b600060405180830381600087803b15801561297057600080fd5b505af1158015612984573d6000803e3d6000fd5b50505050826001600160a01b0316336001600160a01b03167fd4548a62cde0d06b863b584645753edef262cd1d7437a45d3ca817870868047d866040516129cb9190613182565b60405180910390a36040516129df90612d1e565b604051908190038120906001600160a01b0384169033906000805160206131d983398151915290600090a450505050565b6000546001600160a01b031681565b600082612a2e57506000611a9f565b82820282848281612a3b57fe5b0414612a595760405162461bcd60e51b815260040161026c90612fda565b9392505050565b6000612a5983836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612b09565b600082820183811015612a595760405162461bcd60e51b815260040161026c90612e81565b6000612a5983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612b40565b60008183612b2a5760405162461bcd60e51b815260040161026c9190612dec565b506000838581612b3657fe5b0495945050505050565b60008184841115612b645760405162461bcd60e51b815260040161026c9190612dec565b505050900390565b604080518082019091526000808252602082015290565b600060208284031215612b94578081fd5b8135612a59816131c0565b600060208284031215612bb0578081fd5b8151612a59816131c0565b600060208284031215612bcc578081fd5b81518015158114612a59578182fd5b600060408284031215612bec578081fd5b612bf66040613199565b8251612c01816131c0565b81526020830151612c11816131c0565b60208201529392505050565b600060408284031215612c2e578081fd5b612c386040613199565b8251612c43816131c0565b81526020928301519281019290925250919050565b600060208284031215612c69578081fd5b5035919050565b600060208284031215612c81578081fd5b5051919050565b60008060408385031215612c9a578081fd5b823591506020830135612cac816131c0565b809150509250929050565b60008060008060808587031215612ccc578182fd5b843593506020850135612cde816131c0565b92506040850135612cee816131c0565b9396929550929360600135925050565b6318d85cdd60e21b815260040190565b6374616b6560e01b815260040190565b651c1c98d85cdd60d21b815260060190565b65726174696e6760d01b815260060190565b651c1c9bd99a5d60d21b815260060190565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b0393841681529190921660208201526001600160e01b0319909116604082015260600190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6000602082528251806020840152815b81811015612e195760208186018101516040868401015201612dfc565b81811115612e2a5782604083860101525b50601f01601f19169190910160400192915050565b60208082526022908201527f73656e646572206973206e6f7420612070726f66657373696f6e616c2072617460408201526132b960f11b606082015260800190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b602080825260149082015273189bdb99081a5cdcdd59481a5cc819985a5b195960621b604082015260600190565b6020808252601e908201527f73656e64657220697320612070726f66657373696f6e616c2072617465720000604082015260600190565b6020808252600f908201526e1d9bdd19481a5cc8195e1c1a5c9959608a1b604082015260600190565b6020808252818101527f70726f66657373696f6e616c207261746572206973206e6f74206d6174686368604082015260600190565b60208082526018908201527f766f74696e672070726f66697420776974686472617765640000000000000000604082015260600190565b6020808252600e908201526d1d9bdd19481d5b995e1c1a5c995960921b604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252601290820152713b37ba329034b9903737ba103bb4b73732b960711b604082015260600190565b60208082526019908201527f566f74653a2061636365737320756e617574686f72697a656400000000000000604082015260600190565b6020808252601a908201527f70726f706f73616c206973206e6f74207065726d697373697665000000000000604082015260600190565b6020808252600e908201526d189bdb99081d5b9cd95d1d1b195960921b604082015260600190565b6020808252601b908201527f616c72656164792070726f66657373696f6e616c20726174696e670000000000604082015260600190565b6020808252601f908201527f6973737565722063616e277420766f746520666f722073656c6620626f6e6400604082015260600190565b60208082526017908201527f616c726561647920726174696e672066696e6973686564000000000000000000604082015260600190565b90815260200190565b918252602082015260400190565b60405181810167ffffffffffffffff811182821017156131b857600080fd5b604052919050565b6001600160a01b03811681146131d557600080fd5b5056fe47c6d5436a24e6656b2d393f822887795a2f7c894933b84fd021d215778286ada2646970667358221220b59187474b2dac90517f65197e198b85bcbb99fad327a0a998bf15fdf56e9cf964736f6c63430006000033","storage":{"0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563":"d1aaa816cb66169f93d4946a618e592c8fad551b","0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace":"83045a4f9f597c8d227537b7270cd3198e5f403b","0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6":"91e9bb977b8ecd3bb991782dd4970484054abdff","0xc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b":"e430650e5e4517fae8d33d82456cdb5790791144"},"key":"0x0000174ddd6c7ea0121e440f6e3938eb2e7bb642a3e7aeac6b3f32c0a3e1e8d7"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x000017de655c00a400fa3bcbd800e36d75d5a9965032bfce2db56016e4859629"} +{"balance":"0","nonce":2,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x000018866ba68a9392eea3504ff18ba1b6037f40ebabf9ed01ebac5dd7f1477a"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x00001899f970157a035cdecf916bd049076c02bebcc661c543be1fc84fd258a0"} +{"balance":"2999999870571100000","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x000018fd3f94ae3f6c3fc67b9adf0968d86c6c3d83e6eb422332183331ecb808"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0x5dd7ee32defc0552a9ceed0039589d90d8bdf592653ad60a10cc36d7a2fb515a","code":"0x6080604052600080fd00a165627a7a7230582005095fa1852672e830029d802d4cc1b07571c1323502378d3f9910ef6bc6797d0029","key":"0x00001932178b69cc41d920df49af5371bacc6b15bf67102ca87467d940e1e88e"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x0000193bfd93e64c7e187c549a7714aa010317c130946d110bc68da69e6b5dc8"} +{"balance":"0","nonce":1,"root":"0xd26d1351ff040464adb2ca720cb8af42182b3508fa168a772c5b2eeeef73384b","codeHash":"0x470ed7cd5ecb0f8d9911f493ffc9b3d459910c556faad6b093a07d35a6c16ee7","code":"0x608060405234801561001057600080fd5b50600436106100f55760003560e01c806340c10f19116100975780639dc29fac116100665780639dc29fac1461028a578063a457c2d7146102a6578063a9059cbb146102d6578063dd62ed3e14610306576100f5565b806340c10f191461020257806370a082311461021e5780638da5cb5b1461024e57806395d89b411461026c576100f5565b806323b872dd116100d357806323b872dd14610166578063313ce5671461019657806339509351146101b45780633e0dc34e146101e4576100f5565b806306fdde03146100fa578063095ea7b31461011857806318160ddd14610148575b600080fd5b610102610336565b60405161010f9190611462565b60405180910390f35b610132600480360381019061012d91906111f6565b6103c8565b60405161013f9190611447565b60405180910390f35b6101506103e6565b60405161015d91906115e4565b60405180910390f35b610180600480360381019061017b91906111a3565b6103f0565b60405161018d9190611447565b60405180910390f35b61019e6104e8565b6040516101ab91906115ff565b60405180910390f35b6101ce60048036038101906101c991906111f6565b6104f1565b6040516101db9190611447565b60405180910390f35b6101ec61059d565b6040516101f991906115e4565b60405180910390f35b61021c600480360381019061021791906111f6565b6105a7565b005b61023860048036038101906102339190611136565b610645565b60405161024591906115e4565b60405180910390f35b61025661068d565b604051610263919061142c565b60405180910390f35b6102746106b7565b6040516102819190611462565b60405180910390f35b6102a4600480360381019061029f91906111f6565b610749565b005b6102c060048036038101906102bb91906111f6565b6107e7565b6040516102cd9190611447565b60405180910390f35b6102f060048036038101906102eb91906111f6565b6108d2565b6040516102fd9190611447565b60405180910390f35b610320600480360381019061031b9190611163565b6108f0565b60405161032d91906115e4565b60405180910390f35b60606003805461034590611748565b80601f016020809104026020016040519081016040528092919081815260200182805461037190611748565b80156103be5780601f10610393576101008083540402835291602001916103be565b820191906000526020600020905b8154815290600101906020018083116103a157829003601f168201915b5050505050905090565b60006103dc6103d5610977565b848461097f565b6001905092915050565b6000600254905090565b60006103fd848484610b4a565b6000600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000610448610977565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050828110156104c8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104bf90611504565b60405180910390fd5b6104dc856104d4610977565b85840361097f565b60019150509392505050565b60006012905090565b60006105936104fe610977565b84846001600061050c610977565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461058e9190611636565b61097f565b6001905092915050565b6000600554905090565b3373ffffffffffffffffffffffffffffffffffffffff16600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610637576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161062e90611544565b60405180910390fd5b6106418282610dcb565b5050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600480546106c690611748565b80601f01602080910402602001604051908101604052809291908181526020018280546106f290611748565b801561073f5780601f106107145761010080835404028352916020019161073f565b820191906000526020600020905b81548152906001019060200180831161072257829003601f168201915b5050505050905090565b3373ffffffffffffffffffffffffffffffffffffffff16600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146107d9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107d090611544565b60405180910390fd5b6107e38282610f2b565b5050565b600080600160006107f6610977565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050828110156108b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108aa906115a4565b60405180910390fd5b6108c76108be610977565b8585840361097f565b600191505092915050565b60006108e66108df610977565b8484610b4a565b6001905092915050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156109ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e690611584565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610a5f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a56906114c4565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92583604051610b3d91906115e4565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610bba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bb190611564565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610c2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c2190611484565b60405180910390fd5b610c35838383611102565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015610cbb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cb2906114e4565b60405180910390fd5b8181036000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610d4e9190611636565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610db291906115e4565b60405180910390a3610dc5848484611107565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610e3b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e32906115c4565b60405180910390fd5b610e4760008383611102565b8060026000828254610e599190611636565b92505081905550806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610eae9190611636565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051610f1391906115e4565b60405180910390a3610f2760008383611107565b5050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610f9b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f9290611524565b60405180910390fd5b610fa782600083611102565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508181101561102d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611024906114a4565b60405180910390fd5b8181036000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508160026000828254611084919061168c565b92505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516110e991906115e4565b60405180910390a36110fd83600084611107565b505050565b505050565b505050565b60008135905061111b81611b2d565b92915050565b60008135905061113081611b44565b92915050565b60006020828403121561114c5761114b6117d8565b5b600061115a8482850161110c565b91505092915050565b6000806040838503121561117a576111796117d8565b5b60006111888582860161110c565b92505060206111998582860161110c565b9150509250929050565b6000806000606084860312156111bc576111bb6117d8565b5b60006111ca8682870161110c565b93505060206111db8682870161110c565b92505060406111ec86828701611121565b9150509250925092565b6000806040838503121561120d5761120c6117d8565b5b600061121b8582860161110c565b925050602061122c85828601611121565b9150509250929050565b61123f816116c0565b82525050565b61124e816116d2565b82525050565b600061125f8261161a565b6112698185611625565b9350611279818560208601611715565b611282816117dd565b840191505092915050565b600061129a602383611625565b91506112a5826117ee565b604082019050919050565b60006112bd602283611625565b91506112c88261183d565b604082019050919050565b60006112e0602283611625565b91506112eb8261188c565b604082019050919050565b6000611303602683611625565b915061130e826118db565b604082019050919050565b6000611326602883611625565b91506113318261192a565b604082019050919050565b6000611349602183611625565b915061135482611979565b604082019050919050565b600061136c602283611625565b9150611377826119c8565b604082019050919050565b600061138f602583611625565b915061139a82611a17565b604082019050919050565b60006113b2602483611625565b91506113bd82611a66565b604082019050919050565b60006113d5602583611625565b91506113e082611ab5565b604082019050919050565b60006113f8601f83611625565b915061140382611b04565b602082019050919050565b611417816116fe565b82525050565b61142681611708565b82525050565b60006020820190506114416000830184611236565b92915050565b600060208201905061145c6000830184611245565b92915050565b6000602082019050818103600083015261147c8184611254565b905092915050565b6000602082019050818103600083015261149d8161128d565b9050919050565b600060208201905081810360008301526114bd816112b0565b9050919050565b600060208201905081810360008301526114dd816112d3565b9050919050565b600060208201905081810360008301526114fd816112f6565b9050919050565b6000602082019050818103600083015261151d81611319565b9050919050565b6000602082019050818103600083015261153d8161133c565b9050919050565b6000602082019050818103600083015261155d8161135f565b9050919050565b6000602082019050818103600083015261157d81611382565b9050919050565b6000602082019050818103600083015261159d816113a5565b9050919050565b600060208201905081810360008301526115bd816113c8565b9050919050565b600060208201905081810360008301526115dd816113eb565b9050919050565b60006020820190506115f9600083018461140e565b92915050565b6000602082019050611614600083018461141d565b92915050565b600081519050919050565b600082825260208201905092915050565b6000611641826116fe565b915061164c836116fe565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156116815761168061177a565b5b828201905092915050565b6000611697826116fe565b91506116a2836116fe565b9250828210156116b5576116b461177a565b5b828203905092915050565b60006116cb826116de565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b60005b83811015611733578082015181840152602081019050611718565b83811115611742576000848401525b50505050565b6000600282049050600182168061176057607f821691505b60208210811415611774576117736117a9565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600080fd5b6000601f19601f8301169050919050565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60008201527f6365000000000000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a20617070726f766520746f20746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206160008201527f6c6c6f77616e6365000000000000000000000000000000000000000000000000602082015250565b7f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b7f506f736974696f6e546f6b656e3a2063616c6c6572206973206e6f74206f776e60008201527f6572000000000000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b611b36816116c0565b8114611b4157600080fd5b50565b611b4d816116fe565b8114611b5857600080fd5b5056fea2646970667358221220b127e0c0f19fd5986ec3f29ab53ef5d6ee513af341649f2be2ae6b51bf78a47064736f6c63430008060033","storage":{"0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0":"cbff","0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace":"8ac7230489e80000","0x857e54cc16af2cf4a61b5c32ab1995cbed46d989bddfc84e9867d8219d19430d":"8ac7230489e80000","0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b":"4c3532323233000000000000000000000000000000000000000000000000000c","0xc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b":"4c3532323233000000000000000000000000000000000000000000000000000c","0xf652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f":"ebbaa31b1ebd727a1a42e71dc15e304ad8905211"},"key":"0x00001980cb57b3e48dc1fa6f78ba1d522b7b1fa23ad5d22bccde87350745a499"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x000019959e217e2b1143b90ab09f23f8bf954018e0abbc10539bccbf66697906"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x000019a4e59d1659969222b07f3e1115bba4f64d7f9e3aee65e067e62a252b44"} +{"balance":"0","nonce":1,"root":"0xd28d233358a7664994448ce94bb5d626f6be6e17cf5d7d65ac2ece0f51947e0a","codeHash":"0x34791f5b6d8a6a8cfd09996973a647c98601b2dc7c2bc612d4439ba2c82d45dc","code":"0x608060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630900f01014610067578063445df0ac146100b85780638da5cb5b146100e3578063fdacd5761461013a575b600080fd5b34801561007357600080fd5b506100b66004803603602081101561008a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610175565b005b3480156100c457600080fd5b506100cd61025d565b6040518082815260200191505060405180910390f35b3480156100ef57600080fd5b506100f8610263565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561014657600080fd5b506101736004803603602081101561015d57600080fd5b8101908080359060200190929190505050610288565b005b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561025a5760008190508073ffffffffffffffffffffffffffffffffffffffff1663fdacd5766001546040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b15801561024057600080fd5b505af1158015610254573d6000803e3d6000fd5b50505050505b50565b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102e557806001819055505b5056fea165627a7a72305820446724534b7e82d2a2cb3a70a0f8a331347ffa59e1702b6cf54496c5edbf289b0029","storage":{"0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563":"6d6a0175ef93c0a5c0aaca7e3c4fdb60679c96a4"},"key":"0x00001b4e5e6fffaffa15f07b8222425dabdb5b119c4dd879f2966e7e38bb244a"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x00001bc5466cead0af7b327306cdd00f012bd2f7814727464a29933a87701da6"} +{"balance":"939000000000000","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00001cdf338bd5abcd95681cc0f8b2cdec6aab284c3b595925c0b8ac5cefd616"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00001d703bb5b394f94ae40c61d426df8316f51664c161dc5a2dc0c97c2685d6"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x00001e1e8def3d4c68998f743a57b1a5715eacf48e1d893b65cc70ec7bc61cc2"} +{"balance":"20999999853000","nonce":2,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00001f8030fabd196d3b37e9532787ce2455e0507a40847ea8e77e2f13f45818"} +{"balance":"226899946853715359","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00001fee930af8f9b1b49aaebc6e757cda14db516cf60290aacc23699ea3d9c8"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x0000203356db94b3695740f9b50afdf63a4a7f76f40bac7ee66e985ade79a820"} +{"balance":"1","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x0000205e4827cad6280680b12b4a14430862c176cffdf1b89a35219b243f521a"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x0000206f32c2365d3d27b152445722c05210ee029ae2616b86d42d51d8237790"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x000020f71ad1aa843bbbdebac1ee5666766f8e508f23848a7d6371cf99646b25"} +{"balance":"0","nonce":1,"root":"0xfb93eea958ab846cc7f4bdf1e43008039360754dd8190b0bdc33b035d1d78469","codeHash":"0xa348e53d1ab63a476758c63629d3cd3729e23344caeca233e2535d6a394ad2ab","code":"0x363d3d373d3d3d363d7376e1618c85494521d8d35c850d593e26c341fc6e5af43d82803e903d91602b57fd5bf3","storage":{"0x210afe6ebef982fa193bb4e17f9f236cdf09af7788627b5d54d9e3e4b100021b":"7878787800000000000000000000000000000000000000000000000000000008","0xc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b":"837f47b1c9b350400043c056aaa1c80717f4f3560001"},"key":"0x0000212bf9c2f1bbad109410019ed1c07b7fca8e2eef2ecd3c3c9d1714ea4f90"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x000021372b553a9fc2cb4ba4dcdb1d79cc4dfff4ff62ca216b2c49922416052b"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x000023c93cc0f737e64ab93d1a0641cacc498573c45b786ae517432cb647e1ff"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x000024090fb73fa3e0594e1c813e1bcf0e6e4b6b1e29c48d2e3eb33eda3c8c10"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xba024287c5cb347d8fe9c19d86e265532c602e8c07cda87abf12678d2fd2b4e4","code":"0x608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063803fcd4314610046575b600080fd5b34801561005257600080fd5b506100f1600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061010d565b604051808260ff1660ff16815260200191505060405180910390f35b6000600a82101580156101205750601482105b1561012e5760019050610190565b6014821015801561013f5750601e82105b1561014d5760029050610190565b601e821015801561015e5750602882105b1561016c5760039050610190565b6028821015801561017d5750603282105b1561018b5760049050610190565b600090505b959450505050505600a165627a7a72305820697aca7f2222e2ebf3fdecdd45e221cc3d3424cd7005d0fcd5b025d71e2ad45e0029","key":"0x0000240d5edc655063ae76bb20573f55956003a1321979f489f1eda920e69dc8"} +{"balance":"309000000000000","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00002410e33cbd97338c5e7bcb9e8f3d21cd8809528ec0ec5c886844ce886f43"} +{"balance":"99580000000000000","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x0000255f73b957d514c2341ef42e21b55b4cba5a79ce5886986fe3fc38fc1a3e"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x000025b8d6d06c1a0cdaeb94181977406e4718b3eb50f8485830f4865fba4a4d"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x000026020ee048dcce59f69471dcc625eaa6a72b839a269771587c50dec9e409"} +{"balance":"0","nonce":1,"root":"0xbf7f48cefe663e0ee549115b12870efa84b9bacf24c2020e077ccb876fc1e685","codeHash":"0x98e0cda1fa31791cec06d84ff3fc82abe49b6dc8bcbaa4f19614b9e9d0c22dca","code":"0x608060405234801561001057600080fd5b50600436106101c45760003560e01c80639c40706b116100f9578063d13e4c7211610097578063ea6454cd11610071578063ea6454cd146103c2578063f6bb324c146103ca578063f6eb32df146103d2578063f7b89a3e146103da576101c4565b8063d13e4c7214610395578063db0b2279146103b2578063e4020804146103ba576101c4565b8063a85adeab116100d3578063a85adeab14610375578063b088ab661461037d578063b80777ea14610385578063cee64ccd1461038d576101c4565b80639c40706b14610348578063a118babd14610350578063a56c6b2f14610358576101c4565b806350e168f51161016657806370e756431161014057806370e7564314610308578063763d7e6914610310578063856c71dd14610338578063932221fb14610340576101c4565b806350e168f5146102db5780636bc96738146102f85780636f8ebd2e14610300576101c4565b806326c38ce5116101a257806326c38ce51461026c5780632ce8706d1461029057806345d964d7146102985780634dfa2236146102b5576101c4565b80630cba22f8146101c957806310bc8932146101f857806315d76d5f14610250575b600080fd5b6101e6600480360360208110156101df57600080fd5b50356103e2565b60408051918252519081900360200190f35b610200610400565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561023c578181015183820152602001610224565b505050509050019250505060405180910390f35b610258610459565b604080519115158252519081900360200190f35b6102746104d8565b604080516001600160a01b039092168252519081900360200190f35b6102746104e7565b6101e6600480360360208110156102ae57600080fd5b50356104f6565b6101e6600480360360208110156102cb57600080fd5b50356001600160a01b0316610503565b6101e6600480360360208110156102f157600080fd5b503561064a565b6101e66107bf565b6102006107c5565b6101e661081b565b6103366004803603602081101561032657600080fd5b50356001600160a01b0316610a39565b005b610258610caa565b610258610d2a565b610258610da3565b610336610db5565b6103366004803603602081101561036e57600080fd5b5035610e57565b6101e6611242565b610274611248565b6101e6611257565b6101e661125d565b6101e6600480360360208110156103ab57600080fd5b50356112a0565b6101e66112ad565b61025861136b565b6101e66113b0565b6101e66113b6565b6101e66116bc565b6101e66116c2565b600781815481106103ef57fe5b600091825260209091200154905081565b6060600580548060200260200160405190810160405280929190818152602001828054801561044e57602002820191906000526020600020905b81548152602001906001019080831161043a575b505050505090505b90565b600154604080516358c0c2fb60e11b815290516000926001600160a01b03169163b18185f6916004808301926020929190829003018186803b15801561049e57600080fd5b505afa1580156104b2573d6000803e3d6000fd5b505050506040513d60208110156104c857600080fd5b50516104d26113b6565b14905090565b6002546001600160a01b031681565b6009546001600160a01b031681565b600581815481106103ef57fe5b600080600160009054906101000a90046001600160a01b03166001600160a01b031663b18185f66040518163ffffffff1660e01b815260040160206040518083038186803b15801561055457600080fd5b505afa158015610568573d6000803e3d6000fd5b505050506040513d602081101561057e57600080fd5b5051905060005b8181101561063e5760015460408051631ee7794d60e31b81526004810184905290516001600160a01b0380881693169163f73bca68916024808301926020929190829003018186803b1580156105da57600080fd5b505afa1580156105ee573d6000803e3d6000fd5b505050506040513d602081101561060457600080fd5b50516001600160a01b03161415610636576005818154811061062257fe5b906000526020600020015492505050610645565b600101610585565b5060009150505b919050565b600154604080516358c0c2fb60e11b815290516000926001600160a01b03169163b18185f6916004808301926020929190829003018186803b15801561068f57600080fd5b505afa1580156106a3573d6000803e3d6000fd5b505050506040513d60208110156106b957600080fd5b505182106106f85760405162461bcd60e51b8152600401808060200182810382526021815260200180611d306021913960400191505060405180910390fd5b600354600454819003904203818111156107565761074d6007858154811061071c57fe5b90600052602060002001546006868154811061073457fe5b906000526020600020015461178e90919063ffffffff16565b92505050610645565b6107b76007858154811061076657fe5b90600052602060002001546107ab8461079f8560068a8154811061078657fe5b90600052602060002001546117f090919063ffffffff16565b9063ffffffff61185016565b9063ffffffff61178e16565b949350505050565b60085481565b6060600680548060200260200160405190810160405280929190818152602001828054801561044e576020028201919060005260206000209081548152602001906001019080831161043a575050505050905090565b600080600160009054906101000a90046001600160a01b03166001600160a01b031663b18185f66040518163ffffffff1660e01b815260040160206040518083038186803b15801561086c57600080fd5b505afa158015610880573d6000803e3d6000fd5b505050506040513d602081101561089657600080fd5b505190506000805b82811015610a325760015460408051631ee7794d60e31b81526004810184905290516000926001600160a01b03169163f73bca68916024808301926020929190829003018186803b1580156108f257600080fd5b505afa158015610906573d6000803e3d6000fd5b505050506040513d602081101561091c57600080fd5b50516001600160a01b031614801590610a1e575060015460408051631ee7794d60e31b81526004810184905290516000926001600160a01b03169163f73bca68916024808301926020929190829003018186803b15801561097c57600080fd5b505afa158015610990573d6000803e3d6000fd5b505050506040513d60208110156109a657600080fd5b50516040805163d805fa0560e01b815230600482015290516001600160a01b039092169163d805fa0591602480820192602092909190829003018186803b1580156109f057600080fd5b505afa158015610a04573d6000803e3d6000fd5b505050506040513d6020811015610a1a57600080fd5b5051115b15610a2a576001909101905b60010161089e565b5091505090565b600260009054906101000a90046001600160a01b03166001600160a01b031663ab8c71c06040518163ffffffff1660e01b815260040160206040518083038186803b158015610a8757600080fd5b505afa158015610a9b573d6000803e3d6000fd5b505050506040513d6020811015610ab157600080fd5b505160408051633239b71b60e01b815233600482015290516001600160a01b0390921691633239b71b91602480820192602092909190829003018186803b158015610afb57600080fd5b505afa158015610b0f573d6000803e3d6000fd5b505050506040513d6020811015610b2557600080fd5b5051610b625760405162461bcd60e51b815260040180806020018281038252602b815260200180611c8b602b913960400191505060405180910390fd5b6000610b6c61125d565b905060008111610bad5760405162461bcd60e51b815260040180806020018281038252603f815260200180611c4c603f913960400191505060405180910390fd5b600260009054906101000a90046001600160a01b03166001600160a01b0316633013ce296040518163ffffffff1660e01b815260040160206040518083038186803b158015610bfb57600080fd5b505afa158015610c0f573d6000803e3d6000fd5b505050506040513d6020811015610c2557600080fd5b50516040805163a9059cbb60e01b81526001600160a01b038581166004830152602482018590529151919092169163a9059cbb9160448083019260209291908290030181600087803b158015610c7a57600080fd5b505af1158015610c8e573d6000803e3d6000fd5b505050506040513d6020811015610ca457600080fd5b50505050565b60015460408051638cada60f60e01b815290516000926001600160a01b031691638cada60f916004808301926020929190829003018186803b158015610cef57600080fd5b505afa158015610d03573d6000803e3d6000fd5b505050506040513d6020811015610d1957600080fd5b5051610d236113b6565b1015905090565b600154604080516358c0c2fb60e11b815290516000926001600160a01b03169163b18185f6916004808301926020929190829003018186803b158015610d6f57600080fd5b505afa158015610d83573d6000803e3d6000fd5b505050506040513d6020811015610d9957600080fd5b50516104d261081b565b6000610dad6116c2565b610d236118ba565b600154604080516358c0c2fb60e11b815290516000926001600160a01b03169163b18185f6916004808301926020929190829003018186803b158015610dfa57600080fd5b505afa158015610e0e573d6000803e3d6000fd5b505050506040513d6020811015610e2457600080fd5b5051905060005b81811015610e5357610e3d8133611a6a565b15610e4b57610e4b81610e57565b600101610e2b565b5050565b6000610e628261064a565b9050610e6e8233611a6a565b610ea95760405162461bcd60e51b815260040180806020018281038252602e815260200180611d02602e913960400191505060405180910390fd5b60015460408051631ee7794d60e31b81526004810185905290516000926001600160a01b03169163f73bca68916024808301926020929190829003018186803b158015610ef557600080fd5b505afa158015610f09573d6000803e3d6000fd5b505050506040513d6020811015610f1f57600080fd5b50516040805163d805fa0560e01b815230600482015290516001600160a01b039092169163d805fa0591602480820192602092909190829003018186803b158015610f6957600080fd5b505afa158015610f7d573d6000803e3d6000fd5b505050506040513d6020811015610f9357600080fd5b505111610fd15760405162461bcd60e51b815260040180806020018281038252602b815260200180611cd7602b913960400191505060405180910390fd5b60015460408051631ee7794d60e31b81526004810185905290516001600160a01b039092169163f73bca6891602480820192602092909190829003018186803b15801561101d57600080fd5b505afa158015611031573d6000803e3d6000fd5b505050506040513d602081101561104757600080fd5b505160408051635d20a7d360e11b815290516001600160a01b039092169163ba414fa691600480820192602092909190829003018186803b15801561108b57600080fd5b505afa15801561109f573d6000803e3d6000fd5b505050506040513d60208110156110b557600080fd5b505115611101576040805162461bcd60e51b8152602060048201526015602482015274121bdcdd0818d85b9b9bdd0818994819985a5b1959605a1b604482015290519081900360640190fd5b600260009054906101000a90046001600160a01b03166001600160a01b0316633013ce296040518163ffffffff1660e01b815260040160206040518083038186803b15801561114f57600080fd5b505afa158015611163573d6000803e3d6000fd5b505050506040513d602081101561117957600080fd5b50516040805163a9059cbb60e01b81523360048201526024810184905290516001600160a01b039092169163a9059cbb916044808201926020929091908290030181600087803b1580156111cc57600080fd5b505af11580156111e0573d6000803e3d6000fd5b505050506040513d60208110156111f657600080fd5b5050600780546112259183918590811061120c57fe5b9060005260206000200154611bf190919063ffffffff16565b6007838154811061123257fe5b6000918252602090912001555050565b60045481565b6001546001600160a01b031681565b60035481565b6000806112686116c2565b905060006112746118ba565b9050818111156112975761128e818363ffffffff61178e16565b92505050610456565b60009250505090565b600681815481106103ef57fe5b600080600160009054906101000a90046001600160a01b03166001600160a01b031663b18185f66040518163ffffffff1660e01b815260040160206040518083038186803b1580156112fe57600080fd5b505afa158015611312573d6000803e3d6000fd5b505050506040513d602081101561132857600080fd5b505190506000805b82811015610a32576113428133611a6a565b15611363576113606113538261064a565b839063ffffffff611bf116565b91505b600101611330565b60015460408051637b7512a160e01b815290516000926001600160a01b031691637b7512a1916004808301926020929190829003018186803b158015610cef57600080fd5b60005481565b600080600160009054906101000a90046001600160a01b03166001600160a01b031663b18185f66040518163ffffffff1660e01b815260040160206040518083038186803b15801561140757600080fd5b505afa15801561141b573d6000803e3d6000fd5b505050506040513d602081101561143157600080fd5b505190506000805b82811015610a325760015460408051631ee7794d60e31b81526004810184905290516000926001600160a01b03169163f73bca68916024808301926020929190829003018186803b15801561148d57600080fd5b505afa1580156114a1573d6000803e3d6000fd5b505050506040513d60208110156114b757600080fd5b50516001600160a01b0316148015906115b9575060015460408051631ee7794d60e31b81526004810184905290516000926001600160a01b03169163f73bca68916024808301926020929190829003018186803b15801561151757600080fd5b505afa15801561152b573d6000803e3d6000fd5b505050506040513d602081101561154157600080fd5b50516040805163d805fa0560e01b815230600482015290516001600160a01b039092169163d805fa0591602480820192602092909190829003018186803b15801561158b57600080fd5b505afa15801561159f573d6000803e3d6000fd5b505050506040513d60208110156115b557600080fd5b5051115b80156116a8575060015460408051631ee7794d60e31b81526004810184905290516001600160a01b039092169163f73bca6891602480820192602092909190829003018186803b15801561160c57600080fd5b505afa158015611620573d6000803e3d6000fd5b505050506040513d602081101561163657600080fd5b505160408051635d20a7d360e11b815290516001600160a01b039092169163ba414fa691600480820192602092909190829003018186803b15801561167a57600080fd5b505afa15801561168e573d6000803e3d6000fd5b505050506040513d60208110156116a457600080fd5b5051155b156116b4576001909101905b600101611439565b600a5481565b600080600090506000600160009054906101000a90046001600160a01b03166001600160a01b031663b18185f66040518163ffffffff1660e01b815260040160206040518083038186803b15801561171957600080fd5b505afa15801561172d573d6000803e3d6000fd5b505050506040513d602081101561174357600080fd5b5051905060005b818110156117865761177c6006828154811061176257fe5b906000526020600020015484611bf190919063ffffffff16565b925060010161174a565b509091505090565b6000828211156117e5576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b508082035b92915050565b6000826117ff575060006117ea565b8282028284828161180c57fe5b04146118495760405162461bcd60e51b8152600401808060200182810382526021815260200180611cb66021913960400191505060405180910390fd5b9392505050565b60008082116118a6576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b60008284816118b157fe5b04949350505050565b600080600090506000600160009054906101000a90046001600160a01b03166001600160a01b031663b18185f66040518163ffffffff1660e01b815260040160206040518083038186803b15801561191157600080fd5b505afa158015611925573d6000803e3d6000fd5b505050506040513d602081101561193b57600080fd5b5051905060005b818110156119645761195a6007828154811061176257fe5b9250600101611942565b50611a6382600260009054906101000a90046001600160a01b03166001600160a01b0316633013ce296040518163ffffffff1660e01b815260040160206040518083038186803b1580156119b757600080fd5b505afa1580156119cb573d6000803e3d6000fd5b505050506040513d60208110156119e157600080fd5b5051604080516370a0823160e01b815230600482015290516001600160a01b03909216916370a0823191602480820192602092909190829003018186803b158015611a2b57600080fd5b505afa158015611a3f573d6000803e3d6000fd5b505050506040513d6020811015611a5557600080fd5b50519063ffffffff611bf116565b9250505090565b60015460408051631ee7794d60e31b815260048101859052905160009283926001600160a01b039091169163f73bca6891602480820192602092909190829003018186803b158015611abb57600080fd5b505afa158015611acf573d6000803e3d6000fd5b505050506040513d6020811015611ae557600080fd5b50516001600160a01b031614801590611849575060015460408051631ee7794d60e31b81526004810186905290516001600160a01b0380861693169163f73bca68916024808301926020929190829003018186803b158015611b4657600080fd5b505afa158015611b5a573d6000803e3d6000fd5b505050506040513d6020811015611b7057600080fd5b505160408051630f4d898960e11b815290516001600160a01b0390921691631e9b131291600480820192602092909190829003018186803b158015611bb457600080fd5b505afa158015611bc8573d6000803e3d6000fd5b505050506040513d6020811015611bde57600080fd5b50516001600160a01b0316149392505050565b600082820183811015611849576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fdfe5468657265206e6565647320746f20626520616e206f7665727061696420616d6f756e7420746f2062652061626c6520746f2077697468647261772069742e4e656564207772697465207065726d697373696f6e7320746f207769746864726177207061796d656e742e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77486f7374206e6565647320746f20626520636f6d6d697474656420746f207468697320736e617073686f74596f7572206163636f756e7420646f6573206e6f74206f776e20746865207265717565737465642073686172642e4e65656420746f2070726f7669646520612076616c69642073686172642049442ea265627a7a723158200991d70036a72ca6687d9d52adc6e566a85e6d03b43168dc1511a27e21f2810764736f6c634300050d0032","storage":{"0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0":"04","0x0e80cbdd94e47fd796e675f8e406a639970fb67e18fc1a006717046a09be0796":"a5d9f29dc22051024f4f57ba7b15365b522c4de19e29620d4168699be12feec8","0x16db2e4b9f8dc120de98f8491964203ba76de27b27b29c2d25f85a325cd37477":"a2080633891579a37f1146099fa2163f79f40c311d0ef0b64b4493eea026a624","0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563":"04","0x38ace9b5569ba016113e31884532182bc747997e743c0b7f9c307302b5f83760":"01","0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace":"2edb33b704bb7881c5344e4269fd3cd0efa52a6a","0x65dd3971a50696d33d2c7bd274c314cf8643e6bf0e637991a508464bc9aed1eb":"8ae457f659f9ba507c00ecfb2e85603af0531e43d269684045f13d5e8c92ec1d","0x6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af":"1d2c0a044a8660967dfcc2f76d5558a2c5e96060","0x768c3a22b1e4688c94525eb9bc2cf1ce7601fc9e871dc6e10fc44f0f06340ce1":"01","0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b":"5ee748df","0xa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688":"04","0xaf786ca8f985b8adb0de73df0052ad2ed91db8313035df9caa6938d80f1945c8":"01","0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6":"7c966b7249a56514a47bab3ed71fb4b0bf78f7b2","0xb868bdfa8727775661e4ccf117824a175a33f8703d728c04488fbfffcafda9f9":"01","0xc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b":"5df9fade","0xc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a8":"01","0xf652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f":"04"},"key":"0x0000269fc97d690bd4296f9e9b58198bd1015746c350b5f98987ef20f8ea0e98"} +{"balance":"188914000000000","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x0000272a1998123ba7659901a35affe9f29cce9dc2895e711ac1b2cba390796a"} +{"balance":"0","nonce":1,"root":"0xb4050df3990c2cf389261cedca713adb5059202264a422bbc72ad6ce10bdbdf3","codeHash":"0xa46117d4b8655097d1b5ca4cdead5eb5f18fb65cc61668b290ec8f9a35e5261a","code":"0x60806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680638da5cb5b14610051578063f19c020d146100a8575b600080fd5b34801561005d57600080fd5b506100666100eb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156100b457600080fd5b506100e9600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610110565b005b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b1580156101ad57600080fd5b505af11580156101c1573d6000803e3d6000fd5b505050506040513d60208110156101d757600080fd5b810190808051906020019092919050505090507fe4a1d8684cc204d783dc7fc5752122c91b456a98bf4a88b6281b4811237b64b68282604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a18173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b15801561031957600080fd5b505af115801561032d573d6000803e3d6000fd5b5050505050505600a165627a7a72305820b65fbc937b9212f0a7dd1aa5ba93d55974c9f941f5b48a268f8ca0e8174fb2840029","storage":{"0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563":"c8998d0ada2afded9b8fc18721199b1cfd1d9ba0"},"key":"0x000027a60bde44c5665986d8a0d98e0493354508e4580cde12266dea4c304d23"} +{"balance":"0","nonce":1,"root":"0xcdc29f6cc6d3c3825f6f9a3a05bec0e3bdb528177f1da03dd3ee0278474163c6","codeHash":"0xd8fc0e8e4baf258cc1cd4661fc9e2e7b1b9f23f6cc6bdab56fcee29e0069b582","code":"0x608060405234801561001057600080fd5b50600436106101165760003560e01c80638f1a4207116100a2578063a457c2d711610071578063a457c2d7146102f5578063a9059cbb14610325578063dd62ed3e14610355578063f0b9b12014610385578063f851a440146103a157610116565b80638f1a42071461026d578063934aa0231461028957806395d89b41146102a7578063989763ef146102c557610116565b806323b872dd116100e957806323b872dd146101a3578063313ce567146101d357806339509351146101f157806370a0823114610221578063837f39641461025157610116565b806306fdde031461011b578063081ce7af14610139578063095ea7b31461015557806318160ddd14610185575b600080fd5b6101236103bf565b6040516101309190611868565b60405180910390f35b610153600480360381019061014e919061148a565b610451565b005b61016f600480360381019061016a919061144e565b6104eb565b60405161017c919061184d565b60405180910390f35b61018d610509565b60405161019a919061198a565b60405180910390f35b6101bd60048036038101906101b891906113ff565b610513565b6040516101ca919061184d565b60405180910390f35b6101db6107b6565b6040516101e891906119a5565b60405180910390f35b61020b6004803603810190610206919061144e565b6107bf565b604051610218919061184d565b60405180910390f35b61023b6004803603810190610236919061139a565b61086b565b604051610248919061198a565b60405180910390f35b61026b6004803603810190610266919061139a565b6108b3565b005b6102876004803603810190610282919061148a565b61099e565b005b610291610a38565b60405161029e9190611832565b60405180910390f35b6102af610a5e565b6040516102bc9190611868565b60405180910390f35b6102df60048036038101906102da919061139a565b610af0565b6040516102ec919061184d565b60405180910390f35b61030f600480360381019061030a919061144e565b610b10565b60405161031c919061184d565b60405180910390f35b61033f600480360381019061033a919061144e565b610bfb565b60405161034c919061184d565b60405180910390f35b61036f600480360381019061036a91906113c3565b610d91565b60405161037c919061198a565b60405180910390f35b61039f600480360381019061039a919061139a565b610e18565b005b6103a9610eec565b6040516103b69190611832565b60405180910390f35b6060600380546103ce90611b79565b80601f01602080910402602001604051908101604052809291908181526020018280546103fa90611b79565b80156104475780601f1061041c57610100808354040283529160200191610447565b820191906000526020600020905b81548152906001019060200180831161042a57829003601f168201915b5050505050905090565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104d8906118ea565b60405180910390fd5b8060058190555050565b60006104ff6104f8610f12565b8484610f1a565b6001905092915050565b6000600254905090565b600060011515600c60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151514156105e3576105798484846110e5565b60006105848561086b565b9050828110156105c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105c09061190a565b60405180910390fd5b6105dd856105d5610f12565b858403610f1a565b506107ab565b60085482106106cd57600954826105fa9190611a63565b6007819055506006546007546106109190611a32565b60078190555061064584600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166007546110e5565b6000600754836106559190611abd565b90506106628585836110e5565b600061066d8661086b565b9050838110156106b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106a99061190a565b60405180910390fd5b6106c6866106be610f12565b868403610f1a565b50506107aa565b600554826106db9190611a63565b6007819055506006546007546106f19190611a32565b60078190555061072684600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166007546110e5565b6000600754836107369190611abd565b90506107438585836110e5565b600061074e8661086b565b905083811015610793576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161078a9061190a565b60405180910390fd5b6107a78661079f610f12565b868403610f1a565b50505b5b600190509392505050565b60006012905090565b60006108616107cc610f12565b8484600160006107da610f12565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461085c91906119dc565b610f1a565b6001905092915050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610943576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161093a906118ea565b60405180910390fd5b6001600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a2e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a25906118ea565b60405180910390fd5b8060098190555050565b600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b606060048054610a6d90611b79565b80601f0160208091040260200160405190810160405280929190818152602001828054610a9990611b79565b8015610ae65780601f10610abb57610100808354040283529160200191610ae6565b820191906000526020600020905b815481529060010190602001808311610ac957829003601f168201915b5050505050905090565b600c6020528060005260406000206000915054906101000a900460ff1681565b60008060016000610b1f610f12565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905082811015610bdc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bd39061196a565b60405180910390fd5b610bf0610be7610f12565b85858403610f1a565b600191505092915050565b600060011515600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615151415610c6d57610c68610c61610f12565b84846110e5565b610d87565b6008548210610d005760095482610c849190611a63565b600781905550600654600754610c9a9190611a32565b600781905550610cd6610cab610f12565b600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166007546110e5565b600060075483610ce69190611abd565b9050610cfa610cf3610f12565b85836110e5565b50610d86565b60055482610d0e9190611a63565b600781905550600654600754610d249190611a32565b600781905550610d60610d35610f12565b600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166007546110e5565b600060075483610d709190611abd565b9050610d84610d7d610f12565b85836110e5565b505b5b6001905092915050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610ea8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e9f906118ea565b60405180910390fd5b80600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610f8a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f819061194a565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610ffa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ff1906118aa565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040516110d8919061198a565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611155576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161114c9061192a565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156111c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111bc9061188a565b60405180910390fd5b6111d0838383611366565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015611256576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161124d906118ca565b60405180910390fd5b8181036000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546112e991906119dc565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161134d919061198a565b60405180910390a361136084848461136b565b50505050565b505050565b505050565b60008135905061137f81611c49565b92915050565b60008135905061139481611c60565b92915050565b6000602082840312156113ac57600080fd5b60006113ba84828501611370565b91505092915050565b600080604083850312156113d657600080fd5b60006113e485828601611370565b92505060206113f585828601611370565b9150509250929050565b60008060006060848603121561141457600080fd5b600061142286828701611370565b935050602061143386828701611370565b925050604061144486828701611385565b9150509250925092565b6000806040838503121561146157600080fd5b600061146f85828601611370565b925050602061148085828601611385565b9150509250929050565b60006020828403121561149c57600080fd5b60006114aa84828501611385565b91505092915050565b6114bc81611af1565b82525050565b6114cb81611b03565b82525050565b60006114dc826119c0565b6114e681856119cb565b93506114f6818560208601611b46565b6114ff81611c38565b840191505092915050565b60006115176023836119cb565b91507f45524332303a207472616e7366657220746f20746865207a65726f206164647260008301527f65737300000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b600061157d6022836119cb565b91507f45524332303a20617070726f766520746f20746865207a65726f20616464726560008301527f73730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006115e36026836119cb565b91507f45524332303a207472616e7366657220616d6f756e742065786365656473206260008301527f616c616e636500000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000611649600a836119cb565b91507f6f6e6c792061646d696e000000000000000000000000000000000000000000006000830152602082019050919050565b60006116896028836119cb565b91507f45524332303a207472616e7366657220616d6f756e742065786365656473206160008301527f6c6c6f77616e63650000000000000000000000000000000000000000000000006020830152604082019050919050565b60006116ef6025836119cb565b91507f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008301527f64726573730000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006117556024836119cb565b91507f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008301527f72657373000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006117bb6025836119cb565b91507f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008301527f207a65726f0000000000000000000000000000000000000000000000000000006020830152604082019050919050565b61181d81611b2f565b82525050565b61182c81611b39565b82525050565b600060208201905061184760008301846114b3565b92915050565b600060208201905061186260008301846114c2565b92915050565b6000602082019050818103600083015261188281846114d1565b905092915050565b600060208201905081810360008301526118a38161150a565b9050919050565b600060208201905081810360008301526118c381611570565b9050919050565b600060208201905081810360008301526118e3816115d6565b9050919050565b600060208201905081810360008301526119038161163c565b9050919050565b600060208201905081810360008301526119238161167c565b9050919050565b60006020820190508181036000830152611943816116e2565b9050919050565b6000602082019050818103600083015261196381611748565b9050919050565b60006020820190508181036000830152611983816117ae565b9050919050565b600060208201905061199f6000830184611814565b92915050565b60006020820190506119ba6000830184611823565b92915050565b600081519050919050565b600082825260208201905092915050565b60006119e782611b2f565b91506119f283611b2f565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115611a2757611a26611bab565b5b828201905092915050565b6000611a3d82611b2f565b9150611a4883611b2f565b925082611a5857611a57611bda565b5b828204905092915050565b6000611a6e82611b2f565b9150611a7983611b2f565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611ab257611ab1611bab565b5b828202905092915050565b6000611ac882611b2f565b9150611ad383611b2f565b925082821015611ae657611ae5611bab565b5b828203905092915050565b6000611afc82611b0f565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b60005b83811015611b64578082015181840152602081019050611b49565b83811115611b73576000848401525b50505050565b60006002820490506001821680611b9157607f821691505b60208210811415611ba557611ba4611c09565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000601f19601f8301169050919050565b611c5281611af1565b8114611c5d57600080fd5b50565b611c6981611b2f565b8114611c7457600080fd5b5056fea26469706673582212207e725df39f4e151ad83bc53d7a9a2bce59302b49bbe9ec5a1de8a112a0ce7f6b64736f6c63430008000033","storage":{"0x0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9":"ca53d7037e3eff5c03af170c01af3a45615a1cdf","0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0":"01","0x0c4d4ec12fdc62b9ee24db749c9a697ea313a51a458ce1335bc7cda8ba0ccba2":"015af1d78b58c40000","0x22499d05916a9963a481848f6e534b22fdbeb11a60a1b76ddeda1750e9c078fc":"1529c21d0f2fbb100000","0x2d09f7798c4914381f8976ce524a3178047d4079623ec397783b319045ef5793":"01","0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace":"d3c21bcecceda1000000","0x6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af":"5a","0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b":"4e65737300000000000000000000000000000000000000000000000000000008","0x8ad487d3d360d1b7cc3433ea653dd4a766d0c23a5ff1fab2c3e8a09ad68e35b8":"be921dbfab09b4040000","0x964e9c1ffd0f204235f3fb63c9e9f950f9fee0b7db6bcdb2807cd3ac3863a325":"04e1003b28d9280000","0x9a228559b18ebdbf767a61bec589c762daa62397f1d222170c123647b881b0a8":"15270c39601909880000","0xa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688":"04e1003b28d9280000","0xb567648bb5c592465d0659ca135007a213662b1cbd68539328fb9c220faa16cb":"01","0xc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b":"56616e6573736173000000000000000000000000000000000000000000000010","0xc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a8":"e1cee9f742c3dcb3fe0b18085f547bdc784801fd","0xf3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3":"0186a0","0xf652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f":"64"},"key":"0x000027cb54efbbd441e14402889d1efe3517fb0e2f92c37c1f4e85550c777dad"} +{"balance":"7000000000000000000","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x0000280c4c7699821825f120212ac7cd8435e1e42b3da6e793297174ea12177c"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x000028273b48c086855332f34923c62933fdc079744f120c7d4cfbfe89b841ff"} +{"balance":"0","nonce":1,"root":"0x15522165329729bbae94d4e0dd5be391536856c954573eac02a2cdee21f695a9","codeHash":"0x72cb671578492199159dbfbe20d0dd4c50bb70c97117e1833a4208fad5ea9508","code":"0x608060405234801561001057600080fd5b50600436106101a95760003560e01c80636a627842116100f9578063ba9a7a5611610097578063d21220a711610071578063d21220a714610534578063d505accf1461053c578063dd62ed3e1461058d578063fff6cae9146105bb576101a9565b8063ba9a7a56146104fe578063bc25cf7714610506578063c45a01551461052c576101a9565b80637ecebe00116100d35780637ecebe001461046557806389afcb441461048b57806395d89b41146104ca578063a9059cbb146104d2576101a9565b80636a6278421461041157806370a08231146104375780637464fc3d1461045d576101a9565b806323b872dd116101665780633644e515116101405780633644e515146103cb578063485cc955146103d35780635909c0d5146104015780635a3d549314610409576101a9565b806323b872dd1461036f57806330adf81f146103a5578063313ce567146103ad576101a9565b8063022c0d9f146101ae57806306fdde031461023c5780630902f1ac146102b9578063095ea7b3146102f15780630dfe16811461033157806318160ddd14610355575b600080fd5b61023a600480360360808110156101c457600080fd5b8135916020810135916001600160a01b0360408301351691908101906080810160608201356401000000008111156101fb57600080fd5b82018360208201111561020d57600080fd5b8035906020019184600183028401116401000000008311171561022f57600080fd5b5090925090506105c3565b005b610244610b0e565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561027e578181015183820152602001610266565b50505050905090810190601f1680156102ab5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102c1610b35565b604080516001600160701b03948516815292909316602083015263ffffffff168183015290519081900360600190f35b61031d6004803603604081101561030757600080fd5b506001600160a01b038135169060200135610b5f565b604080519115158252519081900360200190f35b610339610b76565b604080516001600160a01b039092168252519081900360200190f35b61035d610b85565b60408051918252519081900360200190f35b61031d6004803603606081101561038557600080fd5b506001600160a01b03813581169160208101359091169060400135610b8b565b61035d610c25565b6103b5610c49565b6040805160ff9092168252519081900360200190f35b61035d610c4e565b61023a600480360360408110156103e957600080fd5b506001600160a01b0381358116916020013516610c54565b61035d610cd6565b61035d610cdc565b61035d6004803603602081101561042757600080fd5b50356001600160a01b0316610ce2565b61035d6004803603602081101561044d57600080fd5b50356001600160a01b0316610fe0565b61035d610ff2565b61035d6004803603602081101561047b57600080fd5b50356001600160a01b0316610ff8565b6104b1600480360360208110156104a157600080fd5b50356001600160a01b031661100a565b6040805192835260208301919091528051918290030190f35b6102446113ae565b61031d600480360360408110156104e857600080fd5b506001600160a01b0381351690602001356113d1565b61035d6113de565b61023a6004803603602081101561051c57600080fd5b50356001600160a01b03166113e4565b61033961154d565b61033961155c565b61023a600480360360e081101561055257600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060ff6080820135169060a08101359060c0013561156b565b61035d600480360360408110156105a357600080fd5b506001600160a01b038135811691602001351661176b565b61023a611788565b600c5460011461060c576040805162461bcd60e51b815260206004820152600f60248201526e14185b98d85ad94e881313d0d2d151608a1b604482015290519081900360640190fd5b6000600c558415158061061f5750600084115b61065a5760405162461bcd60e51b81526004018080602001828103825260238152602001806121df6023913960400191505060405180910390fd5b600080610665610b35565b5091509150816001600160701b03168710801561068a5750806001600160701b031686105b6106db576040805162461bcd60e51b815260206004820152601f60248201527f50616e63616b653a20494e53554646494349454e545f4c495155494449545900604482015290519081900360640190fd5b60065460075460009182916001600160a01b039182169190811690891682148015906107195750806001600160a01b0316896001600160a01b031614155b610760576040805162461bcd60e51b815260206004820152601360248201527250616e63616b653a20494e56414c49445f544f60681b604482015290519081900360640190fd5b8a1561077157610771828a8d6118e8565b891561078257610782818a8c6118e8565b861561083d57886001600160a01b03166384800812338d8d8c8c6040518663ffffffff1660e01b815260040180866001600160a01b03166001600160a01b03168152602001858152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509650505050505050600060405180830381600087803b15801561082457600080fd5b505af1158015610838573d6000803e3d6000fd5b505050505b604080516370a0823160e01b815230600482015290516001600160a01b038416916370a08231916024808301926020929190829003018186803b15801561088357600080fd5b505afa158015610897573d6000803e3d6000fd5b505050506040513d60208110156108ad57600080fd5b5051604080516370a0823160e01b815230600482015290519195506001600160a01b038316916370a0823191602480820192602092909190829003018186803b1580156108f957600080fd5b505afa15801561090d573d6000803e3d6000fd5b505050506040513d602081101561092357600080fd5b5051925060009150506001600160701b0385168a90038311610946576000610955565b89856001600160701b03160383035b9050600089856001600160701b0316038311610972576000610981565b89856001600160701b03160383035b905060008211806109925750600081115b6109cd5760405162461bcd60e51b81526004018080602001828103825260228152602001806121976022913960400191505060405180910390fd5b6000610a016109e384600263ffffffff611a8216565b6109f5876103e863ffffffff611a8216565b9063ffffffff611ae516565b90506000610a196109e384600263ffffffff611a8216565b9050610a4a620f4240610a3e6001600160701b038b8116908b1663ffffffff611a8216565b9063ffffffff611a8216565b610a5a838363ffffffff611a8216565b1015610a9a576040805162461bcd60e51b815260206004820152600a60248201526950616e63616b653a204b60b01b604482015290519081900360640190fd5b5050610aa884848888611b35565b60408051838152602081018390528082018d9052606081018c905290516001600160a01b038b169133917fd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d8229181900360800190a350506001600c55505050505050505050565b6040518060400160405280600b81526020016a50616e63616b65204c507360a81b81525081565b6008546001600160701b0380821692600160701b830490911691600160e01b900463ffffffff1690565b6000610b6c338484611cf8565b5060015b92915050565b6006546001600160a01b031681565b60005481565b6001600160a01b038316600090815260026020908152604080832033845290915281205460001914610c10576001600160a01b0384166000908152600260209081526040808320338452909152902054610beb908363ffffffff611ae516565b6001600160a01b03851660009081526002602090815260408083203384529091529020555b610c1b848484611d5a565b5060019392505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b601281565b60035481565b6005546001600160a01b03163314610ca8576040805162461bcd60e51b81526020600482015260126024820152712830b731b0b5b29d102327a92124a22222a760711b604482015290519081900360640190fd5b600680546001600160a01b039384166001600160a01b03199182161790915560078054929093169116179055565b60095481565b600a5481565b6000600c54600114610d2d576040805162461bcd60e51b815260206004820152600f60248201526e14185b98d85ad94e881313d0d2d151608a1b604482015290519081900360640190fd5b6000600c81905580610d3d610b35565b50600654604080516370a0823160e01b815230600482015290519395509193506000926001600160a01b03909116916370a08231916024808301926020929190829003018186803b158015610d9157600080fd5b505afa158015610da5573d6000803e3d6000fd5b505050506040513d6020811015610dbb57600080fd5b5051600754604080516370a0823160e01b815230600482015290519293506000926001600160a01b03909216916370a0823191602480820192602092909190829003018186803b158015610e0e57600080fd5b505afa158015610e22573d6000803e3d6000fd5b505050506040513d6020811015610e3857600080fd5b505190506000610e57836001600160701b03871663ffffffff611ae516565b90506000610e74836001600160701b03871663ffffffff611ae516565b90506000610e828787611e14565b60005490915080610ebf57610eab6103e86109f5610ea6878763ffffffff611a8216565b611f72565b9850610eba60006103e8611fc4565b610f0e565b610f0b6001600160701b038916610edc868463ffffffff611a8216565b81610ee357fe5b046001600160701b038916610efe868563ffffffff611a8216565b81610f0557fe5b0461205a565b98505b60008911610f4d5760405162461bcd60e51b81526004018080602001828103825260268152602001806122026026913960400191505060405180910390fd5b610f578a8a611fc4565b610f6386868a8a611b35565b8115610f9357600854610f8f906001600160701b0380821691600160701b90041663ffffffff611a8216565b600b555b6040805185815260208101859052815133927f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f928290030190a250506001600c5550949695505050505050565b60016020526000908152604090205481565b600b5481565b60046020526000908152604090205481565b600080600c54600114611056576040805162461bcd60e51b815260206004820152600f60248201526e14185b98d85ad94e881313d0d2d151608a1b604482015290519081900360640190fd5b6000600c81905580611066610b35565b50600654600754604080516370a0823160e01b815230600482015290519496509294506001600160a01b039182169391169160009184916370a08231916024808301926020929190829003018186803b1580156110c257600080fd5b505afa1580156110d6573d6000803e3d6000fd5b505050506040513d60208110156110ec57600080fd5b5051604080516370a0823160e01b815230600482015290519192506000916001600160a01b038516916370a08231916024808301926020929190829003018186803b15801561113a57600080fd5b505afa15801561114e573d6000803e3d6000fd5b505050506040513d602081101561116457600080fd5b5051306000908152600160205260408120549192506111838888611e14565b6000549091508061119a848763ffffffff611a8216565b816111a157fe5b049a50806111b5848663ffffffff611a8216565b816111bc57fe5b04995060008b1180156111cf575060008a115b61120a5760405162461bcd60e51b81526004018080602001828103825260268152602001806121b96026913960400191505060405180910390fd5b6112143084612072565b61121f878d8d6118e8565b61122a868d8c6118e8565b604080516370a0823160e01b815230600482015290516001600160a01b038916916370a08231916024808301926020929190829003018186803b15801561127057600080fd5b505afa158015611284573d6000803e3d6000fd5b505050506040513d602081101561129a57600080fd5b5051604080516370a0823160e01b815230600482015290519196506001600160a01b038816916370a0823191602480820192602092909190829003018186803b1580156112e657600080fd5b505afa1580156112fa573d6000803e3d6000fd5b505050506040513d602081101561131057600080fd5b5051935061132085858b8b611b35565b81156113505760085461134c906001600160701b0380821691600160701b90041663ffffffff611a8216565b600b555b604080518c8152602081018c905281516001600160a01b038f169233927fdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496929081900390910190a35050505050505050506001600c81905550915091565b60405180604001604052806007815260200166043616b652d4c560cc1b81525081565b6000610b6c338484611d5a565b6103e881565b600c5460011461142d576040805162461bcd60e51b815260206004820152600f60248201526e14185b98d85ad94e881313d0d2d151608a1b604482015290519081900360640190fd5b6000600c55600654600754600854604080516370a0823160e01b815230600482015290516001600160a01b0394851694909316926114dc92859287926114d7926001600160701b03169185916370a0823191602480820192602092909190829003018186803b15801561149f57600080fd5b505afa1580156114b3573d6000803e3d6000fd5b505050506040513d60208110156114c957600080fd5b50519063ffffffff611ae516565b6118e8565b600854604080516370a0823160e01b8152306004820152905161154392849287926114d792600160701b90046001600160701b0316916001600160a01b038616916370a0823191602480820192602092909190829003018186803b15801561149f57600080fd5b50506001600c5550565b6005546001600160a01b031681565b6007546001600160a01b031681565b428410156115b3576040805162461bcd60e51b815260206004820152601060248201526f14185b98d85ad94e881156141254915160821b604482015290519081900360640190fd5b6003546001600160a01b0380891660008181526004602090815260408083208054600180820190925582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98186015280840196909652958d166060860152608085018c905260a085019590955260c08085018b90528151808603909101815260e08501825280519083012061190160f01b6101008601526101028501969096526101228085019690965280518085039096018652610142840180825286519683019690962095839052610162840180825286905260ff89166101828501526101a284018890526101c28401879052519193926101e280820193601f1981019281900390910190855afa1580156116ce573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116158015906117045750886001600160a01b0316816001600160a01b0316145b611755576040805162461bcd60e51b815260206004820152601a60248201527f50616e63616b653a20494e56414c49445f5349474e4154555245000000000000604482015290519081900360640190fd5b611760898989611cf8565b505050505050505050565b600260209081526000928352604080842090915290825290205481565b600c546001146117d1576040805162461bcd60e51b815260206004820152600f60248201526e14185b98d85ad94e881313d0d2d151608a1b604482015290519081900360640190fd5b6000600c55600654604080516370a0823160e01b815230600482015290516118e1926001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561182257600080fd5b505afa158015611836573d6000803e3d6000fd5b505050506040513d602081101561184c57600080fd5b5051600754604080516370a0823160e01b815230600482015290516001600160a01b03909216916370a0823191602480820192602092909190829003018186803b15801561189957600080fd5b505afa1580156118ad573d6000803e3d6000fd5b505050506040513d60208110156118c357600080fd5b50516008546001600160701b0380821691600160701b900416611b35565b6001600c55565b604080518082018252601981527f7472616e7366657228616464726573732c75696e74323536290000000000000060209182015281516001600160a01b0385811660248301526044808301869052845180840390910181526064909201845291810180516001600160e01b031663a9059cbb60e01b1781529251815160009460609489169392918291908083835b602083106119955780518252601f199092019160209182019101611976565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146119f7576040519150601f19603f3d011682016040523d82523d6000602084013e6119fc565b606091505b5091509150818015611a2a575080511580611a2a5750808060200190516020811015611a2757600080fd5b50515b611a7b576040805162461bcd60e51b815260206004820152601860248201527f50616e63616b653a205452414e534645525f4641494c45440000000000000000604482015290519081900360640190fd5b5050505050565b6000811580611a9d57505080820282828281611a9a57fe5b04145b610b70576040805162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6d756c2d6f766572666c6f7760601b604482015290519081900360640190fd5b80820382811115610b70576040805162461bcd60e51b815260206004820152601560248201527464732d6d6174682d7375622d756e646572666c6f7760581b604482015290519081900360640190fd5b6001600160701b038411801590611b5357506001600160701b038311155b611b98576040805162461bcd60e51b815260206004820152601160248201527050616e63616b653a204f564552464c4f5760781b604482015290519081900360640190fd5b60085463ffffffff42811691600160e01b90048116820390811615801590611bc857506001600160701b03841615155b8015611bdc57506001600160701b03831615155b15611c4d578063ffffffff16611c0a85611bf586612110565b6001600160e01b03169063ffffffff61212216565b600980546001600160e01b03929092169290920201905563ffffffff8116611c3584611bf587612110565b600a80546001600160e01b0392909216929092020190555b600880546dffffffffffffffffffffffffffff19166001600160701b03888116919091176dffffffffffffffffffffffffffff60701b1916600160701b8883168102919091176001600160e01b0316600160e01b63ffffffff871602179283905560408051848416815291909304909116602082015281517f1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1929181900390910190a1505050505050565b6001600160a01b03808416600081815260026020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b038316600090815260016020526040902054611d83908263ffffffff611ae516565b6001600160a01b038085166000908152600160205260408082209390935590841681522054611db8908263ffffffff61214716565b6001600160a01b0380841660008181526001602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b600080600560009054906101000a90046001600160a01b03166001600160a01b031663017e7e586040518163ffffffff1660e01b815260040160206040518083038186803b158015611e6557600080fd5b505afa158015611e79573d6000803e3d6000fd5b505050506040513d6020811015611e8f57600080fd5b5051600b546001600160a01b038216158015945091925090611f5e578015611f59576000611ed2610ea66001600160701b0388811690881663ffffffff611a8216565b90506000611edf83611f72565b905080821115611f56576000611f0d611efe848463ffffffff611ae516565b6000549063ffffffff611a8216565b90506000611f3283611f2686600363ffffffff611a8216565b9063ffffffff61214716565b90506000818381611f3f57fe5b0490508015611f5257611f528782611fc4565b5050505b50505b611f6a565b8015611f6a576000600b555b505092915050565b60006003821115611fb5575080600160028204015b81811015611faf57809150600281828581611f9e57fe5b040181611fa757fe5b049050611f87565b50611fbf565b8115611fbf575060015b919050565b600054611fd7908263ffffffff61214716565b60009081556001600160a01b038316815260016020526040902054612002908263ffffffff61214716565b6001600160a01b03831660008181526001602090815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b6000818310612069578161206b565b825b9392505050565b6001600160a01b03821660009081526001602052604090205461209b908263ffffffff611ae516565b6001600160a01b038316600090815260016020526040812091909155546120c8908263ffffffff611ae516565b60009081556040805183815290516001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef919081900360200190a35050565b6001600160701b0316600160701b0290565b60006001600160701b0382166001600160e01b0384168161213f57fe5b049392505050565b80820182811015610b70576040805162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6164642d6f766572666c6f7760601b604482015290519081900360640190fdfe50616e63616b653a20494e53554646494349454e545f494e5055545f414d4f554e5450616e63616b653a20494e53554646494349454e545f4c49515549444954595f4255524e454450616e63616b653a20494e53554646494349454e545f4f55545055545f414d4f554e5450616e63616b653a20494e53554646494349454e545f4c49515549444954595f4d494e544544a265627a7a72315820dd874c90d64348bad1028a7fda5ef9e35d9a52cb788ebf815891f87fb2b45dfa64736f6c63430005100032","storage":{"0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0":"11b5ddd04560a2580dd39aaaad9017dce65ef59f","0xa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688":"4fd5685fd4c6d03d1a6044a692f5d17e79e8fd87","0xc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b":"e3846aa118c4b0bba31d62d4b6393d38e9b6b1c38af60c3ad5e3f578773242b5","0xdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7":"01","0xf652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f":"14973565eb1a886d828f2c31745272ed75353a03"},"key":"0x00002828a2c11539b13df58c9d09b48610a5bf63caf5eb813fae5a1c5d26da6e"} +{"balance":"499958000000000000","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x000028b91b50795e2ab7e96ca868e243cef5372929a09b35f05d4e4f04dabb8b"} +{"balance":"0","nonce":1,"root":"0x7f56e5693627614a978d8adcab85767f5013403ed17aad9bfe7bb9f565f95666","codeHash":"0x560f536441e22b94896cd85848bc1026579ef787787e06a49f465e04878ad99e","code":"0x606060405236156100495763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416636ea056a9811461017c578063c0ee0b8a146101af575b61017a5b6000805460408051602090810184905281517fb269681d0000000000000000000000000000000000000000000000000000000081529151600160a060020a039093169263b269681d92600480820193929182900301818787803b15156100af57fe5b6102c65a03f115156100bd57fe5b505060405180519250600160a060020a03831691503480156108fc02916000818181858888f1935050505015156100f057fe5b60008054604080517f28090abb000000000000000000000000000000000000000000000000000000008152600160a060020a033081166004830152858116602483015260448201859052346064830152915191909216926328090abb926084808201939182900301818387803b151561016557fe5b6102c65a03f1151561017357fe5b5050505b50565b005b341561018457fe5b61019b600160a060020a0360043516602435610214565b604080519115158252519081900360200190f35b34156101b757fe5b604080516020600460443581810135601f810184900484028501840190955284845261017a948235600160a060020a03169460248035956064949293919092019181908401838280828437509496506102e595505050505050565b005b6000805460408051602090810184905281517f3c18d318000000000000000000000000000000000000000000000000000000008152600160a060020a03878116600483015292519290931692633c18d318926024808301939282900301818787803b151561027e57fe5b6102c65a03f1151561028c57fe5b50505060405180519050600160a060020a031660003660006040516020015260405180838380828437820191505092505050602060405180830381856102c65a03f415156102d657fe5b50506040515190505b92915050565b5b5050505600a165627a7a72305820c1489a2d3f31f434cb96bb0e856d45b074e1d49509aa3477820df3d34fa776560029","storage":{"0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563":"e3b7489d890e049f40dd293cf1f9ce2492f5547d"},"key":"0x000028bb15684775e12abadc749beb4c088c4c736dd051ccae5add6a78a76c38"} +{"balance":"0","nonce":1,"root":"0xddfe6e19909bdeeee3a36c5ba2df69c768029490ee43e784a1517dcdf7086841","codeHash":"0x8eaafcacf3892a544382d4a6d7832c11f98751cd797661c652db8014edb8b539","code":"0x608060405234801561001057600080fd5b506004361061012c5760003560e01c80638da5cb5b116100ad578063d3fc986411610071578063d3fc986414610343578063e985e9c51461035f578063f2fde38b1461038f578063f3fe3bc3146103ab578063fac333ac146103c95761012c565b80638da5cb5b1461029f57806395d89b41146102bd578063a22cb465146102db578063b88d4fde146102f7578063c87b56dd146103135761012c565b806342842e0e116100f457806342842e0e146101e757806355515211146102035780636352211e1461022157806370a0823114610251578063860d248a146102815761012c565b806301ffc9a71461013157806306fdde0314610161578063081812fc1461017f578063095ea7b3146101af57806323b872dd146101cb575b600080fd5b61014b600480360381019061014691906129e1565b6103f9565b6040516101589190612c27565b60405180910390f35b610169610460565b6040516101769190612c42565b60405180910390f35b61019960048036038101906101949190612a3b565b6104f2565b6040516101a69190612bc0565b60405180910390f35b6101c960048036038101906101c4919061292d565b61060d565b005b6101e560048036038101906101e09190612812565b6109f0565b005b61020160048036038101906101fc9190612812565b610e42565b005b61020b610e62565b6040516102189190612c7f565b60405180910390f35b61023b60048036038101906102369190612a3b565b610ee4565b6040516102489190612bc0565b60405180910390f35b61026b600480360381019061026691906127a5565b610fca565b6040516102789190612c7f565b60405180910390f35b610289611084565b6040516102969190612c42565b60405180910390f35b6102a76110bd565b6040516102b49190612bc0565b60405180910390f35b6102c56110e3565b6040516102d29190612c42565b60405180910390f35b6102f560048036038101906102f091906128ed565b611175565b005b610311600480360381019061030c9190612865565b611272565b005b61032d60048036038101906103289190612a3b565b6112c9565b60405161033a9190612c42565b60405180910390f35b61035d6004803603810190610358919061296d565b6113b9565b005b610379600480360381019061037491906127d2565b6114e0565b6040516103869190612c27565b60405180910390f35b6103a960048036038101906103a491906127a5565b611574565b005b6103b36117a6565b6040516103c09190612c42565b60405180910390f35b6103e360048036038101906103de9190612a3b565b6117df565b6040516103f09190612c64565b60405180910390f35b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b60606005805461046f90612e1b565b80601f016020809104026020016040519081016040528092919081815260200182805461049b90612e1b565b80156104e85780601f106104bd576101008083540402835291602001916104e8565b820191906000526020600020905b8154815290600101906020018083116104cb57829003601f168201915b5050505050905090565b600081600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f3030333030320000000000000000000000000000000000000000000000000000815250906105d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105c79190612c42565b60405180910390fd5b506002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915050919050565b8060006001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614806107065750600460008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b6040518060400160405280600681526020017f30303330303300000000000000000000000000000000000000000000000000008152509061077d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107749190612c42565b60405180910390fd5b5082600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f30303330303200000000000000000000000000000000000000000000000000008152509061085a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108519190612c42565b60405180910390fd5b5060006001600086815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f30303330303800000000000000000000000000000000000000000000000000008152509061093a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109319190612c42565b60405180910390fd5b50856002600087815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550848673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050505050565b8060006001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161480610ac157503373ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b80610b525750600460008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b6040518060400160405280600681526020017f303033303034000000000000000000000000000000000000000000000000000081525090610bc9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bc09190612c42565b60405180910390fd5b5082600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303033303032000000000000000000000000000000000000000000000000000081525090610ca6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c9d9190612c42565b60405180910390fd5b5060006001600086815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146040518060400160405280600681526020017f303033303037000000000000000000000000000000000000000000000000000081525090610d85576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d7c9190612c42565b60405180910390fd5b50600073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303033303031000000000000000000000000000000000000000000000000000081525090610e2e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e259190612c42565b60405180910390fd5b50610e39868661180d565b50505050505050565b610e5d838383604051806020016040528060008152506118c2565b505050565b6000806010600081819054906101000a900461ffff1680929190610e8590612e4d565b91906101000a81548161ffff021916908361ffff1602179055503342600143610eae9190612d28565b40604051602001610ec29493929190612b72565b6040516020818303038152906040528051906020012060001c90508091505090565b60006001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303033303032000000000000000000000000000000000000000000000000000081525090610fc4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fbb9190612c42565b60405180910390fd5b50919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303033303031000000000000000000000000000000000000000000000000000081525090611073576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161106a9190612c42565b60405180910390fd5b5061107d82611e90565b9050919050565b6040518060400160405280600681526020017f303138303032000000000000000000000000000000000000000000000000000081525081565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6060600680546110f290612e1b565b80601f016020809104026020016040519081016040528092919081815260200182805461111e90612e1b565b801561116b5780601f106111405761010080835404028352916020019161116b565b820191906000526020600020905b81548152906001019060200180831161114e57829003601f168201915b5050505050905090565b80600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516112669190612c27565b60405180910390a35050565b6112c285858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506118c2565b5050505050565b606081600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f3030333030320000000000000000000000000000000000000000000000000000815250906113a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161139e9190612c42565b60405180910390fd5b506113b183611ed9565b915050919050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146040518060400160405280600681526020017f303138303031000000000000000000000000000000000000000000000000000081525090611481576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114789190612c42565b60405180910390fd5b5061148c8484611f7e565b6114da8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061216c565b50505050565b6000600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146040518060400160405280600681526020017f30313830303100000000000000000000000000000000000000000000000000008152509061163c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116339190612c42565b60405180910390fd5b50600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f3031383030320000000000000000000000000000000000000000000000000000815250906116e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116dc9190612c42565b60405180910390fd5b508073ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6040518060400160405280600681526020017f303138303031000000000000000000000000000000000000000000000000000081525081565b600981606481106117ef57600080fd5b60109182820401919006600202915054906101000a900461ffff1681565b60006001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905061184e82612276565b61185881836122af565b611862838361241a565b818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b8160006001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16148061199357503373ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b80611a245750600460008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b6040518060400160405280600681526020017f303033303034000000000000000000000000000000000000000000000000000081525090611a9b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a929190612c42565b60405180910390fd5b5083600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303033303032000000000000000000000000000000000000000000000000000081525090611b78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b6f9190612c42565b60405180910390fd5b5060006001600087815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508773ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146040518060400160405280600681526020017f303033303037000000000000000000000000000000000000000000000000000081525090611c57576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c4e9190612c42565b60405180910390fd5b50600073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303033303031000000000000000000000000000000000000000000000000000081525090611d00576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cf79190612c42565b60405180910390fd5b50611d0b878761180d565b611d2a8773ffffffffffffffffffffffffffffffffffffffff166125a2565b15611e865760008773ffffffffffffffffffffffffffffffffffffffff1663150b7a02338b8a8a6040518563ffffffff1660e01b8152600401611d709493929190612bdb565b602060405180830381600087803b158015611d8a57600080fd5b505af1158015611d9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dc29190612a0e565b905063150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146040518060400160405280600681526020017f303033303035000000000000000000000000000000000000000000000000000081525090611e83576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e7a9190612c42565b60405180910390fd5b50505b5050505050505050565b6000600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6060600760008381526020019081526020016000208054611ef990612e1b565b80601f0160208091040260200160405190810160405280929190818152602001828054611f2590612e1b565b8015611f725780601f10611f4757610100808354040283529160200191611f72565b820191906000526020600020905b815481529060010190602001808311611f5557829003601f168201915b50505050509050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303033303031000000000000000000000000000000000000000000000000000081525090612026576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161201d9190612c42565b60405180910390fd5b50600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146040518060400160405280600681526020017f303033303036000000000000000000000000000000000000000000000000000081525090612101576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120f89190612c42565b60405180910390fd5b5061210c828261241a565b808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b81600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303033303032000000000000000000000000000000000000000000000000000081525090612248576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161223f9190612c42565b60405180910390fd5b50816007600085815260200190815260200160002090805190602001906122709291906125ed565b50505050565b6002600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550565b8173ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146040518060400160405280600681526020017f303033303037000000000000000000000000000000000000000000000000000081525090612388576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161237f9190612c42565b60405180910390fd5b506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546123d99190612d28565b925050819055506001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555050565b600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146040518060400160405280600681526020017f3030333030360000000000000000000000000000000000000000000000000000815250906124f4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124eb9190612c42565b60405180910390fd5b50816001600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546125979190612cd2565b925050819055505050565b60008060007fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060001b9050833f91506000801b82141580156125e45750808214155b92505050919050565b8280546125f990612e1b565b90600052602060002090601f01602090048101928261261b5760008555612662565b82601f1061263457805160ff1916838001178555612662565b82800160010185558215612662579182015b82811115612661578251825591602001919060010190612646565b5b50905061266f9190612673565b5090565b5b8082111561268c576000816000905550600101612674565b5090565b60008135905061269f81612f64565b92915050565b6000813590506126b481612f7b565b92915050565b6000813590506126c981612f92565b92915050565b6000815190506126de81612f92565b92915050565b60008083601f8401126126fa576126f9612f25565b5b8235905067ffffffffffffffff81111561271757612716612f20565b5b60208301915083600182028301111561273357612732612f2a565b5b9250929050565b60008083601f8401126127505761274f612f25565b5b8235905067ffffffffffffffff81111561276d5761276c612f20565b5b60208301915083600182028301111561278957612788612f2a565b5b9250929050565b60008135905061279f81612fa9565b92915050565b6000602082840312156127bb576127ba612f34565b5b60006127c984828501612690565b91505092915050565b600080604083850312156127e9576127e8612f34565b5b60006127f785828601612690565b925050602061280885828601612690565b9150509250929050565b60008060006060848603121561282b5761282a612f34565b5b600061283986828701612690565b935050602061284a86828701612690565b925050604061285b86828701612790565b9150509250925092565b60008060008060006080868803121561288157612880612f34565b5b600061288f88828901612690565b95505060206128a088828901612690565b94505060406128b188828901612790565b935050606086013567ffffffffffffffff8111156128d2576128d1612f2f565b5b6128de888289016126e4565b92509250509295509295909350565b6000806040838503121561290457612903612f34565b5b600061291285828601612690565b9250506020612923858286016126a5565b9150509250929050565b6000806040838503121561294457612943612f34565b5b600061295285828601612690565b925050602061296385828601612790565b9150509250929050565b6000806000806060858703121561298757612986612f34565b5b600061299587828801612690565b94505060206129a687828801612790565b935050604085013567ffffffffffffffff8111156129c7576129c6612f2f565b5b6129d38782880161273a565b925092505092959194509250565b6000602082840312156129f7576129f6612f34565b5b6000612a05848285016126ba565b91505092915050565b600060208284031215612a2457612a23612f34565b5b6000612a32848285016126cf565b91505092915050565b600060208284031215612a5157612a50612f34565b5b6000612a5f84828501612790565b91505092915050565b612a7181612d5c565b82525050565b612a88612a8382612d5c565b612e78565b82525050565b612a9781612d6e565b82525050565b612aae612aa982612d7a565b612e8a565b82525050565b6000612abf82612c9a565b612ac98185612cb0565b9350612ad9818560208601612de8565b612ae281612f39565b840191505092915050565b6000612af882612ca5565b612b028185612cc1565b9350612b12818560208601612de8565b612b1b81612f39565b840191505092915050565b612b2f81612db0565b82525050565b612b46612b4182612db0565b612e94565b82525050565b612b5581612dde565b82525050565b612b6c612b6782612dde565b612eb8565b82525050565b6000612b7e8287612b35565b600282019150612b8e8286612a77565b601482019150612b9e8285612b5b565b602082019150612bae8284612a9d565b60208201915081905095945050505050565b6000602082019050612bd56000830184612a68565b92915050565b6000608082019050612bf06000830187612a68565b612bfd6020830186612a68565b612c0a6040830185612b4c565b8181036060830152612c1c8184612ab4565b905095945050505050565b6000602082019050612c3c6000830184612a8e565b92915050565b60006020820190508181036000830152612c5c8184612aed565b905092915050565b6000602082019050612c796000830184612b26565b92915050565b6000602082019050612c946000830184612b4c565b92915050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600082825260208201905092915050565b6000612cdd82612dde565b9150612ce883612dde565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115612d1d57612d1c612ec2565b5b828201905092915050565b6000612d3382612dde565b9150612d3e83612dde565b925082821015612d5157612d50612ec2565b5b828203905092915050565b6000612d6782612dbe565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600061ffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60005b83811015612e06578082015181840152602081019050612deb565b83811115612e15576000848401525b50505050565b60006002820490506001821680612e3357607f821691505b60208210811415612e4757612e46612ef1565b5b50919050565b6000612e5882612db0565b915061ffff821415612e6d57612e6c612ec2565b5b600182019050919050565b6000612e8382612ea6565b9050919050565b6000819050919050565b6000612e9f82612f4a565b9050919050565b6000612eb182612f57565b9050919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b60008160f01b9050919050565b60008160601b9050919050565b612f6d81612d5c565b8114612f7857600080fd5b50565b612f8481612d6e565b8114612f8f57600080fd5b50565b612f9b81612d84565b8114612fa657600080fd5b50565b612fb281612dde565b8114612fbd57600080fd5b5056fea2646970667358221220c6b8131f541c5e4e12c759b6a8ed3b01dcc2d8d2cb9d709de0180b4de02f9bec64736f6c63430008070033","storage":{"0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0":"505245535350414745204e46540000000000000000000000000000000000001a","0x1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae672":"01","0x6686d8eb8768b985fd3304ad2026f3020537409dfacd367567b6cd91a5d65196":"01","0x66efe8ade30f919ca82ebe791b4e579b3ea1ff058c98a1fc91dceeeb39ac7274":"50542cf0903152e1761cfff01d2928c6f229d678","0x7d5e4d5141f4d3c8e353ae70d37b748d88637fab8b5a87113b2328ed71540d35":"6773567349544a7559383448484a5f6a673075644c62774b31367a386641534e","0x8347ebf0c8b79f5c6c9f6e795029b7525d5fd65c2ce3369d160c45e8f3c44c06":"664a3967664e477947424f3771753830674c33564d584b35305548324b546451","0x9188022777db6233175fd7ae9e72470d71c8d9b9146c81e22a2243262f6ab66d":"01","0x9dcf7d47cbb0128a1e1a071da2a7c40b704732458bcc8c76c5a62bd4ead0255b":"011b","0xb70532a05a8dcbffbb6fdd3ec09d8c0eaf6f29bf823f00ee0ce9e4ff01e57cb9":"6d2f45486c4a6c445865457a3468554a4770686133794249484d57574c4a536a","0xbd1e755c331223f87fafe524f8fc81796e4b5552244207f47458eac308168acd":"01","0xcfbbc4373675eee6289be4fd77b98cbfff2711da599faee8621e7d53544b5bdc":"68747470733a2f2f6c68332e676f6f676c6575736572636f6e74656e742e636f","0xe5e679518532bf6a7f3d86f729eab1ce88d35e5687ac0f3138b4b48db0d7cb36":"675f3675716747513d7736303000000000000000000000000000000000000000","0xef3a38bce3b5387cdc32a2195807b6c072f1826acbf0efbd7e07eb6aee8c0ee7":"01","0xf3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3":"50542cf0903152e1761cfff01d2928c6f229d678","0xf652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f":"5052455353504147452e4e46542e323032320000000000000000000000000024"},"key":"0x000028d8dfc347e7f7e76a97a3d397c52cbc278775a82e084dd2f5a4adafe5f0"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x000028de89db12fa9f1ae17cbd384611c065badcd3085d113ca9bdff646221ce"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x000029de0188a06c4133b0ff4411f040fc76e702ad76d060cd047a314bbf78d2"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00002aac3a80681aba04eca6eb2d3b5f6092cbb649a07ac7e0305d1c46085899"} +{"balance":"0","nonce":1,"root":"0x7e3d02b6a7cf68bed9c81d9a169975fd82a4ba175db5cfbf62a7dad5e76a4598","codeHash":"0x5f271e0e91db267330a2e7c3cbe4580510a61e2bb550b66f316973899d5ddf2c","code":"0x608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680635c60da1b146100b0575b600061004b610107565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561008957600080fd5b60405136600082376000803683855af43d806000843e81600081146100ac578184f35b8184fd5b3480156100bc57600080fd5b506100c5610107565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050905600a165627a7a723058203c37cd73dc9533e905d5be25ed9233a03d69875b130eedfe5177af86687ac41e0029","storage":{"0x00291a82c9837c771db09102d189d043cc760ba6216c26ef24c3467ab37670c4":"fb1e5aa0eab18000","0x0300026152329abf007beaf69a0c203c31104edf75ff7853dd41e0877250a3a0":"fb1e5aa0eab18000","0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0":"ca8dfa72947a943edc6cd1fb68ca5a661b1e84c7","0x0eb5be412f275a18f6e4d622aee4ff40b21467c926224771b782d4c095d1444b":"5dbcc700","0x13c059ac9f998913338fd82cfa66c3a4160cdb73740c3dd2e42d59df12620055":"02","0x15a73db43afaa74f24a9f8d519cb6014bc361c2add2793c4b23f812a5baacc03":"01f63cb541d5630000","0x17c2b3c33d1279f111580573fcc6594af0af2685d736b50fda59b60b3baf7678":"01f63cb541d5630000","0x19873dc7cb7cdb90b425c556a17855ae9726cb62ab7df9adf64cf6767035736e":"02","0x24fd5a20bba160bfc8b6716d99b8ce970df159bde8f83b36447f67cfe0e0a521":"02","0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563":"619002b9ea1aca0f11fd8b7f59b7b70bf2135ac1","0x29d164ba03f04b999e57e1e27d66f891c5677ba18f36ba1add2f9e33a2932789":"fb1e5aa0eab18000","0x3174834a93325b829d7c4749c037b96790a64164dcbcedbd065c33f4a390951d":"02","0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace":"3931900f13bf6276070e2e6a78d84220403c79dc0001","0x5d4bb82f0106369cd1d027e3482be13b0901f84a86df2345613c569ef982e8a7":"01f63cb541d5630000","0x60168701e004f041227ea40c61ff8b355581a0610ffd1489a0d729b65e570365":"02","0x63e35c3543482a4cffd2e779aea22c88712464376f14846cf88d6c3ca1556770":"01f63cb541d5630000","0x66b32740ad8041bcc3b909c72d7e1afe60094ec55e3cde329b4b3a28501d826c":"5eaa1500","0x6888f927dd585327fad89e920db63f93a9679dabe5ab5f731231617d0fde17d8":"fb1e5aa0eab18000","0x68aef4de03a0e2a807ff246bfbf457dc78edd9da9da6c4c0560e23d0863d8704":"02","0x6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af":"5dbcc700","0x7d503fc99ed275d76ce2a641f2ca9fb77d94d95d80eb154b1338a675d47b7105":"12d8bfa5d9f651157d922240ac7b5df4b196f56f","0x7e6e3b8cee552737eef1100626f821994bbeaaea0db81f9b59d55664f5e0120c":"799ab86c7fcd566e7015427b3e705f29e9ac9090","0x814f1a9d475e1d3ad7f61f8d3e6dfcfd83ed724ddb29dc1402e9d3e3bf9abc76":"fb1e5aa0eab18000","0x9b53d7dd5c365abb16e39ddb409e56b4fb154eb6650d89ac23388ea77e81ce86":"01f63cb541d5630000","0x9bdde55419bd610a0e957e36e30726241b0d9da2c787db8d963accdf83a461b6":"02","0x9f594bd4e027e32afdd0a972a071686bafd6bd4330ee1807cdce70339b2119b7":"fb1e5aa0eab18000","0xa1c8a201412de8b8f43c472e0bd83f94310a61b9c606bc376b0fe5721fd7d2f7":"7694aa19c928d29bc42c9e3963b1018bb47978d2","0xa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688":"04","0xa9e7f1183662a5850dbef51545195b2349c6c55ab3379bf71d68ec3ea4c6362e":"fb1e5aa0eab18000","0xb93ec6f6c4dd7e2745eb6055e8c934a7f591f8698ac6650bb8a3b972a80419a9":"01f63cb541d5630000","0xc0490152bb1ae612552c302213c70d50829272c78f3d0b847384ceb6646b3d28":"06e091a3b6663abe3526d76c608ec006138edd4b","0xc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b":"e23add8102103c7db5cd61501c7a1cae6e3201c4","0xc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a8":"01","0xc83cdc70bda9680116ba8774efae604351c3d32c3d51a1d73bc1543f9b343785":"02","0xcdb1396680cf88dd5365c5587ad9b4a76fe3c124a6d83cf45343fafada39e243":"01f63cb541d5630000","0xdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7":"b4","0xed6178fa8776c7cec17e1eff099fffa7f1728257817d56fea126febe23a5e099":"fb1e5aa0eab18000","0xf3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3":"b4","0xf652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f":"0be2c691a2c788b57051bf02c2e235591d2d4e2a","0xfc8f2fd4ef4b4b49d870d8c3c48ab6353a5ebac6bb753b892eac4fe7d825e681":"01f63cb541d5630000"},"key":"0x00002b72ae62b05b5516647bad6b9b4e14649ec3a5d6f201cef0f230d17335f4"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00002bc2485e800686b5c846d264a85bda964f2c2ad8ad323c49fe4b269c0b4c"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x00002bf2635b2318cc70f93d11810cb60153f876c6af1967fe522d27d5c53d42"} +{"balance":"1000000000000000000","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00002c2925fcc589c446acd66d42404e9703aa3ad165f88031ab3a52882a506b"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x00002c912cc2a2d8749f917104f749e1c95523112d4995a20cc4e3fe48485e43"} +{"balance":"1000000000000000000","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00002cd3ceb290af66eb8b84cbd87fd7b198b4b4477a0f26945dbf7f549e37e6"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00002ce3ae583381f77dfe2cebc0b0ae1119d7d9bea18682ddd98db3802dcd29"} +{"balance":"100000000000000","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00002d6a85fe99188e4a1e9490fad4e16c2a396fe0b0cc0c420c9e3983fbaaf6"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00002d86f6a8750717957181f4c0ec81981a2effd65259553aa69b69625b9c74"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00002dde1714829263254d37bc492ffc42d9bf2ab4f5d7c77ded05d03e814f5d"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00002ef9d80e35f4bf7a1e28ff15833116d774b0aeaeafb32bed451d5adca8d2"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x00002f045ed83945a0241e5810d65f8760887ff20053e553c5fc589c264681d8"} +{"balance":"1000000000000000000","nonce":1,"root":"0xaeba59c9327b8c949bdb3ed445a381ba441aafb558dafaebb71351e1c226cfd6","codeHash":"0x5146caa8990c91b112b98639628824525211ac32d79a06afdc775a3c24ca294c","code":"0x606060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680638da5cb5b14610176578063cc181ca8146101cb578063e3ac5d2614610220578063f2fde38b14610249575b600254341015806100bf57506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b15156100ca57600080fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f19350505050151561012c57600080fd5b33600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555034600281905550005b341561018157600080fd5b610189610282565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156101d657600080fd5b6101de6102a7565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561022b57600080fd5b6102336102cd565b6040518082815260200191505060405180910390f35b341561025457600080fd5b610280600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506102d3565b005b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60025481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561032e57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561036a57600080fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505600a165627a7a72305820cce0b82207abe5aaa49bcd256ae91fe77912ebdea2bf315278810b122c1a53690029","storage":{"0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563":"32d25a51c4690960f1d18fadfa98111f71de5fa7","0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace":"0f43fc2c04ee0000","0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6":"65284ff6bc028d37a0c3e7c74fea70cd3006fa9a"},"key":"0x00002f0a1caa4bfcaed75b4b0a879032371a96ef2c1f4798625386619328ad02"} +{"balance":"10000000000","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00002fd85f7f3b2f0688f8824fe4f250b61c1a7c7ed1dce000c3fbfb3d77b473"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x00003004f2aeeb7d7a40efbfa9684d86bf89dd50e3ef4991b56ae8b335a273e7"} +{"balance":"23056110000000000","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x0000304567fdd64dfc9453df4ec7830a652fe8339e04ff0be67db388862b9578"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x000030aaeb137e35a2919f73c4c1c569923dba135569499c0fb610e31b24b09c"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x000030d43d10ffcf7cf0aa149595f4aee0a4f523eabe8a562a714e1d2a855fb1"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xd80cd839dd3957d572b90780ada202a13936fa2875daea94216263371e9ef1d2","code":"0x6eb3f879cb30fe243b4dfee438691c043318585733ff","key":"0x0000312e454a82d60f053aa8b7a853d622d07ea7da86fbaa6c79b5d864ba0c9e"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x0000315ebaa1960c1d12afb0b793182c65a8e1ea89ef877164b1f56a468fdbd4"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x0000323aa42f119a88d2a73c84b65aa508acdd006886cc72a7dfb4762d7610f8"} +{"balance":"0","nonce":1,"root":"0x709eb5dda2147c4fb819a20da7a29219edf23b78b89a76895cb5bb987352df30","codeHash":"0x07be01e7e7206fe31ecee91ad75dada65ad6ba433ae647a1b9330469f7c6677c","code":"0x60606040523615610055576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063661172761461014857806382c90ac01461017e578063b76ea962146101b4575b6101465b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163460405180905060006040518083038185876187965a03f1925050501561013d577f23919512b2162ddc59b67a65e3b03c419d4105366f7d4a632f5d3c3bee9b1cff600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1610143565b60006000fd5b5b565b005b341561015057fe5b61017c600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610225565b005b341561018657fe5b6101b2600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506102c8565b005b610223600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190505061036b565b005b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156102825760006000fd5b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b50565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156103255760006000fd5b80600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b50565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156103c85760006000fd5b8173ffffffffffffffffffffffffffffffffffffffff1634826040518082805190602001908083836000831461041d575b80518252602083111561041d576020820191506020810190506020830392506103f9565b505050905090810190601f1680156104495780820380516001836020036101000a031916815260200191505b5091505060006040518083038185876187965a03f192505050151561046e5760006000fd5b5b5b50505600a165627a7a7230582015dd8a30edc4d2b88e51c1e252cdc5a08cd0159c2d5d7b063fdaad85d6e813e40029","storage":{"0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563":"209c4784ab1e8183cf58ca33cb740efbf3fc18ef","0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6":"b42b20ddbeabdc2a288be7ff847ff94fb48d2579"},"key":"0x0000327b0c3734baa7e7abd834f18321260dad937c12cc36909dd83ac9b8154d"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x000032ac71bc9eef3054513a2f4b80873674ea66425fbbb89a80f9666da1e0df"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x000033752912210348828b80310771052ee373cce759b054f3239705cfb4f88e"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00003406c8599d510f1fb3a24f4f0edec0ce5a22d1f1e406f08d43aadfc78150"} +{"balance":"0","nonce":1,"root":"0x364c70bc64b98ddf1b6cbbfa832522d2e4ea9ca309bd43bd6d68b56e75e810b8","codeHash":"0x8d8ce74271ba94b870c38cf8e321818e875578f86f0236d1d428bc7a4c1ea005","code":"0x6060604052361561015d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063088358aa146101625780631865c57d146101f15780633733d9f5146102805780633e8d398d1461030f57806342a20c2f1461036c5780635f29cc9e146103fb57806365ac43411461048a57806368794b87146105195780636945c1fd1461057657806373ed105b146106055780637b39fc8214610662578063914b37a1146106f157806393deb624146107805780639945f708146107dd578063a3f649351461086c578063a46d7fab146108c9578063a58abf7114610958578063a666d429146109e7578063b528d00e14610a44578063bfd9c04b14610ad3578063c5ffa35414610b30578063d0aa53b914610bbf578063d2f59e1c14610c4e578063deccc7f514610cab578063e556831714610d08578063f03ff01d14610d65578063f21205bb14610dc2575b600080fd5b341561016d57600080fd5b610175610e1f565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101b65780820151818401525b60208101905061019a565b50505050905090810190601f1680156101e35780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156101fc57600080fd5b610204610ec8565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156102455780820151818401525b602081019050610229565b50505050905090810190601f1680156102725780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561028b57600080fd5b610293610f71565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156102d45780820151818401525b6020810190506102b8565b50505050905090810190601f1680156103015780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561031a57600080fd5b61036a600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190505061101a565b005b341561037757600080fd5b61037f611093565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156103c05780820151818401525b6020810190506103a4565b50505050905090810190601f1680156103ed5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561040657600080fd5b61040e61113c565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561044f5780820151818401525b602081019050610433565b50505050905090810190601f16801561047c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561049557600080fd5b61049d6111e5565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156104de5780820151818401525b6020810190506104c2565b50505050905090810190601f16801561050b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561052457600080fd5b610574600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190505061128e565b005b341561058157600080fd5b61058961144c565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156105ca5780820151818401525b6020810190506105ae565b50505050905090810190601f1680156105f75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561061057600080fd5b610660600480803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919050506114f5565b005b341561066d57600080fd5b61067561156e565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156106b65780820151818401525b60208101905061069a565b50505050905090810190601f1680156106e35780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156106fc57600080fd5b610704611617565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156107455780820151818401525b602081019050610729565b50505050905090810190601f1680156107725780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561078b57600080fd5b6107db600480803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919050506116c0565b005b34156107e857600080fd5b6107f0611739565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156108315780820151818401525b602081019050610815565b50505050905090810190601f16801561085e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561087757600080fd5b6108c7600480803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919050506117e2565b005b34156108d457600080fd5b6108dc61185b565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561091d5780820151818401525b602081019050610901565b50505050905090810190601f16801561094a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561096357600080fd5b61096b611904565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156109ac5780820151818401525b602081019050610990565b50505050905090810190601f1680156109d95780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156109f257600080fd5b610a42600480803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919050506119ad565b005b3415610a4f57600080fd5b610a57611a26565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610a985780820151818401525b602081019050610a7c565b50505050905090810190601f168015610ac55780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3415610ade57600080fd5b610b2e600480803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050611acf565b005b3415610b3b57600080fd5b610b43611b48565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610b845780820151818401525b602081019050610b68565b50505050905090810190601f168015610bb15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3415610bca57600080fd5b610bd2611bf1565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610c135780820151818401525b602081019050610bf7565b50505050905090810190601f168015610c405780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3415610c5957600080fd5b610ca9600480803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050611c9a565b005b3415610cb657600080fd5b610d06600480803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050611d13565b005b3415610d1357600080fd5b610d63600480803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050611d8c565b005b3415610d7057600080fd5b610dc0600480803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050611e05565b005b3415610dcd57600080fd5b610e1d600480803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050611e7e565b005b610e27611ef7565b600d8054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610ebd5780601f10610e9257610100808354040283529160200191610ebd565b820191906000526020600020905b815481529060010190602001808311610ea057829003601f168201915b505050505090505b90565b610ed0611ef7565b600f8054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610f665780601f10610f3b57610100808354040283529160200191610f66565b820191906000526020600020905b815481529060010190602001808311610f4957829003601f168201915b505050505090505b90565b610f79611ef7565b600b8054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561100f5780601f10610fe45761010080835404028352916020019161100f565b820191906000526020600020905b815481529060010190602001808311610ff257829003601f168201915b505050505090505b90565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561107657600080fd5b816002908051906020019061108c929190611f0b565b505b5b5050565b61109b611ef7565b60058054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156111315780601f1061110657610100808354040283529160200191611131565b820191906000526020600020905b81548152906001019060200180831161111457829003601f168201915b505050505090505b90565b611144611ef7565b60078054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156111da5780601f106111af576101008083540402835291602001916111da565b820191906000526020600020905b8154815290600101906020018083116111bd57829003601f168201915b505050505090505b90565b6111ed611ef7565b60038054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156112835780601f1061125857610100808354040283529160200191611283565b820191906000526020600020905b81548152906001019060200180831161126657829003601f168201915b505050505090505b90565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156112ea57600080fd5b81600f9080519060200190611300929190611f0b565b507f60e3000561dc970753b97ba5279095c770a963d1972f1d8168ab581c319526b06001600f6040518080602001806020018381038352858181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156113b35780601f10611388576101008083540402835291602001916113b3565b820191906000526020600020905b81548152906001019060200180831161139657829003601f168201915b50508381038252848181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156114365780601f1061140b57610100808354040283529160200191611436565b820191906000526020600020905b81548152906001019060200180831161141957829003601f168201915b505094505050505060405180910390a15b5b5050565b611454611ef7565b600e8054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156114ea5780601f106114bf576101008083540402835291602001916114ea565b820191906000526020600020905b8154815290600101906020018083116114cd57829003601f168201915b505050505090505b90565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561155157600080fd5b81600c9080519060200190611567929190611f0b565b505b5b5050565b611576611ef7565b60088054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561160c5780601f106115e15761010080835404028352916020019161160c565b820191906000526020600020905b8154815290600101906020018083116115ef57829003601f168201915b505050505090505b90565b61161f611ef7565b600c8054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156116b55780601f1061168a576101008083540402835291602001916116b5565b820191906000526020600020905b81548152906001019060200180831161169857829003601f168201915b505050505090505b90565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561171c57600080fd5b81600a9080519060200190611732929190611f0b565b505b5b5050565b611741611ef7565b60048054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156117d75780601f106117ac576101008083540402835291602001916117d7565b820191906000526020600020905b8154815290600101906020018083116117ba57829003601f168201915b505050505090505b90565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561183e57600080fd5b81600e9080519060200190611854929190611f0b565b505b5b5050565b611863611ef7565b600a8054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156118f95780601f106118ce576101008083540402835291602001916118f9565b820191906000526020600020905b8154815290600101906020018083116118dc57829003601f168201915b505050505090505b90565b61190c611ef7565b60098054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156119a25780601f10611977576101008083540402835291602001916119a2565b820191906000526020600020905b81548152906001019060200180831161198557829003601f168201915b505050505090505b90565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611a0957600080fd5b8160089080519060200190611a1f929190611f0b565b505b5b5050565b611a2e611ef7565b60028054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611ac45780601f10611a9957610100808354040283529160200191611ac4565b820191906000526020600020905b815481529060010190602001808311611aa757829003601f168201915b505050505090505b90565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611b2b57600080fd5b8160069080519060200190611b41929190611f0b565b505b5b5050565b611b50611ef7565b60068054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611be65780601f10611bbb57610100808354040283529160200191611be6565b820191906000526020600020905b815481529060010190602001808311611bc957829003601f168201915b505050505090505b90565b611bf9611ef7565b60018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611c8f5780601f10611c6457610100808354040283529160200191611c8f565b820191906000526020600020905b815481529060010190602001808311611c7257829003601f168201915b505050505090505b90565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611cf657600080fd5b8160019080519060200190611d0c929190611f0b565b505b5b5050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611d6f57600080fd5b8160059080519060200190611d85929190611f0b565b505b5b5050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611de857600080fd5b81600b9080519060200190611dfe929190611f0b565b505b5b5050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611e6157600080fd5b8160079080519060200190611e77929190611f0b565b505b5b5050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611eda57600080fd5b8160099080519060200190611ef0929190611f0b565b505b5b5050565b602060405190810160405280600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10611f4c57805160ff1916838001178555611f7a565b82800160010185558215611f7a579182015b82811115611f79578251825591602001919060010190611f5e565b5b509050611f879190611f8b565b5090565b611fad91905b80821115611fa9576000816000905550600101611f91565b5090565b905600a165627a7a723058202ada90241e9c42b0c184be70a51d9ef9b8adb2ff103ef534557c9f22776992580029","storage":{"0x0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9":"f7","0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0":"3534343700000000000000000000000000000000000000000000000000000008","0x1edf167807421166f29a87fc522b46543164915401142af67f87687dbc8ae574":"323638313720353036352035303635203420312043484e20434e204c6f6e6767","0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563":"86f33858182ce30f4c6506e51cc89a26d595ec62","0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace":"323032302d31322d323100000000000000000000000000000000000000000014","0x40abea1508c7557b93b3e219e777ce8530b60f9f8452ef1c627dbc62b53708fc":"202852c4ab676129204c562d3130323120747275652074727565200000000000","0x41faab445fe72d12e121ca7567969321cb1961126885af5ac2372f208ce0eeec":"207c7c2000000000000000000000000000000000000000000000000000000000","0x5cfb45a54af5054a79d6e3e06b95e51e6827e1c2eb707f378c7b289bca6900e2":"476f6f6420e2849631204475616c2055736520547269616e676c652055562047","0x613633635594b01395024d35958787d0af086208b30f21b3f0f1c78c2f5fcf9e":"65204e61696c2046696c652042756666696e6720546f6f6c2c207175616e7469","0x6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af":"2b33373132393737393838380000000000000000000000000000000000000018","0x87466a1ae97409dd9d9cd9368751b439509d8b3f8fc2bb47a4264e5d6fd4d324":"7479202d20312c207072696365202d20302e37384555522c207368697070696e","0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b":"302e300000000000000000000000000000000000000000000000000000000006","0x8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac802":"3030310000000000000000000000000000000000000000000000000000000006","0xa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688":"616e6472656a732e6b6f6e616b6f767340676d61696c2e636f6d000000000034","0xaf2c61b129d942dabc1f4485bf6d0d72c1b1fc04813c211ef96a7351dd6b6f91":"6720636f7374202d20302e304555522c2061747472696275746573202d202829","0xafc64d4667876823fbd3f2510daa71752dbb32dda014f138587218722b444b5a":"20312066616c7365207472756520000000000000000000000000000000000000","0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6":"3330393900000000000000000000000000000000000000000000000000000008","0xb2ac7d4e10f072d9f46be3db644ef1be450423557f8fa8d52ccc7cf0d7e8c319":"32373930392035343437203534343720416e6472656a73204b6f6e616b6f7673","0xb5de84fb4dd9cb80d26ac5a8faf68a3c97a78747c9a0ee3f92934a2bebd0d549":"68656e7a68656e20434e2d3434204775616e67646f6e672050726f76696e6365","0xb772b7d5bf80a37f67fcf9771d15af70ca9af379c9d351c4f99c5e4c71ffc4b1":"3339206e756c6c2052696761204c562d52492052c4ab6761732072616a6f6e73","0xb8f4b46da31c4f86b221c0dfbbbba01af520f81092608a89682fdeea4ba5e09c":"616e67204a6968756120526f6164204e6f2e3639392d373231206e756c6c2053","0xb9a4a546c6bdca52fed24c8e5e1ce03b3bedc826c28110195681e2094e3b7f4f":"656c20506f6c6973682052656d6f76657220507573686572204d616e69637572","0xbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd":"4555520000000000000000000000000000000000000000000000000000000006","0xc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b":"302e373800000000000000000000000000000000000000000000000000000008","0xc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a8":"2b3836313831343835363231333100000000000000000000000000000000001c","0xd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb5":"0149","0xde9647372d0c1a3bf7d388adb42a76542657d064a5909aaa3ee76e8d628c8ac5":"202b3337313239373739383838204c5641204c562053616861726f766120382d","0xdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7":"dd","0xf3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3":"77616c5f71697572697369797532303138406f75746c6f6f6b2e636f6d00003a","0xf652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f":"3530363500000000000000000000000000000000000000000000000000000008"},"key":"0x0000346a216203198fa17e41414758e58deeae2fbfb25ae9e65c62a2445fdf6a"} +{"balance":"220000000000000","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x000035fdf0c8ce4eb22d264a0bc8cdaaff40e17c30211bc95d02fbd4166e8021"} +{"balance":"2000000000000000000","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x0000376c89ba2b15131e1045ecb44d6f978e6e7bb1c3df887d604be3c336dd71"} +{"balance":"151461487032320847","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00003781646b0fe34fe262f27aecfcf52739d4397cd8c6dd06ab3aace01fb623"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x000037a36fd08fcbb33145c5561ecdc481c1a9511a0823f4a72590013b47208d"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x00003816d2463d5234a2d44eed70018d7bdab271e454a2fcd93fe9f389c14f88"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x000038a2f1c944fa0381dd5d6855596778df86a8bcb20834927feb85845c38d4"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x000038b04672013a75b8e74c61098ed946b0f4ba156296da99c9ffde5f08b19f"} +{"balance":"5899808338668005000","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00003a0eca157c613d1205dc3408df2df24240f4658908e714f5635d989cf3ce"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00003a1d240fb04f4666d5411f82b4b355b941928ccd1a4f877b534229f178a9"} +{"balance":"2000000000000000000","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00003ab2bc2806ab0d31bd41996bc0503d94d898a32c9c47a13e6e5f9918ba2f"} +{"balance":"1000000000000000000","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00003b182c60f9e3ffdc2d3ff24d9ca1fad5c63c0f274cc93dcf6a52c6803fe2"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00003b2035225b4886c1c972c62f00332eaaa45eb02dc8735d9439b3288e49d2"} +{"balance":"0","nonce":1,"root":"0xa35499b7c78f2899f32d11a2bfb6924fb813f4d62e76179aab31469df32b18fd","codeHash":"0xaa442f3c7e69540d3d42215fcf08df086c4fab9042218c9efbd968de8bea07f9","code":"0x6080604052600436106100705760003560e01c80638feb1b8b1161004e5780638feb1b8b146101fd578063d4ee1d901461024e578063e45bf7a6146102a5578063f2fde38b146102fc57610070565b806359a006801461013e57806379ba50971461018f5780638da5cb5b146101a6575b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f193505050501580156100d8573d6000803e3d6000fd5b507f0fe4cb1d003e6b2859d9f82ed185534d04565d376652186cbd07c0105fdcc5d830604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1005b34801561014a57600080fd5b5061018d6004803603602081101561016157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061034d565b005b34801561019b57600080fd5b506101a4610664565b005b3480156101b257600080fd5b506101bb610801565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561020957600080fd5b5061024c6004803603602081101561022057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610826565b005b34801561025a57600080fd5b50610263610b61565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156102b157600080fd5b506102ba610b87565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561030857600080fd5b5061034b6004803603602081101561031f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610bad565b005b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103a657600080fd5b600081905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561042a57600080fd5b505afa15801561043e573d6000803e3d6000fd5b505050506040513d602081101561045457600080fd5b81019080805190602001909291905050509050600081116104dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f62616c616e6365206d7573742062652067726561746572207468616e2030000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b15801561058657600080fd5b505af115801561059a573d6000803e3d6000fd5b505050507f8664be48506bd501d568d732361f45a27336ed6ea23c69c994d33e971ff7f40130600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060405180910390a1505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146106be57600080fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461087f57600080fd5b600081905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561090357600080fd5b505afa158015610917573d6000803e3d6000fd5b505050506040513d602081101561092d57600080fd5b81019080805190602001909291905050509050600081116109b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f62616c616e6365206d7573742062652067726561746572207468616e2030000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015610a5f57600080fd5b505af1158015610a73573d6000803e3d6000fd5b505050506040513d6020811015610a8957600080fd5b8101908080519060200190929190505050507f8664be48506bd501d568d732361f45a27336ed6ea23c69c994d33e971ff7f40130600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060405180910390a1505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610c0657600080fd5b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505056fea265627a7a7231582001543b5939e998cc829c177eb8dd2927268ba9f47e41ce006f6276379d324b6f64736f6c634300050c0032","storage":{"0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563":"07e80128c7a35d0d43ddcc67fa8b1495871e08bf","0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace":"e8bb7d0000e0b8f7114863d7fee666b5270111b8"},"key":"0x00003b4392961905f01e98b66d6b1694d1695c7e92d69d9579b8aa160579ff52"} +{"balance":"65536","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00003b80a4396be4a9f48ddba9a7c28c8c2cae524fe29b79cdc1159e6e275036"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x00003b926acd084a78b0a0feb44071674afbb7cc7ebaff7b70830a7c419a87d4"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00003bd45f0a1d9de39733d95f4035a67f0679e6680c7bd6fde1a48837e56d36"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00003c02233bf59b8964a553c6f5a26c59462d7dc2947eeebd79bf600e494755"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00003c333f5e467325d02ada712201e89d134a4c93cc1538545ff4ed1bab0f99"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x00003ccf61c38bcdf53e08b45443cc202c4bbd6e0ef1bc0c9c6242146492ce8b"} +{"balance":"0","nonce":1,"root":"0x0e2cdac7997995754ea3b48d7ec83d20ab94c0d7302061203d37a9e46a4daed2","codeHash":"0xaf1a0bb5c18dcfef4610dd48e7b85d45503536b9887b83f5b497dd11b8702d20","code":"0x608060405234801561001057600080fd5b50600436106100565760003560e01c8062f55d9d1461005b5780632c8f55de146100835780638a6d2cc8146100bf578063b416663e146100f8578063beabacc814610175575b600080fd5b6100816004803603602081101561007157600080fd5b50356001600160a01b03166101ab565b005b6100816004803603608081101561009957600080fd5b508035906001600160a01b036020820135811691604081013590911690606001356101ff565b6100dc600480360360208110156100d557600080fd5b50356103b2565b604080516001600160a01b039092168252519081900360200190f35b610100610419565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561013a578181015183820152602001610122565b50505050905090810190601f1680156101675780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6100816004803603606081101561018b57600080fd5b506001600160a01b03813581169160208101359091169060400135610470565b6000546001600160a01b0316156101f35760405162461bcd60e51b81526004018080602001828103825260238152602001806105476023913960400191505060405180910390fd5b806001600160a01b0316ff5b6000546001600160a01b031615610265576000546001600160a01b03163314610265576040805162461bcd60e51b815260206004820152601360248201527239b2b73232b91034b9903737ba1037bbb732b960691b604482015290519081900360640190fd5b606061026f610419565b90506000858251602084016000f590506001600160a01b0381166102da576040805162461bcd60e51b815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f7900000000000000604482015290519081900360640190fd5b604080516317d5759960e31b81526001600160a01b0387811660048301528681166024830152604482018690529151839283169163beabacc891606480830192600092919082900301818387803b15801561033457600080fd5b505af1158015610348573d6000803e3d6000fd5b50506040805162f55d9d60e01b815233600482015290516001600160a01b038516935062f55d9d9250602480830192600092919082900301818387803b15801561039157600080fd5b505af11580156103a5573d6000803e3d6000fd5b5050505050505050505050565b600060ff816103bf610419565b80516020918201206040805160f89590951b6001600160f81b031916858401523060601b60218601526035850196909652605580850191909152855180850390910181526075909301909452508051920191909120919050565b60408051733d602d80600a3d3981f3363d3d373d3d3d363d7360601b60208201523060601b60348201526e5af43d82803e903d91602b57fd5bf360881b604882015281516037818303018152605790910190915290565b6000546001600160a01b0316156104d6576000546001600160a01b031633146104d6576040805162461bcd60e51b815260206004820152601360248201527239b2b73232b91034b9903737ba1037bbb732b960691b604482015290519081900360640190fd5b6040805163a9059cbb60e01b81526001600160a01b038481166004830152602482018490529151859283169163a9059cbb91604480830192600092919082900301818387803b15801561052857600080fd5b505af115801561053c573d6000803e3d6000fd5b505050505050505056fe6d617374657220636f6e74726163742063616e6e6f742062652064657374726f796564a265627a7a72315820c25d8d6c752e7c31557effc6f9c1c9a9e0e5e870ce370c111d5246f44635baa464736f6c63430005110032","storage":{"0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563":"ba75ae10d3869185cd406b48a17a7262fc3da945"},"key":"0x00003d78a55317ba4512f848a8273264ee488d918d09e1dc8f8e0f16e18aa62b"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x00003de78422d336721b64d10d3785399a87e40c6e72566fa707541aecc115f9"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x00003df43eae3c73f21ad61064429cf0abbb3f883f91205dd3f318d35209c711"} +{"balance":"0","nonce":1,"root":"0x67ee914949d18f51f9037db4e62637e7f22eed918d449e55f79892f2dc9d2242","codeHash":"0x66890fa1f3c4a236e8f0f48c6fe129fc9de979a771063989c3b0496a76752366","code":"0x60606040520000a165627a7a72305820a58e6d4b891faa53c5672b590031129f2be22a260b36f2da1f71049ca813425f0029","storage":{"0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563":"652e9d91"},"key":"0x00003dff63764d6009282afd8f25009bf6b17ba86483d4db7a34c249e0e118e8"} +{"balance":"1000000000000000000","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00003e010f9e8aac4c80c9ec1537fab53cb42ba30d4072fa19a317b0f2915e7d"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xd80cd839dd3957d572b90780ada202a13936fa2875daea94216263371e9ef1d2","code":"0x6eb3f879cb30fe243b4dfee438691c043318585733ff","key":"0x00003e1c9955f8a426ca6d877f0b194a99156730a0033ce3c5dbfcfec76037e0"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x00003e222ec14b94d1a023c6ed30a7448c813e25623b5f8c92fe944816e3b068"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0x2a7eb4137fc14ee6b21d11d8455f0c1c09ec63ffa91fc66d9fde1342a2a49eb1","code":"0x608060405234801561001057600080fd5b50600436106100575760003560e01c80632e7ba6ef1461005c5780632eb4a7ab146100ea57806378e97925146101045780639e34070f1461010c578063fc0c546a1461013d575b600080fd5b6100e86004803603608081101561007257600080fd5b8135916001600160a01b0360208201351691604082013591908101906080810160608201356401000000008111156100a957600080fd5b8201836020820111156100bb57600080fd5b803590602001918460208302840111640100000000831117156100dd57600080fd5b509092509050610161565b005b6100f261041e565b60408051918252519081900360200190f35b6100f2610442565b6101296004803603602081101561012257600080fd5b5035610466565b604080519115158252519081900360200190f35b61014561048c565b604080516001600160a01b039092168252519081900360200190f35b7f000000000000000000000000000000000000000000000000000000005fc39f8c4210156101c05760405162461bcd60e51b815260040180806020018281038252602f8152602001806105ed602f913960400191505060405180910390fd5b6101c985610466565b156102055760405162461bcd60e51b81526004018080602001828103825260288152602001806105816028913960400191505060405180910390fd5b600085858560405160200180848152602001836001600160a01b031660601b815260140182815260200193505050506040516020818303038152906040528051906020012090506102ac8383808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152507f29b66d7d07a76abf8f02aef4a30892a779b1d797b60bf2cbdb5cd1b0a247ea1f92508591506104b09050565b6102e75760405162461bcd60e51b81526004018080602001828103825260218152602001806105a96021913960400191505060405180910390fd5b6102f086610559565b7f0000000000000000000000006705bec064ea895102be0d6df3547535bb258f596001600160a01b031663a9059cbb86866040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561036757600080fd5b505af115801561037b573d6000803e3d6000fd5b505050506040513d602081101561039157600080fd5b50516103ce5760405162461bcd60e51b81526004018080602001828103825260238152602001806105ca6023913960400191505060405180910390fd5b604080518781526001600160a01b038716602082015280820186905290517f4ec90e965519d92681267467f775ada5bd214aa92c0dc93d90a5e880ce9ed0269181900360600190a1505050505050565b7f29b66d7d07a76abf8f02aef4a30892a779b1d797b60bf2cbdb5cd1b0a247ea1f81565b7f000000000000000000000000000000000000000000000000000000005fc39f8c81565b6101008104600090815260208190526040902054600160ff9092169190911b9081161490565b7f0000000000000000000000006705bec064ea895102be0d6df3547535bb258f5981565b600081815b855181101561054e5760008682815181106104cc57fe5b602002602001015190508083116105135782816040516020018083815260200182815260200192505050604051602081830303815290604052805190602001209250610545565b808360405160200180838152602001828152602001925050506040516020818303038152906040528051906020012092505b506001016104b5565b509092149392505050565b610100810460009081526020819052604090208054600160ff9093169290921b909117905556fe4d65726b6c654469737472696275746f723a2044726f7020616c726561647920636c61696d65642e4d65726b6c654469737472696275746f723a20496e76616c69642070726f6f662e4d65726b6c654469737472696275746f723a205472616e73666572206661696c65642e4d65726b6c654469737472696275746f723a20446973747269627574696f6e206e6f74207374617274656420796574a2646970667358221220269e02b8d1b0fb78971999ccb974e9eff95b000ba800e2b7795edf29b4bd6fbf64736f6c63430007040033","key":"0x00003e33768ed8b7e3b2d44a835ef5911c4ad358b179916c0f939d46fb452afc"} +{"balance":"0","nonce":1,"root":"0x735066326e0c93fc6f6e0022a30945cb02437653377d70d88515152de328610d","codeHash":"0xd0cb60de21074d87c123ae0412f28c14d7636479cd6d9f13fab6e2c4ffaa858d","code":"0x6080604052600436106100fb5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde03811461010057806309f6c6071461018a5780630ccde0b1146101b157806318160ddd146101c65780631cc54204146101ce57806325d998bb146101e35780632ab4d052146101f7578063313ce5671461020c57806370a08231146102375780637e95cda4146102585780638c71ef73146102c157806395d89b41146102e2578063a9059cbb146102f7578063d95efb981461031d578063e00686e41461033e578063e12ed13c14610353578063e5f65c7114610368578063fb6560671461037d575b600080fd5b34801561010c57600080fd5b506101156103ae565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561014f578181015183820152602001610137565b50505050905090810190601f16801561017c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561019657600080fd5b5061019f61043c565b60408051918252519081900360200190f35b3480156101bd57600080fd5b5061019f610440565b61019f610446565b3480156101da57600080fd5b5061019f610460565b61019f600160a060020a0360043516610466565b34801561020357600080fd5b5061019f610514565b34801561021857600080fd5b5061022161051e565b6040805160ff9092168252519081900360200190f35b34801561024357600080fd5b5061019f600160a060020a0360043516610527565b34801561026457600080fd5b50604080516020600480358082013583810280860185019096528085526102ad953695939460249493850192918291850190849080828437509497506105399650505050505050565b604080519115158252519081900360200190f35b3480156102cd57600080fd5b506102ad600160a060020a036004351661060b565b3480156102ee57600080fd5b50610115610659565b34801561030357600080fd5b5061031b600160a060020a03600435166024356106b3565b005b34801561032957600080fd5b506102ad600160a060020a03600435166107e9565b34801561034a57600080fd5b5061019f6107fe565b34801561035f57600080fd5b5061019f610804565b34801561037457600080fd5b5061019f61080c565b34801561038957600080fd5b50610392610812565b60408051600160a060020a039092168252519081900360200190f35b6000805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156104345780601f1061040957610100808354040283529160200191610434565b820191906000526020600020905b81548152906001019060200180831161041757829003601f168201915b505050505081565b4390565b60035481565b6004544303600a8190556005540260088190556006540290565b60065481565b600160a060020a0381166000908152600e602052604081205460ff16156104f4576004544303600a8190556305f5e100116104ba5750600160a060020a0381166000908152600d602052604090205461050f565b50600a5460055402600881905560035403600b819055600160a060020a0382166000908152600d602052604090205403600981905561050f565b50600160a060020a0381166000908152600d60205260409020545b919050565b6006546003540290565b60025460ff1681565b600d6020526000908152604090205481565b6000806251e56b431161060057600754600160a060020a0316331415610600575060005b82518110156105f757600354600d6000858481518110151561057b57fe5b90602001906020020151600160a060020a0316600160a060020a03168152602001908152602001600020819055506001600e600085848151811015156105bd57fe5b602090810291909101810151600160a060020a03168252810191909152604001600020805460ff191691151591909117905560010161055d565b60019150610605565b600091505b50919050565b600754600090600160a060020a0316156106275750600061050f565b5060078054600160a060020a03831673ffffffffffffffffffffffffffffffffffffffff199091161790556001919050565b60018054604080516020600284861615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156104345780601f1061040957610100808354040283529160200191610434565b600160a060020a0382166000908152600e602052604090205460ff16156106d957600080fd5b336000908152600d60205260409020548111156106f557600080fd5b600160a060020a0382166000908152600d6020526040902054818101101561071c57600080fd5b336000908152600e602052604090205460ff1615610780576004544303600a8190556305f5e100111561078057600a5460055402600881905560035403600b819055336000908152600d602052604090205403600981905581111561078057600080fd5b336000818152600d6020908152604080832080548690039055600160a060020a03861680845292819020805486019055805185815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a35050565b600e6020526000908152604090205460ff1681565b60055481565b600454430390565b60045481565b600754600160a060020a0316815600a165627a7a72305820333d2db591ffdfbdf5e92fa9ea944134285f2c0893675d988cf404721ba6f4ad0029","storage":{"0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0":"7d00","0x1bdfeb23b89a588b7f40a6ad5bee2d0b6627145ce2d338dd55d7344e4016cf6e":"01","0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563":"6d79746573743231000000000000000000000000000000000000000000000010","0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace":"08","0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b":"4f9444","0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6":"5454323100000000000000000000000000000000000000000000000000000008","0xbded2b5191ead2d95bb6a988e9111572ac8736d433fb65547a419af96c6e3738":"01","0xc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b":"02e90edd0000","0xcaa408ea2ac068e9201acf795525bddd098346ad4f79b931ea5a292ed5bf3cf5":"01","0xf652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f":"03"},"key":"0x00003e484626b2eb831aced8c0130ce8a68a3676416aba7ae2c1b299c8609534"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00003eaf1e1628dbc3675ae883a3bfdc2a37cf840534df9565dea1d10f03f9fe"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x00003f0115a7ee686f7002359157a6b3431d5efc8e79a33dc8b89882c851f06f"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0x1d93f60f105899172f7255c030301c3af4564edd4a48577dbdc448aec7ddb0ac","code":"0x6d4946c0e9f43f4dee607b0ef1fa1c3318585733ff","key":"0x00003f09d4ec2b9c82ca9990d99f2a54870e16e98b03224cf4921c9226374efb"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x00003fc8a17b88cd866b1a994e29377e3f2a86bc05bf155181250c28904d986a"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x0000406096b50db7e5a685c4c398916b66dd19de78ab37adf82cfd690c18d88b"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x000041d511d3a7a00e006bb69b4b6b8475ee8b46a2f792edbc7268bdcdd58d7a"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x000041f9860c34aa7496281fb0232dbba589d4d486d485598dd49cc38d00fc35"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x000042abc8b8831021018d5c61f8679ea0ddf54c8b74a474e687ac0eff0b20b5"} +{"balance":"1000000000000000000","nonce":1,"root":"0x27d16f02eddb5c9f3077a63e20563ddb02fd7aac38cd6cd58f2b6a850a1bf8a3","codeHash":"0x906bcc53f1734b95835bed548100120e4922893dcdf84ba9b9f3e601cfd75f31","code":"0x6080604052600436106100ec5760003560e01c80637a3a0e841161008a578063a035b1fe11610059578063a035b1fe1461058d578063a9059cbb146105b8578063e3d670d714610613578063fd6b7ef814610678576101fd565b80637a3a0e841461044c5780637b3e5e7b14610477578063867904b4146104a257806395d89b41146104fd576101fd565b806329dcb0cf116100c657806329dcb0cf14610334578063313ce5671461035f57806338af3eed1461039057806370a08231146103e7576101fd565b806301cb3b201461026257806306fdde031461027957806318160ddd14610309576101fd565b366101fd57600b60019054906101000a900460ff161561010b57600080fd5b600034905080600960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508060026000828254019250508190555061018233600654838161017c57fe5b0461068f565b7fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf633826001604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200183815260200182151515158152602001935050505060405180910390a150005b7f3a0fc1c8574c527b4b4211de21a1c2e1441f2c28e96e9b8938c0211fe98fce1c33604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1005b34801561026e57600080fd5b50610277610739565b005b34801561028557600080fd5b5061028e610815565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156102ce5780820151818401526020810190506102b3565b50505050905090810190601f1680156102fb5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561031557600080fd5b5061031e6108b3565b6040518082815260200191505060405180910390f35b34801561034057600080fd5b506103496108b9565b6040518082815260200191505060405180910390f35b34801561036b57600080fd5b506103746108bf565b604051808260ff1660ff16815260200191505060405180910390f35b34801561039c57600080fd5b506103a56108d2565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156103f357600080fd5b506104366004803603602081101561040a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506108f7565b6040518082815260200191505060405180910390f35b34801561045857600080fd5b5061046161090f565b6040518082815260200191505060405180910390f35b34801561048357600080fd5b5061048c610915565b6040518082815260200191505060405180910390f35b3480156104ae57600080fd5b506104fb600480360360408110156104c557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061068f565b005b34801561050957600080fd5b5061051261091b565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610552578082015181840152602081019050610537565b50505050905090810190601f16801561057f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561059957600080fd5b506105a26109b9565b6040518082815260200191505060405180910390f35b3480156105c457600080fd5b50610611600480360360408110156105db57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506109bf565b005b34801561061f57600080fd5b506106626004803603602081101561063657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506109ce565b6040518082815260200191505060405180910390f35b34801561068457600080fd5b5061068d6109e6565b005b806005540160058190555080600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508173ffffffffffffffffffffffffffffffffffffffff167f277fac902d9d7d8e97adae9b484dc6f3faa34e3590e396095072f2d33091d362826040518082815260200191505060405180910390a25050565b600354421061081357600154600254106107f7576001600b60006101000a81548160ff0219169083151502179055507fec3f991caf7857d61663fd1bba1739e04abd4781238508cde554bb849d790c856000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600254604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a15b6001600b60016101000a81548160ff0219169083151502179055505b565b60078054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156108ab5780601f10610880576101008083540402835291602001916108ab565b820191906000526020600020905b81548152906001019060200180831161088e57829003601f168201915b505050505081565b60055481565b60035481565b600460009054906101000a900460ff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60096020528060005260406000206000915090505481565b60015481565b60025481565b60088054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156109b15780601f10610986576101008083540402835291602001916109b1565b820191906000526020600020905b81548152906001019060200180831161099457829003601f168201915b505050505081565b60065481565b6109ca338383610d1e565b5050565b600a6020528060005260406000206000915090505481565b6003544210610d1c57600b60009054906101000a900460ff16610b94576000600960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490506000600960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000811115610b92573373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f1935050505015610b4c577fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf633826000604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200183815260200182151515158152602001935050505060405180910390a1610b91565b80600960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b5b505b600b60009054906101000a900460ff168015610bfc57503373ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b15610d1b576000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc6002549081150290604051600060405180830381858888f1935050505015610cfe577fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf66000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff166002546000604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200183815260200182151515158152602001935050505060405180910390a1610d1a565b6000600b60006101000a81548160ff0219169083151502179055505b5b5b565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610d5857600080fd5b80600a60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610da457600080fd5b600a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205481600a60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054011015610e3157600080fd5b6000600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054600a60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205401905081600a60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600a60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a380600a60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054600a60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054011461103e57fe5b5050505056fea2646970667358221220ae9b7fddb7d42282fa56c817240a191addc9180031dffe8ef6dd3b06a3ff4d8864736f6c63430006010033","storage":{"0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0":"0b","0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563":"86f8b168d5f14ea06cac61e6fe698044822ec96f","0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace":"0de0b6b3a7640000","0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b":"01","0xa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688":"49434f0000000000000000000000000000000000000000000000000000000006","0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6":"1bc16d674ec80000","0xc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b":"632ad1b8","0xc798482d735407cb61b88f1260a2c25541c134e6023c51bf007108a532d36468":"01","0xe2ea6584a679a9b1fee4bb710669592e9c0ba3244bf9eafc9758bb1c5aa863a8":"0de0b6b3a7640000","0xe32ddb2cf87efc5dbb0eb947c892c4b84dacf9cbb2ea7df8909f019ad47c453c":"0a","0xf3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3":"434f000000000000000000000000000000000000000000000000000000000004","0xf652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f":"0de0b6b3a7640000"},"key":"0x000042afae2df5bf226892bfc387ab26ac230bc508883186326b52f970bc20de"} +{"balance":"569759840420279798","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x000042d2250a7d49022a90ec09e5a1082bac9d529c03b2b5ec29a58793838fb3"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x00004321aebdf376f818521a3646ea56c2a1b267aed4074467a3c16ee936070e"} +{"balance":"0","nonce":1,"root":"0x6b96fb851bade10ac67aa37f6e801e18d44ab30cafd983041761f93adc4adcb6","codeHash":"0x3da0c16ddd3ecc07e7c991e8e1d14f6fa28a277bd1d58b59e97891f3e4d7e47b","code":"0x608060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630900f01014610067578063445df0ac146100b85780638da5cb5b146100e3578063fdacd5761461013a575b600080fd5b34801561007357600080fd5b506100b66004803603602081101561008a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610175565b005b3480156100c457600080fd5b506100cd61025d565b6040518082815260200191505060405180910390f35b3480156100ef57600080fd5b506100f8610263565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561014657600080fd5b506101736004803603602081101561015d57600080fd5b8101908080359060200190929190505050610288565b005b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561025a5760008190508073ffffffffffffffffffffffffffffffffffffffff1663fdacd5766001546040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b15801561024057600080fd5b505af1158015610254573d6000803e3d6000fd5b50505050505b50565b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102e557806001819055505b5056fea165627a7a723058203595da9f44616ce113f1d7ce693f48af84eaea78d86933b3ff2342a95fefbb770029","storage":{"0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563":"ec852ab34492470b3056c6ffe3acae66ab8e1869","0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6":"02"},"key":"0x00004364245d7ce5bb69c5cf4df93f3145e17f028d29cac856e3c20facc5e886"} +{"balance":"1666666666666666666","nonce":1,"root":"0x864d4130b74ce63474be91061822028d01435ae50074a662d11c1edbd9c7ba45","codeHash":"0xf6ed0108c3a68c3a1ed040375b4662490523a500a11c0a3562567ce3bae81e60","code":"0x6060604052361561008b5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416634c33fe9481146100a15780635a0cf9f3146100bf57806379599f96146100e75780637e102b2a146100f9578063b82a097814610110578063d9214ed514610131578063d9a9685214610159578063df9b8fff14610180575b341561009357fe5b61009f5b60006000fd5b565b005b34156100a957fe5b61009f600160a060020a03600435166101a1565b005b6100d3600160a060020a036004351661022a565b604080519115158252519081900360200190f35b34156100ef57fe5b61009f6102cd565b005b341561010157fe5b61009f6004351515610349565b005b341561011857fe5b61009f600160a060020a03600435166024356103cb565b005b6100d3600160a060020a0360043516610463565b604080519115158252519081900360200190f35b341561016157fe5b61009f600160a060020a036004351663ffffffff60243516610506565b005b341561018857fe5b61009f600160a060020a03600435166024356105a8565b005b604080517fe0c703dc000000000000000000000000000000000000000000000000000000008152600060048201819052600160a060020a0384166024830152915173fec343c5512a9ec09dbfa967650f2a4704f8c3489263e0c703dc9260448082019391829003018186803b151561021557fe5b6102c65a03f4151561022357fe5b5050505b50565b604080516000602091820181905282517f29f2e90700000000000000000000000000000000000000000000000000000000815260048101829052600160a060020a0385166024820152604481018290529251909273fec343c5512a9ec09dbfa967650f2a4704f8c348926329f2e90792606480840193829003018186803b15156102b057fe5b6102c65a03f415156102be57fe5b5050604051519150505b919050565b73fec343c5512a9ec09dbfa967650f2a4704f8c34863d30d447d60006040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018082815260200191505060006040518083038186803b151561033557fe5b6102c65a03f4151561034357fe5b5050505b565b604080517ff54713070000000000000000000000000000000000000000000000000000000081526000600482018190528315156024830152915173fec343c5512a9ec09dbfa967650f2a4704f8c3489263f54713079260448082019391829003018186803b151561021557fe5b6102c65a03f4151561022357fe5b5050505b50565b604080517ffe7a0fb9000000000000000000000000000000000000000000000000000000008152600060048201819052600160a060020a03851660248301526044820184905260648201819052915173fec343c5512a9ec09dbfa967650f2a4704f8c3489263fe7a0fb99260848082019391829003018186803b151561044d57fe5b6102c65a03f4151561045b57fe5b5050505b5050565b604080516000602091820181905282517f29f2e90700000000000000000000000000000000000000000000000000000000815260048101829052600160a060020a0385166024820152600160448201529251909273fec343c5512a9ec09dbfa967650f2a4704f8c348926329f2e90792606480840193829003018186803b15156102b057fe5b6102c65a03f415156102be57fe5b5050604051519150505b919050565b604080516000602091820181905282517f0a8b79830000000000000000000000000000000000000000000000000000000081526004810191909152600160a060020a038516602482015263ffffffff84166044820152915173fec343c5512a9ec09dbfa967650f2a4704f8c34892630a8b7983926064808301939192829003018186803b151561044d57fe5b6102c65a03f4151561045b57fe5b5050505b5050565b604080517ffe7a0fb9000000000000000000000000000000000000000000000000000000008152600060048201819052600160a060020a03851660248301526044820184905260016064830152915173fec343c5512a9ec09dbfa967650f2a4704f8c3489263fe7a0fb99260848082019391829003018186803b151561044d57fe5b6102c65a03f4151561045b57fe5b5050505b50505600a165627a7a723058205d2ade12bf7e8c7b93a4fe8ddae311b48dd752a9a428662dae3bfe9948928be50029","storage":{"0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0":"17213080c1a6aaaa","0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563":"bea5c7ce8b86aa461b320f78b4952d5e805067f9","0x6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af":"50750500000a3c","0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b":"22b1c8c1227a0000","0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6":"fe02a56127affbba940bb116fa30a3af10d12f80"},"key":"0x00004540f1b9fd302df8b96c7a650c8b853f95a493cde74c8738cb8253b48f7d"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x0000458619e08a5ad5dcd12295b0ebba81e1f33b9c09f3e602b31b3ba3272831"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x0000461e484d600f2fb29a8ea6297fcbe5a451129922a170f6aa1faec4948b70"} +{"balance":"1000000000000000000","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x0000462f5b991fb4d0ced8d0aeab4d3ab4839b97845cbb8fb308d7fc53be935f"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x00004701591274ff76de9d88afb014f6cf0eb5b0fb77ccf6a4fa1afe4b68929d"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x0000477b1e2e2aad5dbc8563a6a916685f7d63f68befaac8a84b6a99e610a845"} +{"balance":"197894790989435765","nonce":4,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x000047a8be26642b57345d0eccb31aa3f406d6f5fb908934f2189e038f0230ad"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x00004879f0433153c51a5561f1bb328c9445d628bdf4c4c6aa6b403fe730c7c3"} +{"balance":"31414040000000000","nonce":2,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x000048e00047c26da54eb84dc2ba4ceb725bd33885fe53f6a478b481e85ee3f3"} +{"balance":"0","nonce":2,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00004913ee7cf2fd1ebe7a8e46d84b72b797633d3bafabc640137e5e56e87537"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x00004997acbe2b9dc40b9606976ac3db206a66a0b5a37f136cbef3add55b3d08"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x000049a6f9a47485ee4fe62e42ad3cf349eb468f09581e608d386beabe78ff41"} +{"balance":"0","nonce":1,"root":"0xd2d6361e21f92a5b619cc5f0f2aebc71971e044cf29411ff78dfb173408ff321","codeHash":"0xef9832e8327de46eca9b949ae5a8271d704a37f94efffc3d7ec9abbf355a2625","code":"0x6080604052600436106101455763ffffffff60e060020a60003504166306fdde03811461014a578063126891f3146101d45780631a22f0c814610205578063386a8707146102925780634e71e0c8146102bc57806354fd4d50146102d1578063556672a7146102e657806370752e2714610331578063715018a61461036257806373689701146103775780637d95500b1461038c578063845d0849146104d15780638da5cb5b146105805780638e4586af1461059557806391c2c469146105c8578063957aa58c146105dd5780639b9843a314610606578063c0ee0b8a14610651578063c1fd6406146106e1578063d3e598c71461070b578063d5f394881461073e578063d69f208014610753578063ddb9e577146107a1578063e30c39781461083b578063ecda10f514610850578063f2fde38b14610877578063f5ee3348146108aa575b600080fd5b34801561015657600080fd5b5061015f6108d6565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610199578181015183820152602001610181565b50505050905090810190601f1680156101c65780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156101e057600080fd5b506101e9610961565b60408051600160a060020a039092168252519081900360200190f35b34801561021157600080fd5b506102906004803603604081101561022857600080fd5b6001608060020a038235169190810190604081016020820135602060020a81111561025257600080fd5b82018360208201111561026457600080fd5b803590602001918460018302840111602060020a8311171561028557600080fd5b509092509050610970565b005b34801561029e57600080fd5b50610290600480360360208110156102b557600080fd5b5035610ac1565b3480156102c857600080fd5b50610290610cca565b3480156102dd57600080fd5b5061015f610d7f565b3480156102f257600080fd5b506102906004803603606081101561030957600080fd5b50600160a060020a03813516906001608060020a031960208201351690604001351515610dda565b34801561033d57600080fd5b5061034661128f565b604080516001608060020a039092168252519081900360200190f35b34801561036e57600080fd5b5061029061129e565b34801561038357600080fd5b506101e9611337565b34801561039857600080fd5b506103da600480360360608110156103af57600080fd5b508035600160a060020a0390811691602081013590911690604001356001608060020a031916611346565b604051808960ff1660ff168152602001888152602001876001608060020a03166001608060020a03168152602001866001608060020a03166001608060020a03168152602001856001608060020a03166001608060020a03168152602001848152602001836001608060020a03166001608060020a0316815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561048f578181015183820152602001610477565b50505050905090810190601f1680156104bc5780820380516001836020036101000a031916815260200191505b50995050505050505050505060405180910390f35b3480156104dd57600080fd5b5061051f600480360360608110156104f457600080fd5b508035600160a060020a0390811691602081013590911690604001356001608060020a0319166116f8565b604080519a8b526001608060020a03998a1660208c01529789168a89015295881660608a0152938716608089015260a0880192909252851660c0870152841660e0860152831661010085015290911661012083015251908190036101400190f35b34801561058c57600080fd5b506101e9611adb565b3480156105a157600080fd5b50610290600480360360208110156105b857600080fd5b5035600160a060020a0316611aea565b3480156105d457600080fd5b506101e9611c64565b3480156105e957600080fd5b506105f2611c73565b604080519115158252519081900360200190f35b34801561061257600080fd5b506102906004803603606081101561062957600080fd5b50600160a060020a03813516906001608060020a031960208201351690604001351515611c83565b34801561065d57600080fd5b506102906004803603606081101561067457600080fd5b600160a060020a0382351691602081013591810190606081016040820135602060020a8111156106a357600080fd5b8201836020820111156106b557600080fd5b803590602001918460018302840111602060020a831117156106d657600080fd5b509092509050612099565b3480156106ed57600080fd5b506102906004803603602081101561070457600080fd5b5035612185565b34801561071757600080fd5b506102906004803603602081101561072e57600080fd5b50356001608060020a031661232d565b34801561074a57600080fd5b506101e96123a0565b34801561075f57600080fd5b506102906004803603606081101561077657600080fd5b508035600160a060020a0390811691602081013590911690604001356001608060020a0319166123af565b3480156107ad57600080fd5b50610290600480360360608110156107c457600080fd5b600160a060020a03823516916001608060020a031960208201351691810190606081016040820135602060020a8111156107fd57600080fd5b82018360208201111561080f57600080fd5b803590602001918460018302840111602060020a8311171561083057600080fd5b50909250905061274a565b34801561084757600080fd5b506101e9612f1c565b34801561085c57600080fd5b50610865612f2b565b60408051918252519081900360200190f35b34801561088357600080fd5b506102906004803603602081101561089a57600080fd5b5035600160a060020a0316612f31565b3480156108b657600080fd5b50610290600480360360208110156108cd57600080fd5b50351515612fa4565b6002805460408051602060018416156101000260001901909316849004601f810184900484028201840190925281815292918301828280156109595780601f1061092e57610100808354040283529160200191610959565b820191906000526020600020905b81548152906001019060200180831161093c57829003601f168201915b505050505081565b600b54600160a060020a031681565b3360009081526006602052604090205460ff16156109c7576040805160e560020a62461bcd028152602060048201526009602482015260bb60020a680a68c8a6060686060702604482015290519081900360640190fd5b33600081815260066020526040808220805460ff19166001179055600b54815160e060020a6323b872dd02815260048101949094523060248501526001608060020a03871660448501529051600160a060020a0391909116926323b872dd92606480830193919282900301818387803b158015610a4357600080fd5b505af1158015610a57573d6000803e3d6000fd5b50505050610aa533846001608060020a031684848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061301692505050565b5050336000908152600660205260409020805460ff1916905550565b6008546040805160e060020a6325ad1be50281523360048201529051600160a060020a03909216916325ad1be591602480820192602092909190829003018186803b158015610b0f57600080fd5b505afa158015610b23573d6000803e3d6000fd5b505050506040513d6020811015610b3957600080fd5b50511515610b80576040805160e560020a62461bcd028152602060048201526009602482015260b960020a6829a32298181a18181902604482015290519081900360640190fd5b6008546040805160e160020a633ef4e6910281529051610bfb92600160a060020a031691637de9cd22916004808301926020929190829003018186803b158015610bc957600080fd5b505afa158015610bdd573d6000803e3d6000fd5b505050506040513d6020811015610bf357600080fd5b505182613b56565b6000546008546040805160e160020a633ef4e69102815290517f90dfea85a2ac8dfa8a799d2388478b2b7390af9cf86aebd1ad9197db006088de93600160a060020a03908116931691637de9cd22916004808301926020929190829003018186803b158015610c6957600080fd5b505afa158015610c7d573d6000803e3d6000fd5b505050506040513d6020811015610c9357600080fd5b505160408051600160a060020a0393841681529290911660208301526001608060020a03841682820152519081900360600190a150565b600154600160a060020a03163314610d1b576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303230303102604482015290519081900360640190fd5b60015460008054604051600160a060020a0393841693909116917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36001805460008054600160a060020a0319908116600160a060020a03841617909155169055565b6003805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156109595780601f1061092e57610100808354040283529160200191610959565b3360009081526006602052604090205460ff1615610e31576040805160e560020a62461bcd028152602060048201526009602482015260bb60020a680a68c8a6060686060702604482015290519081900360640190fd5b336000818152600660209081526040808320805460ff19166001179055600160a060020a03871683526009825280832084845282528083206001608060020a03198716845290915290206003600982015460ff16600b811115610e9057fe5b1480610eae57506002600982015460ff16600b811115610eac57fe5b145b80610ecb57506006600982015460ff16600b811115610ec957fe5b145b80610ee85750600b600982015460ff16600b811115610ee657fe5b145b1515610f2d576040805160e560020a62461bcd028152602060048201526009602482015260ba60020a6814d1914c0c0d8c0d4d02604482015290519081900360640190fd5b600781015415610f76576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303630303902604482015290519081900360640190fd5b6002600982015460ff16600b811115610f8b57fe5b141561105c5760098101805460ff1916600490811790915542600783015581015460408051600160a060020a038881168252851660208201526001608060020a03198716818301526001608060020a03909216606083015251600080516020615a8f833981519152916080908290030190a160048101546110169083906001608060020a0316613bd2565b60408051600160a060020a038088168252841660208201526001608060020a031986168183015290516000805160206159cf8339815191529181900360600190a1611271565b6006600982015460ff16600b81111561107157fe5b14156110de5760098101805460ff1916600817905542600782015561109885838684613cbe565b60408051600160a060020a038088168252841660208201526001608060020a03198616818301529051600080516020615aaf8339815191529181900360600190a1611271565b600b600982015460ff16600b8111156110f357fe5b1415611168576009818101805460ff1916909117905542600782015561111b858386846141f4565b60408051600160a060020a0380881680835290851660208301526001608060020a0319871682840152606082015290516000805160206159ef8339815191529181900360800190a1611271565b6003600982015460ff16600b81111561117d57fe5b1415611271578215156112065760098101805460ff19166005179055600481015460408051600160a060020a038881168252851660208201526001608060020a03198716818301526001608060020a039092166060830152517f5ba6893ab92a0934e064695f2425b00894434392019b3203777b84a5d4c151a8916080908290030190a1611271565b6009818101805460ff1916909117905542600782015561122885838684614560565b60408051600160a060020a0380881682528416602082018190526001608060020a0319871682840152606082015290516000805160206159ef8339815191529181900360800190a15b5050336000908152600660205260409020805460ff19169055505050565b6007546001608060020a031690565b600054600160a060020a031633146112ef576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303130303102604482015290519081900360640190fd5b60008054604051600160a060020a03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a260008054600160a060020a0319169055565b600a54600160a060020a031681565b6000806000806000806000606061135b615947565b600960008d600160a060020a0316600160a060020a0316815260200190815260200160002060008c600160a060020a0316600160a060020a0316815260200190815260200160002060008b6001608060020a0319166001608060020a031916815260200190815260200160002061012060405190810160405290816000820160a06040519081016040529081600082015481526020016001820160009054906101000a90046001608060020a03166001608060020a03166001608060020a031681526020016001820160109054906101000a90046001608060020a03166001608060020a03166001608060020a031681526020016002820160009054906101000a90046001608060020a03166001608060020a03166001608060020a031681526020016002820160109054906101000a90046001608060020a03166001608060020a03166001608060020a03168152505081526020016003820160a06040519081016040529081600082015481526020016001820160009054906101000a90046001608060020a03166001608060020a03166001608060020a031681526020016001820160109054906101000a90046001608060020a03166001608060020a03166001608060020a031681526020016002820160009054906101000a90046001608060020a03166001608060020a03166001608060020a031681526020016002820160109054906101000a90046001608060020a03166001608060020a03166001608060020a03168152505081526020016006820160009054906101000a90046001608060020a03166001608060020a03166001608060020a031681526020016006820160109054906101000a90046001608060020a03166001608060020a03166001608060020a03168152602001600782015481526020016008820160009054906101000a90046001608060020a03166001608060020a03166001608060020a031681526020016008820160109054906101000a90046001608060020a03166001608060020a03166001608060020a031681526020016009820160009054906101000a900460ff16600b81111561166f57fe5b600b81111561167a57fe5b8152602001600a8201548152505090508060e00151600b81111561169a57fe5b610100820151604080840151606085015160c0860151608087015160a09097015184518086019095526003855260eb60020a620b0b0b026020860152959e50939c50909a509850909650919450925090509397509397509397509397565b60008060008060008060008060008061170f615947565b600960008f600160a060020a0316600160a060020a0316815260200190815260200160002060008e600160a060020a0316600160a060020a0316815260200190815260200160002060008d6001608060020a0319166001608060020a031916815260200190815260200160002061012060405190810160405290816000820160a06040519081016040529081600082015481526020016001820160009054906101000a90046001608060020a03166001608060020a03166001608060020a031681526020016001820160109054906101000a90046001608060020a03166001608060020a03166001608060020a031681526020016002820160009054906101000a90046001608060020a03166001608060020a03166001608060020a031681526020016002820160109054906101000a90046001608060020a03166001608060020a03166001608060020a03168152505081526020016003820160a06040519081016040529081600082015481526020016001820160009054906101000a90046001608060020a03166001608060020a03166001608060020a031681526020016001820160109054906101000a90046001608060020a03166001608060020a03166001608060020a031681526020016002820160009054906101000a90046001608060020a03166001608060020a03166001608060020a031681526020016002820160109054906101000a90046001608060020a03166001608060020a03166001608060020a03168152505081526020016006820160009054906101000a90046001608060020a03166001608060020a03166001608060020a031681526020016006820160109054906101000a90046001608060020a03166001608060020a03166001608060020a03168152602001600782015481526020016008820160009054906101000a90046001608060020a03166001608060020a03166001608060020a031681526020016008820160109054906101000a90046001608060020a03166001608060020a03166001608060020a031681526020016009820160009054906101000a900460ff16600b811115611a2357fe5b600b811115611a2e57fe5b8152602001600a8201548152505090508060000151600001519a508060000151602001519950806000015160400151985080600001516060015197508060000151608001519650806020015160000151955080602001516020015194508060200151604001519350806020015160600151925080602001516080015191508a8a8a8a8a8a8a8a8a8a9a509a509a509a509a509a509a509a509a509a505093979b5093979b91959950939750565b600054600160a060020a031681565b600054600160a060020a03163314611b3b576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303130303102604482015290519081900360640190fd5b60088054600160a060020a031916600160a060020a0383811691909117918290556040805160e060020a6306fdde030281529051611c5693909216916306fdde0391600480820192600092909190829003018186803b158015611b9d57600080fd5b505afa158015611bb1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015611bda57600080fd5b810190808051602060020a811115611bf157600080fd5b82016020810184811115611c0457600080fd5b8151602060020a811182820187101715611c1d57600080fd5b5050929190505050604080519081016040528060108152602001608160020a6f2d3120b1b1b7bab73a26b0b730b3b2b9028152506148d3565b1515611c6157600080fd5b50565b600854600160a060020a031681565b60015460a060020a900460ff1681565b3360009081526006602052604090205460ff1615611cda576040805160e560020a62461bcd028152602060048201526009602482015260bb60020a680a68c8a6060686060702604482015290519081900360640190fd5b336000818152600660209081526040808320805460ff1916600117905560098252808320600160a060020a038816845282528083206001608060020a03198716845290915290206003600982015460ff16600b811115611d3657fe5b1480611d5457506001600982015460ff16600b811115611d5257fe5b145b80611d7157506005600982015460ff16600b811115611d6f57fe5b145b1515611db6576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303630353302604482015290519081900360640190fd5b600781015415611dff576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303630303902604482015290519081900360640190fd5b6001600982015460ff16600b811115611e1457fe5b1415611ee45760098101805460ff19166004179055426007820155600181015460408051600160a060020a038581168252881660208201526001608060020a03198716818301526001608060020a03909216606083015251600080516020615acf833981519152916080908290030190a16001810154611e9e9083906001608060020a0316613b56565b60408051600160a060020a038085168252871660208201526001608060020a031986168183015290516000805160206159cf8339815191529181900360600190a1611271565b6005600982015460ff16600b811115611ef957fe5b1415611f665760098101805460ff19166008179055426007820155611f2082868684613cbe565b60408051600160a060020a038085168252871660208201526001608060020a03198616818301529051600080516020615aaf8339815191529181900360600190a1611271565b6003600982015460ff16600b811115611f7b57fe5b1415611271578215156120045760098101805460ff19166006179055600181015460408051600160a060020a038581168252881660208201526001608060020a03198716818301526001608060020a039092166060830152517f1c0375f21d732bfa91331ed1c863c1320ef9d26275c0eaeb6f34084a28bef88d916080908290030190a1611271565b60098101805460ff1916600b179055600181015460408051600160a060020a038581168252881660208201526001608060020a03198716818301526001608060020a039092166060830152517f2cacb1c0765151b38e22588353ebe7c0079a97c8e0621360daa2979fe0502937916080908290030190a15050336000908152600660205260409020805460ff19169055505050565b600160a060020a038416600090815260066020526040902054849060ff16156120fb576040805160e560020a62461bcd028152602060048201526009602482015260bb60020a680a68c8a6060686060702604482015290519081900360640190fd5b600160a060020a038116600090815260066020908152604091829020805460ff191660011790558151601f850182900482028101820190925283825261216091879187919087908790819084018382808284376000920191909152506149ba92505050565b600160a060020a03166000908152600660205260409020805460ff1916905550505050565b6008546040805160e060020a6325ad1be50281523360048201529051600160a060020a03909216916325ad1be591602480820192602092909190829003018186803b1580156121d357600080fd5b505afa1580156121e7573d6000803e3d6000fd5b505050506040513d60208110156121fd57600080fd5b50511515612244576040805160e560020a62461bcd028152602060048201526009602482015260b960020a6829a32298181a18181902604482015290519081900360640190fd5b6008546040805160e160020a633ef4e69102815290516122bf92600160a060020a031691637de9cd22916004808301926020929190829003018186803b15801561228d57600080fd5b505afa1580156122a1573d6000803e3d6000fd5b505050506040513d60208110156122b757600080fd5b505182613bd2565b6000546008546040805160e160020a633ef4e69102815290517f8bdb8d4e73bff083c2a505c7d0f5434a90e065a6dbbf9c55bfb6efb2f8c2138a93600160a060020a03908116931691637de9cd22916004808301926020929190829003018186803b158015610c6957600080fd5b600054600160a060020a0316331461237e576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303130303102604482015290519081900360640190fd5b600780546001608060020a0319166001608060020a0392909216919091179055565b600454600160a060020a031681565b6008546040805160e060020a6325ad1be50281523360048201529051600160a060020a03909216916325ad1be591602480820192602092909190829003018186803b1580156123fd57600080fd5b505afa158015612411573d6000803e3d6000fd5b505050506040513d602081101561242757600080fd5b5051151561246e576040805160e560020a62461bcd028152602060048201526009602482015260b960020a6829a32298181a18181902604482015290519081900360640190fd5b600160a060020a03838116600090815260096020818152604080842094871684529381528383206001608060020a03198616845290529181209182015460ff16600b8111156124b957fe5b141580156124da57506004600982015460ff16600b8111156124d757fe5b14155b80156124f957506007600982015460ff16600b8111156124f657fe5b14155b8015612517575060098082015460ff16600b81111561251457fe5b14155b801561253657506008600982015460ff16600b81111561253357fe5b14155b80156125555750600a600982015460ff16600b81111561255257fe5b14155b151561259a576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303630353502604482015290519081900360640190fd5b6007810154156125e3576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303630303902604482015290519081900360640190fd5b60098101805460ff1916600a17905542600782015580546000101561267057600181015460408051600160a060020a038088168252861660208201526001608060020a03198516818301526001608060020a03909216606083015251600080516020615acf8339815191529181900360800190a160018101546126709085906001608060020a0316613b56565b6003810154600010156126eb57600481015460408051600160a060020a038088168252861660208201526001608060020a03198516818301526001608060020a03909216606083015251600080516020615a8f8339815191529181900360800190a160048101546126eb9084906001608060020a0316613bd2565b60408051600160a060020a038087168252851660208201526001608060020a031984168183015233606082015290517f7e25898937e36ff2b5e1ceb4720a4cb39b4e677dea23221e5b51030a501f4d419181900360800190a150505050565b3360009081526006602052604090205460ff16156127a1576040805160e560020a62461bcd028152602060048201526009602482015260bb60020a680a68c8a6060686060702604482015290519081900360640190fd5b33600081815260066020526040808220805460ff1916600117905551849084908083838082843760408051919093018190039020600160a060020a038c8116600090815260096020908152858220928b1682529182528481206001608060020a03198e16825290915292909220600a810154929650945050841491506128629050576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303630333902604482015290519081900360640190fd5b6003600982015460ff16600b81111561287757fe5b146128bb576040805160e560020a62461bcd028152602060048201526009602482015260bc60020a6805346453030363034302604482015290519081900360640190fd5b600181015460006001608060020a0390911611612911576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303630343102604482015290519081900360640190fd5b60078101541561295a576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303630303902604482015290519081900360640190fd5b6006810154815460038301546000926001608060020a03169161297c91615492565b019050428110156129c6576040805160e560020a62461bcd028152602060048201526009602482015260b960020a6829a32298181b181a1902604482015290519081900360640190fd5b60098201805460ff1916600790811790915542908301556001820154608060020a81046001608060020a03908116918116918203919082161115612a43576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303630343302604482015290519081900360640190fd5b60408051600160a060020a03808c168252871660208201526001608060020a03198a16818301526001608060020a03831660608201529051600080516020615a2f8339815191529181900360800190a1612a9d8582613b56565b60018301546000608060020a9091046001608060020a03161115612c4257600080516020615a4f83398151915289868a8660000160010160109054906101000a90046001608060020a0316600860009054906101000a9004600160a060020a0316600160a060020a0316637de9cd226040518163ffffffff1660e060020a02815260040160206040518083038186803b158015612b3957600080fd5b505afa158015612b4d573d6000803e3d6000fd5b505050506040513d6020811015612b6357600080fd5b505160408051600160a060020a03968716815294861660208601526001608060020a0319909316848401526001608060020a0391909116606084015292909216608082015290519081900360a00190a16008546040805160e160020a633ef4e6910281529051612c4292600160a060020a031691637de9cd22916004808301926020929190829003018186803b158015612bfc57600080fd5b505afa158015612c10573d6000803e3d6000fd5b505050506040513d6020811015612c2657600080fd5b50516001850154608060020a90046001608060020a0316613b56565b60048301546001608060020a03608060020a82048116918116918203919082161115612ca7576040805160e560020a62461bcd028152602060048201526009602482015260ba60020a6814d1914c0c0d8c0d0d02604482015290519081900360640190fd5b60408051600160a060020a03808d168252881660208201526001608060020a03198b16818301526001608060020a03831660608201529051600080516020615a8f8339815191529181900360800190a1612d018682613bd2565b60048401546000608060020a9091046001608060020a03161115612ea657600080516020615a6f8339815191528a878b8760030160010160109054906101000a90046001608060020a0316600860009054906101000a9004600160a060020a0316600160a060020a0316637de9cd226040518163ffffffff1660e060020a02815260040160206040518083038186803b158015612d9d57600080fd5b505afa158015612db1573d6000803e3d6000fd5b505050506040513d6020811015612dc757600080fd5b505160408051600160a060020a03968716815294861660208601526001608060020a0319909316848401526001608060020a0391909116606084015292909216608082015290519081900360a00190a16008546040805160e160020a633ef4e6910281529051612ea692600160a060020a031691637de9cd22916004808301926020929190829003018186803b158015612e6057600080fd5b505afa158015612e74573d6000803e3d6000fd5b505050506040513d6020811015612e8a57600080fd5b50516004860154608060020a90046001608060020a0316613bd2565b60408051600160a060020a03808d168252881660208201526001608060020a03198b168183015290517f8e830917eea3269cefec70aaab60e41892f53eb8cb8592ef361fed7003072fbf9181900360600190a15050336000908152600660205260409020805460ff191690555050505050505050565b600154600160a060020a031681565b60055481565b600054600160a060020a03163314612f82576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303130303102604482015290519081900360640190fd5b60018054600160a060020a031916600160a060020a0392909216919091179055565b600054600160a060020a03163314612ff5576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303130303102604482015290519081900360640190fd5b6001805491151560a060020a0260a060020a60ff0219909216919091179055565b6001805460a060020a900460ff1615151461306a576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303330303102604482015290519081900360640190fd5b6130726159a0565b61307a6159a0565b6000806000613088866154ab565b93985091965094509250905060006130a18760b061563d565b608060020a9004905060006130b78860c061563d565b905060006130c68960d0615697565b905060006130d58a60e46156f0565b9050836001608060020a031661271114156130f9576007546001608060020a031693505b60006001608060020a038516101561314a576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303630323302604482015290519081900360640190fd5b6127106001608060020a038516111561319c576040805160e560020a62461bcd028152602060048201526009602482015260ba60020a6814d1914c0c0d8c0c8d02604482015290519081900360640190fd5b6131a6898c615742565b600160a060020a03808d16600090815260096020908152604080832093861683529281528282206001608060020a031987168352905220600781015415613226576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303630323502604482015290519081900360640190fd5b80541561326c576040805160e560020a62461bcd028152602060048201526009602482015260b960020a6829a32298181b18191b02604482015290519081900360640190fd5b6000600982015460ff16600b81111561328157fe5b148061329f57506002600982015460ff16600b81111561329d57fe5b145b15156132e4576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303630323702604482015290519081900360640190fd5b600381015415156135145788602001518160030160010160006101000a8154816001608060020a0302191690836001608060020a0316021790555088604001518160030160010160106101000a8154816001608060020a0302191690836001608060020a0316021790555088606001518160030160020160006101000a8154816001608060020a0302191690836001608060020a0316021790555088608001518160030160020160106101000a8154816001608060020a0302191690836001608060020a03160217905550878160060160006101000a8154816001608060020a0302191690836001608060020a03160217905550868160060160106101000a8154816001608060020a0302191690836001608060020a03160217905550858160080160006101000a8154816001608060020a0302191690836001608060020a031602179055508b8160000160010160006101000a8154816001608060020a0302191690836001608060020a0316021790555089604001518160000160010160106101000a8154816001608060020a0302191690836001608060020a0316021790555089606001518160000160020160006101000a8154816001608060020a0302191690836001608060020a0316021790555089608001518160000160020160106101000a8154816001608060020a0302191690836001608060020a03160217905550848160080160106101000a8154816001608060020a0302191690836001608060020a03160217905550613969565b60038101546001608060020a0388160142111561356a576040805160e560020a62461bcd028152602060048201526009602482015260bb60020a680a68c8a60606c6064702604482015290519081900360640190fd5b602089015160048201546001608060020a039081169116146135c5576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303630323902604482015290519081900360640190fd5b60408901516004820154608060020a90046001608060020a03908116911614613627576040805160e560020a62461bcd028152602060048201526009602482015260bc60020a6805346453030363033302604482015290519081900360640190fd5b606089015160058201546001608060020a03908116911614613682576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303630333102604482015290519081900360640190fd5b60808901516005820154608060020a90046001608060020a039081169116146136e4576040805160e560020a62461bcd028152602060048201526009602482015260b960020a6829a32298181b18199902604482015290519081900360640190fd5b60068101546001608060020a0389811691161461373a576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303630333302604482015290519081900360640190fd5b60068101546001608060020a03888116608060020a9092041614613797576040805160e560020a62461bcd028152602060048201526009602482015260ba60020a6814d1914c0c0d8c0ccd02604482015290519081900360640190fd5b60018101546001608060020a038d81169116146137ed576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303630333502604482015290519081900360640190fd5b60408a01516001820154608060020a90046001608060020a0390811691161461384f576040805160e560020a62461bcd028152602060048201526009602482015260b960020a6829a32298181b18199b02604482015290519081900360640190fd5b60608a015160028201546001608060020a039081169116146138aa576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303630333702604482015290519081900360640190fd5b60808a01516002820154608060020a90046001608060020a0390811691161461390c576040805160e560020a62461bcd028152602060048201526009602482015260bb60020a680a68c8a60606c6066702604482015290519081900360640190fd5b60088101546001608060020a03868116608060020a9092041614613969576040805160e560020a62461bcd028152602060048201526009602482015260b960020a6829a32298181b181a9b02604482015290519081900360640190fd5b428155600a81018290556002600982015460ff16600b81111561398857fe5b1415613a7e576009810180546003919060ff19166001830217905550600080516020615a0f8339815191528d84868460000160010160009054906101000a90046001608060020a03168560030160010160009054906101000a90046001608060020a03166040518086600160a060020a0316600160a060020a0316815260200185600160a060020a0316600160a060020a03168152602001846001608060020a0319166001608060020a0319168152602001836001608060020a03166001608060020a03168152602001826001608060020a03166001608060020a031681526020019550505050505060405180910390a1613b47565b6009810180546001919060ff1916828002179055507f8f4067942ce80114f94adf18e4ad859db7d5945317476d120cce9a3b4b43c3bd8d84868460000160010160009054906101000a90046001608060020a03166040518085600160a060020a0316600160a060020a0316815260200184600160a060020a0316600160a060020a03168152602001836001608060020a0319166001608060020a0319168152602001826001608060020a03166001608060020a0316815260200194505050505060405180910390a15b50505050505050505050505050565b600b546040805160e060020a63a9059cbb028152600160a060020a0385811660048301526001608060020a03851660248301529151919092169163a9059cbb91604480830192600092919082900301818387803b158015613bb657600080fd5b505af1158015613bca573d6000803e3d6000fd5b505050505050565b600a5460405160e160020a635f22feb1028152600160a060020a03848116600483019081526001608060020a03851660248401526060604484018181528151606486015281519195939093169363be45fd62938893889388939192916084019060809080838360005b83811015613c53578181015183820152602001613c3b565b50505050905090810190601f168015613c805780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b158015613ca157600080fd5b505af1158015613cb5573d6000803e3d6000fd5b50505050505050565b600281015460018201546001608060020a03608060020a90920482169116811115613d22576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303630343502604482015290519081900360640190fd5b60018201546001608060020a039081168281039182161115613d7d576040805160e560020a62461bcd028152602060048201526009602482015260b960020a6829a32298181b181a1b02604482015290519081900360640190fd5b6000816001608060020a03161115613de95760408051600160a060020a038089168252871660208201526001608060020a03198616818301526001608060020a03831660608201529051600080516020615acf8339815191529181900360800190a1613de98682613b56565b6000826001608060020a03161115613f5457600080516020615a4f83398151915286868685600860009054906101000a9004600160a060020a0316600160a060020a0316637de9cd226040518163ffffffff1660e060020a02815260040160206040518083038186803b158015613e5f57600080fd5b505afa158015613e73573d6000803e3d6000fd5b505050506040513d6020811015613e8957600080fd5b505160408051600160a060020a03968716815294861660208601526001608060020a0319909316848401526001608060020a0391909116606084015292909216608082015290519081900360a00190a16008546040805160e160020a633ef4e6910281529051613f5492600160a060020a031691637de9cd22916004808301926020929190829003018186803b158015613f2257600080fd5b505afa158015613f36573d6000803e3d6000fd5b505050506040513d6020811015613f4c57600080fd5b505183613b56565b600583015460048401546001608060020a03608060020a90920482169116811115613fb8576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303630343702604482015290519081900360640190fd5b60048401546001608060020a039081168281039182161115614013576040805160e560020a62461bcd028152602060048201526009602482015260bb60020a680a68c8a60606c6068702604482015290519081900360640190fd5b6000816001608060020a0316111561407f5760408051600160a060020a03808b168252891660208201526001608060020a03198816818301526001608060020a03831660608201529051600080516020615a8f8339815191529181900360800190a161407f8782613bd2565b6000826001608060020a031611156141ea57600080516020615a6f83398151915288888885600860009054906101000a9004600160a060020a0316600160a060020a0316637de9cd226040518163ffffffff1660e060020a02815260040160206040518083038186803b1580156140f557600080fd5b505afa158015614109573d6000803e3d6000fd5b505050506040513d602081101561411f57600080fd5b505160408051600160a060020a03968716815294861660208601526001608060020a0319909316848401526001608060020a0391909116606084015292909216608082015290519081900360a00190a16008546040805160e160020a633ef4e69102815290516141ea92600160a060020a031691637de9cd22916004808301926020929190829003018186803b1580156141b857600080fd5b505afa1580156141cc573d6000803e3d6000fd5b505050506040513d60208110156141e257600080fd5b505183613bd2565b5050505050505050565b600281015460018201546001608060020a039182169116811115614251576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303630353102604482015290519081900360640190fd5b60018201546001608060020a0390811682810391821611156142ac576040805160e560020a62461bcd028152602060048201526009602482015260b960020a6829a32298181b181a9902604482015290519081900360640190fd5b6000816001608060020a031611156143185760408051600160a060020a038089168252871660208201526001608060020a03198616818301526001608060020a03831660608201529051600080516020615acf8339815191529181900360800190a16143188682613b56565b6008830154600090612710906001608060020a03608060020a909104811685021604905080830360006001608060020a038316111561447857600080516020615a4f83398151915288888885600860009054906101000a9004600160a060020a0316600160a060020a0316637de9cd226040518163ffffffff1660e060020a02815260040160206040518083038186803b1580156143b557600080fd5b505afa1580156143c9573d6000803e3d6000fd5b505050506040513d60208110156143df57600080fd5b505160408051600160a060020a03968716815294861660208601526001608060020a0319909316848401526001608060020a0391909116606084015292909216608082015290519081900360a00190a16008546040805160e160020a633ef4e691028152905161447892600160a060020a031691637de9cd22916004808301926020929190829003018186803b158015613f2257600080fd5b6000816001608060020a031611156144e45760408051600160a060020a03808b168252891660208201526001608060020a03198816818301526001608060020a03831660608201529051600080516020615a2f8339815191529181900360800190a16144e48782613b56565b60048501546001608060020a031660008111156145555760408051600160a060020a03808c1682528a1660208201526001608060020a03198916818301526001608060020a03831660608201529051600080516020615a8f8339815191529181900360800190a16145558882613bd2565b505050505050505050565b600581015460048201546001608060020a0391821691168111156145bd576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303630343902604482015290519081900360640190fd5b60048201546001608060020a039081168281039182161115614618576040805160e560020a62461bcd028152602060048201526009602482015260bc60020a6805346453030363035302604482015290519081900360640190fd5b6000816001608060020a031611156146845760408051600160a060020a038089168252871660208201526001608060020a03198616818301526001608060020a03831660608201529051600080516020615a8f8339815191529181900360800190a16146848582613bd2565b6008830154600090612710906001608060020a03608060020a909104811685021604905080830360006001608060020a03831611156147e457600080516020615a6f83398151915288888885600860009054906101000a9004600160a060020a0316600160a060020a0316637de9cd226040518163ffffffff1660e060020a02815260040160206040518083038186803b15801561472157600080fd5b505afa158015614735573d6000803e3d6000fd5b505050506040513d602081101561474b57600080fd5b505160408051600160a060020a03968716815294861660208601526001608060020a0319909316848401526001608060020a0391909116606084015292909216608082015290519081900360a00190a16008546040805160e160020a633ef4e69102815290516147e492600160a060020a031691637de9cd22916004808301926020929190829003018186803b1580156141b857600080fd5b6000816001608060020a031611156148625760408051600160a060020a03808b168252891660208201526001608060020a03198816818301526001608060020a038316606082015290517f6f139a4814d93b575349ca1291d3b158703a049a6e47698468de572f1dd32d639181900360800190a16148628882613bd2565b60018501546001608060020a031660008111156145555760408051600160a060020a03808c1682528a1660208201526001608060020a03198916818301526001608060020a03831660608201529051600080516020615acf8339815191529181900360800190a16145558982613b56565b6000816040516020018082805190602001908083835b602083106149085780518252601f1990920191602091820191016148e9565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106149765780518252601f199092019160209182019101614957565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b6001805460a060020a900460ff16151514614a0e576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303330303102604482015290519081900360640190fd5b614a166159a0565b614a1e6159a0565b6000806000614a2c866154ab565b9398509196509450925090506000614a458760b061563d565b608060020a900490506000614a5b8860c061563d565b90506000614a6a8960d0615697565b9050826001608060020a03166127111415614a8e576007546001608060020a031692505b60006001608060020a0384161015614adf576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303630303702604482015290519081900360640190fd5b6127106001608060020a0384161115614b31576040805160e560020a62461bcd028152602060048201526009602482015260bb60020a680a68c8a60606c6060702604482015290519081900360640190fd5b614b3b878b615742565b600160a060020a038082166000908152600960209081526040808320938f1683529281528282206001608060020a031986168352905220600781015415614bbb576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303630303902604482015290519081900360640190fd5b600381015415614c04576040805160e560020a62461bcd028152602060048201526009602482015260bc60020a6805346453030363031302604482015290519081900360640190fd5b6000600982015460ff16600b811115614c1957fe5b1480614c3757506001600982015460ff16600b811115614c3557fe5b145b1515614c7c576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303630313102604482015290519081900360640190fd5b80541515614ea95788602001518160000160010160006101000a8154816001608060020a0302191690836001608060020a0316021790555088604001518160000160010160106101000a8154816001608060020a0302191690836001608060020a0316021790555088606001518160000160020160006101000a8154816001608060020a0302191690836001608060020a0316021790555088608001518160000160020160106101000a8154816001608060020a0302191690836001608060020a03160217905550868160060160006101000a8154816001608060020a0302191690836001608060020a03160217905550858160060160106101000a8154816001608060020a0302191690836001608060020a03160217905550848160080160006101000a8154816001608060020a0302191690836001608060020a031602179055508a8160030160010160006101000a8154816001608060020a0302191690836001608060020a0316021790555087604001518160030160010160106101000a8154816001608060020a0302191690836001608060020a0316021790555087606001518160030160020160006101000a8154816001608060020a0302191690836001608060020a0316021790555087608001518160030160020160106101000a8154816001608060020a0302191690836001608060020a03160217905550838160080160106101000a8154816001608060020a0302191690836001608060020a031602179055506152fb565b80546001608060020a03871601421115614efc576040805160e560020a62461bcd028152602060048201526009602482015260b960020a6829a32298181b18189902604482015290519081900360640190fd5b602089015160018201546001608060020a03908116911614614f57576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303630313302604482015290519081900360640190fd5b60408901516001820154608060020a90046001608060020a03908116911614614fb9576040805160e560020a62461bcd028152602060048201526009602482015260ba60020a6814d1914c0c0d8c0c4d02604482015290519081900360640190fd5b606089015160028201546001608060020a03908116911614615014576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303630313502604482015290519081900360640190fd5b60808901516002820154608060020a90046001608060020a03908116911614615076576040805160e560020a62461bcd028152602060048201526009602482015260b960020a6829a32298181b18189b02604482015290519081900360640190fd5b60068101546001608060020a038881169116146150cc576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303630313702604482015290519081900360640190fd5b60068101546001608060020a03878116608060020a9092041614615129576040805160e560020a62461bcd028152602060048201526009602482015260bb60020a680a68c8a60606c6062702604482015290519081900360640190fd5b60048101546001608060020a038c811691161461517f576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303630313902604482015290519081900360640190fd5b60408801516004820154608060020a90046001608060020a039081169116146151e1576040805160e560020a62461bcd028152602060048201526009602482015260bc60020a6805346453030363032302604482015290519081900360640190fd5b606088015160058201546001608060020a0390811691161461523c576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303630323102604482015290519081900360640190fd5b60808801516005820154608060020a90046001608060020a0390811691161461529e576040805160e560020a62461bcd028152602060048201526009602482015260b960020a6829a32298181b18191902604482015290519081900360640190fd5b60088101546001608060020a03858116608060020a90920416146152fb576040805160e560020a62461bcd028152602060048201526009602482015260b960020a6829a32298181b181a9b02604482015290519081900360640190fd5b4260038201556001600982015460ff16600b81111561531657fe5b141561540c576009810180546003919060ff19166001830217905550600080516020615a0f833981519152828d858460000160010160009054906101000a90046001608060020a03168560030160010160009054906101000a90046001608060020a03166040518086600160a060020a0316600160a060020a0316815260200185600160a060020a0316600160a060020a03168152602001846001608060020a0319166001608060020a0319168152602001836001608060020a03166001608060020a03168152602001826001608060020a03166001608060020a031681526020019550505050505060405180910390a1615484565b60098101805460ff19166002179055600481015460408051600160a060020a0385811682528f1660208201526001608060020a03198616818301526001608060020a039092166060830152517f98894361e9b67ded3912b92b852ef3360d137ef4462263904ebda757a98ef2fa916080908290030190a15b505050505050505050505050565b6000818310156154a257816154a4565b825b9392505050565b6154b36159a0565b6154bb6159a0565b6000806000806154cc87600061563d565b608060020a9004905060006154e288601061563d565b608060020a900490506154f36159a0565b6154fe89602061563d565b608060020a90046001608060020a0316602082015261551e89603061563d565b608060020a90046001608060020a0316604082810191909152615542908a9061563d565b608060020a90046001608060020a0316608082015261556289605061563d565b608060020a90046001608060020a0316606082015261557f6159a0565b61558a8a606061563d565b608060020a90046001608060020a031660208201526155aa8a607061563d565b608060020a90046001608060020a031660408201526155ca8a608061563d565b608060020a90046001608060020a031660808201526155ea8a609061563d565b608060020a90046001608060020a03166060820152600061560c8b60a061563d565b608060020a900490506001608060020a038516151561562b57611c2094505b919a9099509297509095509350915050565b600080805b601081101561568f57806008028582860181518110151561565f57fe5b60209101015160029190910a60f860020a91829004909102600160f860020a031916049190911790600101615642565b509392505050565b60008080805b60148160ff1610156156e6576101008302925085858260ff16018151811015156156c357fe5b60209101015160f860020a9081900481020460ff1692830192915060010161569d565b5090949350505050565b600080805b602081101561568f57806008028582860181518110151561571257fe5b60209101015160029190910a60f860020a91829004909102600160f860020a0319160491909117906001016156f5565b60408201516001608060020a0316811015615796576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303630303102604482015290519081900360640190fd5b600082604001516001608060020a0316101515156157ed576040805160e560020a62461bcd028152602060048201526009602482015260b960020a6829a32298181b18181902604482015290519081900360640190fd5b60808201516001608060020a0316811015615841576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303630303302604482015290519081900360640190fd5b600082608001516001608060020a031610151515615898576040805160e560020a62461bcd028152602060048201526009602482015260ba60020a6814d1914c0c0d8c0c0d02604482015290519081900360640190fd5b60608201516001608060020a03168110156158ec576040805160e560020a62461bcd028152602060048201526009602482015260b860020a6853464530303630303502604482015290519081900360640190fd5b600082606001516001608060020a031610151515615943576040805160e560020a62461bcd028152602060048201526009602482015260b960020a6829a32298181b18181b02604482015290519081900360640190fd5b5050565b6102206040519081016040528061595c6159a0565b81526020016159696159a0565b815260006020820181905260408201819052606082018190526080820181905260a0820181905260c0820181905260e09091015290565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091529056fe2c37271449147c96b5ce0044044faa5d20ef048dec8bef059602636e4c3458aefcfcabaa327c4b743db4db69abc110181f3b2ce7688373b79db6e419a5931fb91c99ec4f848a6acf03b727d516dae5964e3a4a5d0cad5e999d5f736c015e452b5bfa7c2f83836f6982a4c6e3e570c00eea5799a1fa5bc706390cc14fe78abbce747f3519d9841957d77774e90a8e2eb9de45c63cdcd3ffe4ae3b42241f3953a28451e328d7273ce87c7508d9f0a84478ece31457f22230882aaafca9af000a45b337ce52f9457488b4768c4965ce744c7085607608f7072a154a402dbcd61afa21bbb3e48090daafd5eb5222de7777a5498507dbff1f8616155eedb975be92cf9003337bb63ad5b56933391cd779be5ccda94d6736fda6c8a535a14b704aa193a165627a7a723058204083d28282c0b511aaaf07ad21c482e3e4fedced5a5cdd6106fdd652caf8df4b0029","storage":{"0x000fa25cd6899ed3bbbdffdcd53c7173160e521ffb34e315333ebf04aaef4808":"5dac3de5","0x0018aa69496e37058b2c6987d9e17e77c760ba6f8868db22e2ce68e2c37c3a30":"03e8000000000000000000000000000668a1","0x002da7685347538966eb6bd1f53a474e805df343540e26e04622a483e28c7137":"96000000000000000000000000000005dc","0x00401e349b306b95f88e7b99987b18a04399998617f570b098112471c537a282":"96000000000000000000000000000005dc","0x0077b39816f15b8beaae38830a93d22a3ddbf25b9e98009097636c10a9840819":"03e8000000000000000000000000000668a1","0x01292b71c9e3c10b33bfe08e18c20a50f3b93ad6e198bc1362a8df9ebf17b938":"4b0000000000000000000000000000005f","0x0153bdcc5afd1c8f1debd05e1409774cc5cee71b143787268b92887dbf80fb75":"06f05b59d3b20000000000000000000010a741a462780000","0x0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9":"5753db1a55022c3ea381099389f91100ad8098d0","0x01b28413e5daa47cf757756e54743bc97d1dc96c11bc8f7114656e107d078258":"06f05b59d3b20000000000000000000010a741a462780000","0x01dfb03516ea411b84f989ca373384eacabef218bba140c82bac94cf1806cc25":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x0240bb18bf393b1fa80f17c3ff1b60924a6c1e0dee65ea04cd6008a2e97e58eb":"96000000000000000000000000000005dc","0x0282e45282bcd0872d0648d2a1ea4c26e1239b88da39372a9d5175b668d7b7fc":"03e8000000000000000000000000000668a1","0x02bef936a9bf72b6a4e0c71a473b9b864eb709825b9bf408c75b1c519abb284b":"96000000000000000000000000000005dc","0x02ec082e777f52a50ab066f92dbdfefdc140212be37ca3abf5506da627f3def3":"06f05b59d3b20000000000000000000010a741a462780000","0x02f34a595a1deea39d1c888c1602365a74b5dc9be567a600783a76f72429ecae":"06f05b59d3b20000000000000000000010a741a462780000","0x03652621f5796d489954f1730061eef2f6e085ac90cc21f2755242a69e65e37c":"06f05b59d3b20000000000000000000010a741a462780000","0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0":"5d8d1ead","0x050a9587e736917e0f640a7e0da796ba6dfa5ac70a757db5995b0ea45a0d40cf":"5d8d43c1","0x05c5ca129072c2851dd97540cbbfdb8ef29f1e37705a66bf1a781d6940078582":"4b0000000000000000000000000000005f","0x05f133c6ce706c7340cd3628b81e415000dee3f301403f3622caf184f8959efd":"5dac1baf","0x066e2615daeac35065506a9e5bfc8eb362813055bd7eebc88f89978198fb0e0c":"5d8d429b","0x069fcb64edd811f27f67468156fb7d55febadeab9b4b639eaf9cf44bd25c4c7f":"06f05b59d3b20000000000000000000010a741a462780000","0x06d85d04b4f213fc56ca1363576f08c4aed798831d23a8c543dc7a623ea8c47a":"02","0x075dc73d2d18876b91f12993a428556c55c1a1c89a47aee1fdfe20ef32e0f924":"06f05b59d3b20000000000000000000010a741a462780000","0x08209969b9e06a616a86b949246eceaeeb03a06678bda17b424fca20e205b259":"96000000000000000000000000000005dc","0x084b93e4385f784f18eb29288c3960e9bb18877a92c6530327f02b7907b21aac":"4b0000000000000000000000000000005f","0x086291b14101b49305275af58f0296dae8011f509d07e9a73d3201f705b8177a":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x08847a46c5700fde691ee8f5622860c2ed2267858e1551bace4a4e325e4d24e4":"025800000000000000000000000000003840","0x0934d9b3a7e5ec065da30c4a700e7705a431f72aedfcc48aed645d6ead14bbb2":"96000000000000000000000000000005dc","0x0a116915e45e47ee2a9da65d2560ba57be1f065e45f3e7d26df4ca82ab10f944":"96000000000000000000000000000005dc","0x0a64b455d51c929c8b62839cfc9b206a4335ccecb405fe3bf3f3bbfba06601fa":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x0a9a6c4ec61981dc87ff655ea0002223225ec10b89055993dbbc518bae0ce120":"09","0x0ae14152b84d552e1cd0cd52203486c73b513666c3469a8be14b4695e96ee41d":"06f05b59d3b20000000000000000000010a741a462780000","0x0b15ebbbb553848b8efffb23b54019bd541d3ded956be03369f8faa5e34fd63e":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x0b1712033c51d19321968d2937b6854edaf86a47aa016e7e769e135d37cff844":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x0b76aa8ec6302ed7806514394275054c46f6fb28acb1b022dcc2ce8427b03589":"06f05b59d3b20000000000000000000010a741a462780000","0x0c383121eb06308bf721a9acc33a48c67766100d68ade55516174b586488ac8c":"025800000000000000000000000000003840","0x0c562b7da18c48539cabcea3366f766f7a590b82792732fd6ecc8a89d8a328d2":"06f05b59d3b20000000000000000000010a741a462780000","0x0c7b0b84d8e55df5616b0a6f9d38674c07fce65cc9bc6a00b462c40742b9b412":"08","0x0d0a68c9d8b5fb07a9c9f3570112107501ec602c1967e07b74c2a76f6361f315":"03e8000000000000000000000000000668a1","0x0d2edbc0c1f395fec1d79c88fb166136800d6f5b6e8a4b4e842cdb4c10d44345":"4b0000000000000000000000000000005f","0x0d3aed8e8edc163da11e8d158d5bfdb28b8b41959172f08b04518afbc84f2a9c":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x0dc41382da1f88a80b6c928c2d7c7367aafbe399b789547c974f4fb21abcba18":"06","0x0e0ca2befd3d8285fd09987c2f86560380397455645982123b607301a51a273b":"03e8000000000000000000000000000668a1","0x0e14c90449507cd7f346f663b2eebd52ee7815ca569daf781a7f383d99d69ebc":"03e8000000000000000000000000000668a1","0x0e4c4653ca832a1aa39079afff2172360cd0a163edc1b2e9e14d25309a623a6d":"5dab87a4","0x0e9e6b4617eb01ba9276e4a7e93834e6bb358c7efcd4ce29c3e974de8aaf378e":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x0ea1995b698a1c15cab80a2a1702c40e9c1e4611f1881d9a73c932d222f1b688":"025800000000000000000000000000003840","0x0ebbbca8a75697eb7560b2c01a406974f221776b5e41366f5073f78314efe050":"4b0000000000000000000000000000005f","0x0ecb492692ad99ea43f96b161392e7c7e5cf84e6058a90bdfbba47b766d1d3b2":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x0f302976e775afca217def10e960a143ffc907876487b72f16839634063b223f":"96000000000000000000000000000005dc","0x0f5553a8084596a47b5a782b214a68ae175d89e7c81ff50dd84f9fb03537c807":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x0fe3a066e21bc0f5adf48850fc8c3c948a019138d277feb4f415568ad577fe56":"03e8000000000000000000000000000668a1","0x0feb8dc883e925f0ca3d55481fa6fdc98111814195eb6793f5f1ff43e27dfc0f":"03e8000000000000000000000000000668a1","0x10d75ad3c9d18909dc8f6bfdfa5fc00c67f4d7a29f844b34fce3620e573deed4":"06f05b59d3b20000000000000000000010a741a462780000","0x11102cb1857ed54679642cad42642439be1e8a0b21db50af3d2225940b29d3f4":"5dac39f9","0x1119b77d98a5756a4c022cf4640b97deba06cf064cf1be29cd364b48d7caa22a":"03e8000000000000000000000000000668a1","0x11375fcafb557f0be927705983f30eed05a688ba5c3b09b8a676b47b9f0c4610":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x1190fb12084c35a199675c945db643985aa214378d19f841b890922ff5bb139e":"025800000000000000000000000000003840","0x120aefcc013893f281556f09c668cd929958aa51ae2af7695ce92d9fc35bc47b":"4b0000000000000000000000000000005f","0x12cdc9c8d02cad57edfb411231417f41b6ec8df93d1ee22e4891fdc264caf8b9":"5dab8a9d","0x12f58a9e9da0a82cc8783de4f975a7230cbdc8eff3a76764fe5014a81351c872":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x133f5fc9c1c81ddbba8fd614bbc7f22d073c2276421c41f178973339b9d11aad":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x13c0e291a3610610f728b6d26de723a8e7c4bdb42607a9590cefc5d79056339b":"5dab897c","0x1422d23b77eec08c12fa12e2143294285b36ea0b20d14b09d77b16869d7e969b":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x14696870312cb2b624c15b5b90c4bf67dac3e893a6e9cda1a6607af93abfb024":"4b0000000000000000000000000000005f","0x1481b3221891c2a29c30f41155293bd8b73105fb851d64537b212e18789a9ea0":"96000000000000000000000000000005dc","0x14cf2ae31065609f69b419f9258adbdc87ed164510b7ec511f7e2a31812a1be7":"025800000000000000000000000000003840","0x14d9315fe3022e119bc4a0a9b15439bf1583af1ffb2118a67bba5605e66e79dd":"5dab88e5","0x152d208ab0c103d8ba208381dd0194497c9c99bcfb022417455359d67adb6248":"025800000000000000000000000000003840","0x1568c273a81af5fca1d960567439daed7c8af9fea54e2a2298c8275cc39f2102":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x15708fdd2adac70b2ad351934ba7e547e35db8aa97f5f44add10ef2fea335135":"4b0000000000000000000000000000005f","0x15867856855690d9491de5e13bd37f1aa446fb0a1fbf3e6ea289befb21366786":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x15bf5b675f9e8a3053ce56bed6753aef06beebbc6d8e9eb1a618aa0257cd135e":"03e8000000000000000000000000000668a1","0x15d77c0dd06f53be3dbf0e29bd6720548eb482104113a057746bd050275c8309":"0a","0x15f1c7eb58f224b55f0eeb283e1085b7dac2aae3079250aff117f84b0a6898b1":"5dab872f","0x15f660a78858f481e4100af786c7e4160b871a68f5b3348eeefb8745ed8d2f80":"025800000000000000000000000000003840","0x1644447d47f0d1d666f1c254f1a4cba9e3e90da455d63b781df6e8f1b1df348b":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x16c4f6f437bf67b90544041d5dcd8b067254a1e5ad3b7b4423274ba0d3226ff5":"025800000000000000000000000000003840","0x1703ae74a9879823fd4b55468997ba62583ca58cc5b6fccf22b981b6a5d381c7":"4b0000000000000000000000000000005f","0x17186480f1c4b158819de5dc5db953b1f0b638618542b25980fdd56ff1b9c383":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x1789282d401cd9ba83bc4b2d13208251d1f9cfe5bcd55b7f9ada1ceaa1264607":"4b0000000000000000000000000000005f","0x17c605dbd56ef4c8f0e076befc961e9a48908bb5e6b01a0ff65d31e9a6dc3b40":"5dac1bd0","0x1827f89342056ec1d658c057e1e53c5d7fd946ab792de3d3983be9764bd4746c":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x186c4b2e4a9f6abeaf2781f0b3557ba6569b6d4dba5a1a83f880e06c79c7ee47":"96000000000000000000000000000005dc","0x19b353dff70b5432ebf44aecaeac7c70ff4c33e971dad9c9fd2354571a9290b2":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x1a3c3203e6e686ae73869200a2966b03bf838b7a28e749cfd6a8d122550f53da":"025800000000000000000000000000003840","0x1acd2ea3371c03f04fbcf8e92eaf8847e6659643ba9271110d36dae15b3b4cf6":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x1b812e8464546c0ee3300e09048ca1338118b43ae0f0c19d52c99d3cb1b97eda":"96000000000000000000000000000005dc","0x1b8c19fbe39164b9f5ffd2a73c6f9e45652e2283c726cd5334905644e34161b2":"5d8d4135","0x1be22fdb87a704d907a21327c987e641d94c53c619b397fee5001d0ec297ced5":"4b0000000000000000000000000000005f","0x1ce91e66330a44344c855177210ddefd1a078c7babcb3e59831d20bf8e88fdfc":"5dac1e34","0x1dcbe092b3d223d8c35b1ac65f64d5fb79b99c6892054849ade5a7360bdac97e":"03","0x1e39064a1235776eb2907045dbe58976e1f148b874fd99ee6f9a55684e06c7e4":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x1e3ab030bab66cb5352b31a88a3792179afadf76de44ff2beee8054148f92614":"03e8000000000000000000000000000668a1","0x1e5f4f812746ee4f355fb957890654053fd5fb8299d3b90628d4999d2cffab0d":"4b0000000000000000000000000000005f","0x1ee7b161412c79e7e90e0e62c40774733050fe6afeeb36e9dabaf287881ebbf7":"025800000000000000000000000000003840","0x1f362a90427e7dbc85c7e822faa351337e82c7a2b4aeb9b0c6c458c2f1e9d2a1":"4b0000000000000000000000000000005f","0x1f5e89a54e09246b045c466da187d8ac1a766283d6dbd5264a760584cb02a015":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x1f6e17153ae6ea0b2c807b854cd75aceb8a9b832a5d483ba68c7a73be35fcce3":"06f05b59d3b20000000000000000000010a741a462780000","0x1f961da4b772d7d76023ae4c0e88ee4652d4455fb5119a5a2b3ef102ed0c18c9":"06f05b59d3b20000000000000000000010a741a462780000","0x203734b343e731bff40dc3e211372f6edff035415f6ce82439251e44a1180d1a":"96000000000000000000000000000005dc","0x21054e025606ffc59bdcf04e8d9d6943f213fb65adf8ce59cc410af91500c6a4":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x2198df6ab541ae4ee9efd90b0c4393b9a1ac19f097d7d4a3c6883dfd43065870":"5d8d4398","0x21b1614e27dcb7aafb796f4eea5ef1b060488e7207513096bfa6ad01e77225a7":"5d8d43eb","0x21bba06c292315a7052ca5925a83bac65b49987dac786d47c21eedd315e687d4":"02","0x21bebda71880eaab704f8af41d7f7a716f2f3ab4ec106eae70313bdae71efdb5":"4b0000000000000000000000000000005f","0x221481e670a6d706e5cfbef66f6d9804c3a699feab1b58f0de703a10688a3853":"03e8000000000000000000000000000668a1","0x22bfe74685fdb3f35cd8d0810300d0a67ff0a539bbc8fcf63ab875a29e8774ff":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x2312ba71ca84cac75ff65bb332644f7a2a82035ff10003d7de105f161d0c1e1d":"96000000000000000000000000000005dc","0x23291a582447b81bd81a183eb0cccb69d0da40642ae2272c83982a9d0e58102b":"5d8d4362","0x23513be945730e9f52a9ecbc166d9a1a6c80e1d0ed07ed9c76014c31b7b5532e":"06f05b59d3b20000000000000000000010a741a462780000","0x237d8f1dfc90ce4a648ee4ebf1b942c94ae3c0f1b818c815eca6669ecac7c43e":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x237f97a87879c5cd89a37740cdb0cfdd466cb5628a1107bc42bd608b9ce82be5":"5dac3d6a","0x24136308ad692b97a483d7c8731b51cbe5be292368266a44887d3d919c766ae5":"025800000000000000000000000000003840","0x242abdabc61d25b05ef53a100674c91a2d89bde5b36409c5618eaf3904a528fa":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x2458343074395f8d850f93651f6bae37a68d2aa2081b034bc3cefbbb243c3597":"025800000000000000000000000000003840","0x24e411156129aef5e78cd899b65da40d7bcc5b9d5490c756f3ef25ba138b3074":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x2537b294b10ba3688b6a2bfee8cdb526702ea79fb0802d62a17ceeecf20d4d95":"06f05b59d3b20000000000000000000010a741a462780000","0x25380b73b883a7480bd978fb30a07bd8e1beb789cb8669e48adbe2c44db6fa87":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x256fbb8816621dc0834ae76ca667695e53290ba7289648a23843016cf21657f1":"5d8d41e3","0x2582741284f482e407d4b8d1db866426c58c733dfa31323f630a3f86ab7b27e5":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x25ca21db2d08fea396d5c27bf7f77210c5fc5abf18f81c32c27e19cfc313717f":"5dab89d4","0x261137495bb8003d9f8ec9f8c2bbed2f1d4852476c57392abbac24d362086cb1":"03e8000000000000000000000000000668a1","0x268cf885d50d76f634254788b428f8b94857570e8e0f3b271f15ccda30c76b2e":"03e8000000000000000000000000000668a1","0x277723692034ef0cd9db49faf2a828b278a2710d4bed241c413103ac9e230a5e":"5dac3c43","0x27b9070f25683d8f78b2c8ca55c5474b1b782a0bcd02d1c45eaa9b31ce044ced":"4b0000000000000000000000000000005f","0x27f1ea7af771f47b1c6074a2b07dec12496490fbdc4e03783f693e6caec359f5":"96000000000000000000000000000005dc","0x2815311a856e41ff75ca5ed2acf564998c16ea743a5b89e7aa4055fbb21c9655":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x2826060ccc2ddeab6a11c149b29c68ac0530a59dc64ca8e38f414ae2d66c761f":"08","0x28323acf07c8f108e4d796bfb9352420213fc56549af540366c810c2a4bb075a":"4b0000000000000000000000000000005f","0x28c4d5c347c41a1f9bc750b837a2503b1e7cf4757d981ef678a2cae4f0b881fc":"5dac3af3","0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563":"c295c18f069245c7b493c4ec6d679d8a867f5538","0x294a0893599e2dc3603e26ceec7c1d54d5ade27e6f3e9d35f83aa1cc869c4c93":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x298892cdc13c86c8a39dc8546070480de3514f6221050eab10666e86e8bc05c0":"5d8d4465","0x29c97db76d15fb76469e03e31a7d38cc801467307c2fabb2e8d9ebcb6e5c7bfc":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x2a03a8bcf568b60827eb197f107dd21b5cc72637e0db8c3f54eb6d1c885345bf":"01","0x2a24e3b2468fdca43a57265c7f12605f0b3582c2e74d372a948c52624047e146":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x2a3c39fc8c25dfe47ba80db11b31498e7702cce85a4446971a7fafc928d7485d":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x2ace53c4d9a84b1f1c62a117ccd1f7f1bd88ca3f92aab61aeee444555a8b0b4b":"06f05b59d3b20000000000000000000010a741a462780000","0x2b0741ce34fd84d790f4cf417d1ee5319cf5f0f2c95f12179e3ff9c32c1a65ef":"025800000000000000000000000000003840","0x2b6efdbf4908245f582c13e5b9884eb57f0fd7d33f32c476d53eba49ad1f50c3":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x2b7a3152a66f2a24a9549117389ddf638ed2571f035b12d2565cc13277dbdb99":"025800000000000000000000000000003840","0x2bb2e96ead8fdd102d3d0979c4ffdcea16c39cd8ae50e390e94a1828e3e23aa9":"5d8d41db","0x2c9548d682145d9cffb6192971b865380158fa91428f5b14ee4b46a98dc6a7fe":"96000000000000000000000000000005dc","0x2cf6635f7f5591d130a537451b9774d84e8dfa95ad3c4b72e8c34fb2b9e07ddf":"5d8d42bb","0x2d659b0cc6d883b19779c0621cef4d6fc1c88434e89d624872b81aad40df0c78":"96000000000000000000000000000005dc","0x2df2964fff8a034274ee00eb014be9fbbe66cc24f2f973ac14a8d6db48793fb6":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x2ef0567bd30b406630011bf89a107315afe4ce16a6aa28336e0bc7c399f8bbaa":"96000000000000000000000000000005dc","0x2f0c7cf35c358332f663097c1713ebeed815a404afaea276e0892dc4d8c7011a":"5dab88a4","0x2f4391f6eaaf33861f6d7138fc0c609a759de3711663eca3923a10fa8bce0d4f":"5dac1b4c","0x2f46a4c0ff2d56382b95e4df7202b6dfbe44079fd495b872f43bfd7d561febb1":"03e8000000000000000000000000000668a1","0x3005869bb718c4fcd7ef488bd3f3e81cd8d3c418541bf7623b0ff0cb48eb06d0":"5dac1de0","0x305edcbbec55c4a272f8e10322c2e594eba9b4ee198d4441c625eef1680388ef":"96000000000000000000000000000005dc","0x3084084f79ad40b9dd9a5eee0556ed3b35152178833f41bc33a5195a38842f51":"96000000000000000000000000000005dc","0x30a3f500102b16d5fcecef61b40de32c4ff24dbd0671415d1465e83199027ec6":"96000000000000000000000000000005dc","0x30c4556537849dcef9c486970b2531c5aac479c2b8176784c12a0b996c45234e":"4b0000000000000000000000000000005f","0x30df35f3573230ffc136d8a76d35d8d14f5da5a9283dcbe04350c40cb5d95dc0":"06f05b59d3b20000000000000000000010a741a462780000","0x316e667a21828517785443aa26a662debdf61d3b6d26a680c9f6e2f2fc3edd83":"4b0000000000000000000000000000005f","0x31843ed1509018880384443494d88624e850f78c02093d1b1bafb789dd362a00":"5d8d4135","0x31c88c25940dfde0e168fdd76ab74e714e1e0e8603888c76f5636250abb02b62":"07","0x324323621a17c397edff2ef8687634cfab2773947fbf7bb377835245645e5225":"96000000000000000000000000000005dc","0x324f3255b95f2acdf50b6d85738fe32542dcea5bcfe7b09d7709d0e7ea795958":"03e8000000000000000000000000000668a1","0x32959a17a6b248d84143f71b2641ec6d320e4a880ba5cb5a13b909a14b6c520b":"04","0x32b00550951d15172631a40b717c9c368bfa53f8cee3e8975fde0284c20f2a3c":"025800000000000000000000000000003840","0x32c1dae8ebb2c09d1d11fd5f9c264bb09f90703eb4bc43000fa6d788d4c8506f":"5dac1b5e","0x32d451ea8d98c1acdf4650227aa15425da4f1f17de4d22a89e2be7a016f73168":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x3396fbfbedbf653d4f1435884db2581779a4df118ff176281d99f8d4361a142c":"06f05b59d3b20000000000000000000010a741a462780000","0x33be5033a2d1a117db959663fc249e03d8bffb7b186d203fea62d9fe30629fd4":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x33ed4548db39b52ee53ac3dd8b5da40f81d6c9263b7deccc4ade95bafbe0b9cc":"96000000000000000000000000000005dc","0x3455157b3f701a7fe407ae015a12642b815cc31b7a5d57b0835c3e4dfe709015":"5dac1ce7","0x3464e50a0b1d8fbb985c1e0aee3054e87c069487365148092ea76d98b38cca50":"04","0x34734c186ba82d28da0162a978a5e8f96d45ea85bee7380c109d6b1a6f68f8df":"5dab87e7","0x35149f207249c5a225fd0904562aef23151b2d04e5de22a50a45c41fd4288ad9":"06f05b59d3b20000000000000000000010a741a462780000","0x351c81c85cf3263e55645a0e6e90e68e16fbc79484cdd047b0a0a6d174e5b4e0":"5dac3a5b","0x353ac8b6fb99ef96ec9d921ba6ed6b7e23ef02316bace2aea01d640b3afc17dc":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x35af421bda2f890af02bb0f0c1ceaecad6f0b7116473ed8ab8f1cc006887c62e":"5dac3c9b","0x35e0e2d1ee6741bc7d9063a694cff61c13a8b69e49df7574c93757d75913bf13":"5dab88c8","0x35ffdcb353a001298a1504899542100b727cd19d502abc4c47129cbdc50a9ddc":"06f05b59d3b20000000000000000000010a741a462780000","0x360255155c4b780fa45639531634d9163417902fdb57d101e1ee7743ba02e2b4":"5dac3b73","0x36caf4da320f51e85c71cd120c59e7d6e93b4d8f68ea03a00ac7dc382ecc19e4":"5d8d41b8","0x377350dfdc6b9d7bdd11be869a04c361061cbda888620b4cd135f62c886d01ed":"5dac1d56","0x37c29e8acbaa50c881f957cf688e73eebe96f55116cce4879722552073e146e6":"06f05b59d3b20000000000000000000010a741a462780000","0x37c4c2c6f48efb878a158ea2e96a2aa356b56e88bed307f44581fa2ec3d1b0d3":"96000000000000000000000000000005dc","0x37eb42336c658fc3e949ce761d2a81947b0d4e93a368b866e8805d4f6054d1a4":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x37f6d373f9a15b758b23b185b694c1b45a6d0d6b913f3ba66702275764c828b5":"025800000000000000000000000000003840","0x37fe6142c45ae60ffea1bbf66fb48f1f0f331cfb32d0f40c97adb7a3f899a1c0":"01","0x381c5e4ab4a194cb9562e13f322576bbf873446664a35a29405cc1b2e3897eb6":"5dab86f9","0x38fb4fb006e5cb579d80aef05278fff7587f66ee8d271e5419658d5b4a8967b6":"4b0000000000000000000000000000005f","0x392c9219c28d9795c240348b05caad3f5bab16864406017e4eda07584bf2ba08":"96000000000000000000000000000005dc","0x393a1701c733da3268629c44b5753018c244e3e9b0927b5ee8483909dfe7f0cf":"5dab8aaf","0x395133e987ba75e863991c9b715dee4e29c3d5675af0a1469f9b98b1c9063af2":"4b0000000000000000000000000000005f","0x39b1c723eb69c9e6492a203c0a81fe3549d30e601e0561317bd70d068fe4e236":"96000000000000000000000000000005dc","0x3a2322efbcbd683818026fdabd5566ef7cde68fb186b4b469ea54f4a704ae354":"4b0000000000000000000000000000005f","0x3a2d125898d265430de7e40d4dbe09a359f3292854972f1410dc97bade6ed1b9":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x3a3f49cac3be5af0f8a5d72a9b11cbeaa67397e83d8cc34f1ef3e07c17645b52":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x3a49e63c69abe9d3f512c364f6a41f9848f8c6afd45591ef0412588bf70b2dac":"025800000000000000000000000000003840","0x3a8dd238c35f1ad07ede13d279e692578774d10520bd4b7e5a41028e9b22073d":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x3ae31b40e35891ae68d486d018dcbb0c14a7a6e2505f050935b97f7a0f2a6c2b":"5dac1d19","0x3b61030a8dca3730912ad4b42890d308e80855591d186a456902a7578a67ec08":"5dac3a70","0x3b851e096964c9030f282730a2efd2cd43b645faad11b985b1996fc55ea60981":"06f05b59d3b20000000000000000000010a741a462780000","0x3be827cf82419c4e53268eb43cd7a6f0e7a0c111110f5057f259b32c3883c312":"5d8d42bb","0x3c7fbad961b1562f78f03853515bae202630026b101d3d63700c1c941e2d773c":"025800000000000000000000000000003840","0x3cb2bb3c9cb207c7b06fb47faa74ffd2fb4e811b64d36af14834fb186865792a":"96000000000000000000000000000005dc","0x3d1b7e94dd42280a70ea8cc0ed25bba3e50469b97b93ebeeb91541ed6554d555":"06f05b59d3b20000000000000000000010a741a462780000","0x3d9ca7be8e2686ff27974c545726dc5c1a5ee7be9a67d6857b0e4c278f945554":"4b0000000000000000000000000000005f","0x3db2f552e17c704acf0208e26550898ccfeeee230895e3851bbcaa50580e642a":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x3e1640221fc947696a1a692d2baab3321a50491b95b3b646eb64d6887f6bc769":"025800000000000000000000000000003840","0x3e24615a221038c15c5d1685631d24c00f05a8d49c307e850daace4f8e9da141":"03e8000000000000000000000000000668a1","0x3e72f043cb0851fbaa458e1d55dedeba37b0ebf413708fae616c12d816a5f009":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x3e9743245fb4afb32bb97b46f87e3e284312cb60bce44262606f70532c964773":"03e8000000000000000000000000000668a1","0x3ea24ffd866e0053eedb949900cd57418e1dc69b6d19d00fa9b3a13b590e3728":"06f05b59d3b20000000000000000000010a741a462780000","0x3f13910ce5f28e95d3c784581c09bceeafa7d66e55e5cf4f79a05ff032b30a0c":"03e8000000000000000000000000000668a1","0x3f59f5d3037553188ab7d78b3075822a80600ca1e2fc0590500428c0dfbab33f":"96000000000000000000000000000005dc","0x3f8bede9f607cdf22e29d63e286b87ff65432fd18b09ae3dda7af24be6261cfb":"4b0000000000000000000000000000005f","0x3fb51cc97613798888c15809dbd0bb7251a2ee4b8f32ee9fb2f30110d4559ece":"5d8d434a","0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace":"55736474436173684f7574000000000000000000000000000000000000000016","0x40b73ccff624de54ccc93437a5ea157c7edd420dda543019bf94f785b465bf6d":"01","0x4143837fa9d16f95d4aa5212d31e527ae40bd0aa562dc6af1acfbab0f984d84f":"4b0000000000000000000000000000005f","0x41d6ba548dfce106a2c48d1f15bba8b7d4c8066507e41ec0283b8d7e0b428ed5":"5dac3d3f","0x42c2601f2052cfd42e5e7a4aca0e504ed8abf3bd83b1cd301f1f59e74cd27275":"5dab8839","0x43acbade05fc5cfe5b9df1703287aff532c00ec05979e3b08a9f9f7948365e86":"96000000000000000000000000000005dc","0x44036001b258c286406dcc70dc4b91cb79339be7b3d28026f2d52a29c55826c3":"03e8000000000000000000000000000668a1","0x444413fe2f8a1cfc8f34c3bf91e7fbd2d56577f8e25ea70e8dfe1c725002d0e8":"5d8d4385","0x44904327807c762cc1b74f60f9a37599fad0d9160c4655b942aa105b0ddc3cf6":"5d8d4269","0x4509c80ceeaa1e7ff7c90e015bca8f002d3a7fb4369da5e937e571244a996581":"0a","0x4517758339362e591c2166eab32800fb15455028ee11d713a66e0b19f461494c":"96000000000000000000000000000005dc","0x455212224928442f24863850b027ce1b657ad8aee7deb4c78f9f2cd7413e7f5c":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x458494aedb05d0fe6c07b5881a210699426525c7db952af8647d1eed68159564":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x45f2b7d261abdf2533a2a51867cf8daf796b86d1e51f3ae42f45ba096eb5d063":"5dac1d59","0x45f55f7a3410f05f29492607279f933b0021652e97be127b8e40293931d3d21b":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x46283a690c6903388befb7c0ef043e9249b96cb88dcfd4908844a0e484b0d9d6":"07","0x4845fc80407ab1005b22293f956bbf44bafa92531429a313d1c993e6bd4d6218":"09","0x4928a7eb56275e5be106c75933de58acba0b40af7bc74b538108e0bb28fa18f0":"04","0x496ccd6abf1564981db4622b7f1e6b9b08f4e17d234c7ebe8fd69c362f439fb9":"5dab8957","0x49a7329076f6b6a1f6389a4bcd484b89455cfe3e7647f134b2b02b59b732242e":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x49fea72fd2e6eb59b0059222b9e6f3ac69d926f131a97a3b53c40fe18758606a":"5dac1b65","0x4a28ef24ec3327b23f301f5960d42ea088c7170ea977601da2124682cf6afe90":"96000000000000000000000000000005dc","0x4a90879e2d149806baeac3959126d93b0bd3a1e812de646150f2c367cc324c2a":"5dac3bf9","0x4aa91690a7ccef7149d3fdb866f7b35cb880e6446aa41f1a64dd2230c7ec6882":"4b0000000000000000000000000000005f","0x4ad36f0f0ac17f8025e79294efa9b493cb2be2c5f77af90d9aa70e0afeec1156":"08","0x4b0b74d1d599d639e229cca200b3462a3721fe726f1a98f874963f408a500d7a":"03e8000000000000000000000000000668a1","0x4bc2590ed289ef7fa3a7fdd51345481a0c64f4f352758bd80a4775bf050b6495":"06f05b59d3b20000000000000000000010a741a462780000","0x4c2c00e6893650746b9561a9a6acf6d32f57a330e0e7987178290543f84521f1":"5dac3d5a","0x4cc31becb2db18913da3c01f64d993368d5eacc44522c92542288ae29de2b054":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x4ce08e70cbe24bf5a4b4b498af6ea80011f0114a5381de5bb1bbdb1021f760dc":"5dac3b1b","0x4ce37126c5f495afda1e018b0a5d8e0517ade73b5602115a277801957e6fb3c7":"96000000000000000000000000000005dc","0x4cfe6a89514b9d7508c981250b9e1ac96e849e112a1b123453d5b3dee9ebaf18":"03e8000000000000000000000000000668a1","0x4d31f847b56edf8a1163d875ccbc5139a3d3fe76ce5798d05c6d3150fea15d05":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x4d36fd1d1fa9a56bdc06d487ecfa33973db09a1a05f37bd02adedb15f5d60c8b":"06f05b59d3b20000000000000000000010a741a462780000","0x4dce034a9248296af24fd71544aa20e0c3f56551f0bb63aaa3b03a688174768f":"5d8d4300","0x4e7b277b7b408326739bf7c71a53eaed7fe1e04aabd1bb5bec73341b4e76e2d3":"5dac1e46","0x4e9d830dc6a762685995e060d1d75c4890cc2e73ca9a6132a32f0f116291255b":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x4f2d7c7e027a94c425c243c52e502b9b75a345ea43efce949c167b8a3882e2fc":"5dab8a5b","0x4f58969124be35d6e6e6483074d05ccee503c15413f857bdab9a4f00ed910b6e":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x4f5f60d4df590e6a810e59a224690f255ce145b75239176240749f3cf8713406":"4b0000000000000000000000000000005f","0x4fab9bc8c6baf125b15586a5f179bc865dbbed6d513f0fd53750795ee5176a75":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x504b2e6a822fd13e58643027eaddb568dafc548a1d98dabb52168535960bc257":"025800000000000000000000000000003840","0x50adc3ce5d08003c3bc58a233d1644ff28578fb108b9a933529a108c7d345495":"03e8000000000000000000000000000668a1","0x50f7242d025eafba1c6d9d2365502d4e5127aeea0b32b7802ecb8664cf122ce6":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x5134444abc1f062ae61b77814325e76d9f09f0b52008dde1798bede39cc408a7":"025800000000000000000000000000003840","0x514efad0bb77d78b619a567754311d494c891074934ed93bfc8fd3a3e29e1abd":"06f05b59d3b20000000000000000000010a741a462780000","0x525642528b4a1dd719414f93d96429a580cafb69641266872f30a2a0e63ae28b":"4b0000000000000000000000000000005f","0x528caec9b2f3483bbd0d2a2415b2fb2b38b8b6948390f9238c034e767cded0c0":"96000000000000000000000000000005dc","0x52e1a37cbe978175772d8ad998da5f88d23ea9dee683680f38aa4f990add1f4c":"5dac1c41","0x5361f4c5ea442a45913b83d3aa72b51056898a225ca01cf71af60ebcc295d296":"025800000000000000000000000000003840","0x5391e66127dc903c5b1323b5bfb756d8e5dfbfd4a01e6b4bfa3a2d8d2f919725":"4b0000000000000000000000000000005f","0x53d7906329d46f68f677249e0fbc3fdd188c3890baa27ba70539e0e2081722af":"96000000000000000000000000000005dc","0x54645371449b98cd6cb7a30f8765c0277cf8c081d3b318fba5788a29a1cad8c3":"025800000000000000000000000000003840","0x54b5c654564c82d3825fa1ccc9d932fdc1db74bdcfc5651f065b8f755bbc8213":"96000000000000000000000000000005dc","0x54d77f30cac40c104eee8fe3b7ea475f9774c2a00a21ccd38eeb72c19b484a2d":"5dac3bb7","0x55030350b87a3260f4d6abfa3eff437eb7cceb292e468b89c280f26e5e0f59bd":"06f05b59d3b20000000000000000000010a741a462780000","0x5534ca8e0fe1206fd8e72b82b6058b237eb78b7d6097a807989d0497771d3321":"5d8d44b9","0x55b01a1b4520a19f285517198cbc98010dc1d03c4aa36fdaa26b68ff11181330":"96000000000000000000000000000005dc","0x55de06a82a013197a6f9443a8b5713978985f74ce28668bf07509c9032fcda58":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x562acfaa1b4635b34ee6f939921315f12dae6b038e4e1bf5ade76fd41b16f2d1":"5dac1bff","0x569dca9b1cd9e180c8022090c25b699e8c68511e67199a42c4caf763d82f83da":"4b0000000000000000000000000000005f","0x570cb8eb2324b8629fe3d529af7fb26b0af8fc3cffd54b92ffa07909575ef59a":"03e8000000000000000000000000000668a1","0x575b7a80bf61d49ae7935ecfa5ec8ccf9f7342dfa42d064c0952fcc435f40bd8":"5d8d4214","0x5760f6a89909da84012686d8a3d4a1898d72871477b01b7c7179750a0eed8667":"025800000000000000000000000000003840","0x581be95bd705453e1035f41b33abd7d1cb7eac433a4e89ca6d9b7514e2183f1b":"025800000000000000000000000000003840","0x58b09a98509fc44f44a7e3abbddf1f83d5f6e8e53ff37ed289f15fecbcc79186":"06f05b59d3b20000000000000000000010a741a462780000","0x5913de93bf4d2b27c7b3f7a46a02f613603f2bdcc99c7a01529095f0eb401d21":"025800000000000000000000000000003840","0x596aef9d2a3c567225eca19776f6f5b439c9ca993b415aa29367fb4e27e6f67e":"5d8d4448","0x5977aed5a0f36628c4de0021e8313bc796ba0cb971b76645381c098f9ac6352c":"96000000000000000000000000000005dc","0x5a1b5aab4c0314e9ae4a76bb432734b045968ddc99ca2e49b01d51e8e277c662":"5dab88f8","0x5a41dacccde01f015a91277ebedb30f440b7997c2d4b1d4e6ebff72f93197142":"06f05b59d3b20000000000000000000010a741a462780000","0x5a86e655529b4f3f24c3c424fb0e78e9f7953af8010c07d3c8c8dd58b4ff630f":"03","0x5aaf18d0ec734b28897825f51895bd3e3ece3af5d286fb88003232e469fd7bcb":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x5acc8013ea78083fad95689322fca8ea8f7f75349a9519048c1c47932d5ec5af":"5d8d419e","0x5b206af542e86fc8e114827cc3e0b84dfefc1cecc9a1657af7060c84b90a0f5f":"5dac3ce6","0x5b31079a44e97d3b01581649e1ab36a4a26f559b60f20133535ad079c1a91917":"5d8d453b","0x5b447b038625d6418a75decc3d05293b701a732133fe053a4145aef0d0cf0cc8":"5d8d4448","0x5b8ff6b90a9c66866c437556eea73be3eaca95015dea052be50bd9d0b79013c8":"96000000000000000000000000000005dc","0x5bd6f1e6836a17181876e7381304ec67269c60cb85954a116071378ce70ace39":"4b0000000000000000000000000000005f","0x5be0f91bb9e3871691f2ca0cb733abf5f2c7978f1c2ce2126b75d8ce1dad3f51":"5dac1b67","0x5be23aeb8b31925d8de75b009b72d2db80f5f64c375b6ac28c3c82c620100895":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x5c060e8a921a5eb2d8aefdf55296a6349085ba50299a301e8d918e539ffe2bca":"06f05b59d3b20000000000000000000010a741a462780000","0x5c29e9eec419f18ede0e2fb86013225782d3bb02dc08a552aa8c9554c90c6308":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x5c8c9a94f5c0e7796c4f2c3f0da53c5e2485e6400c617a6427fbe20d276d6109":"03e8000000000000000000000000000668a1","0x5d0590cf3b46f2e3e2e6221a31816eb0aaea5453c8f6111b75c0deec340ac91a":"09","0x5d2829291ed53a6bac20ab68842b2c9e73686611d5c899af81a10a163805ee35":"025800000000000000000000000000003840","0x5deb15020ba6f40106907cfb8509936f6648d0f9654cefe4ee2992ff06cffdde":"03e8000000000000000000000000000668a1","0x5e20d1b61853554a6ea7f548db8b036747fd10d424785892dbcb89f22e41e5ef":"96000000000000000000000000000005dc","0x5e3dd334c9081948db6f25089e5890ced45be5c4b358e2c0598fbe12dd3fda81":"96000000000000000000000000000005dc","0x5f376bb440fa7bca7c8461c690aebbc35df595962148bcd4c132d2efc544168d":"4b0000000000000000000000000000005f","0x5f5d1d6f90757232b6f159c63758402c72f210159ef00bdaff9095e75b852023":"5dac3d16","0x5feb7ef68c80b7451b2b809cb4ad6e531d0b1cd2dc63340bc9ab91b6d9c2bc51":"4b0000000000000000000000000000005f","0x603077bdede8a5462361346197d55de2b22425705b15c8a04db7678be99929be":"03e8000000000000000000000000000668a1","0x6063f5cb4e003437d96d172ab5805f590c9401f8a4edb64bfb7ec919903fb11e":"07","0x61733e07a65eb992b610cfb61247259cd29a515ddf196c89b635dbf3aee4c072":"5dac1df4","0x617e6676b042e8701430f51acd27f63a2db2922676b6090342e3c5ecc3009062":"08","0x6268f8c0f68841394f60f6966e2c7f3ea02172fa9076d2b791f8e3122b3b9090":"01","0x62a5a73e4177d6c6651e465c7c8f7b1bf677929ee89c82fc7ca01639818ef53d":"5d8d424d","0x630d897cfd23cb2231badb81c85f27432f4185d00500c64b05c582d0e5920be7":"96000000000000000000000000000005dc","0x63286f55b0eeee27d95bda3e8c34b075ba820e2346579fb634893d025abe0a50":"5dac3e52","0x6416c86427445e67e1ebcf4b8d597276f23bd5bf6081346a1a06c20908aea0b3":"5d8d436e","0x64586693522feff1c4d148d24e35bfb7dc3589c5c57d828dc7bfe6ad062d4977":"96000000000000000000000000000005dc","0x64b9858eae3d456eabab7f2a6bf6c2129931c92daf9042956c05dd383efe6568":"025800000000000000000000000000003840","0x64da0eda5c89b3e97faf58f50adfb53a40eebf50c16851ed732817c052992615":"5dac1e53","0x6582b72303fb7e9320912df17834eb55fb1e4eaa31f90ccb0777781886637223":"06f05b59d3b20000000000000000000010a741a462780000","0x65edcb17ed94aa0b11b45c1620f01b5aa55f154146ae58a6d39061610a3bcb97":"5dac3e30","0x665aeff80748636d04910f5053a697f05eb17de6ac21615333dd0f00ddb54c5b":"5d8d443c","0x66f5744bae525ce07cd4b0a4e3d08f68b8d2bac05e7075b4235e52ffc4100d34":"03e8000000000000000000000000000668a1","0x677e142bb7b2e4fdcf5b23290afe66d46caabfb5344aae013d78e7ec17eb08e7":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x68307717b565858d18d807f93d9f7cbe8b7f711e56075aecd52286350e9e2db5":"5dac3cf2","0x692cc63c46250804887b93fc838497be43a679c388ef676e5accad8a80e8fc5f":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x6941803d694aa3043b3ac3e57701277444ca957a217d419c6747b4bf404500ac":"025800000000000000000000000000003840","0x69ce74ad49e944ac6a14138d26c7940e97ebe8af663b9e36a1f16d606dcb7f99":"025800000000000000000000000000003840","0x69dc03a50bd749ca6f026ae5c4e449791b299b704cf34eaf2dd05b11631c62ef":"96000000000000000000000000000005dc","0x69f0efc9cc574bbc25124d01d6b1a66c9419280541875aa4e41ee4c28f275765":"5dab878a","0x69fd91ed335441617a312aa149fe089eca09419ea4c996590af1a8ddc0f642ff":"96000000000000000000000000000005dc","0x6a2445ba9f4382aae1d94ccc5c0883202a1bdfca6c353af5536418b4cfb8ce2f":"4b0000000000000000000000000000005f","0x6b4d114762b3d2c3ac669e73d4d0b1afeb548269d65b4b344df9dd088e48b562":"03","0x6b70ed284dfc23000fc3d097433fb6bd28c25b1d390921fb87c70ca9c061adc1":"03e8000000000000000000000000000668a1","0x6c1ca91327683db934c8932c8119937fe6a00ad34eed1ea3afb1dbb12b563b37":"03e8000000000000000000000000000668a1","0x6d861105a8260635e11883bf0df499fcc204a68f5d990713d2ad7901f851c0d1":"5dac3b89","0x6d8df14c67521dc9b0cc6b04b84a94ec7a56815fe00690501898ca1f2d3d3da2":"06f05b59d3b20000000000000000000010a741a462780000","0x6d93675af3a13a831ae7d3c81156d203212a7bbb096acd04b862bfcf8023f9f5":"01","0x6ded0a03c23425523086aec4f396da576d2c0579c0f2723c188798e7005000be":"4b0000000000000000000000000000005f","0x6e0a3f40bdaf10ae2e27f8748bf484ab397c9f4a37e721bddb7a372c47c28b50":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x6e0d664726c73faab4674308ea8e949e71e58ea5b9a9797a6d34b1176d8901f4":"03","0x6ecc2fe4c68d027aa796a2be3fecbf5a418dbc60184a2ea6d0c1b587efdf6c72":"5dab879a","0x6f1b9da08c90810366e213f221a11a92da478caa4f1e674bc51fb13342684241":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x6f6f32ca5473b797f0b03fdb4a37ae3f1fdc04fd70aea27bc43b0f742f605a7a":"4b0000000000000000000000000000005f","0x70027864e8aaacdbaca2c5c44a3f58e419006ce5e465d7da32b3b5a4d41675df":"03e8000000000000000000000000000668a1","0x70ddd83380c46bd8ee9a0f6523328f10401af3197750ec686ac6ba6fd9b137db":"06","0x712537a05eef319258812c085bb25ea866222ea22c036d388a09dd4a3d277083":"5dab8a77","0x7145bab998fa7ffb2d37499fa2ac21bb832b01add766f2ca79610ba232df43b7":"5dac3d83","0x7199b63c277003a017a7a8c7242e620530fc7d8f1bb48c91f5911caf38f7de73":"06f05b59d3b20000000000000000000010a741a462780000","0x71dc2c49377da9e3f340a8d166f2d9970d28885a50a9e7f92c99fc844d81c27c":"96000000000000000000000000000005dc","0x7236fd11a6abc3671f0bfcfa47f3ce99bb6bc310caa2704684ad8ed59aca68c8":"4b0000000000000000000000000000005f","0x72fb696af8e5bd6ad8bfbb91eec64770860aa13ea63eac50b8d05ade6c30345c":"4b0000000000000000000000000000005f","0x7328365a05481267052ae84edc131c538c67096c9bd32caa6a6d51c3dde6fafc":"4b0000000000000000000000000000005f","0x735e5f0d9fa1f669f50dcc88b0af94f70e70a882bead7fd7aa34519840f92d2f":"5dab887d","0x741bc035171559ffa824731d0c4a4a2a64da25402c1989ba794707547812cd49":"06f05b59d3b20000000000000000000010a741a462780000","0x7441a05a6722adaca1d646bb8fd454c3e2a03725220559f551e112c8bce49f59":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x74510d13f8f433d12bc0d16f409b5fcc8a08b2e5194599fde5d9535b2e7ef979":"5d8d411d","0x74f73565ad617206557de528e6e6f273754b6a3a5ec683eb4c30092dae289e66":"07","0x75120496b0e4b3e3773136857ea318ccf8cf1dcc09dd5555336908d03bcd2f13":"96000000000000000000000000000005dc","0x7570446af2bc533e543c7198b360ce98ee66bbe1eee4bcdd9f7e4ea413df84b7":"03","0x7598022735f0dc0da4f93149d3f1ee7bbd831863e3bbed2b7b2006270c0f6f8d":"96000000000000000000000000000005dc","0x76cedf545b5f68c5713fb6c724361365809ba3c09a52d3c1ade0bf3a5654629b":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x773712fed604a452e4c5e431be904752d6343505bcf838d0a7e3e9431fc71ac8":"06f05b59d3b20000000000000000000010a741a462780000","0x77b5f4d9f7093404c29e918708f23c57d7998ecc3cfe73d6f76cd319a6267655":"5dac3d28","0x77fa7f42b0ee0bf693a5a708dce78d803d9d2aea54e40eb0769ce7ebe1a4f390":"5d8d4505","0x77fa857cce1b976c6bcac5e17850621c7b2866762c756e4f02b5c504f8a5986c":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x784c20fac3e7b8c902cf4c96cd0d8aa8b54a623dab29d259bbfc44a61184cc1b":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x798a7f115b85ace16abfff5c77ea987dfa6ee77b10773f9486bef1e3a26ac1e8":"4b0000000000000000000000000000005f","0x7995577ee80015a4962734583c7bc9803c9060698b02f5fe029432f8b20aea52":"08","0x7a00cf704fec3ed1f02f99c8bcd5da4f1f9bb39302cc85757c7e312091dce51c":"5dac3b72","0x7a0cb953a80ca4bf4c86e1e36e21ed2abc6e496a870940f8ad703f72c82891f0":"5dab89e5","0x7a38f74c2cef63930a2e7a9deb610e6ffa8eb3085ade2e411d6147eb3bb5685e":"5d8d431e","0x7a9cf02f5ac6f8120dfa97cc349cbbce8508862214b21163df014bab1989b0a1":"96000000000000000000000000000005dc","0x7b11f689d78aedfe6e3aa666f0920a9f29606beeeb8b43497a231a0251a7969e":"05","0x7c2bd07458c72e68eb61fad4998988a4e878ca6994cc1c15371c5fa43791042e":"06f05b59d3b20000000000000000000010a741a462780000","0x7c4e2020fa9f142f30af8311398ea4bd03c69fe26a8b828b8dc8863b2eefdb22":"09","0x7cce101a2003ed979cff66630310c082c7184823c57b901b8a08a5d0d4f7f92c":"025800000000000000000000000000003840","0x7ced8979651eb516655fe673b53ba227c09436d5cfc5ff75315fb6d17e942f53":"96000000000000000000000000000005dc","0x7d89b6a24bca0c81bc8c76f5175b231c91546e7c78e42e5c106b1e8de916379c":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x7da55d0a2af5313c3115da22162b2523b9b8a235e3b3c1f77c643142689ebdae":"96000000000000000000000000000005dc","0x7e4f668e09608bc395d58575edeb3709d958a641a5cbde4294bba1bddfc5a7bc":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x7ed1b48fb13eea781367e70dec777d6ba7072e8883390a8cc3fd0872e50caa4e":"03e8000000000000000000000000000668a1","0x7eed3d2ef21d3f95207b89143061d97dd9a55e9c20435199bbcb8fb84752eb94":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x7f02c541877a19cca184ab663e6245d1af10c9fae09a3506c584df44fd1105a1":"09","0x7f08f9efb275dbc3d3478e700c0010dd79fe29f9c0bc9a76cb5196133c695e15":"4b0000000000000000000000000000005f","0x7f0d96e50a90a1b331d11dd5ed64d3f3a0ad8398226f1582a959fb265bec1807":"5d8d416a","0x7fedce181686e1ffa55c2c0f085a4229c13ba9d56464cd7a21f2ab725aa5d1e4":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x8085288fd1f5706ca42b0334e8896a5ca6cf28466d7020738b5b9d9a216f0d29":"5d8d43f9","0x80ac4d197400d5fa7a7dd7971bcfe4512341a22dada73159f915d80ed0efed04":"96000000000000000000000000000005dc","0x80c7514382c22c62a4e7e421e626457d7074436ab731299d55bfc8cee7f3826e":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x81338aaa6d73874f6a451b0d040b61227885cfebaeb81e22f11cb571f095e589":"96000000000000000000000000000005dc","0x818d86b2375e1d9badb1688d7bbba61670279523cb72aad04f4ae838422acf1f":"03e8000000000000000000000000000668a1","0x81d8ed66f5ab6b59ad01b639766af86f03619912838eff54dd091825a2a20113":"06f05b59d3b20000000000000000000010a741a462780000","0x81e119a96eb4fe2b1359bd1d83f902eb531e061904cfe68c1f1dabe06c3fd310":"96000000000000000000000000000005dc","0x822bd717edce5cce99c8ebfa123c1f8a3011c28bf512b3c27ec37cf16685cdf4":"06f05b59d3b20000000000000000000010a741a462780000","0x82d4d96e8e67cdccbc4bd53dadeb9b185b90c0afb2c30030f4541bd5863d9dd8":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x839994da7749498419885126486f481d7537756791feefcb825a6d1036068614":"4b0000000000000000000000000000005f","0x83bdec3c4d2031be46b080b3240d8061722a3d75911419c3aee25ff12caccd63":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x842114f5964621a121d75e4a936fa78d98038c45423b39ebc777aec22451587c":"06f05b59d3b20000000000000000000010a741a462780000","0x84fa467bfb4732b6b07939043004c84751c6ee01cbae9376cbe9bfe7c912fb0b":"025800000000000000000000000000003840","0x85ea53b1cb82c57ff7a340528daf4cfca5da8551958818398a5011f58ce5139e":"96000000000000000000000000000005dc","0x85f53d6b5abecfd81c4f11a6d32bb178ec405c60eeb35b80250af20527051ea2":"025800000000000000000000000000003840","0x8605db109191a4b1c17181cc17d6e1c5f6df662da147fc526721d0d49142e9fb":"5dac3c31","0x8613348eeef21f27fd18b156561ea9195e60289ef889a3b037a339539fe89db8":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x8696f42d910644abc55b7df52bc79900427e2ff4c28cb0d22367bd78af2c13cb":"06","0x86a144bed8ebd7bd0b17151f037ae5cdaa74392bab106faa50f3eb392d743c68":"06f05b59d3b20000000000000000000010a741a462780000","0x86df4d2423500249242dc453255c11251784d2bd30814d332c39512a74a9a8ab":"96000000000000000000000000000005dc","0x86fb7b82ddecd5617de5c3c394555190807a3bd9e62a0e92f0a5d17a0bd946ca":"03","0x877ea9b0858c9f57dcde3a7bed43249c683d33e8ae2e9d5cc616e97868c6354e":"5d8d421f","0x87e42c83517dd42cd31eb613d8c9cfe3b78eff0c04791280bd37ba55ac45f21e":"06f05b59d3b20000000000000000000010a741a462780000","0x87e5a949e2495809249b72a87ca4276ecff8ccc6487ab57b79f06316da858c91":"09","0x87f7dd8046d3061507cd018a91b80a6681d10c84fed6f91b1059ab45c82738e2":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x8825a1b74fb492d6f6ae8b17a6af66bec190b64d097ff5a701f228b82c8d9163":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x884f1d8562048fc99d0a683b25a686497dfec36a848f3eb0821a32f30c64d87d":"02","0x887f7c4aff0b26a8c5522da4140e28f92d6e2d1ab6c062deedf7ed2151d7821f":"03e8000000000000000000000000000668a1","0x891160c2d2b354e994a8e4d9e6ae9039df044774dde38b16b9976825cdd08c36":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x89384f99603f2138fba85293fce0e10e39631e550ab58d6a58832f0bd61688c7":"5dac1c6c","0x8985f4dc0f3493b07f814b5a42ee359d7590b828ecfa79656d1a58a63a2808f4":"4b0000000000000000000000000000005f","0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b":"c295c18f069245c7b493c4ec6d679d8a867f5538","0x8a5f8f0af33da88d5b8eadb13cfff19752e96212f3f9603268009b79c819ffa8":"0a","0x8b098a4dcdf6fad357e1ed97a8a6ffebdd5d39811c1f2cc973ce36a3e7a1129d":"03e8000000000000000000000000000668a1","0x8b14e19ea86d69dfef3a82ccf527e1b0486bbc2e66d5fe080a4d4dfbab055f51":"5dac1c91","0x8b4b7ec2d116568eb6c1b85fa18b2aa236390bdea499c3fe3f5db17cf7acd634":"5dab874d","0x8b54197b319c6310cbefc8fee3e5fceaa9d0730a67f5880384a3c5923a274dc5":"03e8000000000000000000000000000668a1","0x8b62c89904871080acdc0de05201799daf2a7129ecb25414e9c521f00770b316":"03e8000000000000000000000000000668a1","0x8ba31e517b41174cc0eb58c2106909531933546a2646419e0c9f4d6ff248d5d2":"08","0x8beab841ab515c27da153331eff5f2108827c30391f29ae8fa002cd6d905da58":"96000000000000000000000000000005dc","0x8c7d78fcbf5f5941824509d95950c8fbdeed6bdc0a846bf2d9a1a5b75a060670":"06","0x8ca5f430a8b73611e62f7a84f35eb6f1f18a4da10869f64bcab20a008056f841":"025800000000000000000000000000003840","0x8ce7495cbd73519255a6eb94e99f2bfe29f683689172ead74ace9a60407e8d10":"96000000000000000000000000000005dc","0x8d199de17224115afc2af31a9480130b5825db387b27c9cd5981cdbee36f3e4c":"06f05b59d3b20000000000000000000010a741a462780000","0x8d1a2bf71d285d44456b1cf456ad9d429a2d42942266ab3ec0bc899535475c26":"4b0000000000000000000000000000005f","0x8d9841478371d47fe5620339052679154608f2f62b6ecb0ea9b8d217032bf53d":"06f05b59d3b20000000000000000000010a741a462780000","0x8e14acfd575f0402847afdab375fa141be6d5896ff9e4eb463b72adbfa866ec0":"5dac3cc5","0x8e94030294f16aedce544d7000ca35020639a945058d4b18e0ef8bb64d5068b6":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x8ea7544d6afb9e514b3df3a4eadc3df43acd32f0427fe7bb784d6d941276cf02":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x8ec499c9b3851a2cf62412a00664435470806da8a8730b655b359f56a76003da":"04","0x8edee8b6db4f6e9e7ff713552a6be1f5b6d3911ac6ae18a59c616dcc39b4f486":"5dac3bc0","0x8f3ab391bdaa174cd79cc7e01ebc66603fbb8bd4963faefecdd55b6d55546a97":"06f05b59d3b20000000000000000000010a741a462780000","0x8f68608b5ff378e3e812ccb20929701abe0777ee0681c90e34110e2cc28dec21":"025800000000000000000000000000003840","0x9027c7b2defc78880c4c16a3f3dc40a69d33e0a59f08ab896cae04c05d52b102":"5dac1c7f","0x902d4b502c5f5e9786075aac04419da3ac8dd48c6e424c0f1077494685dda723":"96000000000000000000000000000005dc","0x9066a4c99d9c09148775fb54e21155b82f63fe5a0b8d45e95e318a4c87b84bd6":"5dac1d06","0x90f47975791babcdcc6f0384d39bcbc984be90f954c9edb42e74240b5a43c9a3":"03e8000000000000000000000000000668a1","0x90fddb3585c9a0e713a610458127e3fc6adf325564bf083cbed1221f56b865d5":"5dac1be0","0x9115e6574ab1aa5b164b72d901743c8fa2649fcba797688892497f59c5afe3fd":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x916f562b4dc9d0b36978937bd9727cff70fafd4dea07cbfaa694240a1dc6e8e6":"03e8000000000000000000000000000668a1","0x91aeb35ce21cdaadcf2b1ae9d40731febb36a61522d6142b311d7d0f6987bf66":"03e8000000000000000000000000000668a1","0x921ceaf3331238a0d249e6cf2c0fea32cc63e942f277a708b2b5393ef36bfbd0":"4b0000000000000000000000000000005f","0x92bfd15bf379c1bbb8a42043f02cd54cc0f867c7d1b14a1a016c222e478d310b":"5d8d4292","0x93028c444450558365d1ce21dda7cf7324ebd4868d96290dcd2ce9541b4c0078":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x93907b3ea6042de6107b2e4fb1a35eb33021cbf3e46bc0f00710d75937bf0dad":"06f05b59d3b20000000000000000000010a741a462780000","0x93ff8942888e134551cfdb7d15a56cfad56d4687504c1105ae78dd6c0b302940":"03e8000000000000000000000000000668a1","0x95b2f4ab14ad5474f225b1e12293181e33ca6708df4ae9a40b061da8e1569102":"5d8d4428","0x95cff7fd6b6fc04032f70b9a7e34a49482e651f1bb054da5b44b318e1f6a10b8":"4b0000000000000000000000000000005f","0x961c2f4c0ff099b18e0955b66c3bb890d46aaba54ae4cd23888ff16d8e803215":"025800000000000000000000000000003840","0x963b0526a95b86152751ea293cf011aff93439845a4841da56da713af152b60f":"4b0000000000000000000000000000005f","0x9710ede024b038159f16137ad74c23d94adbf4a4839c382575c0a319788f6597":"96000000000000000000000000000005dc","0x975707f24e8ad0351051577862bf18ee4ce26c986d15dda82c39082f90307290":"03e8000000000000000000000000000668a1","0x976a65cb44396274ef46f2f16784dd5a3569d184aa25103744a2556b144329f3":"96000000000000000000000000000005dc","0x97a6bf22e798d152e6696b459c87f99196117e7d9fbf3ca12973fefdd56758ad":"025800000000000000000000000000003840","0x986f21043116240b51b66d3c2482dafcfe46d95355653679094c974672dc56b8":"5dab8acc","0x98b166eda3db191790b093f93affd6ecf1ca0ca2c6df4eef41eb3a944f20f653":"5dac1c5d","0x991982bd87856d27713ec31522dfc52cd87ce085ff231f67a7fec347d07de87d":"08","0x994cad3426fcca648ce19033bb3bcda0ade7b79e1e2aa162cf705e33d3e60c2a":"07","0x9976f76abb30747bbd9e7f27e4420f836913ef237f3a229d354f0e5a18313045":"03e8000000000000000000000000000668a1","0x99e31bdaed66360ee87150725949d8f603a63a69650487ca162e9dd2fee2d9a0":"4b0000000000000000000000000000005f","0x9a35609295461f71912b28bac9623643a52aeb29f045ae020d9bf4d62be8e2e5":"5dac3b4e","0x9a6ab8b1b054cc5179213e70a1e4427a387e047aced8671a7abd4113e874bea3":"025800000000000000000000000000003840","0x9a92d81c130c647499875cdb644c8c9883db32128157d9579a92aaecb33e5d5f":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x9b2c5843e4602640792d727f39b60a43c9e37316fe5e03668c8454cbdd4df7de":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x9b551e17d4fa168169570a6ccbda00876c8f711b2ddf457b7e83bb16958c1831":"5dac1df9","0x9bd7142395e1d8677d1f487abb028e91c23b07ff7d7d15873dc5a71ff3f09a20":"96000000000000000000000000000005dc","0x9cb314a2cce8a782ec84ed746cb8e9a0d4fa0bf634070a352e1909f1561d2fd1":"03e8000000000000000000000000000668a1","0x9d1744d0a80a13c2f915cc04a0c8b12cf94cc8e6beb198fbda9477fd9dae0910":"03e8000000000000000000000000000668a1","0x9d84dbcccf12a342f6387548e7336c6ab24c1dced8520e2492008b098457982c":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x9d857d1b472c8bf6ef4ac421aa0503a3aabcfbf15236a5d4ca25bb9035035194":"5dab87db","0x9d8e5dff94e65018395177a6e06b11d20747ff6b7c70db32d0159f8721a34af6":"5dab8a30","0x9da925a1d1385bc06bc09f4f6d9abd46e3bf92c95ae92eb5ab4a4321dfc76974":"09","0x9dc8a20de846da428a518d5d41e1a067845d0adf8649d214d7b6a21c10571b60":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x9df48be295c5bfcafefd2e8b744eae5caf001322011891f911f8efe17875ffa1":"5dac1b88","0x9e0200b36bdb7e6cc32f6c8d0ad3eeccdc8f25453a3fe791835849f825a3a44b":"5d8d43d2","0x9e0b1feea9cd07aeb03851dd6d9aa04f0f019d5318b11fff02020b59296d8266":"5dac1e25","0x9e0ddd938d32dbe4bf6b1e82bd293159f26a126290bbb6fd975054d1b8660208":"0de0b6b3a764000000000000000000056bc75e2d63100000","0x9e330b8109346428e02842f62353ee188383f9f086d2dec19d3c45f8c60ec5b0":"4b0000000000000000000000000000005f","0x9e5ed1f311b3d158f096677d8007e861704620639f4e5e46e9e8d39686dffd19":"03","0x9ef651d0d82ecc89bc914197aad51924552526283e6a8d596afcb43e2e7d1e9c":"03e8000000000000000000000000000668a1","0x9f05b56b8f4f45bd8b66c39c86d71bab7fefca0794c6e3c79a9d2c369f89d5fb":"5d8d4398","0x9f16b89b81beb54fb166f34e8efc853cc9059b897048d4dff6add1ab629c0485":"06f05b59d3b20000000000000000000010a741a462780000","0x9f2807da31b03be809dc03e0a6f09570b6e493c898323d2c57a24bffcc08d820":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0x9f44ddcdbe05462ad55b8cbf41ad6add3aaa17c22422d889e25ff8bcd0bcc71d":"025800000000000000000000000000003840","0x9f4850ca956074c3d580248a1f6d071b81f5c92037d3f4549873679ab11d875f":"03e8000000000000000000000000000668a1","0x9ff8932329bf1f993e697e7d760b94643185ed1eb4857c2711423b90f7246dfc":"06f05b59d3b20000000000000000000010a741a462780000","0xa0986d86db0183ddffdc69701bfe8eddaf67ae6a433dcc03738f26c7a38dbaeb":"96000000000000000000000000000005dc","0xa18700dd6f7cec64005e4329f7f1075acfc1390d4c5b111fdead74e4458b6e3e":"5dab8746","0xa1b231e667ec0c356a84bceed0d7b229fc8bba3141cbfad64e26e9f76b7c87c3":"5d8d416a","0xa1c7ffcb874e2ee793c98ddc8b851a2c046f16be80638a0671712b01a5a49e8b":"0de0b6b3a764000000000000000000056bc75e2d63100000","0xa262b94e3cd344d621e2f5ad94ca57db0aa61aa8d02a1b773848ca9756e10c68":"04","0xa280c993e88bc81a4b3a2b9e308add3d81dc19a508f1f1c6e224b18259467d53":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0xa31ab68c0bb65d8bab3bde1d29b70745695cf679ebd39c0e4fbf9849d3e521bf":"0de0b6b3a764000000000000000000056bc75e2d63100000","0xa322860d68197472dadb5cc0d9bf978f13a1261abf959c9bcc90cc1500d57eec":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0xa327053acfbf5fe1395e17ee71b1e6c152503870862869f96c387ade159bf81d":"5dab8765","0xa3ad5fe5e8f3ea927f30e90d0dd9d37ebdff2e4c34456b41b4397246f58680a5":"025800000000000000000000000000003840","0xa3d8fc294189ebe839deda5478512b25dfefcd87cb043352015d2ba74e4c11fb":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0xa43f228657735b019d1e453eec471ed3ce167bcf021bf41e23474d0a90177671":"5dac1e60","0xa49981b5f97895dcfd0b54d2c9688e05e112b7c1f89bf8dc0660a24754e5acdd":"06f05b59d3b20000000000000000000010a741a462780000","0xa4dd431c994aa053aeba5b230729eeebf3d9aee99f5ea795429478323f17caec":"03","0xa4f12f33e7942e61b081e41f480855de5594ccb760d63fa3a1458917e230078c":"4b0000000000000000000000000000005f","0xa4f7fb2efb1f731ceb7f067a4294f645a459b5938bb76821cb3287226df311b6":"5dab888c","0xa54edd9f2d00bc082ae07f82014b3a5fd2eb2ef9af3abeb0d43fa8c800ec6b66":"4b0000000000000000000000000000005f","0xa57321549e4d5bdfa04b557708e57692ad09e7dfe8c3e81aef8994079c2dfeea":"06f05b59d3b20000000000000000000010a741a462780000","0xa5db2fe87fa6be5e41c712055a93c5aa2fe316920575b1b5a1f88efc0cf08b77":"025800000000000000000000000000003840","0xa5ea3bd8b49a98f9d0e44f05e84e5c79258e7c25ea21cd0d373c41c9a926dea1":"06f05b59d3b20000000000000000000010a741a462780000","0xa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688":"07d0","0xa67f1dfdec1debf6240102421b58119d48078b74784e371be31b202d81f4bfc1":"0de0b6b3a764000000000000000000056bc75e2d63100000","0xa79fbe1fd5cbf45299f97aebbe0c26f3832201fb5ec1284be3dc5e8b2703b5a6":"025800000000000000000000000000003840","0xa7b4dc8754713af426bc6db3546a69570d82d8d81acd977a3095f0afd64e934c":"07","0xa9799f54003c51947b11785367cb2e919bc8f89240bf2a4942ff721955675e9c":"0de0b6b3a764000000000000000000056bc75e2d63100000","0xa9bf9e4ac756a1d8163b3feb3ff1838f711e27ee3ced7fb473acf24b9dc9d7da":"025800000000000000000000000000003840","0xaaa0171f79b08d3439f5b9f15eae54e9f16d9a8372f5d4d23e15b37460c497c4":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0xaae42f241d30de35e4c2996fae88a893d1a1ebf3577e01fdb1e314f1b5a43c43":"0de0b6b3a764000000000000000000056bc75e2d63100000","0xab6f74dbe61d69e2f60c54f97b90c52f1cbe5341d58cd3803f377b29b7e32982":"96000000000000000000000000000005dc","0xabf0d178fc9116222a0719752dc600529a1ae85ca492e81ca23d08942ecd954a":"5dac3ae3","0xac310795034e72be4881687fdf6d4b6b0e448b6b28ff513ef0c4a27dc89305c4":"03","0xac6406e74593e54cbda2e5a1ffac5e7557a6c9781dddd85edcec722a486042f2":"4b0000000000000000000000000000005f","0xac77178c05f13f4eb4a0dbc678ceb51308df7b36563be3c55f3a140c577d37be":"05","0xacb82e5be2d630eee7c8e0501ba1d0036d69db1bdf2b338a9e220222b2d719ca":"96000000000000000000000000000005dc","0xadac4602ff0cdf08fe5406f85b87c4eac6d22275a91fa34b459c18d674e89df8":"03","0xadcab1a52fa7b82fa46411d86d0c5f391fe4e910cf09cfe6fa3147c8373913e3":"025800000000000000000000000000003840","0xadfe60a79119e57cbd1a6c5a610a0406fc2bc6fb2009c5140a5ef7e00aba8d0c":"0a","0xae34695d5d267c1db35cee74067c46b7ec584dfd90fb71be47be0986fca20d0b":"03e8000000000000000000000000000668a1","0xae5f958620d8aaf5d3d913ca7f348f988e823fa049b104bf1b7fb6817b003d07":"4b0000000000000000000000000000005f","0xaea16d1e8733bbe13e7cd965075f715119e862aebf60c7d92acd80d3cfea6d43":"96000000000000000000000000000005dc","0xaec7937d3c8cb2b15ea1f7a42279c55e8962c2d0c80ee36a6073bd68424e49be":"03","0xaf05ad11e349f069048695c320e6530d002567caeedf4b2685883cb3458e93f7":"5dab8afd","0xaf0acfd4b6cade16d17bdf0d30797855f8be2e855d8a75b7fe36cd26add87925":"03","0xaf7cb5bebf5a08a7a4add90921dad5664c95162600dfb899f534e10a5f3c6aa4":"5dac1db4","0xafab2938f8a73dd1f2e69285e33a21fc4367ed59bf5e0b7ae1e6a5b6f7ad3f40":"07","0xafc297afef6d37bd33539bc16873dcdb95d05c7a9f700169340518111b0852af":"025800000000000000000000000000003840","0xb085c8b4c2b400c1d95451c4bee6d16c79882d5cdf0b51409a0178ae9fc93f33":"96000000000000000000000000000005dc","0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6":"010000000000000000000000000000000000000000","0xb1c1c160f30aa4afa0c3d45af1259febd1ede62ca8460ad9fd1be8637fe89f7a":"0de0b6b3a764000000000000000000056bc75e2d63100000","0xb1f0b22e07a3a027268f57924f2a9943c2b2b0d7d811534fdc0103a4a85da185":"03","0xb225381dc5fac59746e0bca11d9ea02a468f860e545bfeef30df994915772844":"5dac3db6","0xb24f987e448147b678c27175dd0e5e05430c008b4d7e19871f116a7473633bd6":"5d8d424d","0xb27e95818e494a2fcbe123acbb84291715a2e26aa4bdce1624aa2f6b839dddda":"4b0000000000000000000000000000005f","0xb30945fd638aaba3e6b6eec93781df541445dc7a70ca48261d7704c2db50f446":"025800000000000000000000000000003840","0xb35d7bbe1d10f7f4bab2ff4b17712cf0a65644f73b28dc01c2b4af16b1e883e6":"025800000000000000000000000000003840","0xb485c6f22bc2b689663955021614ca3ad4c8beca93248de3fed21df9cb1a00e0":"04","0xb503ea1056f5686200afa6d20c494175bc5b3ea696d70354797a503842547b30":"0de0b6b3a764000000000000000000056bc75e2d63100000","0xb57cbb9ee4ec2b07b9aba6d0e8a0e945938bcf0b97c5dbdb041cbbf44e9aa7c6":"5dac3e41","0xb5ee0da296c38458ee35d27897992c246b2bc6cdfb95cebaac404526d152df51":"4b0000000000000000000000000000005f","0xb66f78a508750e052871ed0ff8c804f74877a524c6c3355f01d586e8eb096b56":"03e8000000000000000000000000000668a1","0xb6b6d93156cbe88b0fe46761e1a2b235941fe842a9fd74acd8837117a9d53002":"5dac3dd6","0xb763e8d10efdc27de55d529e2ead96aaeb72bad1d8ec04773c9b963637e9c638":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0xb84b37ae1136db3e7b0210502e53e3072e5c0d8b98394328f5fbbfa865db8b47":"06f05b59d3b20000000000000000000010a741a462780000","0xb89f5dd737da5ee9faff010c10820352f275ecfefb9d94a66330cb0457376ac5":"0de0b6b3a764000000000000000000056bc75e2d63100000","0xb8d2fafbc4bcdd0d98c7dfc235c6286769f352b85c0d9f26da3ce1606d0e0e74":"06f05b59d3b20000000000000000000010a741a462780000","0xb8fe1e7628d6bd778d0351bdeaa9016fd19c586bbc3ccdbb39b446efa7c0cef0":"03e8000000000000000000000000000668a1","0xb94ec07efb92c57378c7e6b6d79abb6d2c801cc44bba6f1daaf6aca0d99ccbe4":"03e8000000000000000000000000000668a1","0xb97d0208422bdffadbdb1758c5a2f054ab89c9d94dff396105147cdc1df40f4e":"025800000000000000000000000000003840","0xb9a36df7482ac9dad67efdb26890c92bbae80b4f17492dc42686633517da5d43":"5dac1d7b","0xb9b7573facf3bb47c266820d83f01d46fe3e5ca2c68728c85f14cdd1e4e7711f":"5dac1d7c","0xba2ac78adcf8f228a8a878ac2ee73d57963e0c69608b48c770fb0304eeb9e33f":"5dab8af8","0xba62ef9f050eb6f230de581203824389942c3810470a84e85e81f6f377afb51b":"5d8d41b3","0xbb264d06cf22107a20afd42c4b3b7f377c774d9780446d98655e795489e20f3f":"06f05b59d3b20000000000000000000010a741a462780000","0xbb40d992cc24f93a35fcf780db556136368b6c7d6940497728e9cf91ae1b0b99":"5d8d4481","0xbb6f8ef8a05f02e9a1ca9016cc98a511aa9964538dc512446553165ce28a5dee":"025800000000000000000000000000003840","0xbb8c4b4445b8665990f25742dba79d74e87c609e800c8059662119a97d0934cc":"03e8000000000000000000000000000668a1","0xbb981893c63265238d18df30f1f8899679e2ad833b23430cf427c0222d5abcf7":"06f05b59d3b20000000000000000000010a741a462780000","0xbc337b76d66b4774539f433db00df6615e2dd79d61944c45d07ad18ef65814eb":"025800000000000000000000000000003840","0xbc4a0b9d51936e0ce8903de7953acbc90f43071b9a5be7e8f753639a914bb8e2":"025800000000000000000000000000003840","0xbc9473f7ad70858f0510a1cbdb0edc53557c2f14c0c61c72d968ad2d07b60700":"025800000000000000000000000000003840","0xbdd461cdd857abd2a8235eac0d98965fa042c4c6281d10de7587c9bce8bbf96d":"03e8000000000000000000000000000668a1","0xbddd82f20a473eec2fd483e767bd0f52b831b230c0262252fb3bb0c612c33f13":"96000000000000000000000000000005dc","0xbde9e26b1fdf2765714e49e8608f95da0772bc6530ced5dbeb0edc834cfccaa3":"03e8000000000000000000000000000668a1","0xbded5cfed4b38e58db219008772f367496f69a093cf3acecf090d7979d5ca1dd":"4b0000000000000000000000000000005f","0xbe083c9d5839f661583c940332bfcc76fc14f4fc0b97d0eae0fae6b40e16a4ea":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0xbe9365000d0d5fcd1ff9220a95d8ae16b61b0522c43979235affa4e5a00eaa7b":"03e8000000000000000000000000000668a1","0xbee8393e245496647a92b137de9ec272e4a02244ad74e493750e0752e934a8cd":"96000000000000000000000000000005dc","0xbf276178e93daf861d82f97dda918fcf17c53d705f6721c130b6867d4d93cd64":"025800000000000000000000000000003840","0xc00ed6a807d77542d0af961897b860391d42de58724b4f1722be2df1b5a9968a":"4b0000000000000000000000000000005f","0xc12a521a0b327d0e990ea825ab9d647b6fecd56ef3cf27b645c095b0c722c7a2":"5dab87b0","0xc13aae2fb8c446e5474bdc7d639346bc02e9d0dac025626ead90c761aa542344":"5dac1bce","0xc18267fb8edcf8a4178e8799e0f51a8f142170d59d51740138045d43b82f1014":"4b0000000000000000000000000000005f","0xc189c61f8d62acaf0ff51f7e78d27df56ad7ec3777bf6d4ff29a6fac085c285a":"025800000000000000000000000000003840","0xc1d464c4d37b574845ead523db7bef5eeed1ab258fd7ac7fff28a6b28f038678":"5dac3e00","0xc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b":"76312e312e31000000000000000000000000000000000000000000000000000c","0xc2b81d8e230a07fb4c9e1d23bd806a93cc04ec004dacd07c9fcdad2d3743e3ee":"03e8000000000000000000000000000668a1","0xc2fd3f779a584511b798f5776ebf05231c0d77c06ea68b448336a2cdd24954ef":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0xc3db66d301432031431af9670c20378b0ecd13c97d9d29fc684b91b2c1fe06da":"5d8d446f","0xc3e21c55f2b8f8cf6cfa26a36b03d8ebaa750a79dbf00d365eb440b1e0bb7fe9":"5dab8826","0xc3e45103d6d392357799be8bd7be84ace5986bf6b48f30d6a849c2a53ef51572":"07","0xc44838cc17ad3d81f57e244280de06bcaaf584dba021aa291fa1dba79bf05b7f":"01","0xc496901440870b89bd0c99f7dcddb775ad71328cff635507a20f5ee6e74e515a":"06f05b59d3b20000000000000000000010a741a462780000","0xc4cbef1b909c6a1b5085417f98ffcf1e1715cfbfd115574c2c69d78801806a94":"0de0b6b3a764000000000000000000056bc75e2d63100000","0xc5717cff52a8dd14285b5b4c077d4e70c3252e7e91bc3e375fb03a68717c6cc9":"025800000000000000000000000000003840","0xc5ccc49b35c1f42125c82796a881f56fbeceb2002e4e26dd29c61ccd3d12219f":"96000000000000000000000000000005dc","0xc624a3933f32df0b5deb3f5a5ef19f710c1a764fa8fea7edf64ed8df7773b58a":"06f05b59d3b20000000000000000000010a741a462780000","0xc62d4e97d1932312e3850234c7140f99c1fc440a461c5256b11146a0738cb1ab":"5dac39ef","0xc64ebd08670923f2eeb686e4bfbc2580f3461f42c9d1a877300dc67121d2a7e0":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0xc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a8":"fbeea2f705c135fc050ad7ccea86adfcfc545017","0xc6e268b5b0607bbfb9028bddc69f3cdf362adde98bc4f17e101b0b65f9573025":"5dac3a1d","0xc704e01fda8f2038d2f3ec62a226fd7862ffbffe10a2b4f858bac8f469666f7a":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0xc7252079e7f73b95220e39ba813f20f01802e362f476e3f9adca84f223636005":"025800000000000000000000000000003840","0xc85befd97dc6a0fd9548672723f115e25b39cce3d7e2adfe36207845ff83b414":"025800000000000000000000000000003840","0xc898d05f9bcbb8e3ce5746b33335c933e1965e65ad4489b3e57247e925cdaa5b":"0de0b6b3a764000000000000000000056bc75e2d63100000","0xc8b39be3e648e03fe0fe3c0c1789fd20980708720f00f417783292723f44fc58":"06f05b59d3b20000000000000000000010a741a462780000","0xc8dc733e64ef4a9afff04c60c7428c9eaba8624c39df6a64aad4adc5bd8f7700":"03e8000000000000000000000000000668a1","0xc970e23e10cb3347eb13414881426d61086d6f66afb51fa0556ecfd1d5b56d01":"03e8000000000000000000000000000668a1","0xc981165ff093e4f0cb33ffb9270456f8d5cc119a15eb76a5d2870a2ddbf5dcc5":"025800000000000000000000000000003840","0xc9a6f8bab6496d15fe402063aa148d799fb17a1a1421313117cab125bd18bb32":"06f05b59d3b20000000000000000000010a741a462780000","0xca33fae294960ce0c8442e3bee5ee5dba9f35fc1205886319d763349a34d0007":"03","0xcaac18918c7a004632a87927beebfd7312770586fa26dfbf0324159d097b39f5":"4b0000000000000000000000000000005f","0xcac5e33e434e0a3ca670f351b4f2ac62dfbdf93f7ae14b425bf69c3f57bc7c74":"09","0xcb39a18d353bf8c0e81d7cec7e13abbdfca598163d1143e2e7b831c6668f28ed":"4b0000000000000000000000000000005f","0xcb638480617af7831b14379604b94c721dcd419d6ccdc67769fbc85707cbed53":"4b0000000000000000000000000000005f","0xcbebcf13007aa7b0e273403267101fd17324dfb124f10c08d3bbe8512ebca6a9":"4b0000000000000000000000000000005f","0xcc1111ad7355467ceded6dea0c2b915e1b20fc829ac7719da2c9dabc5033f11a":"02","0xcc687a908d44b27c2c5c3b1c0a419c1d5216b8e98fa32574f55ec9a918a87ef8":"4b0000000000000000000000000000005f","0xcd3600e4a7595c772802782cb902ff459760b4f43903bf3da6f7fb7d9e037779":"4b0000000000000000000000000000005f","0xce1403ca34a02534e65ed2080a362e8219ff7e406b313c68e85b31be312bc84e":"03e8000000000000000000000000000668a1","0xce155e673694727f6b47e8b4d81d259b4b94e6f4005c05059c519cd3c13a219a":"5dab8a52","0xce3cb09bc2193211614e1b96626abb5ee32eeda97c75f6da2acc61d5de7b44e7":"4b0000000000000000000000000000005f","0xce9eb04cddebedb0e7ba335af867fff0130812595b82777e39ca900f94ce074d":"06f05b59d3b20000000000000000000010a741a462780000","0xceb130059b2c0e8694ef9e219a69c322663f0f5c143ccaa91953d1c1ab30ecf0":"0de0b6b3a764000000000000000000056bc75e2d63100000","0xceccf4637d0b54bbdbd34979ca4e74b357acb8ed13e4fea3c5bfb3b0c9271b7f":"02","0xcf83f1bdc7fe83ce529ec6aa0129884358a3f8442d87f9d504843573c812b2f0":"025800000000000000000000000000003840","0xcf892d9f1c4a55360b1a8e8a8570c4f9edcaac33944d72aa7cafd082a9a3cd35":"96000000000000000000000000000005dc","0xd01619556d372868718c594007cfed0096735318484d4f055ff24130e7586193":"03e8000000000000000000000000000668a1","0xd0416318a8c447f312abedff8ef8a86355a597701a2682ffc7e8b12b6530b415":"5dac1d27","0xd0f2dacf7c997124f0fd94cb50d314865a6d884d050033db554b957db50e7c1f":"4b0000000000000000000000000000005f","0xd0f341e51028e20362333e185d54dde43445b00656cf4da4d662ed8d1c1261a4":"0a","0xd10ee0952a55933f8d5788f66cdfe6ff3b65c9111a5bf033a81c512532f67f03":"06f05b59d3b20000000000000000000010a741a462780000","0xd113adac9e4f0fed7d3cbbd25125c7703260e959878711417dfa99ae275979d0":"4b0000000000000000000000000000005f","0xd11c8f894af16d3465ff276c35b03633e72256f6b72795e14213afc7390ef61c":"5dac3c61","0xd120bee2d2130333e96715d2c047927d04ecb205146251dd832542cdc9487c98":"4b0000000000000000000000000000005f","0xd1370a717a8f2afcbee4a697ae1a435d9e604b31dfd2a498748aea3dc6f91b44":"5dac3c58","0xd16d0b93bb11fa5a3929b25751b1f988d54cc1fa44545bd6af066741172d7e06":"4b0000000000000000000000000000005f","0xd1b21a0a739384258465db498c2cd849ff0050c2a503f3092ad564cf86eabaf2":"4b0000000000000000000000000000005f","0xd23d25c8f009908827244ff0256a772ba824905117420a7bd40beecaa153b4ec":"0de0b6b3a764000000000000000000056bc75e2d63100000","0xd251180f92576f6945e20c6c55e9cc635058af92b7fba3fe5b2cf6d8ba88c576":"96000000000000000000000000000005dc","0xd28e97753ff911a7b9b94583334ef681dd7ae06ccb57b7938b525aecf803faf1":"06f05b59d3b20000000000000000000010a741a462780000","0xd2be5a7e28ee080e990825d744c06f43a7d3bc5ec3a48c4e4e6c0acbb5b7d5fd":"025800000000000000000000000000003840","0xd2e234c4e36f01b73bd74657ad1a97abd87b07f620ea2efef2c4a093dcb605f7":"5dac1c9d","0xd35897feedd85a413b8041ebaac66616cc12c5815258753749250adb7875fbf3":"0de0b6b3a764000000000000000000056bc75e2d63100000","0xd3628003b10293fc68876904974cee345920ae4824dba0114f20c8e2f6f9b8c2":"5d8d415f","0xd37b0898753322153c42e202d0d82a2dc7539733b90ecf901e0b175fa74628c4":"06f05b59d3b20000000000000000000010a741a462780000","0xd4a286a9760b89cd49fd2a1a120b79607ddfd8a1d23fb2df9c388204d9633801":"5dac3acc","0xd4fcf66bef8a9b63b901d53addff41c077feb00cac4ecb58bfd61f6b589b651d":"03e8000000000000000000000000000668a1","0xd521f0e588235a90c9ba68d1161aa81156b7028546d6dca080b6517ab0f8be0a":"96000000000000000000000000000005dc","0xd7333101664ab346ff7b8cc8eb583d23cc119bfdd5936914559d7884dbf3dbf3":"06f05b59d3b20000000000000000000010a741a462780000","0xd7b9532590850672e52f69ed7e4ecd6fff708bf3a2efbc2d404a2b59295935e9":"025800000000000000000000000000003840","0xd92997ad4b5e3146d3f542f695e5b4a497c1ad93bc4f8371d51def1b57910595":"06f05b59d3b20000000000000000000010a741a462780000","0xd9ae7f35ec5a43e519250ae0ecf36eea2047c0c50af379d633a2c8e868390b59":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0xd9d6b58479f3e3de241f9a6f514dd50cf1b879dcfae6e538d4f894d017362c37":"06f05b59d3b20000000000000000000010a741a462780000","0xda47874c863e3ccf886484eddd3d3ab70ac8b2d690bbd5abc775b4a6c87c3cd6":"025800000000000000000000000000003840","0xdad0d037bb3f97dfa799328c6727e1968c53a4e25802332ad833f8e30a70ba17":"025800000000000000000000000000003840","0xdadc2e86e4d51eb1e579fc3c09651128058ab118af2a9b5730f290e551a807a4":"5dab8866","0xdaf18d65d2b0140c147ce581bf3d1f390ed345d7341fb2f06771ddb1df2cf946":"03e8000000000000000000000000000668a1","0xdb02d41a21594b9977f6465f54339b640e126b8ebbfadda54dacf820aec4e975":"06f05b59d3b20000000000000000000010a741a462780000","0xdb14b244ca1beeae96bb5f30780c536b1d8a3727b9366d02fc144823af02edd3":"96000000000000000000000000000005dc","0xdb2a0df8dff098158c8ec9d2ac657ca557e19494a69589fea8907f69b0d3a8aa":"5d8d41e3","0xdb3849be46aa30ad550259e76d1766ff915913e6f3af785c00aabceb57de407b":"06f05b59d3b20000000000000000000010a741a462780000","0xdb531ca4c2e90e2af22e8384c707444c15940cc09e90adb0177151ab4683df34":"96000000000000000000000000000005dc","0xdb798f23402f9c97825ec7e7f88cec23321c5778cf0f8c4baee1759be7aecabc":"025800000000000000000000000000003840","0xdb7dd688b63e802c0579f21c428052d83f231d3f96432023bad15bfe7c5e95c6":"5dac1cbd","0xdbb53f0bdf3dcf8bdfab59a96da52ec4903322d71cb28fdb2b11b1f4793bd1cf":"0de0b6b3a764000000000000000000056bc75e2d63100000","0xdc1138df10671854c60a2d25b0e1d650da8d7d3cd08c0d3a6b3f8c006200a38d":"025800000000000000000000000000003840","0xdc3a81371f53efe247a45f7d2a050155de80b0e8fa79710566fac550630fd901":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0xdc8e9dfd851cd9c4285f8e6cf1ad4b66037dcb52ec59ade31ce620b7bffc6cde":"06f05b59d3b20000000000000000000010a741a462780000","0xddcc0ee003f80ec81b352bd0f06f110831dae75316d7da5ddd2e89f502fe3955":"0de0b6b3a764000000000000000000056bc75e2d63100000","0xde150fbb9b9ea35ad8cf6ce002f5196c2b5c71e579e97161d1b8acac3f6cbe8e":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0xdf42e8e49656c60e95640e38d118b8edac9271214576c70996842c0466fd34dd":"03e8000000000000000000000000000668a1","0xdf80ed4c34fed4214dedaf2a72ac6e619b9b94021634ccb69e007c04887cfd05":"025800000000000000000000000000003840","0xdf9313988d7188d8c0746ac0679b7df49e76663117446c75ccd0b811f7159331":"04","0xdfa14d668921dbb97097b9a227e061483e92969bfec4a3de66cc0bbcf47dc36a":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0xe01277946369a2a5f24d15f37e9533fc6807f6268ecf5697173d99bd0de825e6":"03e8000000000000000000000000000668a1","0xe02709f67257906bfef9cea3a5bfb6f51883ff5e70ac9e107307f57348356d00":"06f05b59d3b20000000000000000000010a741a462780000","0xe18586b93045d90bfb7f3907b6f4bdfbdca535875bb6701890d57fe1fdc8878d":"03e8000000000000000000000000000668a1","0xe18ed677534e40913418e9f38254d77b403013fe9465c984fbb79fdfe7527d79":"0de0b6b3a764000000000000000000056bc75e2d63100000","0xe1e75b66a6138296fab9e97b1a9c2a95b19cc935c4ed699e9b90f8f53ae420ac":"09","0xe216fc25c1fbe1ae5cd295ce20270f397a7ea90e36ff881d5ba5dee291cf93e5":"5dac1cd9","0xe2da03bf6e06a1cd733bc19b3105fa83888df651a995035e08e3cbb5fa2375e8":"5dab899a","0xe31cfac90e32713a11b7c40e22512389c2b24de7a0329494bfedc8a2ccd9bd71":"0de0b6b3a764000000000000000000056bc75e2d63100000","0xe363b309843effc23ccd6c14dbe3e1210737aced79471c17cb5d7b2b06a52730":"03e8000000000000000000000000000668a1","0xe364637449cb20b4abdf623bf93215b9ee8458519c3a0cdba85ebeec2e17f749":"025800000000000000000000000000003840","0xe397f16d63452991ef412ba5484bd1aa89c0017802b9804f3bb64c92d967c5da":"5d8d412a","0xe3b8c541f2712f54c97200a4cdf9e4722962610e783adba81a5c264c0f7f8e79":"5dac3a11","0xe40cd06a97fa45e16c4ba0c51171beae552fbbee090239ffe6adc4f4977d5fa2":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0xe4f7447c305230028ef03f4c3a6073d95546051bd2e0c9425c226009ee886f32":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0xe5db28442108976959fb098c3db07821971960bb29dc741c48d165cb23144351":"5dac3ca1","0xe60467a47f3249fe3276096d7d6beef6b747db9bb710770e41efd7314250bd33":"02","0xe66d750f7b2667bca8f358f7d7d557ea563caac59bc42aa6e5973b784a1bc851":"03","0xe67f6481fb2780b732331bc1d0cb494147a202fa9c5a1569da2cfe755f2f1534":"03e8000000000000000000000000000668a1","0xe68729acab5f912b96adfd001f3c58a60a054584d21dc64219d21a1a606033d7":"03e8000000000000000000000000000668a1","0xe6c5c4be881505a83e696454454dd4af455dfa30973a296297ceb06f3be0c4db":"5d8d4229","0xe6f4ae786aa62245033521871c89b61a086aa324c6af99f35effd60d669dc823":"4b0000000000000000000000000000005f","0xe717b596fac9b51a8e2c76448e6a299a6737cbf1a50bae95c6b03a0771a25671":"03e8000000000000000000000000000668a1","0xe777e538ceea019c3a32952380f5357e41eaedf1b0b3ba313f0eb993dc90b84f":"03e8000000000000000000000000000668a1","0xe984f20cb22084880d58108c304564e44eafb02c2901e635c58f690d1bca10a9":"04","0xe9eb56cca6101f6447cb8c2a8671d2d6a0164f6932a83685ccd5e22324ba2427":"4b0000000000000000000000000000005f","0xea3d8e06271c27aca88fb7d9a0b332741ebc1018c31d7fe5f5f87633dcdf1334":"4b0000000000000000000000000000005f","0xea9c986cc7dbbcec69a5de979b6813070753b335c7af195547c056c2ea952893":"06f05b59d3b20000000000000000000010a741a462780000","0xeb366065cc51016b0bc238408629f5825f072f6d7ccca8da69446c699b18400c":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0xeb416dc9c8adb726e90ae4a82d4b1a98a3d139d225f2af286108f19ea1290749":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0xeb9e5fbd82121cc9c2f6383bac3c458131bbfc2621ffcc3570dea9a6b84e7463":"025800000000000000000000000000003840","0xeba6eb236579bb05c2782ab8845b967fb54cce51162c1ba98fd37778c7bf6832":"06f05b59d3b20000000000000000000010a741a462780000","0xec8905ddc338823ec530b510d463452e178e32029abf714014c13739ba080480":"025800000000000000000000000000003840","0xec8b9ee5e99b1d0f1f19eb08a1d518c9d9d481b19db4f2306cec38f8c331d87f":"025800000000000000000000000000003840","0xece2c60444418ba7609eb01cadf3d1f92989a88d46746db94d5e10e0b5ca8cc8":"02","0xed2f873a27d0cdc32f8f048dbbe6a43b8b9b76660556433571b2479ffafb2494":"025800000000000000000000000000003840","0xed3b4e77628100c2c3ef131573c30c0fe7564230ab18cdc115529acd86b476e9":"06f05b59d3b20000000000000000000010a741a462780000","0xee001beda81ee13f3738ffbf85f68acfe19323407a3e5635595f6676c5764271":"4b0000000000000000000000000000005f","0xee065d8ffa2ef23ae5de2c99fbaf2543ff04ec4cea63a156b7deb9e602675af0":"0de0b6b3a764000000000000000000056bc75e2d63100000","0xee2b93d6b0b3322473b70d067225fad8dcdfbdc6d9527a09d607a0bee109da67":"0de0b6b3a764000000000000000000056bc75e2d63100000","0xee2bfd90ff2ce8b4314ef3996bfa6d3b36609a6ce32fff458a4e126647e7001f":"06f05b59d3b20000000000000000000010a741a462780000","0xee6555912ff176acaea5f3cc1c5c235879b184b8ab90dfbcaed84f09f0abe645":"04","0xee9038a4bcbcbf8e3ae4224f57b393cb9b5eecb7dc9c1fffa658ca1011e9e125":"025800000000000000000000000000003840","0xeecdfc29d0e753c876287c44fc4776fc20c9271372bfe7202b59a27b3e32228c":"0de0b6b3a764000000000000000000056bc75e2d63100000","0xeee38820928f72b4def8d47318e0a6db0cb6e2069c4bbd0b34e5dbbd84b896c7":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0xef276b822b09b501e6ba9867acc8e6f2b281cb3acc779abe84e82bba884e69ca":"02","0xef2ef7ed482b99eb9143b4fdffb1abdb8c322eb251bbe41642a6ce5cb2851421":"03e8000000000000000000000000000668a1","0xf0529146f828846ac8052b7ef941b00b81a962d953a9bb4c1adc699a892874b8":"04","0xf06cbb735ed5c1ad63bde36760cca4b8ed9c75b74b3a102299c36d51718ebb56":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0xf06f021b8d70a9d18bde9c7ff04cb7f328bf5fdd8bc2ce1fcb202d5b9eff9065":"025800000000000000000000000000003840","0xf0e244f936ceef327138ed4d54ff6e00ce1320d39e0ae1949f4ca33d99229e98":"5dac3c80","0xf16437dd4be26c28c70135e1063d80b33270c6a5cf1f5e877186535889fd90db":"5dac1e1f","0xf30e3f0e1023bd6085a1cadcef0fcda2c61560c31b0cc0bc9dbdcfb48aa1a211":"4b0000000000000000000000000000005f","0xf3d1b434819a43cfadd569b6d46e4e5cc3f86d42378e1ba8421af86e7c6e838e":"96000000000000000000000000000005dc","0xf3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3":"76242809e28b8fb08c05255cf2ca4b008c91366d","0xf43b3e8eee249e54eb6812a16dab4b28b0a32837d18dd683405de126e12d514c":"5dab8a3a","0xf4425046297865ebe4c0e07abfb3a220a258b8bce51287791f6a53c1681f72b9":"4b0000000000000000000000000000005f","0xf4643048b0eb3c1641afd26ac3b802c95582343801d59ee3e9cb27ab0cea49cb":"03","0xf51a65bc4ab808899589432a4248d3e67acb3ea91dd43b5b0282db4672c13d19":"5d8d418c","0xf53ddbb3777a9b0a47720c1f632d8e83dc6007d604aef1a20a4de7b785b32724":"5dac3ac1","0xf57c32f83a38de2b747fa6b090131da2123fd3d586911fd8440c732fb3ab1687":"0de0b6b3a764000000000000000000056bc75e2d63100000","0xf5b9cdab7a632fba0c527ff0c985961ee3ad6212b397477285e872a1e1eda427":"5dab8926","0xf5f0c19f1118390346e5822e22457050588f362c234dfc2b12d9ea886961bdf8":"06f05b59d3b20000000000000000000010a741a462780000","0xf654ae964502b6467cd72697d5ba8caf1274c17777e4f7bf907ce2ed344cb23a":"5dab8797","0xf68208118c313ab391c589bba1d5be7ef8bc73b9febab7b6ab614e8a8eafde71":"5d8d454b","0xf6a7022a306030ae614a9a4f5105fa4adf5b071bf95df9488e8f87910e6a273f":"0de0b6b3a764000000000000000000056bc75e2d63100000","0xf6eae36e80d93cb09f956ffb04fc370fcc90051a4568af9229a9d3f68480677f":"96000000000000000000000000000005dc","0xf702eedb5b9c06c6d45a605f6b34c0fc3c8442935c1f1e68db1be95ad9995af7":"4b0000000000000000000000000000005f","0xf73eeb62bfb991de2981c4c6f977d11937e8772576481c9a68a448bc9d231a2d":"0de0b6b3a764000000000000000000056bc75e2d63100000","0xf7cb666a9944f3645fe11cc2bfcc918497fd101d12d09b60e207ff0522b5b665":"025800000000000000000000000000003840","0xf82337104fdaf2d335a957e98af9ab26b08a1f7f93ae363c9b15b10705d8c3ef":"5dac3b33","0xf8a148ecabdf320148dc3796dfa5b012eaa56433baae01b0f01a85786aa4c02f":"0de0b6b3a764000000000000000000056bc75e2d63100000","0xf8fdc01b50c566311d5245f8ca1f01d94f766898b9f5357b9e72c5c54c969a39":"0de0b6b3a764000000000000000000056bc75e2d63100000","0xf92265e9f666a6da92391bcf4318112593ff863d424e7969f841980711fe7df6":"96000000000000000000000000000005dc","0xf93c171f5b307f6e358ab5eb0b14b7c415369be063bbf2073593cb8ed0aa7ee6":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0xf98fd4d5e25b147fc6bfe83b0d4cbcfe38ccc90785fb9910a7c8c98c27ebb165":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0xfa0ac453224b1baedfe5de8d52d7471ab10ae3dbb5806c33940293fdc9a8628b":"06f05b59d3b20000000000000000000010a741a462780000","0xfa1eb17807b2dead527f33cd108ec4215ef14928c3998af18b20ba3094c222bb":"03e8000000000000000000000000000668a1","0xfaa0b8e629076a5dbac7bcd1414ddb64319b0c317110c24733768a2480959e86":"21451ea0035ebf7cdcb55dff18f4d9989cc21212d4992c0eb348fab83b2a3dc4","0xfada3cb380eeac46a8a73cbe85bcb2161e006fa4df5a287f5303211baba88dc3":"025800000000000000000000000000003840","0xfae11ba1c05ffd34e9667e1d38ceac0f9d46585de674b6887d7e6e89e996e82c":"0de0b6b3a764000000000000000000056bc75e2d63100000","0xfaef8289d2b5c063a0180f147a60851ce388f382721867d69f1f72cfc9ba523a":"5dac1c0a","0xfb132931d90f52c4726d7cd809e4c54e41f35864c0ee39370515d3b1aa3d8050":"03e8000000000000000000000000000668a1","0xfbb8d45e3a935ff7c709e508129e4704a9f90c90ae88b7f3ff1aaee2e504a618":"0de0b6b3a764000000000000000000056bc75e2d63100000","0xfbdd1a0010602a5da82f4a53c70ee0edab732a2365fd084f6af5777ddbd328af":"03e8000000000000000000000000000668a1","0xfcd624681d0611a9ac833023e9a71f8fa1a4c422aa4dea80e96663b1ecdf7d08":"04","0xfce4570b32ad1ae5aa579f6f91262ff7ba6a04cd3adf759403887994a2f5de6b":"03e8000000000000000000000000000668a1","0xfd7bd090415fa7c6468cac3105a60df755dca8e2aaf6aa9e142fcd40b269c077":"5d8d4343","0xfd87b6a61229b8cc53749f2ab417661e29ad9ad126eea0e2d89b2d03bcb4eed6":"5dac1b92","0xfdd6172390adc7495eff40bd417c7accef0e43575fcf74e7931d1f1b71ab18af":"025800000000000000000000000000003840","0xfdd8639136e3703bdcffea9564dd021e680f5a7e73723227bbc1665043984b1b":"03e8000000000000000000000000000668a1","0xfec106350e796ab52c40de815e2d6275bd4b4efef6acfc9e5f4c0d891966e246":"0de0b6b3a764000000000000000000056bc75e2d63100000","0xfec5d8f603249c8d9c7137dc32144edd391460c77bbc3606c34716684b328069":"5dab8905","0xff55ec598f26e7bd95893381dae79428b1a459b8158789442ccf53ffad539ff9":"5dac3c12"},"key":"0x00004a4fa8c0580d1747935320a6d16231150e0deb3057cc429cd3dcae0f17c9"} +{"balance":"0","nonce":1,"root":"0xfab2fdd4411cbca4bbabcd4d36a182b617a09dbf085372bd462a91a939ffbeb6","codeHash":"0xc56f16311c2e4182512c0f3cd670ef698e97d21c294e5ec79cc34e4d7b14a4a0","code":"0x6060604052600436106100565763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416633018205f811461014057806392eefe9b1461017c578063bef72fa2146101bc575b60015460009015156100675761013d565b6000805460015473ffffffffffffffffffffffffffffffffffffffff9091169163f39ec1f79190604051602001526040517c010000000000000000000000000000000000000000000000000000000063ffffffff84160281526004810191909152602401602060405180830381600087803b15156100e457600080fd5b6102c65a03f115156100f557600080fd5b505050604051805190509050604051601f19601f36011680820160405236600083376000803684865af4808015610138576040513d81016040523d6000823e3d81f35b600080fd5b50005b341561014b57600080fd5b6101536101e1565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b341561018757600080fd5b6101a873ffffffffffffffffffffffffffffffffffffffff600435166101fd565b604051901515815260200160405180910390f35b34156101c757600080fd5b6101cf610265565b60405190815260200160405180910390f35b60005473ffffffffffffffffffffffffffffffffffffffff1690565b600080543373ffffffffffffffffffffffffffffffffffffffff90811691161461022657600080fd5b506000805473ffffffffffffffffffffffffffffffffffffffff831673ffffffffffffffffffffffffffffffffffffffff199091161790556001919050565b600154815600a165627a7a7230582024efa3d396327d15592d02078e301e1bb188bd7e3344de3149feb5979ac738d30029","storage":{"0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563":"20e776eaf1da267599351ab70c31150eb42f56b2","0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace":"01","0x994452ca945fc06d1777a30fa362b9c46e60d68a4139d06bd55f306f36add5b7":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6":"5368617265546f6b656e00000000000000000000000000000000000000000000","0xf652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f":"c63dc134cc1158ee9e259c343a7a37c7abe9d297"},"key":"0x00004ab5c532db8082e29e35f39823fe8b0fb1cf452fbfe560eee46b4e332e86"} +{"balance":"1000000000000000000","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00004b9b238cccd26d63bda6e148344f7223067dadd62a7a2ada3eab1c136b75"} +{"balance":"1000000000000000000","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00004bec97953b89f64edf9f8c4f4c9ba00046a069f0ab44b029f672afd4ed82"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xd80cd839dd3957d572b90780ada202a13936fa2875daea94216263371e9ef1d2","code":"0x6eb3f879cb30fe243b4dfee438691c043318585733ff","key":"0x00004c34fea1bc020cadee3509659a5de8dcc37aec2291146e388fe911b8cea1"} +{"balance":"968500237867001","nonce":2,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00004c3b63590fc142322d83412e24adf99ea19dbb6037342c5f15771086e9dd"} +{"balance":"1","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xe724d40619441ced66a271e59627b7bcd39c77447a4315561b4d21e7b7c9321c","code":"0x40","key":"0x00004c552f35bcec63c766c5c34c099a2a5451f37693bdbf7ff6ab76c34f62ee"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00004cdafb578c980c56412474d49e61f4d7b418347767efae93dd99b776a177"} +{"balance":"0","nonce":1,"root":"0xe3b9763ce717aa004c084a8181b74d504995e7104095fe6dff5725defb10e002","codeHash":"0x5feff1d0e639e46940ad6f7ea615ae95e1ae43d68c4e0a375e370f4c8a73ef1b","code":"0x6060604052361561017a5763ffffffff60e060020a60003504166306fdde03811461017f5780630753c30c14610209578063095ea7b31461022a5780630e136b191461024c5780630ecb93c01461027357806318160ddd1461029257806323b872dd146102b757806326976e3f146102df57806327e235e31461030e578063313ce5671461032d57806335390714146103405780633eaaf86b146103535780633f4ba83a1461036657806359bf1abe146103795780635c658165146103985780635c975abb146103bd57806370a08231146103d05780638456cb59146103ef578063893d20e8146104025780638da5cb5b1461041557806395d89b4114610428578063a9059cbb1461043b578063c0324c771461045d578063cc872b6614610476578063db006a751461048c578063dd62ed3e146104a2578063dd644f72146104c7578063e47d6060146104da578063e4997dc5146104f9578063e5b5019a14610518578063f2fde38b1461052b578063f3bdc2281461054a575b600080fd5b341561018a57600080fd5b610192610569565b60405160208082528190810183818151815260200191508051906020019080838360005b838110156101ce5780820151838201526020016101b6565b50505050905090810190601f1680156101fb5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561021457600080fd5b610228600160a060020a0360043516610607565b005b341561023557600080fd5b610228600160a060020a03600435166024356106aa565b341561025757600080fd5b61025f610757565b604051901515815260200160405180910390f35b341561027e57600080fd5b610228600160a060020a0360043516610767565b341561029d57600080fd5b6102a56107e7565b60405190815260200160405180910390f35b34156102c257600080fd5b610228600160a060020a036004358116906024351660443561086e565b34156102ea57600080fd5b6102f2610932565b604051600160a060020a03909116815260200160405180910390f35b341561031957600080fd5b6102a5600160a060020a0360043516610941565b341561033857600080fd5b6102a5610953565b341561034b57600080fd5b6102a5610959565b341561035e57600080fd5b6102a561095f565b341561037157600080fd5b610228610965565b341561038457600080fd5b61025f600160a060020a03600435166109e4565b34156103a357600080fd5b6102a5600160a060020a0360043581169060243516610a06565b34156103c857600080fd5b61025f610a23565b34156103db57600080fd5b6102a5600160a060020a0360043516610a33565b34156103fa57600080fd5b610228610ad3565b341561040d57600080fd5b6102f2610b57565b341561042057600080fd5b6102f2610b66565b341561043357600080fd5b610192610b75565b341561044657600080fd5b610228600160a060020a0360043516602435610be0565b341561046857600080fd5b610228600435602435610cb9565b341561048157600080fd5b610228600435610d4f565b341561049757600080fd5b610228600435610dfe565b34156104ad57600080fd5b6102a5600160a060020a0360043581169060243516610eaf565b34156104d257600080fd5b6102a5610f5a565b34156104e557600080fd5b61025f600160a060020a0360043516610f60565b341561050457600080fd5b610228600160a060020a0360043516610f75565b341561052357600080fd5b6102a5610ff2565b341561053657600080fd5b610228600160a060020a0360043516610ff8565b341561055557600080fd5b610228600160a060020a036004351661104e565b60078054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156105ff5780601f106105d4576101008083540402835291602001916105ff565b820191906000526020600020905b8154815290600101906020018083116105e257829003601f168201915b505050505081565b60005433600160a060020a0390811691161461062257600080fd5b600a805460a060020a74ff0000000000000000000000000000000000000000199091161773ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0383161790557fcc358699805e9a8b7f77b522628c7cb9abd07d9efb86b6fb616af1609036a99e81604051600160a060020a03909116815260200160405180910390a150565b604060443610156106ba57600080fd5b600a5460a060020a900460ff161561074857600a54600160a060020a031663aee92d3333858560405160e060020a63ffffffff8616028152600160a060020a0393841660048201529190921660248201526044810191909152606401600060405180830381600087803b151561072f57600080fd5b6102c65a03f1151561074057600080fd5b505050610752565b610752838361110c565b505050565b600a5460a060020a900460ff1681565b60005433600160a060020a0390811691161461078257600080fd5b600160a060020a03811660009081526006602052604090819020805460ff191660011790557f42e160154868087d6bfdc0ca23d96a1c1cfa32f1b72ba9ba27b69b98a0d819dc90829051600160a060020a03909116815260200160405180910390a150565b600a5460009060a060020a900460ff161561086657600a54600160a060020a03166318160ddd6000604051602001526040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561084457600080fd5b6102c65a03f1151561085557600080fd5b50505060405180519050905061086b565b506001545b90565b60005460a060020a900460ff161561088557600080fd5b600160a060020a03831660009081526006602052604090205460ff16156108ab57600080fd5b600a5460a060020a900460ff161561092757600a54600160a060020a0316638b477adb3385858560405160e060020a63ffffffff8716028152600160a060020a0394851660048201529284166024840152921660448201526064810191909152608401600060405180830381600087803b151561072f57600080fd5b6107528383836111be565b600a54600160a060020a031681565b60026020526000908152604090205481565b60095481565b60045481565b60015481565b60005433600160a060020a0390811691161461098057600080fd5b60005460a060020a900460ff16151561099857600080fd5b6000805474ff0000000000000000000000000000000000000000191690557f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b3360405160405180910390a1565b600160a060020a03811660009081526006602052604090205460ff165b919050565b600560209081526000928352604080842090915290825290205481565b60005460a060020a900460ff1681565b600a5460009060a060020a900460ff1615610ac357600a54600160a060020a03166370a082318360006040516020015260405160e060020a63ffffffff8416028152600160a060020a039091166004820152602401602060405180830381600087803b1515610aa157600080fd5b6102c65a03f11515610ab257600080fd5b505050604051805190509050610a01565b610acc826113bd565b9050610a01565b60005433600160a060020a03908116911614610aee57600080fd5b60005460a060020a900460ff1615610b0557600080fd5b6000805474ff0000000000000000000000000000000000000000191660a060020a1790557f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff62560405160405180910390a1565b600054600160a060020a031690565b600054600160a060020a031681565b60088054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156105ff5780601f106105d4576101008083540402835291602001916105ff565b60005460a060020a900460ff1615610bf757600080fd5b600160a060020a03331660009081526006602052604090205460ff1615610c1d57600080fd5b600a5460a060020a900460ff1615610cab57600a54600160a060020a0316636e18980a33848460405160e060020a63ffffffff8616028152600160a060020a0393841660048201529190921660248201526044810191909152606401600060405180830381600087803b1515610c9257600080fd5b6102c65a03f11515610ca357600080fd5b505050610cb5565b610cb582826113d8565b5050565b60005433600160a060020a03908116911614610cd457600080fd5b60148210610ce157600080fd5b60328110610cee57600080fd5b6003829055600954610d0a908290600a0a63ffffffff61155c16565b60048190556003547fb044a1e409eac5c48e5af22d4af52670dd1a99059537a78b31b48c6500a6354e9160405191825260208201526040908101905180910390a15050565b60005433600160a060020a03908116911614610d6a57600080fd5b60015481810111610d7a57600080fd5b60008054600160a060020a031681526002602052604090205481810111610da057600080fd5b60008054600160a060020a03168152600260205260409081902080548301905560018054830190557fcb8241adb0c3fdb35b70c24ce35c5eb0c17af7431c99f827d44a445ca624176a9082905190815260200160405180910390a150565b60005433600160a060020a03908116911614610e1957600080fd5b60015481901015610e2957600080fd5b60008054600160a060020a031681526002602052604090205481901015610e4f57600080fd5b60018054829003905560008054600160a060020a031681526002602052604090819020805483900390557f702d5967f45f6513a38ffc42d6ba9bf230bd40e8f53b16363c7eb4fd2deb9a449082905190815260200160405180910390a150565b600a5460009060a060020a900460ff1615610f4757600a54600160a060020a031663dd62ed3e848460006040516020015260405160e060020a63ffffffff8516028152600160a060020a03928316600482015291166024820152604401602060405180830381600087803b1515610f2557600080fd5b6102c65a03f11515610f3657600080fd5b505050604051805190509050610f54565b610f518383611592565b90505b92915050565b60035481565b60066020526000908152604090205460ff1681565b60005433600160a060020a03908116911614610f9057600080fd5b600160a060020a03811660009081526006602052604090819020805460ff191690557fd7e9ec6e6ecd65492dce6bf513cd6867560d49544421d0783ddf06e76c24470c90829051600160a060020a03909116815260200160405180910390a150565b60001981565b60005433600160a060020a0390811691161461101357600080fd5b600160a060020a0381161561104b576000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0383161790555b50565b6000805433600160a060020a0390811691161461106a57600080fd5b600160a060020a03821660009081526006602052604090205460ff16151561109157600080fd5b61109a82610a33565b600160a060020a038316600090815260026020526040808220919091556001805483900390559091507f61e6e66b0d6339b2980aecc6ccc0039736791f0ccde9ed512e789a7fbdd698c6908390839051600160a060020a03909216825260208201526040908101905180910390a15050565b6040604436101561111c57600080fd5b811580159061114f5750600160a060020a0333811660009081526005602090815260408083209387168352929052205415155b1561115957600080fd5b600160a060020a03338116600081815260056020908152604080832094881680845294909152908190208590557f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259085905190815260200160405180910390a3505050565b60008080606060643610156111d257600080fd5b600160a060020a0380881660009081526005602090815260408083203390941683529290522054600354909450611224906127109061121890889063ffffffff61155c16565b9063ffffffff6115bd16565b92506004548311156112365760045492505b60001984101561127857611250848663ffffffff6115d416565b600160a060020a03808916600090815260056020908152604080832033909416835292905220555b611288858463ffffffff6115d416565b600160a060020a0388166000908152600260205260409020549092506112b4908663ffffffff6115d416565b600160a060020a0380891660009081526002602052604080822093909355908816815220546112e9908363ffffffff6115e616565b600160a060020a03871660009081526002602052604081209190915583111561137f5760008054600160a060020a0316815260026020526040902054611335908463ffffffff6115e616565b60008054600160a060020a03908116825260026020526040808320939093559054811691908916906000805160206115f68339815191529086905190815260200160405180910390a35b85600160a060020a031687600160a060020a03166000805160206115f68339815191528460405190815260200160405180910390a350505050505050565b600160a060020a031660009081526002602052604090205490565b600080604060443610156113eb57600080fd5b6114066127106112186003548761155c90919063ffffffff16565b92506004548311156114185760045492505b611428848463ffffffff6115d416565b600160a060020a033316600090815260026020526040902054909250611454908563ffffffff6115d416565b600160a060020a033381166000908152600260205260408082209390935590871681522054611489908363ffffffff6115e616565b600160a060020a0386166000908152600260205260408120919091558311156115205760008054600160a060020a03168152600260205260409020546114d5908463ffffffff6115e616565b60008054600160a060020a0390811682526002602052604080832093909355905481169133909116906000805160206115f68339815191529086905190815260200160405180910390a35b84600160a060020a031633600160a060020a03166000805160206115f68339815191528460405190815260200160405180910390a35050505050565b60008083151561156f576000915061158b565b5082820282848281151561157f57fe5b041461158757fe5b8091505b5092915050565b600160a060020a03918216600090815260056020908152604080832093909416825291909152205490565b60008082848115156115cb57fe5b04949350505050565b6000828211156115e057fe5b50900390565b60008282018381101561158757fe00ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa165627a7a72305820cee6768a2085eaebe57dee9cb6531b1dc31e8c14f98b679ba6d4a726db448e460029","storage":{"0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563":"fc03585c25d2baaa99d131fa6e1961f005c38aac","0x6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af":"02","0xa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688":"4b72697368204a61790000000000000000000000000000000000000000000012","0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6":"01d1a94a2000","0xeb4a4ec1eb44e65d9c4857236416711a1601b122388a575fdd6dd6ebcb60bd8b":"01d1a94a2000","0xf3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3":"4b4a415900000000000000000000000000000000000000000000000000000008"},"key":"0x00004d3df4052b67c409d901d5748697409d6fb784c2aecede92245e56294bfd"} +{"balance":"0","nonce":19,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00004d67c8ce075b83a4c0a444e3cbf8ec5b3e444e1607c4f3bbeb9100390cc9"} +{"balance":"0","nonce":1,"root":"0x8c61a0eed3de5078c8589a634ce8a3a7a2cafe5d398245440def8f333cc0e482","codeHash":"0x37f8e32ea3879b986e8fef93d6e8bf9a2dbe2a2ffab2035960e3e8f7740429a2","code":"0x608060405234801561001057600080fd5b50600436106102325760003560e01c80635221366311610130578063ad60ffcc116100b8578063dd62ed3e1161007c578063dd62ed3e14610928578063e5406dbf14610956578063ee52a2f3146109ae578063f09d14d7146109d7578063fed4416a14610abd57610232565b8063ad60ffcc146108c1578063b6b55f25146108c9578063c68dbb37146108e6578063d44fa33e14610903578063d8270dce1461092057610232565b806370a08231116100ff57806370a0823114610833578063936553c41461085957806395d89b4114610861578063a457c2d714610869578063a9059cbb1461089557610232565b806352213663146106b557806353d9133e1461076b57806359b5e75e146107885780636f4d469b1461079057610232565b80632115c9c5116101be5780633babaad5116101825780633babaad5146105a85780633ded6530146105c757806346b607f5146105e457806346ee84b01461060a578063481c6a75146106ad57610232565b80632115c9c51461050357806323b872dd1461050b5780632e1a7d4d14610541578063313ce5671461055e578063395093511461057c57610232565b806306fdde031161020557806306fdde03146102b1578063095ea7b31461032e57806318160ddd1461036e5780631c5918d2146103765780631fa98406146104fb57610232565b8063023f21de1461023757806302d05d3f146102565780630499123f1461027a57806305a2ee2a146102a9575b600080fd5b6102546004803603602081101561024d57600080fd5b5035610ac5565b005b61025e610cd6565b604080516001600160a01b039092168252519081900360200190f35b6102976004803603602081101561029057600080fd5b5035610ce5565b60408051918252519081900360200190f35b61025e610e8b565b6102b9610e9a565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102f35781810151838201526020016102db565b50505050905090810190601f1680156103205780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61035a6004803603604081101561034457600080fd5b506001600160a01b038135169060200135610f31565b604080519115158252519081900360200190f35b610297610f4f565b61037e610f55565b6040518080602001898152602001888152602001876001600160a01b03166001600160a01b0316815260200180602001806020018681526020018515151515815260200184810384528c818151815260200191508051906020019080838360005b838110156103f75781810151838201526020016103df565b50505050905090810190601f1680156104245780820380516001836020036101000a031916815260200191505b5084810383528851815288516020918201918a019080838360005b8381101561045757818101518382015260200161043f565b50505050905090810190601f1680156104845780820380516001836020036101000a031916815260200191505b50848103825287518152875160209182019189019080838360005b838110156104b757818101518382015260200161049f565b50505050905090810190601f1680156104e45780820380516001836020036101000a031916815260200191505b509b50505050505050505050505060405180910390f35b6102b96110d2565b610254611160565b61035a6004803603606081101561052157600080fd5b506001600160a01b038135811691602081013590911690604001356111fb565b6102546004803603602081101561055757600080fd5b5035611288565b610566611511565b6040805160ff9092168252519081900360200190f35b61035a6004803603604081101561059257600080fd5b506001600160a01b03813516906020013561151a565b610254600480360360208110156105be57600080fd5b5035151561156e565b61025e600480360360208110156105dd57600080fd5b5035611633565b61035a600480360360208110156105fa57600080fd5b50356001600160a01b0316611836565b6102546004803603602081101561062057600080fd5b81019060208101813564010000000081111561063b57600080fd5b82018360208201111561064d57600080fd5b8035906020019184602083028401116401000000008311171561066f57600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092955061184b945050505050565b61025e6118f5565b610254600480360360408110156106cb57600080fd5b6001600160a01b0382351691908101906040810160208201356401000000008111156106f657600080fd5b82018360208201111561070857600080fd5b8035906020019184600183028401116401000000008311171561072a57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611904945050505050565b6102546004803603602081101561078157600080fd5b5035611a38565b61035a611a92565b610254600480360360208110156107a657600080fd5b8101906020810181356401000000008111156107c157600080fd5b8201836020820111156107d357600080fd5b803590602001918460208302840111640100000000831117156107f557600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611aa0945050505050565b6102976004803603602081101561084957600080fd5b50356001600160a01b0316611b46565b610297611b61565b6102b9611b67565b61035a6004803603604081101561087f57600080fd5b506001600160a01b038135169060200135611bc8565b61035a600480360360408110156108ab57600080fd5b506001600160a01b038135169060200135611c36565b610297611c4a565b610297600480360360208110156108df57600080fd5b5035611c99565b610297600480360360208110156108fc57600080fd5b5035611ec7565b61035a6004803603602081101561091957600080fd5b5035611ee5565b610297611f2d565b6102976004803603604081101561093e57600080fd5b506001600160a01b0381358116916020013516611f33565b61095e611f5e565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561099a578181015183820152602001610982565b505050509050019250505060405180910390f35b610254600480360360608110156109c457600080fd5b5080359060208101359060400135611fb5565b6109df61222f565b60405180806020018060200180602001848103845287818151815260200191508051906020019060200280838360005b83811015610a27578181015183820152602001610a0f565b50505050905001848103835286818151815260200191508051906020019060200280838360005b83811015610a66578181015183820152602001610a4e565b50505050905001848103825285818151815260200191508051906020019060200280838360005b83811015610aa5578181015183820152602001610a8d565b50505050905001965050505050505060405180910390f35b6102b96124d8565b6008546001600160a01b03163314610b13576040805162461bcd60e51b815260206004820152600c60248201526b37b7363c9036b0b730b3b2b960a11b604482015290519081900360640190fd5b610b1c81611ee5565b610b63576040805162461bcd60e51b8152602060048201526013602482015272185cdcd95d081b9bdd081cdd5c1c1bdc9d1959606a1b604482015290519081900360640190fd5b6000805b600e54811015610c665782600d8281548110610b7f57fe5b90600052602060002001541415610c5e57610b9983611633565b6001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015610bee57600080fd5b505afa158015610c02573d6000803e3d6000fd5b505050506040513d6020811015610c1857600080fd5b505115610c565760405162461bcd60e51b8152600401808060200182810382526021815260200180612c9c6021913960400191505060405180910390fd5b809150610c66565b600101610b67565b506001600e5403811015610cab57600d6001600e540381548110610c8657fe5b9060005260206000200154600d8281548110610c9e57fe5b6000918252602090912001555b600d6001600e540381548110610cbd57fe5b60009182526020822001555050600e8054600019019055565b6007546001600160a01b031681565b600c54604080516321f8a72160e01b81526c45786368616e6765526174657360981b600482015290516000926001600160a01b0316916321f8a721916024808301926020929190829003018186803b158015610d4057600080fd5b505afa158015610d54573d6000803e3d6000fd5b505050506040513d6020811015610d6a57600080fd5b50516001600160a01b031663654a60ac83610d8481611633565b6001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015610dd957600080fd5b505afa158015610ded573d6000803e3d6000fd5b505050506040513d6020811015610e0357600080fd5b5051604080516001600160e01b031960e086901b16815260048101939093526024830191909152631cd554d160e21b6044830152516064808301926020929190829003018186803b158015610e5757600080fd5b505afa158015610e6b573d6000803e3d6000fd5b505050506040513d6020811015610e8157600080fd5b505190505b919050565b600c546001600160a01b031681565b60038054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610f265780601f10610efb57610100808354040283529160200191610f26565b820191906000526020600020905b815481529060010190602001808311610f0957829003601f168201915b505050505090505b90565b6000610f45610f3e612533565b8484612537565b5060015b92915050565b60025490565b60606000806000606080600080610f6a610e9a565b610f72610f4f565b610f7a611c4a565b600854600b54600554600980546040805160206002610100600186161581026000190190951604601f81018290048202830182019093528282526001600160a01b03909716969395600a95909493900460ff1692909186918301828280156110235780601f10610ff857610100808354040283529160200191611023565b820191906000526020600020905b81548152906001019060200180831161100657829003601f168201915b5050865460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152959950889450925084019050828280156110b15780601f10611086576101008083540402835291602001916110b1565b820191906000526020600020905b81548152906001019060200180831161109457829003601f168201915b50505050509250975097509750975097509750975097509091929394959697565b600a805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156111585780601f1061112d57610100808354040283529160200191611158565b820191906000526020600020905b81548152906001019060200180831161113b57829003601f168201915b505050505081565b6008546001600160a01b031633146111ae576040805162461bcd60e51b815260206004820152600c60248201526b37b7363c9036b0b730b3b2b960a11b604482015290519081900360640190fd5b6111b6610f4f565b156111f8576040805162461bcd60e51b815260206004820152600d60248201526c6d75737420626520656d70747960981b604482015290519081900360640190fd5b33ff5b6000611208848484612623565b61127e84611214612533565b61127985604051806060016040528060288152602001612d48602891396001600160a01b038a16600090815260016020526040812090611252612533565b6001600160a01b03168152602081019190915260400160002054919063ffffffff61277f16565b612537565b5060019392505050565b8061129233611b46565b10156112cf5760405162461bcd60e51b8152600401808060200182810382526023815260200180612dff6023913960400191505060405180910390fd5b60006112d9611c4a565b9050600061130c6112e8610f4f565b61130085670de0b6b3a764000063ffffffff61281616565b9063ffffffff61286f16565b905061131833846128b1565b60005b600e5481101561146e576000611347600d838154811061133757fe5b9060005260206000200154611633565b604080516370a0823160e01b815230600482015290519192506000916001600160a01b038416916370a08231916024808301926020929190829003018186803b15801561139357600080fd5b505afa1580156113a7573d6000803e3d6000fd5b505050506040513d60208110156113bd57600080fd5b5051905060006113df670de0b6b3a7640000611300848863ffffffff61281616565b90508015611463576040805163a9059cbb60e01b81523360048201526024810183905290516001600160a01b0385169163a9059cbb9160448083019260209291908290030181600087803b15801561143657600080fd5b505af115801561144a573d6000803e3d6000fd5b505050506040513d602081101561146057600080fd5b50505b50505060010161131b565b506000611481828463ffffffff61281616565b90507f79d44cc8beeed36226f14818b2ecaca7ef252bcd56c9ae35f5a86869dbdefb97303383876114b133611b46565b6114b9611c4a565b6114c1610f4f565b604080516001600160a01b039889168152969097166020870152858701949094526060850192909252608084015260a083015260c08201524260e08201529051908190036101000190a150505050565b60055460ff1690565b6000610f45611527612533565b846112798560016000611538612533565b6001600160a01b03908116825260208083019390935260409182016000908120918c16815292529020549063ffffffff6129ad16565b6008546001600160a01b031633146115bc576040805162461bcd60e51b815260206004820152600c60248201526b37b7363c9036b0b730b3b2b960a11b604482015290519081900360640190fd5b60055460ff6101009091041615158115151415611619576040805162461bcd60e51b8152602060048201526016602482015275199b1859c81b5d5cdd08189948191a5999995c995b9d60521b604482015290519081900360640190fd5b600580549115156101000261ff0019909216919091179055565b600c54604080516321f8a72160e01b8152680a6f2dce8d0cae8d2f60bb1b6004820152905160009283926001600160a01b03909116916321f8a72191602480820192602092909190829003018186803b15801561168f57600080fd5b505afa1580156116a3573d6000803e3d6000fd5b505050506040513d60208110156116b957600080fd5b505160408051633260803960e01b81526004810186905290516001600160a01b0390921691633260803991602480820192602092909190829003018186803b15801561170457600080fd5b505afa158015611718573d6000803e3d6000fd5b505050506040513d602081101561172e57600080fd5b505190506001600160a01b03811661177b576040805162461bcd60e51b815260206004820152600b60248201526a696e76616c6964206b657960a81b604482015290519081900360640190fd5b6000816001600160a01b031663ec5568896040518163ffffffff1660e01b815260040160206040518083038186803b1580156117b657600080fd5b505afa1580156117ca573d6000803e3d6000fd5b505050506040513d60208110156117e057600080fd5b505190506001600160a01b03811661182f576040805162461bcd60e51b815260206004820152600d60248201526c696e76616c69642070726f787960981b604482015290519081900360640190fd5b9392505050565b60066020526000908152604090205460ff1681565b6008546001600160a01b03163314611899576040805162461bcd60e51b815260206004820152600c60248201526b37b7363c9036b0b730b3b2b960a11b604482015290519081900360640190fd5b60005b81518110156118f1576000600660008484815181106118b757fe5b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff191691151591909117905560010161189c565b5050565b6008546001600160a01b031681565b6008546001600160a01b03163314611952576040805162461bcd60e51b815260206004820152600c60248201526b37b7363c9036b0b730b3b2b960a11b604482015290519081900360640190fd5b600880546001600160a01b0319166001600160a01b0384161790558051611980906009906020840190612be0565b507f6ed15082ad038474841528b5badca105106d4463e44b5d434130dfb299aa3669828260405180836001600160a01b03166001600160a01b0316815260200180602001828103825283818151815260200191508051906020019080838360005b838110156119f95781810151838201526020016119e1565b50505050905090810190601f168015611a265780820380516001836020036101000a031916815260200191505b50935050505060405180910390a15050565b6008546001600160a01b03163314611a86576040805162461bcd60e51b815260206004820152600c60248201526b37b7363c9036b0b730b3b2b960a11b604482015290519081900360640190fd5b611a8f81612a07565b50565b600554610100900460ff1681565b6008546001600160a01b03163314611aee576040805162461bcd60e51b815260206004820152600c60248201526b37b7363c9036b0b730b3b2b960a11b604482015290519081900360640190fd5b60005b81518110156118f157600160066000848481518110611b0c57fe5b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff1916911515919091179055600101611af1565b6001600160a01b031660009081526020819052604090205490565b600e5481565b60048054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610f265780601f10610efb57610100808354040283529160200191610f26565b6000610f45611bd5612533565b8461127985604051806060016040528060258152602001612dda6025913960016000611bff612533565b6001600160a01b03908116825260208083019390935260409182016000908120918d1681529252902054919063ffffffff61277f16565b6000610f45611c43612533565b8484612623565b600080805b600e54811015611c9357611c89611c7c600d8381548110611c6c57fe5b9060005260206000200154610ce5565b839063ffffffff6129ad16565b9150600101611c4f565b50905090565b6008546000906001600160a01b0316331480611cbd5750600554610100900460ff16155b80611cd757503360009081526006602052604090205460ff165b611d1f576040805162461bcd60e51b81526020600482015260146024820152731bdb9b1e481b595b58995c9cc8185b1b1bddd95960621b604482015290519081900360640190fd5b6000611d29611c4a565b90506000611d35610f4f565b9050611d47631cd554d160e21b611633565b604080516323b872dd60e01b81523360048201523060248201526044810187905290516001600160a01b0392909216916323b872dd916064808201926020929091908290030181600087803b158015611d9f57600080fd5b505af1158015611db3573d6000803e3d6000fd5b505050506040513d6020811015611dc957600080fd5b5051611e14576040805162461bcd60e51b81526020600482015260156024820152741d1bdad95b881d1c985b9cd9995c8819985a5b1959605a1b604482015290519081900360640190fd5b60008115611e3757611e3083611300878563ffffffff61281616565b9050611e3a565b50835b611e443382612a49565b7f87fdcba84e083ebb8fd661bbafee3eb38764ec6f0cbeea8ed52deffa67bd45dc30338784611e7233611b46565b604080516001600160a01b039687168152949095166020850152838501929092526060830152608082015285880160a082015284840160c08201524260e08201529051908190036101000190a1949350505050565b600d8181548110611ed457fe5b600091825260209091200154905081565b6000805b600e54811015611f245782600d8281548110611f0157fe5b90600052602060002001541415611f1c576001915050610e86565b600101611ee9565b50600092915050565b600b5481565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6060600d805480602002602001604051908101604052809291908181526020018280548015610f2657602002820191906000526020600020905b815481526020019060010190808311611f98575050505050905090565b6008546001600160a01b03163314612003576040805162461bcd60e51b815260206004820152600c60248201526b37b7363c9036b0b730b3b2b960a11b604482015290519081900360640190fd5b61200c83611ee5565b61205d576040805162461bcd60e51b815260206004820152601b60248201527f756e737570706f7274656420736f757263652063757272656e63790000000000604482015290519081900360640190fd5b61206681611ee5565b6120b7576040805162461bcd60e51b815260206004820181905260248201527f756e737570706f727465642064657374696e6174696f6e2063757272656e6379604482015290519081900360640190fd5b600c54604080516321f8a72160e01b8152680a6f2dce8d0cae8d2f60bb1b600482015290516000926001600160a01b0316916321f8a721916024808301926020929190829003018186803b15801561210e57600080fd5b505afa158015612122573d6000803e3d6000fd5b505050506040513d602081101561213857600080fd5b50516040805163ee52a2f360e01b815260048101879052602481018690526044810185905290516001600160a01b039092169163ee52a2f3916064808201926020929091908290030181600087803b15801561219357600080fd5b505af11580156121a7573d6000803e3d6000fd5b505050506040513d60208110156121bd57600080fd5b5051600854604080513081526001600160a01b039092166020830152818101879052606082018690526080820185905260a082018390524260c0830152519192507f2f3156bec1dba8438caa2579a04e750d9ca242f1c16d87594c77efdbede59bbe919081900360e00190a150505050565b606080606080600e54604051908082528060200260200182016040528015612261578160200160208202803883390190505b5090506060600e54604051908082528060200260200182016040528015612292578160200160208202803883390190505b5090506060600e546040519080825280602002602001820160405280156122c3578160200160208202803883390190505b50600c54604080516321f8a72160e01b81526c45786368616e6765526174657360981b600482015290519293506000926001600160a01b03909216916321f8a72191602480820192602092909190829003018186803b15801561232557600080fd5b505afa158015612339573d6000803e3d6000fd5b505050506040513d602081101561234f57600080fd5b5051905060005b600e548110156124cb576000600d828154811061236f57fe5b9060005260206000200154905061238581611633565b6001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156123da57600080fd5b505afa1580156123ee573d6000803e3d6000fd5b505050506040513d602081101561240457600080fd5b5051855186908490811061241457fe5b6020026020010181815250508086838151811061242d57fe5b602002602001018181525050826001600160a01b031663ac82f608826040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561247d57600080fd5b505afa158015612491573d6000803e3d6000fd5b505050506040513d60208110156124a757600080fd5b505184518590849081106124b757fe5b602090810291909101015250600101612356565b5092969195509350915050565b6009805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156111585780601f1061112d57610100808354040283529160200191611158565b3390565b6001600160a01b03831661257c5760405162461bcd60e51b8152600401808060200182810382526024815260200180612db66024913960400191505060405180910390fd5b6001600160a01b0382166125c15760405162461bcd60e51b8152600401808060200182810382526022815260200180612cdf6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b0383166126685760405162461bcd60e51b8152600401808060200182810382526025815260200180612d916025913960400191505060405180910390fd5b6001600160a01b0382166126ad5760405162461bcd60e51b8152600401808060200182810382526023815260200180612c796023913960400191505060405180910390fd5b6126f081604051806060016040528060268152602001612d01602691396001600160a01b038616600090815260208190526040902054919063ffffffff61277f16565b6001600160a01b038085166000908152602081905260408082209390935590841681522054612725908263ffffffff6129ad16565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b6000818484111561280e5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156127d35781810151838201526020016127bb565b50505050905090810190601f1680156128005780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60008261282557506000610f49565b8282028284828161283257fe5b041461182f5760405162461bcd60e51b8152600401808060200182810382526021815260200180612d276021913960400191505060405180910390fd5b600061182f83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612b39565b6001600160a01b0382166128f65760405162461bcd60e51b8152600401808060200182810382526021815260200180612d706021913960400191505060405180910390fd5b61293981604051806060016040528060228152602001612cbd602291396001600160a01b038516600090815260208190526040902054919063ffffffff61277f16565b6001600160a01b038316600090815260208190526040902055600254612965908263ffffffff612b9e16565b6002556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b60008282018381101561182f576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600d8054600181810183556000929092527fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb50191909155600e80549091019055565b6001600160a01b038216612aa4576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b600254612ab7908263ffffffff6129ad16565b6002556001600160a01b038216600090815260208190526040902054612ae3908263ffffffff6129ad16565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b60008183612b885760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156127d35781810151838201526020016127bb565b506000838581612b9457fe5b0495945050505050565b600061182f83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061277f565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10612c2157805160ff1916838001178555612c4e565b82800160010185558215612c4e579182015b82811115612c4e578251825591602001919060010190612c33565b50612c5a929150612c5e565b5090565b610f2e91905b80821115612c5a5760008155600101612c6456fe45524332303a207472616e7366657220746f20746865207a65726f20616464726573736e6f6e2d656d7074792061737365742063616e6e6f742062652072656d6f76656445524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e6365536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7745524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726f696e73756666696369656e742062616c616e6365206f662066756e6420746f6b656e73a265627a7a723158208d2ccfc27fe2091fe72e4a4b8d1767174afcfc08a3709e9c1c705852d22e570764736f6c63430005110032","storage":{"0x0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9":"5f188f32","0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0":"0112","0x3819a2a3d807bf2d1c3dbcaf7dcbd6520dcf27eac31dabd804865b66b4cbe7e8":"7358525000000000000000000000000000000000000000000000000000000000","0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace":"0bf2c7da894d8600c2","0x41faab445fe72d12e121ca7567969321cb1961126885af5ac2372f208ce0eeec":"7344454649000000000000000000000000000000000000000000000000000000","0x53d6526ba25135ee9b7818af08de00c5de7689560a774381dbc83fd3237178c8":"734c544300000000000000000000000000000000000000000000000000000000","0x5cfb45a54af5054a79d6e3e06b95e51e6827e1c2eb707f378c7b289bca6900e2":"7355534400000000000000000000000000000000000000000000000000000000","0x613633635594b01395024d35958787d0af086208b30f21b3f0f1c78c2f5fcf9e":"6942544300000000000000000000000000000000000000000000000000000000","0x6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af":"706f6f7073746572000000000000000000000000000000000000000000000010","0x7f74e20ecdcd2f748620b10ae92a0aea6211766173d58a0cd4fcf4b1c94b3454":"734c494e4b000000000000000000000000000000000000000000000000000000","0x87466a1ae97409dd9d9cd9368751b439509d8b3f8fc2bb47a4264e5d6fd4d324":"6945544800000000000000000000000000000000000000000000000000000000","0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b":"4448460000000000000000000000000000000000000000000000000000000006","0x93cf6b199a1626bd2fa8fb1ae340b5d4b12e6d06019ad4593eda7768ac924eb7":"73424e4200000000000000000000000000000000000000000000000000000000","0xa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688":"ba7f81cc0dbae9fd5d56afc65cfd668536cac50d","0xad9e8eb447b06a29f484d6289d0ef5b801ccac675f2902e9e8acced18c7ab377":"0bf2c7da894d8600c2","0xaf2c61b129d942dabc1f4485bf6d0d72c1b1fc04813c211ef96a7351dd6b6f91":"7345544800000000000000000000000000000000000000000000000000000000","0xb9a4a546c6bdca52fed24c8e5e1ce03b3bedc826c28110195681e2094e3b7f4f":"7342544300000000000000000000000000000000000000000000000000000000","0xbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd":"0a","0xc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b":"506f6f70737465727320746f696c657420626f776c000000000000000000002a","0xc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a8":"416374697665000000000000000000000000000000000000000000000000000c","0xd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb5":"0a","0xdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7":"4da3b8fb742bc69531ec7adbaa06effded1a22ba","0xf3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3":"a5a69107816c5e3dfa5561e6b621dfe6294f6e5b"},"key":"0x00004df65431811e8b76d0ef8a4cde8720418942db0b6e8e9ee643907fb54de0"} +{"balance":"0","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xd80cd839dd3957d572b90780ada202a13936fa2875daea94216263371e9ef1d2","code":"0x6eb3f879cb30fe243b4dfee438691c043318585733ff","key":"0x00004e1113975a9052fea2bb518d2c16d64b18576e1ba33c6e261b3922c9d026"} +{"balance":"978999999853001","nonce":1,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00004e28b7408f90e359db039bc1f99c67eb725f57e8d503a19912c4f49574b7"} +{"balance":"0","nonce":1,"root":"0xc36a9db8f197437cb1389512c9b189adc5a3aa2d17d7ef687c5037b5e1e77a86","codeHash":"0x0a4f8af5baab816861c34fd8ef5986ea210d3ac7c74e3921da20ac40c13b2e25","code":"0x608060405234801561001057600080fd5b50600436106100935760003560e01c8063313ce56711610066578063313ce5671461022157806370a082311461024257806395d89b411461029a578063a9059cbb1461031d578063dd62ed3e1461038157610093565b806306fdde0314610098578063095ea7b31461011b57806318160ddd1461017f57806323b872dd1461019d575b600080fd5b6100a06103f9565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100e05780820151818401526020810190506100c5565b50505050905090810190601f16801561010d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101676004803603604081101561013157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610432565b60405180821515815260200191505060405180910390f35b610187610524565b6040518082815260200191505060405180910390f35b610209600480360360608110156101b357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061052e565b60405180821515815260200191505060405180910390f35b610229610941565b604051808260ff16815260200191505060405180910390f35b6102846004803603602081101561025857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610946565b6040518082815260200191505060405180910390f35b6102a261098e565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156102e25780820151818401526020810190506102c7565b50505050905090810190601f16801561030f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103696004803603604081101561033357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506109c7565b60405180821515815260200191505060405180910390f35b6103e36004803603604081101561039757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610bf5565b6040518082815260200191505060405180910390f35b6040518060400160405280600881526020017f484b55546f6b656e00000000000000000000000000000000000000000000000081525081565b600081600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b6000600254905090565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548211156105c7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180610cb06022913960400191505060405180910390fd5b600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482111561069c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526033815260200180610cd26033913960400191505060405180910390fd5b6106ed826000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610c7c90919063ffffffff16565b6000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506107be82600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610c7c90919063ffffffff16565b600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061088f826000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610c9390919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b600081565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6040518060400160405280600481526020017f484b55540000000000000000000000000000000000000000000000000000000081525081565b60008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054821115610a60576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180610cb06022913960400191505060405180910390fd5b610ab1826000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610c7c90919063ffffffff16565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610b44826000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610c9390919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a36001905092915050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600082821115610c8857fe5b818303905092915050565b600080828401905083811015610ca557fe5b809150509291505056fe53656e64657220646f6573206e6f74206861766520656e6f75676820746f6b656e7353656e646572206973206e6f7420617070726f76656420746f20636f6d706c6574652074686973207472616e73616374696f6ea26469706673582212200693535226ebb39fa49877f925a10ac3d0816e1daa657648e065c3f57249a46f64736f6c634300060c0033","storage":{"0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace":"0186a0","0x92f0673a13e84bdb227b350ccb1dbc0dcea524c1009f8374c68875430f3fea87":"0186a0"},"key":"0x00004e732dce1ba7760122d24aeddd44776673a2143ab8efb3857cd04cad84b3"} +{"balance":"65536","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00004ef5832c909f4d7e624bbf6c9002140a097a11409cc6e619295cccaac283"} +{"balance":"968500237846001","nonce":3,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","key":"0x00004f270c76b858fb3223027ed3960e5632b50a9115c7d82d70b1562e63852f"} +{"balance":"3","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","address":"0x00000000000000000000000000000000000000df","key":"0x005e54f1867fd030f90673b8b625ac8f0656e44a88cfc0b3af3e3f3c3d486960"} +{"balance":"2000010000000701","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","address":"0x0000000000000000000000000000000000000088","key":"0x021fe3360ba8c02e194f8e7facdeb9088b3cf433b6498bd6900d50df0266ffe3"} +{"balance":"1","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","address":"0x000000000000000000000000000000000000008e","key":"0x028e62cb4665fce19ae1fc13a604618d7d20be037fc68b63beb3384dfa5ab776"} +{"balance":"10000000557","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","address":"0x0000000000000000000000000000000000000068","key":"0x02cb51767354e1fe6bd4a49b64b3721ffddbc95fed1b8ead005c39bbc07bc4d8"} \ No newline at end of file diff --git a/test-validator/src/lib.rs b/test-validator/src/lib.rs index 5985d9567b..f095cd3ec3 100644 --- a/test-validator/src/lib.rs +++ b/test-validator/src/lib.rs @@ -50,6 +50,7 @@ use { }, }; use evm_state::Storage; +use solana_ledger::blockstore::EvmStateJson; #[derive(Clone)] pub struct AccountInfo<'a> { pub address: Pubkey, @@ -553,7 +554,7 @@ impl TestValidator { let _ = create_new_ledger( ledger_path, - None, + EvmStateJson::None, &genesis_config, config .max_genesis_archive_unpacked_size From 247f6d2ae4c4f616c06a64bb372571b1887497ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dj8yf0=CE=BCl?= Date: Tue, 25 Apr 2023 21:16:17 +0300 Subject: [PATCH 03/11] chore(merge): make compile at merge with `dump geth` --- evm-utils/evm-state/src/storage/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/evm-utils/evm-state/src/storage/mod.rs b/evm-utils/evm-state/src/storage/mod.rs index b44a80f723..94ff866604 100644 --- a/evm-utils/evm-state/src/storage/mod.rs +++ b/evm-utils/evm-state/src/storage/mod.rs @@ -461,7 +461,7 @@ impl Storage { { let mut account: Account = accounts .get(address.as_bytes()) - .and_then(|accounts| rlp::decode(&accounts).ok()) + .and_then(|accounts| triedb::rlp::decode(&accounts).ok()) .unwrap_or_default(); account.nonce = nonce; @@ -490,7 +490,7 @@ impl Storage { .apply_increase(storage_patch, |_| vec![]) .leak_root() } - accounts.insert(address.as_bytes(), &rlp::encode(&account)); + accounts.insert(address.as_bytes(), &triedb::rlp::encode(&account)); } else { accounts.delete(address.as_bytes()); } From 0d6d00d53232fbea5cc4e01f974e6f986bb4e3c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dj8yf0=CE=BCl?= Date: Wed, 26 Apr 2023 00:43:04 +0300 Subject: [PATCH 04/11] feat(evm-utils/evm-state): connect to fast_rlp feature of triedb, part 2 --- Cargo.lock | 1 + .../evm-state/src/rlp_roundtrip_tests.rs | 42 +++++- evm-utils/evm-state/src/transactions.rs | 127 +++++++++++++++--- storage-proto/Cargo.toml | 1 + storage-proto/src/convert.rs | 6 +- 5 files changed, 158 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index de8cf9e099..8228ade320 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7707,6 +7707,7 @@ dependencies = [ "solana-sdk", "solana-transaction-status", "tonic-build 0.8.4", + "triedb", ] [[package]] diff --git a/evm-utils/evm-state/src/rlp_roundtrip_tests.rs b/evm-utils/evm-state/src/rlp_roundtrip_tests.rs index c28cba2dc7..1d4ab62b99 100644 --- a/evm-utils/evm-state/src/rlp_roundtrip_tests.rs +++ b/evm-utils/evm-state/src/rlp_roundtrip_tests.rs @@ -1,4 +1,4 @@ -use crate::transaction_roots::EthereumReceipt; +use crate::{transaction_roots::EthereumReceipt, TransactionAction, UnsignedTransaction}; use super::types::Account; @@ -137,4 +137,44 @@ fn test_check_ethereum_receipt_roundtrip() { }; check_roundtrip!(receipt => EthereumReceipt); +} + +#[test] +fn test_check_tranaaction_action_roundtrip() { + let ta1 = TransactionAction::Create; + + + check_roundtrip!(ta1 => TransactionAction); + + let ta2 = TransactionAction::Call(H160([56; 20])); + + check_roundtrip!(ta2 => TransactionAction); + +} +#[test] +fn test_check_unsigned_transaction_roundtrip() { + let ta2 = TransactionAction::Call(H160([56; 20])); + + let ut2 = UnsignedTransaction { + nonce: U256([46;4]), + gas_price: U256([543; 4]), + gas_limit: U256([342;4]), + action: ta2, + value: U256([20000; 4]), + input: vec![34, 45, 12, 123, 243], + }; + + check_roundtrip!(ut2 => UnsignedTransaction); + let ta1 = TransactionAction::Create; + + let ut1 = UnsignedTransaction { + nonce: U256([46;4]), + gas_price: U256([543; 4]), + gas_limit: U256([342;4]), + action: ta1, + value: U256([23000;4]), + input: vec![34, 45, 12, 123, 243], + }; + check_roundtrip!(ut1 => UnsignedTransaction); + } \ No newline at end of file diff --git a/evm-utils/evm-state/src/transactions.rs b/evm-utils/evm-state/src/transactions.rs index 0e22a307d7..ae8f4aada6 100644 --- a/evm-utils/evm-state/src/transactions.rs +++ b/evm-utils/evm-state/src/transactions.rs @@ -1,5 +1,5 @@ use borsh::{BorshDeserialize, BorshSchema, BorshSerialize}; -use bytes::BufMut; +use bytes::{BufMut, Buf}; use evm::{backend::Log, ExitReason, ExitRevert}; use primitive_types::{H160, H256, U256}; use rlp::{Decodable as DecodableOld, DecoderError, Encodable as EncodableOld, Rlp, RlpStream}; @@ -129,6 +129,8 @@ impl Transaction { Serialize, Deserialize, )] + + pub struct UnsignedTransaction { pub nonce: U256, pub gas_price: U256, @@ -139,8 +141,7 @@ pub struct UnsignedTransaction { } impl UnsignedTransaction { - #[cfg(test)] - fn signing_rlp_append_old(&self, s: &mut RlpStream, chain_id: Option) { + fn signing_rlp_append(&self, s: &mut RlpStream, chain_id: Option) { s.begin_list(if chain_id.is_some() { 9 } else { 6 }); s.append(&self.nonce); s.append(&self.gas_price); @@ -155,21 +156,14 @@ impl UnsignedTransaction { s.append(&0u8); } } - fn signing_rlp_append(&self, chain_id: Option) { - unimplemented!(); - } - #[cfg(test)] - pub fn signing_hash_old(&self, chain_id: Option) -> H256 { + + pub fn signing_hash(&self, chain_id: Option) -> H256 { let mut stream = RlpStream::new(); - self.signing_rlp_append_old(&mut stream, chain_id); + self.signing_rlp_append(&mut stream, chain_id); H256::from_slice(Keccak256::digest(stream.as_raw()).as_slice()) } - pub fn signing_hash(&self, chain_id: Option) -> H256 { - unimplemented!(); - } - pub fn sign(self, key: &SecretKey, chain_id: Option) -> Transaction { let hash = self.signing_hash(chain_id); // hash is always MESSAGE_SIZE bytes. @@ -333,6 +327,47 @@ impl DecodableOld for TransactionAction { }) } } +impl Encodable for TransactionAction { + + fn encode(&self,out: &mut dyn BufMut) { + match self { + TransactionAction::Create => { + let empty : &[u8] = &[]; + empty.encode(out); + }, + TransactionAction::Call(address) => { + address.encode(out); + }, + } + } + fn length(&self) -> usize { + match self { + TransactionAction::Create => { + let empty : &[u8] = &[]; + empty.length() + }, + TransactionAction::Call(address) => { + address.length() + }, + } + + } +} + +impl<'de> Decodable<'de> for TransactionAction { + fn decode(buf: &mut &'de [u8]) -> Result { + let mut buf_view = *buf; + let h = fastrlp::Header::decode(&mut buf_view)?; + dbg!("header : {:?}", &h); + if h.payload_length == 0 { + let _h = fastrlp::Header::decode(buf)?; + return Ok(Self::Create); + } + let address : H160 = ::decode(buf)?; + Ok(TransactionAction::Call(address)) + + } +} impl EncodableOld for Transaction { fn rlp_append(&self, s: &mut RlpStream) { @@ -367,6 +402,7 @@ impl DecodableOld for Transaction { } } +#[cfg(test)] impl EncodableOld for UnsignedTransaction { fn rlp_append(&self, s: &mut RlpStream) { s.begin_list(6); @@ -379,6 +415,8 @@ impl EncodableOld for UnsignedTransaction { } } + +#[cfg(test)] impl DecodableOld for UnsignedTransaction { fn decode(rlp: &Rlp<'_>) -> Result { Ok(Self { @@ -392,6 +430,65 @@ impl DecodableOld for UnsignedTransaction { } } +impl Encodable for UnsignedTransaction { + fn encode(&self,out: &mut dyn BufMut) { + + let len = self.nonce.length() + self.gas_price.length() + + self.gas_limit.length() + self.action.length() + self.value.length() + self.input.length(); + fastrlp::Header { + list: true, + payload_length: len, + }.encode(out); + self.nonce.encode(out); + self.gas_price.encode(out); + self.gas_limit.encode(out); + self.action.encode(out); + self.value.encode(out); + self.input.encode(out); + } + + fn length(&self) -> usize { + + let len = self.nonce.length() + self.gas_price.length() + + self.gas_limit.length() + self.action.length() + self.value.length() + self.input.length(); + fastrlp::Header { + list: true, + payload_length: len, + } + .length() + + len + + } +} + + +impl<'de> Decodable<'de> for UnsignedTransaction { + fn decode(buf: &mut &'de [u8]) -> Result { + let h = fastrlp::Header::decode(buf)?; + if !h.list { + return Err(fastrlp::DecodeError::UnexpectedString); + } + let payload_view = &mut &buf[..h.payload_length]; + let cnt = fastrlp::count(*payload_view)?; + if cnt!= 6 { + return Err(fastrlp::DecodeError::ListLengthMismatch { expected: 6, got: cnt }); + } + + let nonce = fastrlp::Decodable::decode(payload_view)?; + let gas_price = fastrlp::Decodable::decode(payload_view)?; + let gas_limit = fastrlp::Decodable::decode(payload_view)?; + let action = fastrlp::Decodable::decode(payload_view)?; + let value = fastrlp::Decodable::decode(payload_view)?; + let input: &[u8] = fastrlp::Decodable::decode(payload_view)?; + buf.advance(h.payload_length); + Ok(Self { + nonce, gas_price, gas_limit, action, value, input: input.to_vec(), + }) + } +} + + + impl From for UnsignedTransaction { fn from(val: Transaction) -> UnsignedTransaction { UnsignedTransaction { @@ -673,9 +770,9 @@ mod test { let chain_id = 0x77; let mut stream = RlpStream::new(); - tx.signing_rlp_append_old(&mut stream, Some(chain_id)); + tx.signing_rlp_append(&mut stream, Some(chain_id)); println!("rlp = {}", hex::encode(stream.out())); - println!("hash = {:x}", tx.signing_hash_old(Some(chain_id))); + println!("hash = {:x}", tx.signing_hash(Some(chain_id))); let tx = tx.sign(&secret_key, Some(chain_id)); assert_eq!(tx.signature.chain_id(), Some(chain_id)); diff --git a/storage-proto/Cargo.toml b/storage-proto/Cargo.toml index 9dd5f933ab..affae16421 100644 --- a/storage-proto/Cargo.toml +++ b/storage-proto/Cargo.toml @@ -19,6 +19,7 @@ solana-sdk = { path = "../sdk", version = "=1.9.29" } solana-transaction-status = { path = "../transaction-status", version = "=1.9.29" } rlp = "0.5.0" +triedb = { git = "https://github.com/velas/triedb", tag = "fast_rlp", features = ["rocksdb"] } evm-state = { path = "../evm-utils/evm-state" } [dev-dependencies] enum-iterator = "0.7.0" diff --git a/storage-proto/src/convert.rs b/storage-proto/src/convert.rs index 36640f9eaf..0f0c8b1d4b 100644 --- a/storage-proto/src/convert.rs +++ b/storage-proto/src/convert.rs @@ -1115,9 +1115,9 @@ impl From for generated_evm::UnsignedTransactionWithCaller { fn from(unsigned: evm_state::UnsignedTransactionWithCaller) -> Self { - let bytes = rlp::encode(&unsigned.unsigned_tx); + let bytes = triedb::rlp::encode(&unsigned.unsigned_tx); Self { - rlp_encoded_body: bytes.to_vec(), + rlp_encoded_body: bytes, chain_id: unsigned.chain_id, caller: unsigned.caller.into_vec(), signed_compatible: unsigned.signed_compatible, @@ -1136,7 +1136,7 @@ impl TryFrom chain_id: unsigned.chain_id, signed_compatible: unsigned.signed_compatible, caller: convert_from_bytes(unsigned.caller)?, - unsigned_tx: rlp::decode(&unsigned.rlp_encoded_body) + unsigned_tx: triedb::rlp::decode(&unsigned.rlp_encoded_body) .map_err(|_| "Failed to deserialize rlp tx body")?, }) } From 374ca28b4f696b9119a04108122ad29938e1ea25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dj8yf0=CE=BCl?= <26653921+dj8yfo@users.noreply.github.com> Date: Wed, 26 Apr 2023 08:45:06 +0300 Subject: [PATCH 05/11] [ur] feat(velas-validator): integrate evm state rpc into validator (#439) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * state replication implementation * use any address for a server * update link to a triedb dep * update service with a new triedb implementation * Use previous triedb version for interface * use async db interface * update reply for a changeset route * update a link to the triedb dep * one more build fix * update path to an archive * update api, change names * update replica server * chore(triedb): update triedb repo link * feat(replica-node): state-diff work * chore(all): partially fix/ignore clippy on 1.63 * feat(replica-node): state-diff client/server * feat(replica-node): continue light archive node work * feat(replica-lib,replica-node): add secondary storage variant * chore(replica-lib): reivew module structure fixes * chore(replica-node): module structure review comments * feat(replica-lib,replica-node): master blocknum range routine * feat(replica-lib,replica-node): bootstrap state with SpliceCountStack * feat(replica-node): client skip height if already present * feat(replica-node): errors on tree consistency broken {child nodes unexpectedly not found} * feat(evm-state): expose api for secondary mode try_catch_up_with_primary * feat(replica-lib): add background task for syncing secondary with primary * feat(replica-node): skip bootstrap height, if already present * chore(replica-lib, replica-node):: replace anyhow with thiserror * chore(replica-lib): split into finer modules * chore(replica-lib): state diff request check hashes server-side; better error-handling * chore(replica-lib): increase threshold on state bootstrap make client issue requests close to the threshold instead of 1/20 of threshold; * chore(replica-lib): add debug print on duration of EvmHeightIndex fetches * chore(replica-node): cut away poc implementation details Cut away details, all of which are sure to be changed in next iteration * [ur] feat(evm-utils/evm-height-rangemap): evm-height-rangemap tool (#431) * feat(evm-utils/evm-height-rangemap): evm-height-rangemap tool 1. send heights via channel 2. fetch height from cache or wait until fetched indefinetely (Option) 3. timeout in LedgerStorage 4. correct Err handling (panic in worker when giving up on error to fetch a new height, channel closed, panic in worker sending heights to channel) 5. BlockNotFound(..) results in None : Option 6. addded backon for retries with exponential backoff 7. split ranges into subranges for multiple LedgerStorage workers 8. add checking of nodes presence in rocksdb 9. add persisting of results to range_map.json of destination * chore(evm-block-recovery): add explicit error message * chore(evm-block-recovery): use single connection for bigtable_fetcha clone single connection for workers instead of using multiple distinct connections * chore(evm-state::storage): create two_modes enum * chore(evm-block-recovery): routines::scan_evm_state_roots review fixes 2 * feat(replica-node): reimplement RangeJSON 1. allow for optional finer range storing for detailed view of a client's progress, a rangemap 2. reintroduce Mutex, as it's gonna be used concurrently on server anyway, and very likely, on client too 3. add custom logic of computing next chunk of work 3.1. all heights outside of covered `coarse` range, reachable by `JUMP_OVER_ABYSS_GAP`from `KICKSTART_POINT` param 3.2 add tests 4. compute the right `JUMP_OVER_ABYSS_GAP` constant from old_formatted.json 4.1. remove server threshold param * feat(replica-node): client sync algorithm shell: outline, `prefetch_height` call - [x] outline - [x] bootstarp client with multiple connections, as `tonic::client::Grpc::unary` takes `&mut self` receiver - [x] query `SERVER_RANGE` - [x] bootstrap logic - [x] if own range empty, bootstrap to first height available in range - [x] remove boostrap_height client cli param - [x] `SERVER_RANGE` check server range - [x] if own range not empty, compute diff range from self range.start as `KICKSTART_POINT` - [x] process if not empty , break `SERVER_RANGE` - [x] compute diff range from self range.end as `KICKSTART_POINT` - [x] process if not empty , break `SERVER_RANGE` - [x] if both are empty, sleep before next iteration - [x] add retryables submodule - [x] add retried wrapper around get_evm_confirmed_state_root - [x] implement new `prefetch_height` - [x] place `prefetch_height` logic stub in overall algorithm shell; if kickstart point is not found on server, sleep before next iteration - [x] or panic!, if wrong chain - [x] `prefetch_height_retried` - [x] classify error cases, which should be thrown through - [x] add prefetch_height to boostrap as well: no point bootstrapping the wrong chain * feat(replica-node): client sync algorithm shell ; add `prefetch_range` call to `EvmHeightIndex` - [x] add `prefetch_range` call to `EvmHeightIndex` - [x] add method to trait - [x] noop implementation for `LedgerStorage` - [x] add `prefetch_range_retried` default impl to `EvmHeightIndex` * feat(replica-node): create `LedgerStorageCached` as an implementation of `EvmHeightIndex` * feat(replica-node): client sync algorithm shell; implement `prefetch_range` grpc call - [x] implement `prefetch_range` grpc call - [x] singe try on server, no point in retrying - [x] `prefetch_range_retried` on client grpc - [x] move `ChunkedRange` iterator into `range_processor.rs` code - [x] resplit incoming range vector into `MAX_PREFETCH_RANGE_CHUNK`-s - [x] put `kickstart_point` into its own struct/module (`Arc>`) - [x] set its initial value to one passed in as argument - [x] process each subrange, taking in `kickstart_point`, and returning one `Result` - [x] issue bigtable.`prefetch_roots_retried` at the start of each range - [x] issue `prefetch_range_retried` to server at the start of each range - [x] test interactively * feat(replica-node): client sync algorithm shell; `get_state_diff` call cut out pure - [x] `get_state_diff` call cut out pure - [x] `download_and_apply_diff` -> cut out `get_diff` - [x] classify server errors, which mean give up, no retries `Result<, StageOneError>` - [x] failed_precondition - [x] `ServerError::HashMismatch` fail fast - [x] `ServerProtoError::StateDiffBlocksTooFar { .. }` fail fast - [x] not_found - [x] `ServerError::EvmHeight::Bigtable::BlockNotFound` fail fast - [x] `ServerError::Lock::LockRootNotFound` fail fast - [x] `ServerError::NotFoundNested` fail fast - [x] illegal argument - [x] `EvmHeightError::ZeroHeightForbidden` fail fast - [x] `ServerProtoError::EmptyHash` : fail fast - [x] `ServerProtoError::CouldNotParseHash(..)` : fail fast - [x] test - [x] change `stage_one` signature - [x] move `get_and_apply` diff to its own module, it doesn't belong to proto - [x] extract stages - [x] stage1 - [x] `get_diff_retried` - [x] stage2 - [x] stage3 * feat(replica-node): client sync algorithm shell; kilosievert module - [x] write `kilosievert` module - [x] `concrete_chamber` - [x] `steel_container` - [x] make constants `max_concrete_chamber_wall_inches` and `max_steel_container_wall_inches` configurable via cli flags - [x] move `get_evm_confirmed_state_root_retried(target)` into async task for cases where block is absent on bt(testnet) * chore(replica-node): add bootstrap progress hint... * feat(replica-node): syntactic shugar and running totals debug info [✓] syntactic shugar and running totals debug info ├── [✓] forbid backwards ranges (< self.range.start) │ ├── [✓] remove diff against left kickstart_point │ └── [✓] amend tests ├── [✓] running total of number of nodes inserted over blockrange reported every 1000 nodes └── [✓] local ├── [✓] `eager_replica_balanced ` │ ├── [✓] 05:43 s │ ├── [✓] 05:41 s │ ├── [✓] 05:37 s │ ├── [✓] 05:29 s │ └── [✓] 05:33 s ├── [✓] `not that bad replica` │ ├── [✓] 05:14 s │ ├── [✓] 05:09 s │ ├── [✓] 05:13 s │ ├── [✓] 05:13 s │ └── [✓] 05:10 s ├── [✓] `eager_replica_simple` │ ├── [✓] 05:20 s │ ├── [✓] 05:26 s │ ├── [✓] 05:27 s │ ├── [✓] 05:28 s │ └── [✓] 05:23 s └── [✓] `eager_replica_balanced` large channel size (200) └── [✓] 05:38 s * feat(replica-node): jump over large gaps: move constant `MAX_CLIENT_WORK_CHUNK` to a param in `RangeJSON` logic [✓] jump over large gaps: move constant `MAX_CLIENT_WORK_CHUNK` to a param in `RangeJSON` logic ├── [✓] remove `upward` flag in `Entry` └── [✓] add stuff in pipeline to increase `MAX_CLIENT_WORK_CHUNK` from min 10x -> `MAX_JUMP_OVER_ABYSS_GAP` if range apply routine results in range not changed └── [✓] simply increase constant * feat(replica-node): bootstrap requests backon implement to eat up errors [✓] bootstrap requests backon implement to eat up errors ├── [✓] `get_evm_confirmed_state_root` -> `get_evm_confirmed_state_root_retried` │ └── [✓] outline ├── [✓] ...`Self::get_array_of_nodes` │ └── [✓] classify business logic errors │ ├── [✓] `ServerProtoError::ExceededMaxChunkGetArrayOfNodes`, │ ├── [✓] `ServerProtoError::CouldNotParseHash` │ └── [✓] `ServerError::NotFoundTopLevel` └── [✓] simplify retry code, replace `backon` with маленьке звiрятко загортае шоколад у фольгу * feat(replica-node): split errors in finer modules: `common`, `server` and `client` [✓] split errors in finer modules: `common`, `server` and `client` ├── [✓] common │ ├── [✓] lock │ └── [✓] evm_height ├── [✓] server │ ├── [✓] proto │ └── [✓] move to lock error │ ├── [✓] `NotFound` │ └── [✓] `NotFoundNested` └── [✓] client ├── [✓] proto ├── [✓] check_height ├── [✓] range_sync │ └── [✓] stages │ ├── [✓] one │ │ └── [✓] request │ │ └── [✓] network │ │ └── [✓] replace `one::request::network::Error::from_with_metadata` with `From` │ └── [✓] two ├── [✓] bootstrap │ └── [✓] fetch_nodes │ └── [✓] get │ └── [✓] replace `bootstrap::fetch_nodes::get::Error::from_with_metadata` with `From` └── [✓] run a few tests locally ├── [✓] with missing starting height └── [✓] normal * chore(replica-lib): clippy * feat(replica-node): add `bigtable`, `local`, `json` cli flag for getting source of data [x] add timeout to instantiated LedgerStorage (bt) (hangs noticed in testing) [x] add timeout to instantiated state_api grpc client [✓] add `bigtable`, `solana_blockstore`, `json` cli flag for getting source of data (to __triedb_repica__) ├── [✓] add `scratchpad` to evm-block-recovery for conveniences ├── [✓] implement `bigtable`, `ReadRange` │ ├── [✓] fix `EvmHeight::get_evm_confirmed_state_root` to return option │ │ └── [✓] (possibly very long on testnet on ranges of missing blocks) │ ├── [✓] add/test `get_first_available_block` │ │ ├── [✓] testnet │ │ └── [✓] mainnet │ └── [✓] implement `get_last_available_block` via `bigtable.get_evm_confirmed_full_blocks_nums` call (with start hint) │ ├── [✓] testnet │ ├── [✓] mainnet │ └── [✓] add check to service start, if it's empty after hinting │ └── [✓] test at `triedb` server start │ └── [✓] failure with large default hint on testnet ├── [✓] implement `local` `ReadRange` │ └── [✓] `get_first_available_block` and `get_last_available_block` (for range) ├── [✓] add flags to switch between json and stuff (on __server__) │ ├── [✓] add optional flag _blockstore_path_ │ ├── [✓] _range_source_ │ │ ├── [✓] `json` │ │ │ ├── [✓] optional flag _range_file_, which is required now │ │ │ └── [✓] retest │ │ ├── [✓] `bigtable` │ │ │ └── [✓] widen `ReadRange` and `WriteRange` methods signature to be result with `evm_height::Error` │ │ └── [✓] `solana_blockstore` │ │ └── [✓] test │ └── [✓] _height_index_source_ - it's separate from range │ ├── [✓] `bigtable` │ │ └── [✓] optional flag to support len hinting `ENV_MAINNET_HINT` -> flag; `bigtable_length_hint` │ │ └── [✓] test testnet │ └── [✓] `solana_blockstore` │ ├── [✓] use `Box` instead of `S: EvmHeight` │ │ ├── [✓] removed `where S: EvmHeightIndex + Send + Sync + 'static,` │ │ └── [✓] on __server__, on __client__ `Arc` may be required due to `Clone` used extensively │ └── [✓] `solana_blockstore` │ └── [✓] implement `EvmHeight` └── [✓] perform test with 2 `solana_blockstore` values startup : Ok(62793454..62816191) ├── [✓] no sync for secondary `solana_blockstgore` implemented in `triedb_replica` └── [✓] increase timeout for client from 20 sec -> 60 sec [x] fix clippy * feat(velas-validator): integrate evm state rpc server into validator [✓] figure out the structure of the output command ├── [✓] add error count for process nodes stages instead of printing errors to log (_replica-lib_) ├── [✓] split `start_and_join` into `start`, and `join` is already there ├── [✓] `evm-state-rpc-port` -> `ValidatorConfig.evm_state_rpc_port` │ └── [✓] `pub evm_state_rpc_port: Option`, ├── [✓] `solana_replica_lib::triedb::Config` -> `replica-lib/src/triedb/mod.rs` ├── [✓] if `evm-state-archive` specified check for `evm-state-rpc-port` │ └── [✓] if port specified `Config::parse_validator(&matches)?` │ └── [✓] clone Arc for `solana_blockstore` ├── [✓] test │ ├── [✓] `bigtable` │ └── [✓] `solana_blockstore` (start range ...) │ └── [✓] `BlockstoreError::SlotCleanedUp` for faster error traversal (hangs) ├── [✓] fix clippy ├── [✓] make tests compile └── [✓] fix syncup secondary issue for `standalone` run with `solana_blockstore` └── [✓] test * chore(clippy): fix * feat(replica-node,velas-validator): missing cli args for working with large gaps on imperfect NEW_ARCHIVE [✓] missing cli args for working with large gaps on imperfect NEW_ARCHIVE ├── [✓] client │ ├── [✓] timeout │ │ └── [✓] `grpc-timeout-sec` u64 │ └── [✓] height diff (#[doc(hidden)]) │ └── [✓] `max-height-diff` usize └── [✓] server └── [✓] height diff, print error to log if lower than min VALUE ├── [✓] `parse_standalone` call site │ └── [✓] `max-height-diff` usize └── [✓] `parse_validator` call site └── [✓] `evm-state-rpc-max-height-diff` usize * chore(replica-node): increase db_workers permits required on large height diffs [✓] missing cli args for working with large gaps on imperfect NEW_ARCHIVE ├── [✓] client │ ├── [✓] timeout │ │ └── [✓] `grpc-timeout-sec` u64 │ ├── [✓] height diff (#[doc(hidden)]) │ │ └── [✓] `max-height-diff` usize │ └── [✓] add error on init if `db_workers` param is lower than `DB_SEMAPHORE_PERMITS_PER_LARGE_DIFF` └── [✓] server └── [✓] height diff, print error to log if lower than min VALUE ├── [✓] `parse_standalone` call site │ ├── [✓] `max-height-diff` usize │ └── [✓] make server whisper curses if this param is specified as too low on start (10_000) └── [✓] `parse_validator` call site └── [✓] `evm-state-rpc-max-height-diff` usize * chore(solana-ledger): review fix, add comment to new api * chore(replica-node): add clap required_if arg properties * chore(clippy): clippy * chore(solana-logger): attempt a stupid build fix --------- Co-authored-by: Julian Pokrovsky --- .gitignore | 1 + Cargo.lock | 198 ++++++++---- core/src/validator.rs | 55 +++- evm-utils/evm-block-recovery/src/cli.rs | 2 + evm-utils/evm-block-recovery/src/main.rs | 1 + evm-utils/evm-block-recovery/src/routines.rs | 3 + .../src/routines/scratchpad.rs | 7 + evm-utils/evm-state/src/storage/mod.rs | 15 +- ledger/src/blockstore.rs | 8 + ledger/src/blockstore_db.rs | 20 ++ local-cluster/src/validator_configs.rs | 2 + logger/Cargo.toml | 1 + replica-lib/Cargo.toml | 34 ++- replica-lib/build.rs | 1 + replica-lib/proto/triedb_repl.proto | 62 ++++ replica-lib/src/lib.rs | 6 + replica-lib/src/triedb/bigtable.rs | 4 + replica-lib/src/triedb/bigtable/cache.rs | 134 +++++++++ replica-lib/src/triedb/bigtable/no_cache.rs | 73 +++++ replica-lib/src/triedb/blockstore.rs | 54 ++++ replica-lib/src/triedb/client/mod.rs | 54 ++++ replica-lib/src/triedb/client/proto.rs | 137 +++++++++ .../src/triedb/client/proto/helpers.rs | 43 +++ .../src/triedb/client/proto/retried.rs | 103 +++++++ replica-lib/src/triedb/client/sync.rs | 65 ++++ .../src/triedb/client/sync/bootstrap.rs | 169 +++++++++++ .../triedb/client/sync/bootstrap/helpers.rs | 66 ++++ .../sync/bootstrap/splice_count_stack.rs | 75 +++++ replica-lib/src/triedb/client/sync/common.rs | 36 +++ .../src/triedb/client/sync/range_processor.rs | 156 ++++++++++ .../sync/range_processor/chunked_range.rs | 22 ++ .../sync/range_processor/kickstart_point.rs | 36 +++ .../sync/range_processor/kilosievert.rs | 2 + .../kilosievert/concrete_chamber.rs | 98 ++++++ .../concrete_chamber/steel_container.rs | 126 ++++++++ .../kilosievert/diff_stages.rs | 131 ++++++++ replica-lib/src/triedb/error.rs | 37 +++ replica-lib/src/triedb/error/client.rs | 6 + .../src/triedb/error/client/bootstrap.rs | 20 ++ .../error/client/bootstrap/fetch_nodes.rs | 13 + .../error/client/bootstrap/fetch_nodes/get.rs | 53 ++++ .../src/triedb/error/client/check_height.rs | 20 ++ replica-lib/src/triedb/error/client/proto.rs | 14 + .../src/triedb/error/client/range_sync.rs | 21 ++ .../triedb/error/client/range_sync/stages.rs | 2 + .../error/client/range_sync/stages/one.rs | 13 + .../client/range_sync/stages/one/request.rs | 13 + .../range_sync/stages/one/request/network.rs | 77 +++++ .../error/client/range_sync/stages/two.rs | 18 ++ .../client/range_sync/stages/two/apply.rs | 13 + replica-lib/src/triedb/error/common.rs | 2 + .../src/triedb/error/common/evm_height.rs | 41 +++ replica-lib/src/triedb/error/common/lock.rs | 30 ++ replica-lib/src/triedb/error/server.rs | 55 ++++ replica-lib/src/triedb/error/server/proto.rs | 29 ++ replica-lib/src/triedb/error/tests.rs | 198 ++++++++++++ replica-lib/src/triedb/mod.rs | 178 +++++++++++ replica-lib/src/triedb/range.rs | 155 ++++++++++ replica-lib/src/triedb/range/diff.rs | 282 ++++++++++++++++++ replica-lib/src/triedb/server/config.rs | 129 ++++++++ replica-lib/src/triedb/server/mod.rs | 40 +++ replica-lib/src/triedb/server/proto.rs | 156 ++++++++++ .../src/triedb/server/proto/helpers.rs | 104 +++++++ .../src/triedb/server/proto/storage.rs | 120 ++++++++ replica-lib/src/triedb/server/service.rs | 239 +++++++++++++++ .../src/triedb/server/service/helpers.rs | 131 ++++++++ replica-node/Cargo.toml | 21 ++ replica-node/src/bin/triedb.rs | 220 ++++++++++++++ replica-node/src/bin/triedb_client.rs | 260 ++++++++++++++++ sdk/src/genesis_config.rs | 5 +- validator/Cargo.toml | 2 + validator/src/main.rs | 58 ++++ 72 files changed, 4717 insertions(+), 58 deletions(-) create mode 100644 evm-utils/evm-block-recovery/src/routines/scratchpad.rs create mode 100644 replica-lib/proto/triedb_repl.proto create mode 100644 replica-lib/src/triedb/bigtable.rs create mode 100644 replica-lib/src/triedb/bigtable/cache.rs create mode 100644 replica-lib/src/triedb/bigtable/no_cache.rs create mode 100644 replica-lib/src/triedb/blockstore.rs create mode 100644 replica-lib/src/triedb/client/mod.rs create mode 100644 replica-lib/src/triedb/client/proto.rs create mode 100644 replica-lib/src/triedb/client/proto/helpers.rs create mode 100644 replica-lib/src/triedb/client/proto/retried.rs create mode 100644 replica-lib/src/triedb/client/sync.rs create mode 100644 replica-lib/src/triedb/client/sync/bootstrap.rs create mode 100644 replica-lib/src/triedb/client/sync/bootstrap/helpers.rs create mode 100644 replica-lib/src/triedb/client/sync/bootstrap/splice_count_stack.rs create mode 100644 replica-lib/src/triedb/client/sync/common.rs create mode 100644 replica-lib/src/triedb/client/sync/range_processor.rs create mode 100644 replica-lib/src/triedb/client/sync/range_processor/chunked_range.rs create mode 100644 replica-lib/src/triedb/client/sync/range_processor/kickstart_point.rs create mode 100644 replica-lib/src/triedb/client/sync/range_processor/kilosievert.rs create mode 100644 replica-lib/src/triedb/client/sync/range_processor/kilosievert/concrete_chamber.rs create mode 100644 replica-lib/src/triedb/client/sync/range_processor/kilosievert/concrete_chamber/steel_container.rs create mode 100644 replica-lib/src/triedb/client/sync/range_processor/kilosievert/diff_stages.rs create mode 100644 replica-lib/src/triedb/error.rs create mode 100644 replica-lib/src/triedb/error/client.rs create mode 100644 replica-lib/src/triedb/error/client/bootstrap.rs create mode 100644 replica-lib/src/triedb/error/client/bootstrap/fetch_nodes.rs create mode 100644 replica-lib/src/triedb/error/client/bootstrap/fetch_nodes/get.rs create mode 100644 replica-lib/src/triedb/error/client/check_height.rs create mode 100644 replica-lib/src/triedb/error/client/proto.rs create mode 100644 replica-lib/src/triedb/error/client/range_sync.rs create mode 100644 replica-lib/src/triedb/error/client/range_sync/stages.rs create mode 100644 replica-lib/src/triedb/error/client/range_sync/stages/one.rs create mode 100644 replica-lib/src/triedb/error/client/range_sync/stages/one/request.rs create mode 100644 replica-lib/src/triedb/error/client/range_sync/stages/one/request/network.rs create mode 100644 replica-lib/src/triedb/error/client/range_sync/stages/two.rs create mode 100644 replica-lib/src/triedb/error/client/range_sync/stages/two/apply.rs create mode 100644 replica-lib/src/triedb/error/common.rs create mode 100644 replica-lib/src/triedb/error/common/evm_height.rs create mode 100644 replica-lib/src/triedb/error/common/lock.rs create mode 100644 replica-lib/src/triedb/error/server.rs create mode 100644 replica-lib/src/triedb/error/server/proto.rs create mode 100644 replica-lib/src/triedb/error/tests.rs create mode 100644 replica-lib/src/triedb/mod.rs create mode 100644 replica-lib/src/triedb/range.rs create mode 100644 replica-lib/src/triedb/range/diff.rs create mode 100644 replica-lib/src/triedb/server/config.rs create mode 100644 replica-lib/src/triedb/server/mod.rs create mode 100644 replica-lib/src/triedb/server/proto.rs create mode 100644 replica-lib/src/triedb/server/proto/helpers.rs create mode 100644 replica-lib/src/triedb/server/proto/storage.rs create mode 100644 replica-lib/src/triedb/server/service.rs create mode 100644 replica-lib/src/triedb/server/service/helpers.rs create mode 100644 replica-node/src/bin/triedb.rs create mode 100644 replica-node/src/bin/triedb_client.rs diff --git a/.gitignore b/.gitignore index 65f0eed257..d416480ff2 100644 --- a/.gitignore +++ b/.gitignore @@ -30,5 +30,6 @@ log-*/ /spl_*.so .DS_Store +justfile # scripts that may be generated by cargo *-bpf commands **/cargo-*-bpf-child-script-*.sh diff --git a/Cargo.lock b/Cargo.lock index 8228ade320..e118a88943 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -47,15 +47,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "aho-corasick" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" -dependencies = [ - "memchr", -] - [[package]] name = "aliasable" version = "0.1.3" @@ -110,6 +101,12 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + [[package]] name = "arrayvec" version = "0.7.2" @@ -461,6 +458,16 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitvec" +version = "0.17.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41262f11d771fd4a61aa3ce019fca363b4b6c282fca9da2a31186d3965a47a5c" +dependencies = [ + "either", + "radium 0.3.0", +] + [[package]] name = "bitvec" version = "1.0.1" @@ -468,7 +475,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" dependencies = [ "funty", - "radium", + "radium 0.7.0", "tap", "wyz", ] @@ -480,7 +487,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ae2468a89544a466886840aa467a25b766499f4f04bf7d9fcd10ecee9fccef" dependencies = [ "arrayref", - "arrayvec", + "arrayvec 0.7.2", "cc", "cfg-if 1.0.0", "constant_time_eq", @@ -612,6 +619,12 @@ dependencies = [ "serde", ] +[[package]] +name = "byte-slice-cast" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0a5e3906bcbf133e33c1d4d95afc664ad37fbdb9f6568d8043e7ea8c27d93d3" + [[package]] name = "byte-slice-cast" version = "1.2.2" @@ -1861,7 +1874,7 @@ dependencies = [ "ethereum-types", "hash-db", "hash256-std-hasher", - "parity-scale-codec", + "parity-scale-codec 3.4.0", "rlp", "rlp-derive", "scale-info", @@ -1881,7 +1894,7 @@ dependencies = [ "impl-codec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "impl-rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "impl-serde 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "primitive-types", + "primitive-types 0.11.1", "scale-info", "uint", ] @@ -1898,8 +1911,8 @@ dependencies = [ "evm-gasometer", "evm-runtime", "log 0.4.17", - "parity-scale-codec", - "primitive-types", + "parity-scale-codec 3.4.0", + "primitive-types 0.11.1", "rlp", "scale-info", "serde", @@ -1956,7 +1969,7 @@ dependencies = [ "opentelemetry", "opentelemetry-jaeger", "paw", - "primitive-types", + "primitive-types 0.11.1", "regex", "reqwest", "rlp", @@ -1991,8 +2004,8 @@ name = "evm-core" version = "0.35.0" source = "git+https://github.com/velas/evm?tag=v0.35-with-traces#90a980bb9d7ccbb21b2897e71b889847f7beeade" dependencies = [ - "parity-scale-codec", - "primitive-types", + "parity-scale-codec 3.4.0", + "primitive-types 0.11.1", "scale-info", "serde", ] @@ -2005,7 +2018,7 @@ dependencies = [ "environmental", "evm-core", "evm-runtime", - "primitive-types", + "primitive-types 0.11.1", ] [[package]] @@ -2023,7 +2036,7 @@ dependencies = [ "jsonrpc-derive", "jsonrpc-http-server", "jsonrpc-pubsub 18.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "primitive-types", + "primitive-types 0.11.1", "rlp", "rustc-hex", "secp256k1", @@ -2041,7 +2054,7 @@ dependencies = [ "auto_impl 0.5.0", "environmental", "evm-core", - "primitive-types", + "primitive-types 0.11.1", "sha3 0.10.7", ] @@ -2072,7 +2085,7 @@ dependencies = [ "log 0.4.17", "once_cell", "paste", - "primitive-types", + "primitive-types 0.11.1", "quickcheck 0.9.2", "quickcheck_macros 0.9.1", "rand 0.6.1", @@ -2087,7 +2100,7 @@ dependencies = [ "snafu", "tempfile", "thiserror", - "triedb", + "triedb 0.5.0 (git+https://github.com/velas/triedb?tag=fast_rlp)", ] [[package]] @@ -2141,13 +2154,13 @@ name = "fastrlp" version = "0.3.0" source = "git+https://github.com/velas/fastrlp?tag=second_release_candidate#f4e921c54f7669e157b2e7e8f5385eed54e105cc" dependencies = [ - "arrayvec", + "arrayvec 0.7.2", "auto_impl 1.0.1", "bytes 1.4.0", "ethbloom 0.11.1", "ethereum", "fastrlp-derive", - "primitive-types", + "primitive-types 0.11.1", "thiserror", ] @@ -2500,7 +2513,7 @@ version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "029d74589adefde59de1a0c4f4732695c32805624aec7b68d91503d4dba79afc" dependencies = [ - "aho-corasick 0.7.20", + "aho-corasick", "bstr", "fnv", "log 0.4.17", @@ -2922,13 +2935,22 @@ dependencies = [ "borsh", ] +[[package]] +name = "impl-codec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1be51a921b067b0eaca2fad532d9400041561aa922221cc65f95a85641c6bf53" +dependencies = [ + "parity-scale-codec 1.3.7", +] + [[package]] name = "impl-codec" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" dependencies = [ - "parity-scale-codec", + "parity-scale-codec 3.4.0", ] [[package]] @@ -2936,7 +2958,7 @@ name = "impl-codec" version = "0.6.0" source = "git+https://github.com/velas/parity-common?tag=primitive-types-v0.11-with-borsh-support-nostd#55f2602045ea3088d0484b15f617bd0cd230501c" dependencies = [ - "parity-scale-codec", + "parity-scale-codec 3.4.0", ] [[package]] @@ -3295,7 +3317,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82bc5d5ca345b067619615f62ac6f93e7daa67eb82d080bc380ed480708ec9e3" dependencies = [ - "primitive-types", + "primitive-types 0.11.1", "tiny-keccak", ] @@ -4065,15 +4087,27 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +[[package]] +name = "parity-scale-codec" +version = "1.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4b26b16c7687c3075982af47719e481815df30bc544f7a6690763a25ca16e9d" +dependencies = [ + "arrayvec 0.5.2", + "bitvec 0.17.4", + "byte-slice-cast 0.3.5", + "serde", +] + [[package]] name = "parity-scale-codec" version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "637935964ff85a605d114591d4d2c13c5d1ba2806dae97cea6bf180238a749ac" dependencies = [ - "arrayvec", - "bitvec", - "byte-slice-cast", + "arrayvec 0.7.2", + "bitvec 1.0.1", + "byte-slice-cast 1.2.2", "impl-trait-for-tuples", "parity-scale-codec-derive", "serde", @@ -4453,6 +4487,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "primitive-types" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3824ae2c5e27160113b9e029a10ec9e3f0237bad8029f69c7724393c9fdefd8" +dependencies = [ + "fixed-hash 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-codec 0.4.2", + "uint", +] + [[package]] name = "primitive-types" version = "0.11.1" @@ -4549,7 +4594,7 @@ dependencies = [ "rand 0.8.5", "rand_chacha 0.3.1", "rand_xorshift 0.3.0", - "regex-syntax 0.6.29", + "regex-syntax", "rusty-fork", "tempfile", "unarray", @@ -4799,6 +4844,12 @@ dependencies = [ "proc-macro2 1.0.56", ] +[[package]] +name = "radium" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "def50a86306165861203e7f84ecffbbdfdea79f0e51039b33de1e952358c47ac" + [[package]] name = "radium" version = "0.7.0" @@ -5113,13 +5164,13 @@ dependencies = [ [[package]] name = "regex" -version = "1.8.1" +version = "1.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" +checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d" dependencies = [ - "aho-corasick 1.0.1", + "aho-corasick", "memchr", - "regex-syntax 0.7.1", + "regex-syntax", ] [[package]] @@ -5134,12 +5185,6 @@ version = "0.6.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" -[[package]] -name = "regex-syntax" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" - [[package]] name = "repair-check" version = "0.1.0" @@ -5440,10 +5485,10 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0cfdffd972d76b22f3d7f81c8be34b2296afd3a25e0a547bd9abe340a4dbbe97" dependencies = [ - "bitvec", + "bitvec 1.0.1", "cfg-if 1.0.0", "derive_more", - "parity-scale-codec", + "parity-scale-codec 3.4.0", "scale-info-derive", ] @@ -6483,7 +6528,7 @@ dependencies = [ "log 0.4.17", "lru", "matches", - "primitive-types", + "primitive-types 0.11.1", "rand 0.7.3", "rand_chacha 0.2.2", "raptorq", @@ -6619,7 +6664,7 @@ dependencies = [ "num-derive", "num-traits", "once_cell", - "primitive-types", + "primitive-types 0.11.1", "quickcheck 1.0.3", "quickcheck_macros 1.0.0", "ripemd160", @@ -6940,7 +6985,7 @@ dependencies = [ "solana-vote-program", "tikv-jemallocator", "tokio", - "triedb", + "triedb 0.5.0 (git+https://github.com/velas/triedb?tag=fast_rlp)", ] [[package]] @@ -6991,6 +7036,7 @@ dependencies = [ "env_logger 0.9.3", "lazy_static", "log 0.4.17", + "regex", ] [[package]] @@ -7320,16 +7366,35 @@ dependencies = [ name = "solana-replica-lib" version = "1.9.29" dependencies = [ + "assert_matches", + "async-trait", + "clap 2.34.0", "crossbeam-channel", + "derivative", + "derive_more", + "evm-rpc", + "evm-state", "futures-util", "log 0.4.17", + "primitive-types 0.8.0", "prost 0.11.9", + "rangemap", + "rlp", + "rocksdb", + "serde", + "serde_json", + "sha3 0.9.1", + "solana-client", + "solana-ledger", "solana-rpc", "solana-runtime", "solana-sdk", + "solana-storage-bigtable", + "thiserror", "tokio", "tonic 0.8.3", "tonic-build 0.8.4", + "triedb 0.5.0 (git+https://github.com/velas/triedb?tag=optimal_children_expose_error)", ] [[package]] @@ -7338,8 +7403,13 @@ version = "1.9.29" dependencies = [ "clap 2.34.0", "crossbeam-channel", + "env_logger 0.9.3", + "etcommon-hexutil", + "evm-state", + "futures 0.3.28", "log 0.4.17", "rand 0.7.3", + "regex", "serial_test 0.5.1", "solana-clap-utils", "solana-core", @@ -7355,9 +7425,13 @@ dependencies = [ "solana-runtime", "solana-sdk", "solana-send-transaction-service", + "solana-storage-bigtable", "solana-streamer", "solana-version", "tempfile", + "thiserror", + "tokio", + "tonic 0.8.3", "tonic-build 0.8.4", "velas-validator", ] @@ -7442,7 +7516,7 @@ dependencies = [ "jsonrpc-core", "jsonrpc-core-client", "log 0.4.17", - "primitive-types", + "primitive-types 0.11.1", "reqwest", "serde", "serde_json", @@ -7707,7 +7781,7 @@ dependencies = [ "solana-sdk", "solana-transaction-status", "tonic-build 0.8.4", - "triedb", + "triedb 0.5.0 (git+https://github.com/velas/triedb?tag=fast_rlp)", ] [[package]] @@ -9064,7 +9138,28 @@ dependencies = [ "etcommon-hexutil", "fastrlp", "log 0.4.17", - "primitive-types", + "primitive-types 0.11.1", + "rayon", + "rlp", + "rocksdb", + "serde", + "sha3 0.9.1", + "termtree", + "thiserror", +] + +[[package]] +name = "triedb" +version = "0.5.0" +source = "git+https://github.com/velas/triedb?tag=optimal_children_expose_error#6cef9352ebda60189a5cd4c9a424fb6dcb5e37ee" +dependencies = [ + "anyhow", + "bincode", + "dashmap 4.0.2", + "derivative", + "etcommon-hexutil", + "log 0.4.17", + "primitive-types 0.11.1", "rayon", "rlp", "rocksdb", @@ -9414,6 +9509,7 @@ dependencies = [ "sysctl", "tempfile", "tikv-jemallocator", + "tokio", ] [[package]] diff --git a/core/src/validator.rs b/core/src/validator.rs index 3735426ebd..785c40c063 100644 --- a/core/src/validator.rs +++ b/core/src/validator.rs @@ -121,9 +121,11 @@ pub struct ValidatorConfig { pub account_paths: Vec, pub account_shrink_paths: Option>, pub rpc_config: JsonRpcConfig, + pub evm_state_rpc_config: Option, pub accountsdb_repl_service_config: Option, pub geyser_plugin_config_files: Option>, pub rpc_addrs: Option<(SocketAddr, SocketAddr)>, // (JsonRpc, JsonRpcPubSub) + pub evm_state_rpc_addr: Option, pub pubsub_config: PubSubConfig, pub snapshot_config: Option, pub max_ledger_shreds: Option, @@ -184,9 +186,11 @@ impl Default for ValidatorConfig { account_paths: Vec::new(), account_shrink_paths: None, rpc_config: JsonRpcConfig::default(), + evm_state_rpc_config: None, accountsdb_repl_service_config: None, geyser_plugin_config_files: None, rpc_addrs: None, + evm_state_rpc_addr: None, pubsub_config: PubSubConfig::default(), snapshot_config: None, broadcast_stage_type: BroadcastStageType::Standard, @@ -312,6 +316,7 @@ pub struct Validator { pub bank_forks: Arc>, accountsdb_repl_service: Option, geyser_plugin_service: Option, + evm_state_rpc_service: Option, } // in the distant future, get rid of ::new()/exit() and use Result properly... @@ -499,6 +504,7 @@ impl Validator { transaction_notifier, ); + *start_progress.write().unwrap() = ValidatorStartProgress::StartingServices; if !config.no_os_network_stats_reporting { @@ -677,7 +683,7 @@ impl Validator { max_slots.clone(), leader_schedule_cache.clone(), max_complete_transaction_status_slot, - evm_state_archive, + evm_state_archive.clone(), config.jaeger_collector_url.clone(), )), if !config.rpc_config.full_api { @@ -711,6 +717,47 @@ impl Validator { (None, None, None, None, None) }; + let evm_state_rpc_service = match (config.evm_state_rpc_addr.as_ref(), config.evm_state_rpc_config.as_ref(), evm_state_archive) { + (Some(addr), Some(config), Some(archive)) => { + + let runtime = tokio::runtime::Builder::new_multi_thread() + .worker_threads(30) + .thread_name("velas-evm-state-rpc-worker") + .enable_all() + .build(); + match runtime { + Ok(runtime) => { + let used_storage = solana_replica_lib::triedb::server::UsedStorage::WritableWithGC( + archive + ); + + match solana_replica_lib::triedb::server::RunningService::start( + *addr, + config.clone(), + used_storage, + runtime, + Some(blockstore.clone()), + ) { + Ok(service) => Some(service), + Err(err) => { + error!("error starting solana_replica_lib::triedb::server {:#?}", err); + None + }, + + } + + }, + Err(err) => { + error!("error initializing velas-evm-state-rpc-worker runtime {:#?}", err); + None + } + + } + + }, + _ => None, + }; + if config.dev_halt_at_slot.is_some() { // Simulate a confirmed root to avoid RPC errors with CommitmentConfig::finalized() and // to ensure RPC endpoints like getConfirmedBlock, which require a confirmed root, work @@ -950,6 +997,7 @@ impl Validator { ); *start_progress.write().unwrap() = ValidatorStartProgress::Running; + Self { gossip_service, serve_repair_service, @@ -976,6 +1024,7 @@ impl Validator { bank_forks, accountsdb_repl_service, geyser_plugin_service, + evm_state_rpc_service, } } @@ -1109,6 +1158,10 @@ impl Validator { if let Some(geyser_plugin_service) = self.geyser_plugin_service { geyser_plugin_service.join().expect("geyser_plugin_service"); } + + if let Some(evm_state_rpc_service) = self.evm_state_rpc_service { + evm_state_rpc_service.join().expect("evm_state_rpc_service"); + } } } diff --git a/evm-utils/evm-block-recovery/src/cli.rs b/evm-utils/evm-block-recovery/src/cli.rs index 455261a673..4ac71ddff4 100644 --- a/evm-utils/evm-block-recovery/src/cli.rs +++ b/evm-utils/evm-block-recovery/src/cli.rs @@ -54,6 +54,8 @@ pub enum Command { ScanEvmStateRoots(ScanEvmStateRootsArgs), + ScratchPad, + /// Generetes Shell Completions for this Utility Completion(CompletionArgs), } diff --git a/evm-utils/evm-block-recovery/src/main.rs b/evm-utils/evm-block-recovery/src/main.rs index 1058cadecd..d5647f3c57 100644 --- a/evm-utils/evm-block-recovery/src/main.rs +++ b/evm-utils/evm-block-recovery/src/main.rs @@ -52,6 +52,7 @@ async fn main() { RepeatEvm(args) => repeat_evm(args).await, RepeatNative(args) => repeat_native(args).await, ScanEvmStateRoots(ref args) => scan_evm_state_roots::command(args).await, + ScratchPad => scratchpad::command().await, Completion(args) => completion(args), }; diff --git a/evm-utils/evm-block-recovery/src/routines.rs b/evm-utils/evm-block-recovery/src/routines.rs index c3c2a94426..a5230b18c8 100644 --- a/evm-utils/evm-block-recovery/src/routines.rs +++ b/evm-utils/evm-block-recovery/src/routines.rs @@ -7,6 +7,9 @@ pub(crate) mod repeat; pub(crate) mod restore_chain; pub(crate) mod upload; pub(crate) mod scan_evm_state_roots; +// a tmp placeholder to test out various new commands or approaches +// it's convenient, as all potentially required dependencies have been imported +pub(crate) mod scratchpad; pub use check_evm::check_evm; pub use check_native::check_native; diff --git a/evm-utils/evm-block-recovery/src/routines/scratchpad.rs b/evm-utils/evm-block-recovery/src/routines/scratchpad.rs new file mode 100644 index 0000000000..df18c3a186 --- /dev/null +++ b/evm-utils/evm-block-recovery/src/routines/scratchpad.rs @@ -0,0 +1,7 @@ +use crate::error::AppError; + + +pub async fn command() -> Result<(), AppError> { + println!("scratchpad"); + Ok(()) +} \ No newline at end of file diff --git a/evm-utils/evm-state/src/storage/mod.rs b/evm-utils/evm-state/src/storage/mod.rs index 94ff866604..fdbcc4d276 100644 --- a/evm-utils/evm-state/src/storage/mod.rs +++ b/evm-utils/evm-state/src/storage/mod.rs @@ -31,7 +31,7 @@ use crate::{ use triedb::{ empty_trie_hash, gc::{DatabaseTrieMut, DbCounter, TrieCollection}, - rocksdb::{RocksDatabaseHandleGC, RocksHandle}, + rocksdb::{RocksDatabaseHandle, RocksDatabaseHandleGC, RocksHandle, SyncRocksHandle}, FixedSecureTrieMut, rlp::{Encodable, Decodable}, }; @@ -263,6 +263,17 @@ impl StorageSecondary { Self::open(Location::Persisent(path.as_ref().to_owned()), gc_enabled) } + pub fn try_catch_up(&self) -> Result<()> { + self.db.0.try_catch_up_with_primary()?; + Ok(()) + } + + pub fn rocksdb_trie_handle( + &self, + ) -> SyncRocksHandle { + SyncRocksHandle::new(RocksDatabaseHandle::new(self.db())) + } + fn open(location: Location, gc_enabled: bool) -> Result { log::warn!("gc_enabled {}", gc_enabled); let db_opts = default_db_opts()?; @@ -732,7 +743,7 @@ impl Storage { static SECONDARY_MODE_PATH_SUFFIX: &str = "velas-secondary"; -fn account_extractor(data: &[u8]) -> Vec { +pub fn account_extractor(data: &[u8]) -> Vec { if let Ok(account) = triedb::rlp::decode::(data) { vec![account.storage_root] } else { diff --git a/ledger/src/blockstore.rs b/ledger/src/blockstore.rs index e31df4f100..aee2235cf8 100644 --- a/ledger/src/blockstore.rs +++ b/ledger/src/blockstore.rs @@ -3625,6 +3625,14 @@ impl Blockstore { ); Ok(()) } + + // result indicates, if this was indeed opened in `secondary` mode + // and called the underlying rocksdb catch up method + // true - if catch_up occured + // false - if this function call was a noop + pub fn try_catch_up_with_primary(&self) -> Result { + self.db.try_catch_up() + } } // Update the `completed_data_indexes` with a new shred `new_shred_index`. If a diff --git a/ledger/src/blockstore_db.rs b/ledger/src/blockstore_db.rs index 22b52d0129..49d672cf8f 100644 --- a/ledger/src/blockstore_db.rs +++ b/ledger/src/blockstore_db.rs @@ -662,6 +662,22 @@ impl Rocks { fn is_primary_access(&self) -> bool { self.1 == ActualAccessType::Primary } + + pub(crate) fn try_catch_up(&self) -> Result{ + let res = match self.1 { + ActualAccessType::Secondary => { + self.0.try_catch_up_with_primary()?; + true + + }, + ActualAccessType::Primary => { + false + } + }; + + Ok(res) + + } } pub trait Column { @@ -1402,6 +1418,10 @@ impl Database { pub fn set_oldest_block_num(&self, oldest_block_num: BlockNum) { self.backend.3.set(oldest_block_num); } + + pub(crate) fn try_catch_up(&self) -> Result{ + self.backend.try_catch_up() + } } impl LedgerColumn diff --git a/local-cluster/src/validator_configs.rs b/local-cluster/src/validator_configs.rs index cbf7c3b86d..67eed7c4c3 100644 --- a/local-cluster/src/validator_configs.rs +++ b/local-cluster/src/validator_configs.rs @@ -14,9 +14,11 @@ pub fn safe_clone_config(config: &ValidatorConfig) -> ValidatorConfig { account_paths: config.account_paths.clone(), account_shrink_paths: config.account_shrink_paths.clone(), rpc_config: config.rpc_config.clone(), + evm_state_rpc_config: None, accountsdb_repl_service_config: config.accountsdb_repl_service_config.clone(), geyser_plugin_config_files: config.geyser_plugin_config_files.clone(), rpc_addrs: config.rpc_addrs, + evm_state_rpc_addr: None, pubsub_config: config.pubsub_config.clone(), snapshot_config: config.snapshot_config.clone(), max_ledger_shreds: config.max_ledger_shreds, diff --git a/logger/Cargo.toml b/logger/Cargo.toml index 50a49d8e21..c3c8c234e6 100644 --- a/logger/Cargo.toml +++ b/logger/Cargo.toml @@ -10,6 +10,7 @@ documentation = "https://docs.rs/solana-logger" edition = "2021" [dependencies] +regex = "=1.7.3" env_logger = "0.9.0" lazy_static = "1.4.0" log = "0.4.14" diff --git a/replica-lib/Cargo.toml b/replica-lib/Cargo.toml index 2ae4eaf2f8..e306e0ed51 100644 --- a/replica-lib/Cargo.toml +++ b/replica-lib/Cargo.toml @@ -10,6 +10,8 @@ homepage = "https://solana.com/" documentation = "https://docs.rs/solana-validator" [dependencies] + +thiserror = "1.0.40" crossbeam-channel = "0.5" futures-util = "0.3" log = "0.4.11" @@ -17,8 +19,38 @@ prost = "0.11.0" solana-rpc = { path = "../rpc", version = "=1.9.29" } solana-runtime = { path = "../runtime", version = "=1.9.29" } solana-sdk = { path = "../sdk", version = "=1.9.29" } -tokio = { version = "1.14.1", features = ["full"] } +solana-client = { path = "../client", version = "=1.9.29" } +solana-storage-bigtable = { path = "../storage-bigtable", version = "=1.9.29" } +solana-ledger = { path = "../ledger", version = "=1.9.29" } +clap = "2.33.1" + +sha3 = "0.9.1" + +rlp = "0.5.0" + +tokio = { version = "1.14.1", features = ["full", "time"] } tonic = { version = "0.8.1", features = ["tls", "transport", "gzip"] } +async-trait = "0.1.64" + +# Additional deps for triedb_repl_server +derive_more = "0.99.11" + +derivative="2.2" +evm-state = { path = "../evm-utils/evm-state" } +evm-rpc = { path = "../evm-utils/evm-rpc" } +primitive-types = "0.8.0" +rocksdb = { git = "https://github.com/velas/rust-rocksdb", version = "0.19.0", default-features = false } + +triedb = { git = "https://github.com/velas/triedb", tag = "optimal_children_expose_error", features = ["rocksdb"] } + +rangemap = { version = "1.3.0", features = ["serde1"]} + +# Additional deps for triedb_repl_client +serde_json = "1.0.82" +serde = "1.0.152" + +[dev-dependencies] +assert_matches = "1.5.0" [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] diff --git a/replica-lib/build.rs b/replica-lib/build.rs index a90b012986..7d118e973d 100644 --- a/replica-lib/build.rs +++ b/replica-lib/build.rs @@ -1,5 +1,6 @@ fn main() -> Result<(), Box> { // compiling protos using path on build time tonic_build::configure().compile(&["proto/accountsdb_repl.proto"], &["proto"])?; + tonic_build::configure().compile(&["proto/triedb_repl.proto"], &["proto"])?; Ok(()) } diff --git a/replica-lib/proto/triedb_repl.proto b/replica-lib/proto/triedb_repl.proto new file mode 100644 index 0000000000..784f064085 --- /dev/null +++ b/replica-lib/proto/triedb_repl.proto @@ -0,0 +1,62 @@ +syntax = "proto3"; +package triedb_repl; + +import "google/protobuf/empty.proto"; + +service Backend { + rpc ping (google.protobuf.Empty) returns (PingReply); + rpc getArrayOfNodes (GetArrayOfNodesRequest) returns (GetArrayOfNodesReply); + rpc prefetchHeight (PrefetchHeightRequest) returns (PrefetchHeightReply); + rpc getStateDiff (GetStateDiffRequest) returns (GetStateDiffReply); + rpc prefetchRange (PrefetchRangeRequest) returns (google.protobuf.Empty); + rpc getBlockRange (google.protobuf.Empty) returns (GetBlockRangeReply); +} + +message PingReply { + string message = 1; +} + +message Hash { + string value = 1; +} + +message GetArrayOfNodesRequest { + repeated Hash hashes = 1; +} + +message PrefetchHeightRequest { + uint64 height = 1; +} + +message PrefetchHeightReply { + Hash hash = 1; +} + +message GetArrayOfNodesReply { + repeated bytes nodes = 1; +} + +message GetBlockRangeReply { + uint64 start = 1; + uint64 end = 2; +} + +message PrefetchRangeRequest { + uint64 start = 1; + uint64 end = 2; +} +message GetStateDiffRequest { + uint64 from = 1; + uint64 to = 2; + Hash first_root = 3; + Hash second_root = 4; +} + +message Insert { + Hash hash = 1; + bytes data = 2; +} + +message GetStateDiffReply { + repeated Insert changeset = 1; +} diff --git a/replica-lib/src/lib.rs b/replica-lib/src/lib.rs index 13715c691a..2ad635f2c9 100644 --- a/replica-lib/src/lib.rs +++ b/replica-lib/src/lib.rs @@ -1,7 +1,13 @@ #![allow(clippy::integer_arithmetic)] +#[cfg(test)] +#[macro_use] +extern crate assert_matches; + pub mod accountsdb_repl_client; pub mod accountsdb_repl_server; pub mod accountsdb_repl_server_factory; pub mod replica_accounts_server; pub mod replica_confirmed_slots_server; + +pub mod triedb; diff --git a/replica-lib/src/triedb/bigtable.rs b/replica-lib/src/triedb/bigtable.rs new file mode 100644 index 0000000000..30f37d8fd3 --- /dev/null +++ b/replica-lib/src/triedb/bigtable.rs @@ -0,0 +1,4 @@ +mod cache; +mod no_cache; + +pub use cache::CachedRootsLedgerStorage; diff --git a/replica-lib/src/triedb/bigtable/cache.rs b/replica-lib/src/triedb/bigtable/cache.rs new file mode 100644 index 0000000000..75e98c54bf --- /dev/null +++ b/replica-lib/src/triedb/bigtable/cache.rs @@ -0,0 +1,134 @@ +use std::{ + collections::HashMap, + ops::Range, + sync::{Arc, Mutex}, +}; + +use evm_state::{BlockNum, H256}; + +use async_trait::async_trait; +use solana_storage_bigtable::LedgerStorage; + +use crate::triedb::{error::evm_height, EvmHeightIndex, ReadRange, MAX_PREFETCH_RANGE_CHUNK}; + +#[derive(Clone)] +struct Inner { + map: HashMap, + last_hint: BlockNum, +} + +#[derive(Clone)] +pub struct CachedRootsLedgerStorage { + bigtable: LedgerStorage, + cache: Arc>, +} + +impl CachedRootsLedgerStorage { + pub fn new(bigtable: LedgerStorage, hint: BlockNum) -> Self { + let inner = Inner { + map: HashMap::new(), + last_hint: hint, + }; + Self { + bigtable, + cache: Arc::new(Mutex::new(inner)), + } + } + + pub async fn get_first_available_block(&self) -> Result { + let first = self.bigtable.get_evm_first_available_block().await?; + + match first { + Some(height) => Ok(height), + None => Err(evm_height::Error::NoFirst), + } + } + + pub async fn get_last_available_block(&self) -> Result { + let hint = self.cache.lock().expect("poison").last_hint; + + let vec = self + .bigtable + .get_evm_confirmed_full_blocks_nums(hint, 0) + .await?; + + match vec.len() { + 0 => Err(evm_height::Error::NoLast), + _ => { + let result = vec[vec.len() - 1]; + self.cache.lock().expect("poison").last_hint = result; + Ok(result) + } + } + } +} + +#[async_trait] +impl ReadRange for CachedRootsLedgerStorage { + async fn get(&self) -> Result, evm_height::Error> { + let start = self.get_first_available_block().await?; + let end = self.get_last_available_block().await? + 1; + + Ok(start..end) + } +} + +#[async_trait] +impl EvmHeightIndex for CachedRootsLedgerStorage { + async fn get_evm_confirmed_state_root( + &self, + block_num: evm_state::BlockNum, + ) -> Result, evm_height::Error> { + if block_num == 0 { + return Err(evm_height::Error::ForbidZero); + } + if let Some(result) = self.cache.lock().expect("poison").map.get(&block_num) { + return Ok(Some(*result)); + } + let block = self.bigtable.get_evm_confirmed_full_block(block_num).await; + let block = match block { + Err(solana_storage_bigtable::Error::BlockNotFound(..)) => { + return Ok(None); + } + Err(err) => Err(err)?, + Ok(block) => block, + }; + let result = block.header.state_root; + + self.cache + .lock() + .expect("poison") + .map + .insert(block_num, result); + Ok(Some(result)) + } + + async fn prefetch_roots( + &self, + range: &Range, + ) -> Result<(), evm_height::Error> { + if (range.end - range.start) > MAX_PREFETCH_RANGE_CHUNK { + return Err(evm_height::Error::ExceedMaxChunk { + max: MAX_PREFETCH_RANGE_CHUNK, + actual: range.end - range.start, + }); + } + let block_res = self + .bigtable + .get_evm_confirmed_full_blocks(range.start, range.end - 1) + .await?; + + log::info!( + "prefetch roots response retrieved from bt: {}", + block_res.len() + ); + let mut inner = self.cache.lock().expect("poison"); + for block in block_res { + let bn = block.header.block_number; + let hash = block.header.state_root; + + inner.map.insert(bn, hash); + } + Ok(()) + } +} diff --git a/replica-lib/src/triedb/bigtable/no_cache.rs b/replica-lib/src/triedb/bigtable/no_cache.rs new file mode 100644 index 0000000000..8add6a0ece --- /dev/null +++ b/replica-lib/src/triedb/bigtable/no_cache.rs @@ -0,0 +1,73 @@ +use std::ops::Range; + +use async_trait::async_trait; +use evm_state::{BlockNum, H256}; +use solana_storage_bigtable::LedgerStorage; + +use crate::triedb::{error::evm_height, EvmHeightIndex}; + +pub struct LedgerStorageWrapped { + inner: LedgerStorage, + len_hint: BlockNum, +} + +#[allow(unused)] +impl LedgerStorageWrapped { + pub fn new(bigtable: LedgerStorage, hint: BlockNum) -> Self { + Self { + inner: bigtable, + len_hint: hint, + } + } + + pub async fn get_first_available_block(&self) -> Result { + let first = self.inner.get_evm_first_available_block().await?; + + match first { + Some(height) => Ok(height), + None => Err(evm_height::Error::NoFirst), + } + } + + pub async fn get_last_available_block(&self) -> Result { + let vec = self + .inner + .get_evm_confirmed_full_blocks_nums(self.len_hint, 0) + .await?; + + match vec.len() { + 0 => Err(evm_height::Error::NoLast), + _ => Ok(vec[vec.len() - 1]), + } + } +} + +#[async_trait] +impl EvmHeightIndex for LedgerStorageWrapped { + async fn get_evm_confirmed_state_root( + &self, + block_num: evm_state::BlockNum, + ) -> Result, evm_height::Error> { + if block_num == 0 { + return Err(evm_height::Error::ForbidZero); + } + let block = self.inner.get_evm_confirmed_full_block(block_num).await; + + let block = match block { + Err(solana_storage_bigtable::Error::BlockNotFound(..)) => { + return Ok(None); + } + Err(err) => Err(err)?, + Ok(block) => block, + }; + + Ok(Some(block.header.state_root)) + } + + async fn prefetch_roots( + &self, + _range: &Range, + ) -> Result<(), evm_height::Error> { + Ok(()) + } +} diff --git a/replica-lib/src/triedb/blockstore.rs b/replica-lib/src/triedb/blockstore.rs new file mode 100644 index 0000000000..448ae630da --- /dev/null +++ b/replica-lib/src/triedb/blockstore.rs @@ -0,0 +1,54 @@ +use std::{ops::Range, sync::Arc}; + +use async_trait::async_trait; +use evm_state::{BlockNum, H256}; +use solana_ledger::{blockstore::Blockstore, blockstore_db::BlockstoreError}; + +use super::{error::evm_height, EvmHeightIndex, ReadRange}; + +#[async_trait] +impl ReadRange for Arc { + async fn get(&self) -> Result, evm_height::Error> { + let start = self.get_first_available_evm_block()?; + let end = self.get_last_available_evm_block()?; + + let end = end.ok_or(evm_height::Error::NoLast)?; + + Ok(start..end + 1) + } +} + +#[async_trait] +impl EvmHeightIndex for Arc { + async fn get_evm_confirmed_state_root( + &self, + block_num: evm_state::BlockNum, + ) -> Result, evm_height::Error> { + if block_num == 0 { + return Err(evm_height::Error::ForbidZero); + } + + let result = self.get_evm_block(block_num); + let (block, confirmed) = match result { + Ok((block, confirmed)) => (block, confirmed), + Err(BlockstoreError::SlotCleanedUp) => { + return Ok(None); + } + Err(err) => { + return Err(err)?; + } + }; + + if !confirmed { + return Ok(None); + } + Ok(Some(block.header.state_root)) + } + + async fn prefetch_roots( + &self, + _range: &Range, + ) -> Result<(), evm_height::Error> { + Ok(()) + } +} diff --git a/replica-lib/src/triedb/client/mod.rs b/replica-lib/src/triedb/client/mod.rs new file mode 100644 index 0000000000..564b734377 --- /dev/null +++ b/replica-lib/src/triedb/client/mod.rs @@ -0,0 +1,54 @@ +use std::time::Duration; + +use proto::app_grpc::backend_client::BackendClient; + +use super::range::RangeJSON; +use evm_state::Storage; +use log; + +mod proto; +mod sync; + +pub struct Client { + pub state_rpc_address: String, + storage: Storage, + client: BackendClient, + range: RangeJSON, + block_storage: S, + request_workers: u32, + db_workers: u32, + max_height_gap: usize +} + +impl Client { + pub async fn connect( + state_rpc_address: String, + timeout_seconds: u64, + range: RangeJSON, + storage: Storage, + block_storage: S, + request_workers: u32, + db_workers: u32, + max_height_gap: usize, + ) -> Result { + log::info!("starting the client routine {}", state_rpc_address); + + let endpoint: tonic::transport::Endpoint = state_rpc_address.clone().try_into()?; + + // for getting 641_000 of nodes in single request 20 sec timeout has been seen + // to be surpassed + let endpoint = endpoint.timeout(Duration::new(timeout_seconds, 0)); + let client = BackendClient::connect(endpoint).await?; + + Ok(Self { + client, + range, + state_rpc_address, + storage, + block_storage, + request_workers, + db_workers, + max_height_gap, + }) + } +} diff --git a/replica-lib/src/triedb/client/proto.rs b/replica-lib/src/triedb/client/proto.rs new file mode 100644 index 0000000000..efda0fecf9 --- /dev/null +++ b/replica-lib/src/triedb/client/proto.rs @@ -0,0 +1,137 @@ +use evm_rpc::FormatHex; +use evm_state::BlockNum; +use evm_state::H256; +use tonic::Code; + +use std::ops::Range; + +use crate::triedb::DiffRequest; + +use self::app_grpc::backend_client::BackendClient; +use self::app_grpc::GetStateDiffReply; +pub(super) mod helpers; +mod retried; + +pub mod app_grpc { + tonic::include_proto!("triedb_repl"); +} + +impl From for std::ops::Range { + fn from(value: app_grpc::GetBlockRangeReply) -> Self { + value.start..value.end + } +} + +impl super::Client { + pub async fn ping( + client: &mut BackendClient, + ) -> Result<(), tonic::Status> { + let request = tonic::Request::new(()); + let response = client.ping(request).await?; + log::trace!("PING | RESPONSE={:?}", response); + Ok(()) + } + + pub async fn get_array_of_nodes( + client: &mut BackendClient, + hashes: Vec, + ) -> Result { + let request = tonic::Request::new(app_grpc::GetArrayOfNodesRequest { + hashes: hashes + .into_iter() + .map(|h| app_grpc::Hash { + value: h.format_hex(), + }) + .collect(), + }); + let response = client.get_array_of_nodes(request).await?; + log::trace!("PING | RESPONSE={:?}", response); + Ok(response.into_inner()) + } + + pub async fn get_block_range( + client: &mut BackendClient, + state_rpc_address: &str, + ) -> Result { + let request = tonic::Request::new(()); + let response = client.get_block_range(request).await?; + + let response = response.into_inner(); + log::info!( + "block_range retrieved: {} -> {}, {}", + response.start, + response.end, + state_rpc_address + ); + Ok(response) + } + + pub async fn prefetch_height( + client: &mut BackendClient, + height: BlockNum, + state_rpc_address: &str, + ) -> Result, tonic::Status> { + let request = tonic::Request::new(app_grpc::PrefetchHeightRequest { height }); + + let response = client.prefetch_height(request).await; + if let Err(ref err) = response { + if err.code() == Code::NotFound { + log::error!("not found {:?}", err); + return Ok(None); + } + } + let response = response?; + + let response = response.into_inner(); + log::info!( + "prefetch_height response retrieved: {} -> {:?}, {}", + height, + response + .hash + .as_ref() + .map(|hash| hash.value.clone()) + .unwrap_or_else(|| "empty".to_string()), + state_rpc_address + ); + Ok(Some(response)) + } + + pub async fn prefetch_range( + client: &mut BackendClient, + range: &Range, + state_rpc_address: &str, + ) -> Result<(), tonic::Status> { + let request = tonic::Request::new(app_grpc::PrefetchRangeRequest { + start: range.start, + end: range.end, + }); + + client.prefetch_range(request).await?; + log::info!( + "prefetch_range response retrieved: {:?}, {}", + range, + state_rpc_address, + ); + Ok(()) + } + + pub async fn get_diff( + client: &mut BackendClient, + request: DiffRequest, + state_rpc_address: &str, + ) -> Result { + let response = client + .get_state_diff(helpers::state_diff_request(request)) + .await?; + + let response = response.into_inner(); + log::trace!( + "changeset retrieved {:?} -> {:?} {}, {}", + request.expected_hashes.0, + request.expected_hashes.1, + response.changeset.len(), + state_rpc_address, + ); + Ok(response) + } +} diff --git a/replica-lib/src/triedb/client/proto/helpers.rs b/replica-lib/src/triedb/client/proto/helpers.rs new file mode 100644 index 0000000000..c6092a3231 --- /dev/null +++ b/replica-lib/src/triedb/client/proto/helpers.rs @@ -0,0 +1,43 @@ +use evm_rpc::FormatHex; +use evm_state::H256; + +use crate::triedb::{error::client, DiffRequest, TryConvert}; + +use super::app_grpc; + +impl TryConvert> for H256 { + type Error = client::proto::Error; + + fn try_from(hash: Option) -> Result { + let hash = hash.ok_or(client::proto::Error::EmptyHash)?; + let res = H256::from_hex(&hash.value) + .map_err(|_| client::proto::Error::ParseHash(hash.value.clone()))?; + Ok(res) + } +} + +pub(in crate::triedb::client) fn parse_diff_response( + in_: app_grpc::GetStateDiffReply, +) -> Result, client::proto::Error> { + let mut result: Vec = vec![]; + for insert in in_.changeset { + let hash = >::try_from(insert.hash)?; + result.push(triedb::DiffChange::Insert(hash, insert.data.into())); + } + Ok(result) +} + +pub(super) fn state_diff_request( + request: DiffRequest, +) -> tonic::Request { + tonic::Request::new(app_grpc::GetStateDiffRequest { + from: request.heights.0, + to: request.heights.1, + first_root: Some(app_grpc::Hash { + value: request.expected_hashes.0.format_hex(), + }), + second_root: Some(app_grpc::Hash { + value: request.expected_hashes.1.format_hex(), + }), + }) +} diff --git a/replica-lib/src/triedb/client/proto/retried.rs b/replica-lib/src/triedb/client/proto/retried.rs new file mode 100644 index 0000000000..040ab77e7b --- /dev/null +++ b/replica-lib/src/triedb/client/proto/retried.rs @@ -0,0 +1,103 @@ +use std::ops::Range; + +use evm_state::{BlockNum, H256}; + +use crate::triedb::{client::Client, error::client::bootstrap::fetch_nodes, retry_logged}; + +use super::app_grpc::{self, backend_client::BackendClient}; + +impl Client { + pub(crate) async fn get_server_range_retried(&self) -> Result, tonic::Status> { + let res = retry_logged( + || { + let mut client = self.client.clone(); + async move { Self::get_block_range(&mut client, &self.state_rpc_address).await } + }, + format!("fetch servers_range {}", self.state_rpc_address), + log::Level::Trace, + ) + .await?; + + Ok(res.into()) + } + + pub(crate) async fn prefetch_height_retried( + &self, + height: BlockNum, + ) -> Result, tonic::Status> { + let res = + retry_logged( + || { + let mut client = self.client.clone(); + async move { + Self::prefetch_height(&mut client, height, &self.state_rpc_address).await + } + }, + format!( + "issue prefetch_height request {}, {height}", + self.state_rpc_address + ), + log::Level::Info, + ) + .await?; + + Ok(res) + } + + pub(crate) async fn prefetch_range_retried( + &self, + range: &Range, + ) -> Result<(), tonic::Status> { + retry_logged( + || { + let mut client = self.client.clone(); + async move { + Self::prefetch_range(&mut client, range, &self.state_rpc_address).await + } + }, + format!( + "send prefetch_range request {} {:?}", + self.state_rpc_address, range + ), + log::Level::Info, + ) + .await?; + + Ok(()) + } + + pub(crate) async fn get_array_of_nodes_retried( + client: &BackendClient, + rpc_address: &String, + hashes: Vec, + ) -> Result< + Result, + fetch_nodes::get::SlowError, + > { + let res = retry_logged( + || { + let hashes = hashes.clone(); + let mut client = client.clone(); + async move { + let result = Self::get_array_of_nodes(&mut client, hashes).await; + match result { + Ok(res) => Ok(Ok(res)), + Err(err) => match err.into() { + fetch_nodes::get::Error::Fast(fast) => Ok(Err(fast)), + fetch_nodes::get::Error::Slow(slow) => Err(slow), + }, + } + } + }, + format!( + "get_array_of_nodes request {} {}", + rpc_address, + hashes.len() + ), + log::Level::Trace, + ) + .await?; + + Ok(res) + } +} diff --git a/replica-lib/src/triedb/client/sync.rs b/replica-lib/src/triedb/client/sync.rs new file mode 100644 index 0000000000..7fa8d151a4 --- /dev/null +++ b/replica-lib/src/triedb/client/sync.rs @@ -0,0 +1,65 @@ +use std::{ + thread::{self, sleep}, + time, +}; + +use crate::triedb::{range::RangeJSON, EvmHeightIndex, ReadRange}; + +use super::Client; + +mod bootstrap; +mod common; +mod range_processor; + +impl Client +where + S: EvmHeightIndex + Clone + Sync + Send + 'static, +{ + pub async fn sync(&mut self) { + loop { + let server_range = match self.get_server_range_retried().await { + Err(err) => { + log::error!("get_block_range error after multiple retries {:?}", err); + sleep(time::Duration::new(30, 0)); + continue; + } + Ok(range) => range, + }; + if server_range.is_empty() { + log::error!("server range empty"); + sleep(time::Duration::new(100, 0)); + continue; + } + let self_range = self.range.get().await.expect("get range"); + if self_range.is_empty() { + match self.bootstrap_state(server_range.start).await { + Err(err) => { + log::error!("after some tries {:?}", err); + sleep(time::Duration::new(30, 0)); + continue; + } + Ok(_) => continue, + } + } else { + let right_diff = RangeJSON::diff( + self_range.clone(), + server_range, + self_range.end - 1, + self.max_height_gap, + ); + let result = match right_diff.is_empty() { + true => { + log::error!("server range is too far away"); + sleep(time::Duration::new(100, 0)); + continue; + } + false => self.process_ranges(right_diff, self_range.end - 1).await, + }; + if let Err(err) = result { + log::error!("{:?}", err); + thread::sleep(time::Duration::new(30, 0)); + } + } + } + } +} diff --git a/replica-lib/src/triedb/client/sync/bootstrap.rs b/replica-lib/src/triedb/client/sync/bootstrap.rs new file mode 100644 index 0000000000..d0d088b14e --- /dev/null +++ b/replica-lib/src/triedb/client/sync/bootstrap.rs @@ -0,0 +1,169 @@ +use evm_state::{storage::account_extractor, BlockNum, H256}; +use triedb::gc::DbCounter; +use triedb::gc::RootGuard; + +use crate::triedb::client::proto::app_grpc::backend_client::BackendClient; +use crate::triedb::client::Client; +use crate::triedb::error::client; +use crate::triedb::error::client::bootstrap::fetch_nodes; +use crate::triedb::ReadRange; +use crate::triedb::WriteRange; +use crate::triedb::{collection, error::client::bootstrap, EvmHeightIndex}; + +use self::splice_count_stack::SpliceCountStack; + +mod helpers; +mod splice_count_stack; + +type NodeFullInfo = ((H256, bool), Vec); + +impl Client +where + S: EvmHeightIndex + Sync, +{ + pub async fn fetch_nodes_of_hashes( + client: &mut BackendClient, + rpc_address: &String, + input: Vec<(H256, bool)>, + ) -> Result)>, fetch_nodes::Error> { + let response = { + let input = input.iter().map(|el| el.0).collect(); + Self::get_array_of_nodes_retried(client, rpc_address, input).await + }; + + let nodes = match response { + Ok(Ok(result)) => result, + Ok(Err(fast)) => { + let err = fetch_nodes::get::Error::Fast(fast); + let err = fetch_nodes::Error::Get(input.len(), err); + Err(err) + }?, + Err(slow) => { + let err = fetch_nodes::get::Error::Slow(slow); + let err = fetch_nodes::Error::Get(input.len(), err); + Err(err) + }?, + }; + + if nodes.nodes.len() != input.len() { + return Err(client::proto::Error::NodesLenMismatch( + input.len(), + nodes.nodes.len(), + ))?; + } + + for (index, element) in input.iter().enumerate() { + helpers::verify_hash(&nodes.nodes[index], element.0)?; + } + + let res: Vec<_> = input.into_iter().zip(nodes.nodes).collect(); + Ok(res) + } + + pub async fn bootstrap_state(&mut self, height: BlockNum) -> Result<(), bootstrap::Error> { + if self.range.get().await.expect("get range").contains(&height) { + log::warn!("skipping height {} as already present", height); + return Ok(()); + } + + let root_hash = self + .block_storage + .get_evm_confirmed_state_root_retried(height) + .await?; + log::info!( + "starting bootstrap at height {}, hash {:?}", + height, + root_hash + ); + + match self.check_height(root_hash, height).await { + Ok(..) => {} + Err(err) => match err { + mismatch @ client::check_height::Error::HashMismatch { .. } => { + panic!("different chains {:?}", mismatch); + } + other => { + return Err(other)?; + } + }, + }; + let collection = collection(&self.storage); + + let mut stack_children: SpliceCountStack> = + SpliceCountStack::new("children".to_string()); + + let mut stack_fetched: SpliceCountStack, fetch_nodes::Error>> = + SpliceCountStack::new("fetched and verified data".to_string()); + + let root_guard = RootGuard::new(&collection.database, root_hash, account_extractor); + let first_with_data = Self::fetch_nodes_of_hashes( + &mut self.client, + &self.state_rpc_address, + vec![(root_hash, true)], + ) + .await; + let first_with_data = first_with_data?; + + let children_layer = helpers::compute_and_maybe_split_children(&first_with_data)?; + children_layer.into_iter().for_each(|childs_vec| { + stack_children.push(childs_vec); + }); + let mut total: usize = 0; + for ((hash, _direct), value) in first_with_data { + collection + .database + .gc_insert_node(hash, &value, account_extractor); + total += 1; + } + loop { + let fetched = stack_fetched.pop(); + match fetched { + Some(fetched) => { + let fetched = fetched?; + let children_layer = helpers::compute_and_maybe_split_children(&fetched)?; + children_layer.into_iter().for_each(|childs_vec| { + stack_children.push(childs_vec); + }); + for ((hash, _direct), value) in fetched { + collection + .database + .gc_insert_node(hash, &value, account_extractor); + total += 1; + if total % 200_000 == 0 { + log::info!("bootstrapping ... {}", total); + } + } + } + None => { + let next_child_slice = stack_children.pop(); + match next_child_slice { + Some(next_child_slice) => { + let first_with_data = Self::fetch_nodes_of_hashes( + &mut self.client, + &self.state_rpc_address, + next_child_slice, + ) + .await; + stack_fetched.push(first_with_data); + } + None => { + break; + } + } + } + } + } + + let to = root_guard.leak_root(); + log::debug!("persisted root {} {}", to, total); + collection.database.gc_pin_root(to); + log::debug!( + "persisted root count after leak {}", + collection.database.gc_count(to) + ); + self.range.update(height).expect("persist range update"); + self.range.flush().expect("persist range update"); + + Ok(()) + } +} diff --git a/replica-lib/src/triedb/client/sync/bootstrap/helpers.rs b/replica-lib/src/triedb/client/sync/bootstrap/helpers.rs new file mode 100644 index 0000000000..bad16c4a50 --- /dev/null +++ b/replica-lib/src/triedb/client/sync/bootstrap/helpers.rs @@ -0,0 +1,66 @@ +use evm_state::{storage::account_extractor, H256}; + +use rlp::Rlp; +use sha3::{Digest, Keccak256}; +use triedb::{gc::ReachableHashes, merkle::MerkleNode}; + +use crate::triedb::{error::client, MAX_CHUNK_HASHES}; + +pub fn no_childs(_: &[u8]) -> Vec { + vec![] +} +pub(super) fn verify_hash(value: &[u8], hash: H256) -> Result<(), client::proto::Error> { + let actual_hash = H256::from_slice(Keccak256::digest(value).as_slice()); + if hash != actual_hash { + return Err(client::proto::Error::NodesHashMismatch(hash, actual_hash))?; + } + Ok(()) +} + +fn map_node_to_next_layer( + parent: &((H256, bool), Vec), +) -> Result, triedb::Error> { + let ((_hash, direct), node) = parent; + let node = MerkleNode::decode(&Rlp::new(node))?; + + let (direct_childs, indirect_childs) = if *direct { + ReachableHashes::collect(&node, account_extractor).childs() + } else { + // prevent more than one layer of indirection + let childs = ReachableHashes::collect(&node, no_childs).childs(); + assert!( + childs.1.is_empty(), + "There should be no subtrie with 'no_childs' extractor" + ); + // All direct childs for indirect childs should be handled as indirect. + (vec![], childs.0) + }; + + let paths: Vec<_> = direct_childs + .into_iter() + .map(|k| (k, true)) + .chain(indirect_childs.into_iter().map(|k| (k, false))) + .collect(); + Ok(paths) +} +pub(super) fn compute_and_maybe_split_children( + layer: &Vec<((H256, bool), Vec)>, +) -> Result>, triedb::Error> { + let mut childs_all = vec![]; + for element in layer { + let res = map_node_to_next_layer(element)?; + childs_all.extend(res.into_iter()); + } + let res: Vec<_> = if childs_all.len() > MAX_CHUNK_HASHES { + childs_all + .rchunks(MAX_CHUNK_HASHES) + .map(|el| el.to_vec()) + .filter(|el| !el.is_empty()) + .collect() + } else if childs_all.is_empty() { + vec![] + } else { + vec![childs_all] + }; + Ok(res) +} diff --git a/replica-lib/src/triedb/client/sync/bootstrap/splice_count_stack.rs b/replica-lib/src/triedb/client/sync/bootstrap/splice_count_stack.rs new file mode 100644 index 0000000000..296b95279c --- /dev/null +++ b/replica-lib/src/triedb/client/sync/bootstrap/splice_count_stack.rs @@ -0,0 +1,75 @@ +// one - SpliceCountStack> +// two - SpliceCountStack)>>> +pub struct SpliceCountStack { + tag: String, + inner: Vec, + count: Option, +} + +pub trait Length { + fn length(&self) -> Option; +} + +impl Length for Vec { + fn length(&self) -> Option { + Some(self.len()) + } +} + +impl Length for Result, ERR> { + fn length(&self) -> Option { + match self { + Ok(vecy) => Some(vecy.len()), + Err(..) => None, + } + } +} + +impl SpliceCountStack { + pub fn new(tag: String) -> Self { + Self { + inner: Vec::new(), + count: Some(0), + tag, + } + } +} + +impl SpliceCountStack { + pub fn push(&mut self, chunk: S) { + if let Some(length) = chunk.length() { + if length == 0 { + panic!("cannot push empty chunks, no use"); + } + if let Some(count) = self.count { + self.count = Some(count + length); + } + } else { + self.count = None; + } + self.inner.push(chunk); + log::debug!( + "(after push) current total \"{}\": {:?}", + self.tag, + self.count + ); + } + pub fn pop(&mut self) -> Option { + let ret = self.inner.pop(); + if let Some(ref chunk) = ret { + if let Some(length) = chunk.length() { + if let Some(count) = self.count { + self.count = Some(count - length); + } + } else { + self.count = None; + } + } + log::debug!( + "(after pop) current total \"{}\": {:?}", + self.tag, + self.count + ); + ret + } +} diff --git a/replica-lib/src/triedb/client/sync/common.rs b/replica-lib/src/triedb/client/sync/common.rs new file mode 100644 index 0000000000..b2dba3056f --- /dev/null +++ b/replica-lib/src/triedb/client/sync/common.rs @@ -0,0 +1,36 @@ +use evm_state::{BlockNum, H256}; + +use crate::triedb::{client::Client, error::client, EvmHeightIndex, TryConvert}; + +impl Client +where + S: EvmHeightIndex + Sync, +{ + pub(super) async fn check_height( + &mut self, + expected_hash: H256, + kickstart_point: BlockNum, + ) -> Result { + let prefetch = self.prefetch_height_retried(kickstart_point).await; + + let hash = match prefetch { + Ok(reply) => { + let reply = reply.ok_or(client::check_height::Error::HeightAbsent { + height: kickstart_point, + })?; + let hash = >::try_from(reply.hash); + hash.map_err(Into::::into) + } + Err(err) => Err(err.into()), + }?; + + if hash != expected_hash { + return Err(client::check_height::Error::HashMismatch { + actual: hash, + expected: expected_hash, + height: kickstart_point, + }); + } + Ok(hash) + } +} diff --git a/replica-lib/src/triedb/client/sync/range_processor.rs b/replica-lib/src/triedb/client/sync/range_processor.rs new file mode 100644 index 0000000000..3c1a9fb4d8 --- /dev/null +++ b/replica-lib/src/triedb/client/sync/range_processor.rs @@ -0,0 +1,156 @@ +use std::{ops::Range, time::Duration}; + +use evm_state::BlockNum; +use tokio::{sync::mpsc, time::sleep}; + +use crate::triedb::{ + client::Client, error::client, EvmHeightIndex, WriteRange, MAX_PREFETCH_RANGE_CHUNK, +}; + +use self::{chunked_range::ChunkedRange, kickstart_point::KickStartPoint}; +mod chunked_range; +mod kickstart_point; +mod kilosievert; + +impl Client +where + S: EvmHeightIndex + Clone + Sync + Send + 'static, +{ + pub(super) async fn process_ranges( + &mut self, + ranges: Vec>, + kickstart_point: BlockNum, + ) -> Result<(), client::range_sync::Error> { + let expected_hash = self + .block_storage + .get_evm_confirmed_state_root_retried(kickstart_point) + .await?; + + let hash = match self.check_height(expected_hash, kickstart_point).await { + Ok(hash) => hash, + Err(err) => match err { + mismatch @ client::check_height::Error::HashMismatch { .. } => { + panic!("different chains {:?}", mismatch); + } + other => { + return Err(other)?; + } + }, + }; + + let ranges = ranges + .into_iter() + .flat_map(|range| ChunkedRange { + range, + chunk_size: MAX_PREFETCH_RANGE_CHUNK, + }) + .collect::>(); + + let mut kick = KickStartPoint::new(kickstart_point, hash); + for range in ranges { + kick = self.process_range(range, kick).await?; + } + if kick.get().height - kickstart_point < 10 { + sleep(Duration::new(3, 0)).await; + + } + Ok(()) + } + + pub(super) async fn process_range( + &mut self, + range: Range, + kickstart_point: KickStartPoint, + ) -> Result { + log::warn!("start range {:?}", range); + self.block_storage.prefetch_roots_retried(&range).await?; + + self.prefetch_range_retried(&range).await?; + + let (stage_one_output, stage_two_input) = mpsc::channel(STAGE_TWO_CHANNEL_CAPACITY); + let _jh_stage_one = tokio::task::spawn({ + let block_storage = self.block_storage.clone(); + let rpc_address = self.state_rpc_address.to_owned(); + let request_workers = self.request_workers; + + let range = range.clone(); + let kickstart_point = kickstart_point.clone(); + let client = self.client.clone(); + + async move { + kilosievert::concrete_chamber::process( + &client, + &block_storage, + range, + kickstart_point, + rpc_address, + stage_one_output, + request_workers, + ) + .await; + } + }); + + let (stage_two_output, mut stage_three_input) = mpsc::channel(STAGE_THREE_CHANNEL_CAPACITY); + let _jh_stage_two = tokio::task::spawn({ + let kickstart_point = kickstart_point.clone(); + let storage = self.storage.clone(); + let db_workers = self.db_workers; + + async move { + kilosievert::concrete_chamber::steel_container::process( + kickstart_point, + storage, + stage_two_input, + stage_two_output, + db_workers, + ) + .await; + } + }); + + let mut count_total_nodes = 0; + let mut thousands_count = 0; + let mut count_total_errs = 0; + let mut err_hundrends_count = 0; + while let Some(result) = stage_three_input.recv().await { + match result { + Err(err) => { + log::debug!("{:#?}", err); + count_total_errs += 1; + if count_total_errs / 100 > err_hundrends_count { + err_hundrends_count = count_total_errs / 100; + log::info!( + "running total nodes {}, errs {}", + count_total_nodes, + count_total_errs + ); + } + } + Ok(result) => { + log::debug!("{:#?}", result); + count_total_nodes += result.changeset_len; + if count_total_nodes / 100_000 > thousands_count { + thousands_count = count_total_nodes / 100_000; + log::info!( + "running total nodes {}, errs {}", + count_total_nodes, + count_total_errs + ); + } + self.range + .update(result.request.heights.1) + .expect("persist range"); + } + } + } + + log::warn!("done range {:?}", range); + self.range.flush().expect("persist range"); + Ok(kickstart_point) + } +} + +const STAGE_TWO_CHANNEL_CAPACITY: usize = 50; + +const STAGE_THREE_CHANNEL_CAPACITY: usize = 10000; diff --git a/replica-lib/src/triedb/client/sync/range_processor/chunked_range.rs b/replica-lib/src/triedb/client/sync/range_processor/chunked_range.rs new file mode 100644 index 0000000000..7002a04a0e --- /dev/null +++ b/replica-lib/src/triedb/client/sync/range_processor/chunked_range.rs @@ -0,0 +1,22 @@ +use evm_state::BlockNum; + +pub(super) struct ChunkedRange { + pub range: std::ops::Range, + pub chunk_size: BlockNum, +} + +impl Iterator for ChunkedRange { + type Item = std::ops::Range; + + fn next(&mut self) -> Option { + if self.range.is_empty() { + return None; + } + + let start = self.range.start; + let next = std::cmp::min(self.range.start + self.chunk_size, self.range.end); + + self.range.start = next; + Some(start..next) + } +} diff --git a/replica-lib/src/triedb/client/sync/range_processor/kickstart_point.rs b/replica-lib/src/triedb/client/sync/range_processor/kickstart_point.rs new file mode 100644 index 0000000000..8ffb509ad7 --- /dev/null +++ b/replica-lib/src/triedb/client/sync/range_processor/kickstart_point.rs @@ -0,0 +1,36 @@ +use std::sync::{Arc, Mutex}; + +use evm_state::{BlockNum, H256}; + +#[derive(Clone)] +pub struct KickStartPoint { + data: Arc>, +} + +#[derive(Clone, Copy)] +pub struct Entry { + pub height: BlockNum, + pub hash: H256, +} + +impl KickStartPoint { + pub fn new(height: BlockNum, hash: H256) -> Self { + let entry = Entry { height, hash }; + + Self { + data: Arc::new(Mutex::new(entry)), + } + } + + pub fn get(&self) -> Entry { + *self.data.lock().expect("poison") + } + + pub fn update(&self, height: BlockNum, hash: H256) { + let mut lock = self.data.lock().expect("poison"); + if height > lock.height { + lock.height = height; + lock.hash = hash; + } + } +} diff --git a/replica-lib/src/triedb/client/sync/range_processor/kilosievert.rs b/replica-lib/src/triedb/client/sync/range_processor/kilosievert.rs new file mode 100644 index 0000000000..054515eb25 --- /dev/null +++ b/replica-lib/src/triedb/client/sync/range_processor/kilosievert.rs @@ -0,0 +1,2 @@ +pub(super) mod concrete_chamber; +mod diff_stages; diff --git a/replica-lib/src/triedb/client/sync/range_processor/kilosievert/concrete_chamber.rs b/replica-lib/src/triedb/client/sync/range_processor/kilosievert/concrete_chamber.rs new file mode 100644 index 0000000000..41b1e6c8b7 --- /dev/null +++ b/replica-lib/src/triedb/client/sync/range_processor/kilosievert/concrete_chamber.rs @@ -0,0 +1,98 @@ +use std::{ + ops::Range, + sync::Arc, + time::{Duration, Instant}, +}; + +use evm_state::BlockNum; +use tokio::sync::{mpsc::Sender, Semaphore}; + +use crate::triedb::{ + client::{ + proto::app_grpc::backend_client::BackendClient, + sync::range_processor::kickstart_point::KickStartPoint, + }, + debug_elapsed, + error::client::range_sync::stages, + DiffRequest, EvmHeightIndex, +}; + +use super::diff_stages; + +pub mod steel_container; + +#[derive(Debug)] +pub struct StageOnePayload { + pub ledger_storage_dur: Duration, + pub diff_request_dur: Duration, + pub request: DiffRequest, + pub changeset: Vec, +} + +pub async fn process( + job_for_a_cowboy: &BackendClient, + block_storage: &S, + range: Range, + kickstart_point: KickStartPoint, + state_rpc_address: String, + stage_one_output: Sender>, + request_workers: u32, +) where + S: EvmHeightIndex + Clone + Sync + Send + 'static, +{ + let s = Arc::new(Semaphore::new(request_workers as usize)); + + for target in range { + let permit = s + .clone() + .acquire_owned() + .await + .expect("semaphore closed?!?"); + + let from = kickstart_point.get(); + let _jh = tokio::task::spawn({ + let block_storage = block_storage.clone(); + let state_rpc_address = state_rpc_address.clone(); + let job_for_a_cowboy = job_for_a_cowboy.clone(); + let stage_one_output = stage_one_output.clone(); + + async move { + let mut instant = Instant::now(); + let target_hash = block_storage + .get_evm_confirmed_state_root_retried(target) + .await; + let ledger_storage_dur = debug_elapsed(&mut instant); + let target_hash = match target_hash { + Ok(hash) => hash, + Err(err) => { + let send_res = stage_one_output.send(Err(err.into())).await; + if send_res.is_err() { + log::error!("stage two input closed"); + } + return; + } + }; + + let request = DiffRequest { + heights: (from.height, target), + expected_hashes: (from.hash, target_hash), + }; + let result = + diff_stages::one::(&job_for_a_cowboy, request, &state_rpc_address).await; + let result = result.map(|(diff_request_dur, request, changeset)| StageOnePayload { + ledger_storage_dur, + diff_request_dur, + request, + changeset, + }); + + let send_res = stage_one_output.send(result.map_err(Into::into)).await; + if send_res.is_err() { + log::error!("stage two input closed"); + } + + drop(permit); + } + }); + } +} diff --git a/replica-lib/src/triedb/client/sync/range_processor/kilosievert/concrete_chamber/steel_container.rs b/replica-lib/src/triedb/client/sync/range_processor/kilosievert/concrete_chamber/steel_container.rs new file mode 100644 index 0000000000..92e5def00e --- /dev/null +++ b/replica-lib/src/triedb/client/sync/range_processor/kilosievert/concrete_chamber/steel_container.rs @@ -0,0 +1,126 @@ +use std::{sync::Arc, time::Duration}; + +use evm_state::Storage; +use tokio::sync::{ + mpsc::{Receiver, Sender}, + Semaphore, +}; +use triedb::gc::DbCounter; + +use crate::triedb::{ + client::sync::range_processor::{kickstart_point::KickStartPoint, kilosievert::diff_stages}, + collection, + error::client::range_sync::stages, + DiffRequest, DB_SEMAPHORE_PERMITS_PER_LARGE_DIFF, +}; + +use super::StageOnePayload; + +#[derive(Debug)] +pub struct StageTwoPayload { + pub apply_duration: Duration, + pub request: DiffRequest, + pub changeset_len: usize, + pub result_root_gc_count: usize, +} + +const SEMAPHORE_PERMITS_THRESHOLD: u64 = 100_000; + +pub async fn process( + kickstart_point: KickStartPoint, + storage: Storage, + mut stage_two_input: Receiver>, + stage_two_output: Sender>, + db_workers: u32, +) { + let s = Arc::new(Semaphore::new(db_workers as usize)); + while let Some(stage_one_result) = stage_two_input.recv().await { + let stage_one = match stage_one_result { + Err(err) => { + let send_res = stage_two_output.send(Err(err.into())).await; + if send_res.is_err() { + log::error!("stage three input closed"); + } + continue; + } + Ok(stage_one) => stage_one, + }; + log::debug!( + "< {:?} {:?} {} > - {:#?} ", + stage_one.ledger_storage_dur, + stage_one.diff_request_dur, + stage_one.changeset.len(), + stage_one.request + ); + + let n_permits = if (stage_one.request.heights.1 - stage_one.request.heights.0) + > SEMAPHORE_PERMITS_THRESHOLD + { + DB_SEMAPHORE_PERMITS_PER_LARGE_DIFF + } else { + 1 + }; + let permit = s + .clone() + .acquire_many_owned(n_permits) + .await + .expect("semaphore closed?!?"); + let _jh = tokio::task::spawn({ + let stage_two_output = stage_two_output.clone(); + let storage = storage.clone(); + let kickstart_point = kickstart_point.clone(); + + async move { + let changeset_len = stage_one.changeset.len(); + // + // rocksdb's `ColumnFamily` being not `Send` prevents it being used across `await` point + // + let result = tokio::task::spawn_blocking(move || { + let result: Result = { + let collection = collection(&storage); + let apply_result = + diff_stages::two((stage_one.request, stage_one.changeset), &collection); + match apply_result { + Ok((duration, root_guard)) => { + let target = root_guard.leak_root(); + assert_eq!(stage_one.request.expected_hashes.1, target); + + collection.database.gc_pin_root(target); + let result_count = collection.database.gc_count(target); + kickstart_point.update(stage_one.request.heights.1, target); + Ok(StageTwoPayload { + apply_duration: duration, + changeset_len, + request: stage_one.request, + result_root_gc_count: result_count, + }) + } + Err(err) => { + let err = stages::two::Error::Apply(stage_one.request, err); + Err(err) + } + } + // let guard = + }; + result + }) + .await; + let result = match result { + Err(err) => { + let err = stages::two::Error::TaskPanicked(stage_one.request, err); + + Err(err) + } + Ok(result) => result, + }; + + let send_res = stage_two_output.send(result).await; + + if send_res.is_err() { + log::error!("stage three input closed"); + } + drop(permit); + } + }); + } +} diff --git a/replica-lib/src/triedb/client/sync/range_processor/kilosievert/diff_stages.rs b/replica-lib/src/triedb/client/sync/range_processor/kilosievert/diff_stages.rs new file mode 100644 index 0000000000..7d3a6a2e2d --- /dev/null +++ b/replica-lib/src/triedb/client/sync/range_processor/kilosievert/diff_stages.rs @@ -0,0 +1,131 @@ +use std::time::{Duration, Instant}; + +use evm_state::{storage::account_extractor, H256}; + +use crate::triedb::{ + client::{ + proto::{ + app_grpc::{backend_client::BackendClient, GetStateDiffReply}, + helpers, + }, + Client, + }, + debug_elapsed, + error::client::range_sync::stages, + lock_root, retry_logged, DiffRequest, RocksHandleA, +}; + +type ChildExtractorFn = fn(&[u8]) -> Vec; + +#[cfg(feature = "(schematic stages description)")] +pub async fn get_and_apply_diff<'a, S>( + client: &mut BackendClient, + request: DiffRequest, + state_rpc_address: &str, + collection: &'a triedb::gc::TrieCollection>, +) -> Result, ChildExtractorFn>, ClientError> { + use crate::triedb::DiffRequest; + + let one_output = one::(client, request, state_rpc_address).await?; + two(one_output, collection).await +} + +type OneResponse = Result; + +pub async fn get_diff_retried( + client: &BackendClient, + request: DiffRequest, + state_rpc_address: &str, +) -> Result { + retry_logged( + || { + let mut client = client.clone(); + async move { + let result = Client::::get_diff(&mut client, request, state_rpc_address).await; + match result { + Ok(res) => Ok(OneResponse::Ok(res)), + Err(err) => match err.into() { + stages::one::request::network::Error::Fast(fast) => Ok(Err(fast)), + stages::one::request::network::Error::Slow(slow) => Err(slow), + }, + } + } + }, + format!("get_diff {:?} {}", request, state_rpc_address), + log::Level::Trace, + ) + .await +} + +pub async fn one( + client: &BackendClient, + request: DiffRequest, + state_rpc_address: &str, +) -> Result<(Duration, DiffRequest, Vec), stages::one::request::Error> { + let mut start = Instant::now(); + + let response = get_diff_retried::(client, request, state_rpc_address).await; + + let network_dur = debug_elapsed(&mut start); + let response = match response { + Ok(Ok(result)) => result, + Ok(Err(fast)) => { + let err = stages::one::request::network::Error::Fast(fast); + let err = stages::one::request::Error::Network(request, err); + Err(err) + }?, + Err(slow) => { + let err = stages::one::request::network::Error::Slow(slow); + let err = stages::one::request::Error::Network(request, err); + Err(err) + }?, + }; + + let diff_changes = helpers::parse_diff_response(response) + .map_err(|err| stages::one::request::Error::Proto(request, err))?; + + let _ = debug_elapsed(&mut start); + Ok((network_dur, request, diff_changes)) +} + +pub fn two<'a>( + incoming: (DiffRequest, Vec), + collection: &'a triedb::gc::TrieCollection>, +) -> Result< + ( + Duration, + triedb::gc::RootGuard<'a, RocksHandleA<'a>, ChildExtractorFn>, + ), + stages::two::apply::Error, +> { + let mut start = Instant::now(); + let (request, diff_changes) = incoming; + + let diff_patch = triedb::verify_diff( + &collection.database, + request.expected_hashes.1, + diff_changes, + account_extractor, + false, + )?; + // let _ = debug_elapsed(&mut start); + + let _from_guard = lock_root( + &collection.database, + request.expected_hashes.0, + account_extractor, + )?; + // debug_elapsed(&mut start); + + let to_guard = + collection.apply_diff_patch(diff_patch, account_extractor as ChildExtractorFn)?; + let applied_dur = debug_elapsed(&mut start); + Ok((applied_dur, to_guard)) +} + +#[doc(hidden)] +#[cfg(feature = "(stage_three)")] +async fn stage_three() { + // unfortunately, the fact of presence of stage_three means, that the project is impossible + // to complete +} diff --git a/replica-lib/src/triedb/error.rs b/replica-lib/src/triedb/error.rs new file mode 100644 index 0000000000..9645a583d3 --- /dev/null +++ b/replica-lib/src/triedb/error.rs @@ -0,0 +1,37 @@ +use thiserror::Error; + +pub mod client; +mod common; +pub mod server; + +pub use common::evm_height; +pub use common::lock; + +#[cfg(test)] +mod tests; + +#[derive(Error, Debug)] +pub enum RangeJsonInitError { + #[error(transparent)] + IoError(#[from] std::io::Error), + #[error(transparent)] + SerdeJson(#[from] serde_json::Error), +} + +pub fn source_matches_type( + mut err: &(dyn std::error::Error + 'static), +) -> bool { + let type_name = std::any::type_name::(); + loop { + if let Some(transport) = err.downcast_ref::() { + log::error!("matching source type `{:?}`: `{}`", transport, type_name); + break true; + } + if let Some(source) = err.source() { + log::debug!("Caused by: {}", source); + err = source; + } else { + break false; + } + } +} diff --git a/replica-lib/src/triedb/error/client.rs b/replica-lib/src/triedb/error/client.rs new file mode 100644 index 0000000000..5867155213 --- /dev/null +++ b/replica-lib/src/triedb/error/client.rs @@ -0,0 +1,6 @@ +// common +pub mod check_height; +pub mod proto; + +pub mod bootstrap; +pub mod range_sync; diff --git a/replica-lib/src/triedb/error/client/bootstrap.rs b/replica-lib/src/triedb/error/client/bootstrap.rs new file mode 100644 index 0000000000..6a816250eb --- /dev/null +++ b/replica-lib/src/triedb/error/client/bootstrap.rs @@ -0,0 +1,20 @@ +use thiserror::Error; +use triedb::Error as TriedbError; + +use crate::triedb::error::evm_height; + +use super::check_height; + +pub mod fetch_nodes; + +#[derive(Error, Debug)] +pub enum Error { + #[error("evm height : `{0}`")] + EvmHeight(#[from] evm_height::Error), + #[error("fetch nodes: `{0}`")] + FetchNodes(#[from] fetch_nodes::Error), + #[error("check height: `{0}`")] + CheckHeight(#[from] check_height::Error), + #[error("triedb error {0}")] + Triedb(#[from] TriedbError), +} diff --git a/replica-lib/src/triedb/error/client/bootstrap/fetch_nodes.rs b/replica-lib/src/triedb/error/client/bootstrap/fetch_nodes.rs new file mode 100644 index 0000000000..eda038a388 --- /dev/null +++ b/replica-lib/src/triedb/error/client/bootstrap/fetch_nodes.rs @@ -0,0 +1,13 @@ +use thiserror::Error; + +use crate::triedb::error::client::proto; + +pub mod get; + +#[derive(Error, Debug)] +pub enum Error { + #[error("get nodes {0}")] + Get(usize, #[source] get::Error), + #[error("proto violated error {0}")] + Proto(#[from] proto::Error), +} diff --git a/replica-lib/src/triedb/error/client/bootstrap/fetch_nodes/get.rs b/replica-lib/src/triedb/error/client/bootstrap/fetch_nodes/get.rs new file mode 100644 index 0000000000..8c14f10133 --- /dev/null +++ b/replica-lib/src/triedb/error/client/bootstrap/fetch_nodes/get.rs @@ -0,0 +1,53 @@ +use tonic::Code; + +use thiserror::Error; + +#[derive(Error, Debug)] +#[error("the last after many retries {0:?}")] +pub struct SlowError(#[source] tonic::Status); + +#[derive(Error, Debug)] +pub enum FastError { + #[error("server exceeded max chunk of get nodes {0:?}")] + ExceedMaxChunk(#[source] tonic::Status), + #[error("server could not parse hash {0:?}")] + ParseHash(#[source] tonic::Status), + #[error("server not found {0:?}")] + NotFound(#[source] tonic::Status), + #[error("unknown {0:?}")] + Unknown(#[source] tonic::Status), +} + +#[derive(Error, Debug)] +pub enum Error { + #[error("fast {0}")] + Fast(FastError), + #[error("retried {0}")] + Slow(SlowError), +} + +impl From for Error { + fn from(value: tonic::Status) -> Self { + match value.code() { + Code::FailedPrecondition => match value.message() { + message if message.contains("ExceedNodesMaxChunk") => { + Self::Fast(FastError::ExceedMaxChunk(value)) + } + _ => Self::Fast(FastError::Unknown(value.clone())), + }, + Code::NotFound => match value.message() { + message if message.contains("NotFoundTop") => { + Self::Fast(FastError::NotFound(value)) + } + + _ => Self::Fast(FastError::Unknown(value.clone())), + }, + Code::InvalidArgument => match value.message() { + message if message.contains("HashParse") => Self::Fast(FastError::ParseHash(value)), + + _ => Self::Fast(FastError::Unknown(value.clone())), + }, + _ => Self::Slow(SlowError(value)), + } + } +} diff --git a/replica-lib/src/triedb/error/client/check_height.rs b/replica-lib/src/triedb/error/client/check_height.rs new file mode 100644 index 0000000000..8e2b491ee6 --- /dev/null +++ b/replica-lib/src/triedb/error/client/check_height.rs @@ -0,0 +1,20 @@ +use evm_state::{BlockNum, H256}; +use thiserror::Error; + +use super::proto; + +#[derive(Error, Debug)] +pub enum Error { + #[error("proto violated error {0}")] + Proto(#[from] proto::Error), + #[error("grpc error {0}")] + GRPCUnhandled(#[from] tonic::Status), + #[error("mismatch at height: {actual:?} instead of {expected:?}, {height}")] + HashMismatch { + actual: H256, + expected: H256, + height: BlockNum, + }, + #[error("prefetch height absent: {height}")] + HeightAbsent { height: BlockNum }, +} diff --git a/replica-lib/src/triedb/error/client/proto.rs b/replica-lib/src/triedb/error/client/proto.rs new file mode 100644 index 0000000000..9831e331a6 --- /dev/null +++ b/replica-lib/src/triedb/error/client/proto.rs @@ -0,0 +1,14 @@ +use evm_state::H256; +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum Error { + #[error("invalid GetStateDiffReply: some of the hashes is empty")] + EmptyHash, + #[error("invalid GetStateDiffReply: could not parse hash \"{0}\"")] + ParseHash(String), + #[error("GetArrayOfNodesReply: len mismatch on input/output {0} {1}")] + NodesLenMismatch(usize, usize), + #[error("GetArrayOfNodesReply: hash mismatch on expected/actual{0:?} {1:?}")] + NodesHashMismatch(H256, H256), +} diff --git a/replica-lib/src/triedb/error/client/range_sync.rs b/replica-lib/src/triedb/error/client/range_sync.rs new file mode 100644 index 0000000000..084f872bcd --- /dev/null +++ b/replica-lib/src/triedb/error/client/range_sync.rs @@ -0,0 +1,21 @@ +use thiserror::Error; + +use crate::triedb::error::{evm_height, lock}; + +use super::{check_height, proto}; + +pub mod stages; + +#[derive(Error, Debug)] +pub enum Error { + #[error("proto violated error {0}")] + Proto(#[from] proto::Error), + #[error("check height: `{0}`")] + CheckHeight(#[from] check_height::Error), + #[error(transparent)] + Lock(#[from] lock::Error), + #[error("grpc error {0}")] + GRPCUnhandled(#[from] tonic::Status), + #[error("evm height : `{0}`")] + EvmHeight(#[from] evm_height::Error), +} diff --git a/replica-lib/src/triedb/error/client/range_sync/stages.rs b/replica-lib/src/triedb/error/client/range_sync/stages.rs new file mode 100644 index 0000000000..486a47cbd8 --- /dev/null +++ b/replica-lib/src/triedb/error/client/range_sync/stages.rs @@ -0,0 +1,2 @@ +pub mod one; +pub mod two; diff --git a/replica-lib/src/triedb/error/client/range_sync/stages/one.rs b/replica-lib/src/triedb/error/client/range_sync/stages/one.rs new file mode 100644 index 0000000000..2916901d21 --- /dev/null +++ b/replica-lib/src/triedb/error/client/range_sync/stages/one.rs @@ -0,0 +1,13 @@ +use thiserror::Error; + +use crate::triedb::error::evm_height; + +pub mod request; + +#[derive(Error, Debug)] +pub enum Error { + #[error("request {0}")] + Request(#[from] request::Error), + #[error("evm_height {0}")] + EvmHeight(#[from] evm_height::Error), +} diff --git a/replica-lib/src/triedb/error/client/range_sync/stages/one/request.rs b/replica-lib/src/triedb/error/client/range_sync/stages/one/request.rs new file mode 100644 index 0000000000..e3828d5fb9 --- /dev/null +++ b/replica-lib/src/triedb/error/client/range_sync/stages/one/request.rs @@ -0,0 +1,13 @@ +use thiserror::Error; + +use crate::triedb::{error::client::proto, DiffRequest}; + +pub mod network; + +#[derive(Error, Debug)] +pub enum Error { + #[error("network {0:?} {1}")] + Network(DiffRequest, #[source] network::Error), + #[error("parse diff response {0:?} {1}")] + Proto(DiffRequest, #[source] proto::Error), +} diff --git a/replica-lib/src/triedb/error/client/range_sync/stages/one/request/network.rs b/replica-lib/src/triedb/error/client/range_sync/stages/one/request/network.rs new file mode 100644 index 0000000000..796265d86f --- /dev/null +++ b/replica-lib/src/triedb/error/client/range_sync/stages/one/request/network.rs @@ -0,0 +1,77 @@ +use thiserror::Error; + +use tonic::Code; + +#[derive(Error, Debug)] +pub enum FastError { + #[error("server hash mismatch {0:?}")] + HashMismatch(#[source] tonic::Status), + #[error("server blocks too far {0:?}")] + ExceedDiffMaxGap(#[source] tonic::Status), + #[error("server block not found {0:?}")] + BlockNotFound(#[source] tonic::Status), + #[error("server zero height metadata reqeusted {0:?}")] + ZeroHeight(#[source] tonic::Status), + #[error("server proto, empty hash {0:?}")] + EmptyHash(#[source] tonic::Status), + #[error("server proto, could not parse {0:?}")] + ParseHash(#[source] tonic::Status), + #[error("server lock or check root, {0:?}")] + LockRoot(#[source] tonic::Status), + #[error("server deeply broken tree, {0:?}")] + TreeBroken(#[source] tonic::Status), + #[error("unknown {0:?}")] + Unknown(#[source] tonic::Status), +} + +#[derive(Error, Debug)] +#[error("the last after many retries {0:?}")] +pub struct SlowError(#[source] tonic::Status); + +#[derive(Error, Debug)] +pub enum Error { + #[error("fast {0}")] + Fast(FastError), + #[error("retried {0}")] + Slow(SlowError), +} + +impl From for Error { + fn from(value: tonic::Status) -> Self { + match value.code() { + Code::FailedPrecondition => match value.message() { + message if message.contains("HashMismatch") => { + Self::Fast(FastError::HashMismatch(value)) + } + message if message.contains("ExceedBlocksMaxGap") => { + Self::Fast(FastError::ExceedDiffMaxGap(value)) + } + _ => Self::Fast(FastError::Unknown(value.clone())), + }, + Code::NotFound => match value.message() { + message if message.contains("Bigtable(BlockNotFound") => { + Self::Fast(FastError::BlockNotFound(value)) + } + message if message.contains("NotFoundTop") => { + Self::Fast(FastError::LockRoot(value)) + } + + message if message.contains("NotFoundNested") => { + Self::Fast(FastError::TreeBroken(value)) + } + + _ => Self::Fast(FastError::Unknown(value.clone())), + }, + Code::InvalidArgument => match value.message() { + message if message.contains("ForbidZero") => { + Self::Fast(FastError::ZeroHeight(value)) + } + message if message.contains("HashEmpty") => Self::Fast(FastError::EmptyHash(value)), + message if message.contains("HashParse") => Self::Fast(FastError::ParseHash(value)), + + _ => Self::Fast(FastError::Unknown(value.clone())), + }, + _ => Self::Slow(SlowError(value)), + } + } +} diff --git a/replica-lib/src/triedb/error/client/range_sync/stages/two.rs b/replica-lib/src/triedb/error/client/range_sync/stages/two.rs new file mode 100644 index 0000000000..933dfcbfdc --- /dev/null +++ b/replica-lib/src/triedb/error/client/range_sync/stages/two.rs @@ -0,0 +1,18 @@ +use thiserror::Error; +use tokio::task::JoinError; + +use crate::triedb::DiffRequest; + +use super::one; + +pub mod apply; + +#[derive(Error, Debug)] +pub enum Error { + #[error("stage one {0}")] + StageOne(#[from] one::Error), + #[error("apply {0:?} {1}")] + Apply(DiffRequest, #[source] apply::Error), + #[error("joined blocking db task panicked {0:?} {1}")] + TaskPanicked(DiffRequest, #[source] JoinError), +} diff --git a/replica-lib/src/triedb/error/client/range_sync/stages/two/apply.rs b/replica-lib/src/triedb/error/client/range_sync/stages/two/apply.rs new file mode 100644 index 0000000000..49ae889ad9 --- /dev/null +++ b/replica-lib/src/triedb/error/client/range_sync/stages/two/apply.rs @@ -0,0 +1,13 @@ +use thiserror::Error; + +use triedb::Error as TriedbError; + +use crate::triedb::error::lock; + +#[derive(Error, Debug)] +pub enum Error { + #[error("triedb error {0}")] + Triedb(#[from] TriedbError), + #[error("lock error {0}")] + Lock(#[from] lock::Error), +} diff --git a/replica-lib/src/triedb/error/common.rs b/replica-lib/src/triedb/error/common.rs new file mode 100644 index 0000000000..9d70189af1 --- /dev/null +++ b/replica-lib/src/triedb/error/common.rs @@ -0,0 +1,2 @@ +pub mod evm_height; +pub mod lock; diff --git a/replica-lib/src/triedb/error/common/evm_height.rs b/replica-lib/src/triedb/error/common/evm_height.rs new file mode 100644 index 0000000000..1fe0172d4a --- /dev/null +++ b/replica-lib/src/triedb/error/common/evm_height.rs @@ -0,0 +1,41 @@ +use evm_state::BlockNum; +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum Error { + #[error("bigtable error : `{0}`")] + Bigtable(#[from] solana_storage_bigtable::Error), + + #[error("blockstore error : `{0}`")] + Blockstore(#[from] solana_ledger::blockstore::BlockstoreError), + + #[error("not found : `{0}`")] + NoHeightFound(BlockNum), + #[error("no first block found")] + NoFirst, + #[error("no first block found")] + NoLast, + #[error("zero hight forbidden")] + ForbidZero, + #[error("max block chunk exceeded: {actual}, {max}")] + ExceedMaxChunk { actual: BlockNum, max: BlockNum }, +} + +impl From for tonic::Status { + fn from(err: Error) -> Self { + match err { + Error::Bigtable(ref bigtable) => match bigtable { + solana_storage_bigtable::Error::BlockNotFound(..) => { + tonic::Status::not_found(format!("{:?}", err)) + } + _ => tonic::Status::internal(format!("{:?}", err)), + }, + Error::Blockstore { .. } => tonic::Status::internal(format!("{:?}", err)), + Error::ForbidZero => tonic::Status::invalid_argument(format!("{:?}", err)), + Error::ExceedMaxChunk { .. } => tonic::Status::resource_exhausted(format!("{:?}", err)), + Error::NoHeightFound { .. } => tonic::Status::not_found(format!("{:?}", err)), + Error::NoFirst { .. } => tonic::Status::out_of_range(format!("{:?}", err)), + Error::NoLast { .. } => tonic::Status::out_of_range(format!("{:?}", err)), + } + } +} diff --git a/replica-lib/src/triedb/error/common/lock.rs b/replica-lib/src/triedb/error/common/lock.rs new file mode 100644 index 0000000000..a294cbc201 --- /dev/null +++ b/replica-lib/src/triedb/error/common/lock.rs @@ -0,0 +1,30 @@ +use thiserror::Error; + +use evm_state::H256; +use rocksdb::Error as RocksError; + +#[derive(Error, Debug)] +pub enum Error { + #[error("not found (top level): {0:?}")] + NotFoundTop(H256), + #[error( + "not found (nested in GetStateDiffRequest): either under {from:?} or {to:?}, {description}" + )] + NotFoundNested { + from: H256, + to: H256, + description: String, + }, + #[error(transparent)] + RocksDB(#[from] RocksError), +} + +impl From for tonic::Status { + fn from(err: Error) -> Self { + match err { + Error::NotFoundTop(..) => tonic::Status::not_found(format!("{:?}", err)), + Error::NotFoundNested { .. } => tonic::Status::not_found(format!("{:?}", err)), + Error::RocksDB { .. } => tonic::Status::internal(format!("{:?}", err)), + } + } +} diff --git a/replica-lib/src/triedb/error/server.rs b/replica-lib/src/triedb/error/server.rs new file mode 100644 index 0000000000..fabaca3bd8 --- /dev/null +++ b/replica-lib/src/triedb/error/server.rs @@ -0,0 +1,55 @@ +use evm_state::{BlockNum, H256}; +use std::ops::Range; +use thiserror::Error; + +use super::{evm_height, lock}; + +use rocksdb::Error as RocksError; + +pub mod proto; + +#[derive(Error, Debug)] +pub enum Error { + #[error("proto violated error {0}")] + Proto(#[from] proto::Error), + #[error("evm height : `{0}`")] + EvmHeight(#[from] evm_height::Error), + // probably means different chains or forks were involved + #[error("not completely present {ours:?}, requested - {requested:?}")] + PrefetchRange { + ours: Range, + requested: Range, + }, + #[error("hash mismatch in GetStateDiffRequest: height: {height}, expected: {expected}, actual: {actual}")] + HashMismatch { + height: evm_state::BlockNum, + expected: H256, + actual: H256, + }, + #[error("rocksdb error {0}")] + RocksDB(#[from] RocksError), + #[error(transparent)] + Lock(#[from] lock::Error), + #[error("triedb diff")] + TriedbDiff, +} + +impl From for tonic::Status { + fn from(err: Error) -> Self { + match err { + Error::Proto(err) => err.into(), + hash_mismatch @ Error::HashMismatch { .. } => { + tonic::Status::failed_precondition(format!("{:?}", hash_mismatch)) + } + Error::Lock(lock) => lock.into(), + rocks @ Error::RocksDB(..) => tonic::Status::internal(format!("{:?}", rocks)), + Error::EvmHeight(inner) => inner.into(), + triedb_diff @ Error::TriedbDiff => { + tonic::Status::internal(format!("{:?}", triedb_diff)) + } + prefetch_range @ Error::PrefetchRange { .. } => { + tonic::Status::not_found(format!("{:?}", prefetch_range)) + } + } + } +} diff --git a/replica-lib/src/triedb/error/server/proto.rs b/replica-lib/src/triedb/error/server/proto.rs new file mode 100644 index 0000000000..ab273bc365 --- /dev/null +++ b/replica-lib/src/triedb/error/server/proto.rs @@ -0,0 +1,29 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum Error { + #[error("invalid request: some of the hashes is empty")] + HashEmpty, + #[error("invalid request: could not parse hash \"{0}\"")] + HashParse(String), + #[error("get array of nodes request: exceeded max array len {actual}, max {max}")] + ExceedNodesMaxChunk { actual: usize, max: usize }, + #[error("requested diff of blocks too far away {from:?} -> {to:?}")] + ExceedBlocksMaxGap { from: u64, to: u64 }, +} + +impl From for tonic::Status { + fn from(err: Error) -> Self { + match err { + Error::HashEmpty | Error::HashParse(..) => { + tonic::Status::invalid_argument(format!("{:?}", err)) + } + Error::ExceedNodesMaxChunk { .. } => { + tonic::Status::failed_precondition(format!("{:?}", err)) + } + Error::ExceedBlocksMaxGap { .. } => { + tonic::Status::failed_precondition(format!("{:?}", err)) + } + } + } +} diff --git a/replica-lib/src/triedb/error/tests.rs b/replica-lib/src/triedb/error/tests.rs new file mode 100644 index 0000000000..7db6e715d3 --- /dev/null +++ b/replica-lib/src/triedb/error/tests.rs @@ -0,0 +1,198 @@ +use evm_state::empty_trie_hash; +use tonic::Code; + +use crate::triedb::error::{client, client::range_sync::stages::one, evm_height, lock, server}; + +#[test] +fn test_from_with_metadata_diff_request() { + { + let err = server::Error::HashMismatch { + height: 10, + expected: empty_trie_hash(), + actual: empty_trie_hash(), + }; + + let status: tonic::Status = err.into(); + + let result: one::request::network::Error = status.into(); + + assert_matches!( + result, + one::request::network::Error::Fast( + one::request::network::FastError::HashMismatch { .. } + ) + ); + } + // #### fence + { + let err = server::proto::Error::ExceedBlocksMaxGap { + from: 1, + to: 70000000, + }; + + let status: tonic::Status = err.into(); + + let result: one::request::network::Error = status.into(); + + assert_matches!( + result, + one::request::network::Error::Fast( + one::request::network::FastError::ExceedDiffMaxGap { .. } + ) + ); + } // #### fence + { + let random_status = + tonic::Status::new(Code::FailedPrecondition, "undecipherable gibberish"); + let random_status_result = random_status.into(); + assert_matches!( + random_status_result, + one::request::network::Error::Fast(one::request::network::FastError::Unknown(..)) + ); + } + // #### fence + { + let bt_err = solana_storage_bigtable::Error::BlockNotFound(70000000); + let evm_height = Into::::into(bt_err); + let err = Into::::into(evm_height); + + let status: tonic::Status = err.into(); + + let result: one::request::network::Error = status.into(); + + assert_matches!( + result, + one::request::network::Error::Fast( + one::request::network::FastError::BlockNotFound { .. } + ) + ); + } // #### fence + // #### fence + { + let evm_height = evm_height::Error::ForbidZero; + let err = Into::::into(evm_height); + + let status: tonic::Status = err.into(); + + let result: one::request::network::Error = status.into(); + + assert_matches!( + result, + one::request::network::Error::Fast(one::request::network::FastError::ZeroHeight { .. }) + ); + } // #### fence + // #### fence + { + let empty = server::proto::Error::HashEmpty; + let err = Into::::into(empty); + + let status: tonic::Status = err.into(); + + let result: one::request::network::Error = status.into(); + + assert_matches!( + result, + one::request::network::Error::Fast(one::request::network::FastError::EmptyHash { .. }) + ); + } // #### fence + + { + let parse = server::proto::Error::HashParse("gibberish".to_owned()); + let err = Into::::into(parse); + + let status: tonic::Status = err.into(); + + let result: one::request::network::Error = status.into(); + + assert_matches!( + result, + one::request::network::Error::Fast(one::request::network::FastError::ParseHash { .. }) + ); + } // #### fence + + { + let lock = lock::Error::NotFoundTop(empty_trie_hash()); + let err = Into::::into(lock); + + let status: tonic::Status = err.into(); + + let result: one::request::network::Error = status.into(); + + assert_matches!( + result, + one::request::network::Error::Fast(one::request::network::FastError::LockRoot { .. }) + ); + } // #### fence + + { + let lock = lock::Error::NotFoundNested { + from: empty_trie_hash(), + to: empty_trie_hash(), + description: "giggsdfsfl".to_owned(), + }; + let err = Into::::into(lock); + + let status: tonic::Status = err.into(); + + let result: one::request::network::Error = status.into(); + + assert_matches!( + result, + one::request::network::Error::Fast(one::request::network::FastError::TreeBroken { .. }) + ); + } // #### fence +} + +#[test] +fn test_from_with_metadata_get_nodes() { + { + let empty = server::proto::Error::ExceedNodesMaxChunk { + actual: 100, + max: 50, + }; + let err = Into::::into(empty); + + let status: tonic::Status = err.into(); + + let result: client::bootstrap::fetch_nodes::get::Error = status.into(); + + assert_matches!( + result, + client::bootstrap::fetch_nodes::get::Error::Fast( + client::bootstrap::fetch_nodes::get::FastError::ExceedMaxChunk { .. } + ) + ); + } + + { + let empty = server::proto::Error::HashParse("gibberish".to_string()); + let err = Into::::into(empty); + + let status: tonic::Status = err.into(); + + let result: client::bootstrap::fetch_nodes::get::Error = status.into(); + + assert_matches!( + result, + client::bootstrap::fetch_nodes::get::Error::Fast( + client::bootstrap::fetch_nodes::get::FastError::ParseHash { .. } + ) + ); + } + + { + let err = lock::Error::NotFoundTop(empty_trie_hash()); + + let status: tonic::Status = err.into(); + + let result: client::bootstrap::fetch_nodes::get::Error = status.into(); + + assert_matches!( + result, + client::bootstrap::fetch_nodes::get::Error::Fast( + client::bootstrap::fetch_nodes::get::FastError::NotFound { .. } + ) + ); + } +} +// #### fence diff --git a/replica-lib/src/triedb/mod.rs b/replica-lib/src/triedb/mod.rs new file mode 100644 index 0000000000..c29587068f --- /dev/null +++ b/replica-lib/src/triedb/mod.rs @@ -0,0 +1,178 @@ +pub mod bigtable; +mod blockstore; +pub mod client; +pub mod error; +pub mod range; +pub mod server; +pub use bigtable::CachedRootsLedgerStorage; +pub use server::config::{Config, HeightIndexSource, ParseError, RangeSource}; + +use std::{ + ops::Range, + time::{Duration, Instant}, +}; + +use evm_state::{BlockNum, Storage, H256}; +use triedb::{gc::DbCounter, Database}; + +use rocksdb::{DBWithThreadMode, SingleThreaded}; + +use self::error::{evm_height, lock}; + +use async_trait::async_trait; +use std::future::Future; + +type RocksHandleA<'a> = triedb::rocksdb::RocksHandle<'a, &'a triedb::rocksdb::DB>; + +pub(self) fn collection(storage: &Storage) -> triedb::gc::TrieCollection> { + triedb::gc::TrieCollection::new(storage.rocksdb_trie_handle()) +} + +pub trait TryConvert: Sized { + type Error; + + fn try_from(value: S) -> Result; +} + + +// maximum number of hashes for GetArrayOfNodesRequest (should be around 200 MB +// worth of corresponding nodes) +const MAX_CHUNK_HASHES: usize = 1_000_000; + +pub const DB_SEMAPHORE_PERMITS_PER_LARGE_DIFF: u32 = 10; + +const MAX_TIMES: usize = 8; +const MIN_DELAY_SEC: u64 = 1; + +#[derive(Clone, Copy, Debug)] +pub struct DiffRequest { + pub heights: (evm_state::BlockNum, evm_state::BlockNum), + pub expected_hashes: (H256, H256), +} + +async fn retry_logged( + mut f: FutureFn, + msg: String, + level: log::Level, +) -> Result +where + Fut: Future>, + FutureFn: FnMut() -> Fut, +{ + let mut count = 0; + let msg = &msg; + + log::log!(level, "attempting try to {} ({})", msg, count); + let mut result = (f)().await; + let mut delay = Duration::new(MIN_DELAY_SEC, 0); + + if let Err(..) = &result { + for _ in 0..MAX_TIMES - 1 { + tokio::time::sleep(delay).await; + + log::log!(level, "attempting try to {} ({})", msg, count); + result = (f)().await; + + if result.is_ok() { + break; + } + count += 1; + delay *= 2; + } + } + result +} + +#[async_trait] +pub trait WriteRange: ReadRange { + fn update(&self, index: BlockNum) -> std::io::Result<()>; + + fn flush(&self) -> std::io::Result<()>; +} + +#[async_trait] +pub trait ReadRange: Send + Sync { + async fn get(&self) -> Result, evm_height::Error>; +} + +#[async_trait] +pub trait EvmHeightIndex: Send + Sync { + async fn get_evm_confirmed_state_root( + &self, + block_num: evm_state::BlockNum, + ) -> Result, evm_height::Error>; + + async fn get_evm_confirmed_state_root_retried( + &self, + block_num: evm_state::BlockNum, + ) -> Result { + retry_logged( + || async { + let result = self.get_evm_confirmed_state_root(block_num).await; + match result { + Ok(Some(hash)) => Ok(hash), + Ok(None) => Err(evm_height::Error::NoHeightFound(block_num)), + Err(err) => Err(err), + } + }, + format!("get_evm_confirmed_state_root {}", block_num), + log::Level::Trace, + ) + .await + } + + async fn prefetch_roots( + &self, + range: &Range, + ) -> Result<(), evm_height::Error>; + + async fn prefetch_roots_retried( + &self, + range: &Range, + ) -> Result<(), evm_height::Error> { + retry_logged( + || async { self.prefetch_roots(range).await }, + format!("prefetch_roots {:?}", range), + log::Level::Info, + ) + .await + } +} + +// bigtable bulk api limited by Vladimir +const MAX_PREFETCH_RANGE_CHUNK: BlockNum = 5_000; + +pub(self) fn lock_root( + db: &D, + locked: H256, + func: F, +) -> Result, lock::Error> +where + D: Database + DbCounter, + F: FnMut(&[u8]) -> Vec, +{ + let guard = triedb::gc::RootGuard::new(db, locked, func); + if locked != triedb::empty_trie_hash() && !db.node_exist(locked) { + return Err(lock::Error::NotFoundTop(locked)); + } + Ok(guard) +} + +pub(self) fn check_root( + db: &DBWithThreadMode, + checked: H256, +) -> Result<(), lock::Error> +where +{ + if checked != triedb::empty_trie_hash() && db.get(checked)?.is_none() { + return Err(lock::Error::NotFoundTop(checked)); + } + Ok(()) +} + +pub fn debug_elapsed(start: &mut Instant) -> Duration { + let duration = start.elapsed(); + + *start = Instant::now(); + duration +} diff --git a/replica-lib/src/triedb/range.rs b/replica-lib/src/triedb/range.rs new file mode 100644 index 0000000000..f89472cd0b --- /dev/null +++ b/replica-lib/src/triedb/range.rs @@ -0,0 +1,155 @@ +use std::{ + path::{Path, PathBuf}, + sync::{Arc, Mutex, MutexGuard}, +}; + +use evm_state::BlockNum; +use rangemap::RangeSet; + +use super::{ + error::{evm_height, RangeJsonInitError}, + ReadRange, WriteRange, +}; +use async_trait::async_trait; +mod diff; + +/// Empty: +/// { +/// "range": { +/// "start": 0, +/// "end": 0 +/// } +/// } +/// +/// Non-empty: +/// { +/// "range": { +/// "start": 3197919, +/// "end": 3197932 +/// } +/// } +#[derive(Debug, Clone)] +struct Inner { + update_count: usize, + coarse: std::ops::Range, + fine: Option>, +} + +impl Inner { + fn deserialize_self(coarse: &str, fine: Option<&str>) -> Result { + let coarse: std::ops::Range = serde_json::from_str(coarse)?; + let fine: Option> = match fine { + None => None, + Some(fine) => Some(serde_json::from_str(fine)?), + }; + Ok(Self { + update_count: 0, + coarse, + fine, + }) + } + + fn serialize_self(&self) -> Result<(String, Option), serde_json::Error> { + let coarse_str = serde_json::to_string_pretty(&self.coarse)?; + let fine_str = match self.fine { + None => None, + Some(ref fine) => Some(serde_json::to_string_pretty(fine)?), + }; + Ok((coarse_str, fine_str)) + } + + fn update_coarse(&mut self, index: BlockNum) { + if self.coarse.is_empty() { + self.coarse = index..index + 1; + return; + } + if self.coarse.contains(&index) { + return; + } + if index >= self.coarse.end { + self.coarse.end = index + 1; + } else { + self.coarse.start = index; + } + } + fn update_fine(&mut self, index: BlockNum) { + if let Some(ref mut fine) = self.fine { + fine.insert(index..index + 1); + } + } + + fn update(&mut self, index: BlockNum) { + self.update_coarse(index); + self.update_fine(index); + } +} + +#[derive(Debug, Clone)] +pub struct RangeJSON { + coarse_file_path: PathBuf, + fine_file_path: Option, + inner: Arc>, +} + +const FLUSH_EVERY: usize = 100; + +impl RangeJSON { + pub fn new>( + coarse_file_path: P, + fine_file_path: Option

, + ) -> Result { + let coarse_str = std::fs::read_to_string(coarse_file_path.as_ref())?; + let fine_str = match fine_file_path { + Some(ref fine_file_path) => Some(std::fs::read_to_string(fine_file_path.as_ref())?), + None => None, + }; + let ranges: Inner = Inner::deserialize_self(&coarse_str, fine_str.as_deref())?; + log::info!("RangeJSON::new {:#?}", ranges); + Ok(Self { + inner: Arc::new(Mutex::new(ranges)), + coarse_file_path: coarse_file_path.as_ref().to_owned(), + fine_file_path: fine_file_path.map(|path| path.as_ref().to_owned()), + }) + } + + fn flush_internal(&self, inner: MutexGuard) -> std::io::Result<()> { + let (coarse, fine) = inner + .serialize_self() + .expect("serialization of a struct can never fail, can it"); + std::fs::write(&self.coarse_file_path, coarse.as_bytes())?; + if let Some(ref fine_file_path) = self.fine_file_path { + std::fs::write( + fine_file_path, + fine.expect("invariant broken: non null if fine_file_path is non-null") + .as_bytes(), + )?; + } + Ok(()) + } +} + +#[async_trait] +impl ReadRange for RangeJSON { + async fn get(&self) -> Result, evm_height::Error> { + let res = self.inner.lock().expect("lock poisoned").coarse.clone(); + Ok(res) + } +} +#[async_trait] +impl WriteRange for RangeJSON { + fn update(&self, index: BlockNum) -> std::io::Result<()> { + let mut inner = self.inner.lock().expect("lock poisoned"); + inner.update(index); + inner.update_count += 1; + if inner.update_count % FLUSH_EVERY == 0 { + self.flush_internal(inner)?; + } + Ok(()) + } + + fn flush(&self) -> std::io::Result<()> { + let inner = self.inner.lock().expect("lock poisoned"); + self.flush_internal(inner)?; + Ok(()) + } +} diff --git a/replica-lib/src/triedb/range/diff.rs b/replica-lib/src/triedb/range/diff.rs new file mode 100644 index 0000000000..153b67d301 --- /dev/null +++ b/replica-lib/src/triedb/range/diff.rs @@ -0,0 +1,282 @@ +use std::ops::Range; + +use evm_state::BlockNum; +use rangemap::RangeSet; + +use super::RangeJSON; + +impl RangeJSON { + fn event_horizon(kickstart_point: BlockNum, max_gap: usize) -> Range { + let start = kickstart_point.saturating_sub(max_gap as BlockNum); + let end = kickstart_point.saturating_add(max_gap as BlockNum + 1); + start..end + } + + fn filter_right(input: RangeSet, base: Range) -> Vec> { + let mut result = vec![]; + for element in input.into_iter() { + if element.start < base.start { + // forbidding backwards ranges for now + continue; + } else { + result.push(element); + } + } + result + } + fn intersect(a: &Range, b: &Range) -> Range { + let start = std::cmp::max(a.start, b.start); + let end = std::cmp::min(a.end, b.end); + start..end + } + fn bound(input: RangeSet, event_horizon: Range) -> RangeSet { + let bounded = input.overlapping(&event_horizon); + let mut result = RangeSet::new(); + for range in bounded { + result.insert(Self::intersect(range, &event_horizon)); + } + // println!("bounded: {:#?}", result); + result + } + + pub fn diff( + input: Range, + target: std::ops::Range, + kickstart_point: BlockNum, + max_gap: usize, + ) -> Vec> { + let from = RangeSet::from_iter([input.clone()]); + + let difference = RangeSet::from_iter(from.gaps(&target)); + // println!("difference: {:#?}", difference); + let event_horizon = Self::event_horizon(kickstart_point, max_gap); + // println!("event_horizon: {:#?}", event_horizon); + let bounded = Self::bound(difference, event_horizon); + Self::filter_right(bounded, input) + } +} + +#[cfg(test)] +mod tests { + use evm_state::BlockNum; + + use crate::triedb::range::RangeJSON; + const TEST_MAX_JUMP_OVER_ABYSS_GAP: usize = 100_000; + + const TEST_LARGE_MAX_JUMP_OVER_ABYSS_GAP: usize = 700_000; + + #[test] + fn test_1() { + let input = 1_000_000..1_005_000; + let target = 1..60_000_000; + let kickstart_point = 1_004_999; + println!("{:?} -> {:?} {:?}", input, target, kickstart_point); + let result = RangeJSON::diff(input, target, kickstart_point, TEST_MAX_JUMP_OVER_ABYSS_GAP); + println!("{:#?}", result); + + assert_eq!(1005000..1105000, result[0]); + assert_eq!( + 100000, + result + .clone() + .into_iter() + .flatten() + .collect::>() + .len() + ); + } + + #[test] + fn test_2() { + let input = 1_000_000..1_005_000; + let target = 1..60_000_000; + let kickstart_point = 1_000_000; + println!("{:?} -> {:?} {:?}", input, target, kickstart_point); + let result = RangeJSON::diff(input, target, kickstart_point, TEST_MAX_JUMP_OVER_ABYSS_GAP); + println!("{:#?}", result); + + assert_eq!(1005000..1100001, result[0]); + assert_eq!( + 95001, + result + .clone() + .into_iter() + .flatten() + .collect::>() + .len() + ); + } + + #[test] + fn test_3() { + let input = 1..2; + let target = 1..60_000_000; + let kickstart_point = 1; + println!("{:?} -> {:?} {:?}", input, target, kickstart_point); + let result = RangeJSON::diff(input, target, kickstart_point, TEST_MAX_JUMP_OVER_ABYSS_GAP); + println!("{:#?}", result); + + assert_eq!(2..100002, result[0]); + assert_eq!( + 100_000, + result + .clone() + .into_iter() + .flatten() + .collect::>() + .len() + ); + } + + #[test] + fn test_4() { + let input = 1..10002; + let target = 1..60_000_000; + let kickstart_point = 10001; + println!("{:?} -> {:?} {:?}", input, target, kickstart_point); + let result = RangeJSON::diff(input, target, kickstart_point, TEST_MAX_JUMP_OVER_ABYSS_GAP); + println!("{:#?}", result); + + assert_eq!(10002..110002, result[0]); + assert_eq!( + 100_000, + result + .clone() + .into_iter() + .flatten() + .collect::>() + .len() + ); + } + + #[test] + fn test_5() { + let input = 5000..95000; + let target = 1..60_000_000; + let kickstart_point = 94999; + println!("{:?} -> {:?} {:?}", input, target, kickstart_point); + let result = RangeJSON::diff(input, target, kickstart_point, TEST_MAX_JUMP_OVER_ABYSS_GAP); + println!("{:#?}", result); + + assert_eq!(95000..195000, result[0]); + assert_eq!( + 100_000, + result + .clone() + .into_iter() + .flatten() + .collect::>() + .len() + ); + } + + #[test] + fn test_6() { + let input = 100000..200000; + let target = 1..60_000_000; + let kickstart_point = 100000; + println!("{:?} -> {:?} {:?}", input, target, kickstart_point); + let result = RangeJSON::diff(input, target, kickstart_point, TEST_MAX_JUMP_OVER_ABYSS_GAP); + println!("{:#?}", result); + + assert_eq!(200000..200001, result[0]); + assert_eq!( + 1, + result + .clone() + .into_iter() + .flatten() + .collect::>() + .len() + ); + } + + #[test] + fn test_7() { + let input = 100000..200000; + let target = 1..60_000_000; + let kickstart_point = 200000; + println!("{:?} -> {:?} {:?}", input, target, kickstart_point); + let result = RangeJSON::diff(input, target, kickstart_point, TEST_MAX_JUMP_OVER_ABYSS_GAP); + println!("{:#?}", result); + + assert_eq!(200000..300001, result[0]); + assert_eq!( + 100_001, + result + .clone() + .into_iter() + .flatten() + .collect::>() + .len() + ); + } + + #[test] + fn test_8() { + let input = 1..200000; + let target = 200000..60_000_000; + let kickstart_point = 1; + println!("{:?} -> {:?} {:?}", input, target, kickstart_point); + let result = RangeJSON::diff(input, target, kickstart_point, TEST_MAX_JUMP_OVER_ABYSS_GAP); + println!("{:#?}", result); + + assert_eq!(0, result.len()); + assert_eq!( + 0, + result + .clone() + .into_iter() + .flatten() + .collect::>() + .len() + ); + } + + #[test] + fn test_9() { + let input = 1..200000; + let target = 200000..60_000_000; + let kickstart_point = 199999; + println!("{:?} -> {:?} {:?}", input, target, kickstart_point); + let result = RangeJSON::diff(input, target, kickstart_point, TEST_MAX_JUMP_OVER_ABYSS_GAP); + println!("{:#?}", result); + + assert_eq!(200000..300000, result[0]); + assert_eq!( + 100_000, + result + .clone() + .into_iter() + .flatten() + .collect::>() + .len() + ); + } + + #[test] + fn test_10() { + let input = 1..200000; + let target = 200000..60_000_000; + let kickstart_point = 199999; + println!("{:?} -> {:?} {:?}", input, target, kickstart_point); + let result = RangeJSON::diff( + input, + target, + kickstart_point, + TEST_LARGE_MAX_JUMP_OVER_ABYSS_GAP, + ); + println!("{:#?}", result); + + assert_eq!(200000..900000, result[0]); + assert_eq!( + TEST_LARGE_MAX_JUMP_OVER_ABYSS_GAP, + result + .clone() + .into_iter() + .flatten() + .collect::>() + .len() + ); + } +} diff --git a/replica-lib/src/triedb/server/config.rs b/replica-lib/src/triedb/server/config.rs new file mode 100644 index 0000000000..9504dc7fb8 --- /dev/null +++ b/replica-lib/src/triedb/server/config.rs @@ -0,0 +1,129 @@ +use std::num::ParseIntError; + +use clap::ArgMatches; +use evm_state::BlockNum; +use thiserror::Error; + +#[derive(Debug, Clone)] +pub enum RangeSource { + JSON { file: Option }, + SolanaBlockstore, + BigtableBlockstore, +} + +#[derive(Debug, Clone)] +pub enum HeightIndexSource { + SolanaBlockstore, + BigtableBlockstore, +} + +#[derive(Debug, Clone)] +pub struct Config { + pub range_source: RangeSource, + pub height_index_source: HeightIndexSource, + pub bigtable_length_hint: BlockNum, + pub max_diff_height_gap: usize, +} + +#[derive(Debug, Error)] +pub enum ParseError { + #[error("no range source specified")] + NoRangeSource, + #[error("no evm height index source specified")] + NoHeightIndex, + #[error("parse int error {0}")] + ParseInt(#[from] ParseIntError), + #[error("invalid option {0}, class {1}")] + InvalidOption(String, String), +} +const MAINNET_HINT_DEFAULT: &str = "62800000"; +// The difference between 58896219 and 59409340 is 513121. +// 700_000 =~ 513121 * 1.33 +// "Max difference of block height, that server won't reject diff requests of" +const MAX_HEIGHT_DIFF_DEFAULT: &str = "700000"; + +impl TryFrom<(&str, Option<&str>)> for RangeSource { + type Error = ParseError; + fn try_from(value: (&str, Option<&str>)) -> Result { + match value.0 { + "json" => Ok(RangeSource::JSON { + file: value.1.map(|str| str.to_string()), + }), + "bigtable" => Ok(RangeSource::BigtableBlockstore), + "solana_blockstore" => Ok(RangeSource::SolanaBlockstore), + _ => Err(ParseError::InvalidOption( + value.0.to_string(), + "range".to_string(), + )), + } + } +} + +impl TryFrom<&str> for HeightIndexSource { + type Error = ParseError; + fn try_from(value: &str) -> Result { + match value { + "bigtable" => Ok(HeightIndexSource::BigtableBlockstore), + "solana_blockstore" => Ok(HeightIndexSource::SolanaBlockstore), + _ => Err(ParseError::InvalidOption( + value.to_string(), + "height_index".to_string(), + )), + } + } +} + +impl Config { + pub fn parse_standalone(matches: &ArgMatches) -> Result { + let range_source = matches + .value_of("range_source") + .ok_or(ParseError::NoRangeSource)?; + let range_file = matches.value_of("range_file"); + let height_index_source = matches + .value_of("height_index_source") + .ok_or(ParseError::NoRangeSource)?; + let bigtable_length_hint: BlockNum = matches + .value_of("bigtable_length_hint") + .unwrap_or(MAINNET_HINT_DEFAULT) + .parse()?; + + let max_diff_height_gap: usize = matches + .value_of("max_height_diff") + .unwrap_or(MAX_HEIGHT_DIFF_DEFAULT) + .parse()?; + + let res = Self { + range_source: (range_source, range_file).try_into()?, + height_index_source: height_index_source.try_into()?, + bigtable_length_hint, + max_diff_height_gap, + }; + Ok(res) + } + + pub fn parse_validator(matches: &ArgMatches) -> Result { + let range_source = matches + .value_of("evm_height_index_source") + .ok_or(ParseError::NoRangeSource)?; + let range_file = None; + let height_index_source = matches + .value_of("evm_height_index_source") + .ok_or(ParseError::NoRangeSource)?; + let bigtable_length_hint: BlockNum = matches + .value_of("bigtable_evm_blockstore_length_hint") + .unwrap_or(MAINNET_HINT_DEFAULT) + .parse()?; + let max_diff_height_gap: usize= matches + .value_of("evm_state_rpc_max_height_diff") + .unwrap_or(MAX_HEIGHT_DIFF_DEFAULT) + .parse()?; + + let res = Self { + range_source: (range_source, range_file).try_into()?, + height_index_source: height_index_source.try_into()?, + bigtable_length_hint, + max_diff_height_gap, + }; + Ok(res) + } +} diff --git a/replica-lib/src/triedb/server/mod.rs b/replica-lib/src/triedb/server/mod.rs new file mode 100644 index 0000000000..4dc3a8c07a --- /dev/null +++ b/replica-lib/src/triedb/server/mod.rs @@ -0,0 +1,40 @@ +pub(crate) mod config; +mod proto; +mod service; + +use evm_state::{Storage as StorageOptimistic, StorageSecondary}; +pub use service::{RunError, RunningService, Service, StartError}; + +use self::proto::app_grpc::backend_server::BackendServer; + +use super::{EvmHeightIndex, ReadRange}; +// use derivative::Derivative; + +#[derive(Debug, Clone)] +pub enum UsedStorage { + WritableWithGC(StorageOptimistic), + ReadOnlyNoGC(StorageSecondary), +} + +pub struct Server { + storage: UsedStorage, + range: Box, + block_threshold: evm_state::BlockNum, + block_storage: Box, +} + +impl Server { + pub fn new( + storage: UsedStorage, + range: Box, + block_threshold: evm_state::BlockNum, + block_storage: Box, + ) -> BackendServer { + BackendServer::new(Server { + storage, + range, + block_threshold, + block_storage, + }) + } +} diff --git a/replica-lib/src/triedb/server/proto.rs b/replica-lib/src/triedb/server/proto.rs new file mode 100644 index 0000000000..d7ad4fd21d --- /dev/null +++ b/replica-lib/src/triedb/server/proto.rs @@ -0,0 +1,156 @@ +use evm_rpc::FormatHex; +use log::debug; + +use evm_state::H256; + +use super::Server; +use app_grpc::backend_server::{Backend, BackendServer}; +use tonic::{Request, Response, Status}; + +use app_grpc::PingReply; +pub mod app_grpc { + tonic::include_proto!("triedb_repl"); +} +mod helpers; +mod storage; + +use crate::triedb::{ + error::{evm_height, server}, + TryConvert, MAX_CHUNK_HASHES, +}; + +#[tonic::async_trait] +impl Backend for Server { + async fn ping(&self, request: Request<()>) -> Result, Status> { + debug!("got a ping request: {:?}", request); + + let reply = app_grpc::PingReply { + message: "ABDULA STATUS 7".to_string(), + }; + + Ok(Response::new(reply)) + } + + async fn get_array_of_nodes( + &self, + request: Request, + ) -> Result, Status> { + let request = request.into_inner(); + debug!( + "got a get_array_of_nodes request: {:?}", + request.hashes.len() + ); + if request.hashes.len() > MAX_CHUNK_HASHES { + return Err(server::proto::Error::ExceedNodesMaxChunk { + actual: request.hashes.len(), + max: MAX_CHUNK_HASHES, + })?; + } + let mut nodes = vec![]; + for hash in request.hashes { + let key = >::try_from(hash)?; + let bytes = self.get_node_body(key)?; + nodes.push(bytes); + } + + let reply = app_grpc::GetArrayOfNodesReply { nodes }; + + Ok(Response::new(reply)) + } + + async fn get_state_diff( + &self, + request: Request, + ) -> Result, Status> { + debug!("got a state_diff request: {:?}", request); + + let inner = request.into_inner(); + let height_diff = if inner.to >= inner.from { + inner.to - inner.from + } else { + inner.from - inner.to + }; + if height_diff > self.block_threshold { + return Err(server::proto::Error::ExceedBlocksMaxGap { + to: inner.to, + from: inner.from, + })?; + } + let (from_hash, to_hash) = self.fetch_state_roots(inner.from, inner.to).await?; + + helpers::check_hash(inner.from, inner.first_root, from_hash)?; + helpers::check_hash(inner.to, inner.second_root, to_hash)?; + Ok(self.state_diff_body(from_hash, to_hash)?) + } + + async fn get_block_range( + &self, + _request: tonic::Request<()>, + ) -> Result, tonic::Status> { + debug!("got a get_block_range request"); + let r: std::ops::Range = self.range.get().await?; + let reply = app_grpc::GetBlockRangeReply { + start: r.start, + end: r.end, + }; + + Ok(Response::new(reply)) + } + + async fn prefetch_height( + &self, + request: tonic::Request, + ) -> Result, tonic::Status> { + debug!("got a prefetch_height request {:?}", request); + let height = request.into_inner().height; + let hash = self + .block_storage + .get_evm_confirmed_state_root(height) + .await + .map_err(Into::::into)?; + + let hash = match hash { + Some(hash) => hash, + None => Err(evm_height::Error::NoHeightFound(height)) + .map_err(Into::::into)?, + }; + + // we have to minimally ensure a client has some basis to try to start work from + // otherwise a well-behaving client can trigger long chunks of work, all of which + // are doomed to fail + self.get_node_body(hash)?; + Ok(Response::new(app_grpc::PrefetchHeightReply { + hash: Some(app_grpc::Hash { + value: hash.format_hex(), + }), + })) + } + + async fn prefetch_range( + &self, + request: tonic::Request, + ) -> Result, tonic::Status> { + debug!("got a prefetch_range request {:?}", request); + let req = request.into_inner(); + let requested = req.start..req.end; + let self_range = self.range.get().await?; + if !self_range.contains(&requested.start) || !self_range.contains(&(requested.end - 1)) { + return Err(server::Error::PrefetchRange { + ours: self_range, + requested, + })?; + } + + self.block_storage + .prefetch_roots(&requested) + .await + .map_err(Into::::into)?; + Ok(Response::new(())) + } +} + +impl BackendServer { + pub fn join(&self) -> Result<(), ()> { + Ok(()) + } +} diff --git a/replica-lib/src/triedb/server/proto/helpers.rs b/replica-lib/src/triedb/server/proto/helpers.rs new file mode 100644 index 0000000000..faa0772021 --- /dev/null +++ b/replica-lib/src/triedb/server/proto/helpers.rs @@ -0,0 +1,104 @@ +use std::time::Instant; + +use evm_rpc::FormatHex; +use evm_state::H256; +use triedb::DiffChange; + +use crate::triedb::{ + debug_elapsed, + error::{evm_height, server}, + server::Server, + TryConvert, +}; + +use super::app_grpc; + +impl TryConvert for H256 { + type Error = server::Error; + + fn try_from(hash: app_grpc::Hash) -> Result { + let res = H256::from_hex(&hash.value) + .map_err(|_| server::proto::Error::HashParse(hash.value.clone()))?; + Ok(res) + } +} + +pub(super) fn check_hash( + height: evm_state::BlockNum, + actual: Option, + expected: H256, +) -> Result<(), server::Error> { + let actual = match actual { + Some(val) => val, + None => { + return Err(server::proto::Error::HashEmpty)?; + } + }; + + let actual: H256 = FormatHex::from_hex(&actual.value) + .map_err(|_e| server::proto::Error::HashParse(actual.value.clone()))?; + + if actual != expected { + return Err(server::Error::HashMismatch { + height, + expected, + actual, + }); + } + Ok(()) +} + +pub(super) fn map_changeset(changeset: Vec) -> Vec { + let mut reply_changeset = vec![]; + + for change in changeset { + match change { + triedb::DiffChange::Insert(hash, data) => { + let raw_insert = app_grpc::Insert { + hash: Some(app_grpc::Hash { + value: hash.format_hex(), + }), + data: data.into(), + }; + reply_changeset.push(raw_insert); + } + triedb::DiffChange::Removal(..) => { + // skip + // no need to transfer it over the wire + } + } + } + reply_changeset +} +impl Server { + pub(super) async fn fetch_state_roots( + &self, + from_height: evm_state::BlockNum, + to_height: evm_state::BlockNum, + ) -> Result<(H256, H256), server::Error> { + let mut start = Instant::now(); + let from = self + .block_storage + .get_evm_confirmed_state_root(from_height) + .await?; + + let from = match from { + Some(from) => from, + None => Err(evm_height::Error::NoHeightFound(from_height)) + .map_err(Into::::into)?, + }; + let to = self + .block_storage + .get_evm_confirmed_state_root(to_height) + .await?; + + let to = match to { + Some(to) => to, + None => Err(evm_height::Error::NoHeightFound(to_height)) + .map_err(Into::::into)?, + }; + + let _ = debug_elapsed(&mut start); + Ok((from, to)) + } +} diff --git a/replica-lib/src/triedb/server/proto/storage.rs b/replica-lib/src/triedb/server/proto/storage.rs new file mode 100644 index 0000000000..45cbdd2902 --- /dev/null +++ b/replica-lib/src/triedb/server/proto/storage.rs @@ -0,0 +1,120 @@ +use std::{any::Any, panic, time::Instant}; + +use evm_state::{Storage, StorageSecondary, H256}; +use tonic::Response; +use triedb::DiffChange; + +use crate::triedb::{ + check_root, debug_elapsed, + error::{lock, server}, + lock_root, + server::{Server, UsedStorage}, +}; + +use super::app_grpc; + +fn get_state_diff_gc_storage( + from: H256, + to: H256, + storage: &Storage, +) -> Result, server::Error> { + let mut start = Instant::now(); + + let db_handle = storage.rocksdb_trie_handle(); + let _from_guard = lock_root(&db_handle, from, evm_state::storage::account_extractor)?; + let _to_guard = lock_root(&db_handle, to, evm_state::storage::account_extractor)?; + let _ = debug_elapsed(&mut start); + + let ach = triedb::rocksdb::SyncRocksHandle::new(triedb::rocksdb::RocksDatabaseHandle::new( + storage.db(), + )); + + let changeset = triedb::diff(&ach, evm_state::storage::account_extractor, from, to) + .map_err(|_err| server::Error::TriedbDiff)?; + let disk_io = debug_elapsed(&mut start); + log::debug!( + "disk i/o retrieved diff changeset {:?} {}", + disk_io, + changeset.len() + ); + Ok(changeset) +} + +fn get_state_diff_secondary_storage( + from: H256, + to: H256, + storage: &StorageSecondary, +) -> Result, server::Error> { + let mut start = Instant::now(); + + let db = storage.db(); + check_root(db, from)?; + check_root(db, to)?; + let _ = debug_elapsed(&mut start); + + let ach = storage.rocksdb_trie_handle(); + + let changeset = triedb::diff(&ach, evm_state::storage::account_extractor, from, to) + .map_err(|_err| server::Error::TriedbDiff)?; + let disk_io = debug_elapsed(&mut start); + log::debug!( + "disk i/o retrieved diff changeset {:?} {}", + disk_io, + changeset.len() + ); + Ok(changeset) +} +impl Server { + pub(super) fn get_node_body(&self, key: H256) -> Result, server::Error> { + let maybe_bytes = match self.storage { + UsedStorage::WritableWithGC(ref storage) => storage.db().get(key), + + UsedStorage::ReadOnlyNoGC(ref storage) => storage.db().get(key), + }; + + let bytes = maybe_bytes?.ok_or(lock::Error::NotFoundTop(key))?; + Ok(bytes) + } + pub(super) fn state_diff_body( + &self, + from: H256, + to: H256, + ) -> Result, server::Error> { + let storage = &self.storage; + let catched: Result, server::Error>, Box> = + panic::catch_unwind(|| { + let changeset = match storage { + UsedStorage::WritableWithGC(ref storage) => { + get_state_diff_gc_storage(from, to, storage)? + } + UsedStorage::ReadOnlyNoGC(ref storage) => { + get_state_diff_secondary_storage(from, to, storage)? + } + }; + Ok(changeset) + }); + let changeset = match catched { + Ok(result) => result?, + Err(panic_msg) => { + let description = if let Some(description) = panic_msg.downcast_ref::() { + format!("{:?}", description) + } else { + format!("{:?}", panic_msg) + }; + return Err(lock::Error::NotFoundNested { + from, + to, + description, + })?; + } + }; + + let reply_changeset = super::helpers::map_changeset(changeset); + + let reply = app_grpc::GetStateDiffReply { + changeset: reply_changeset, + }; + + Ok(Response::new(reply)) + } +} diff --git a/replica-lib/src/triedb/server/service.rs b/replica-lib/src/triedb/server/service.rs new file mode 100644 index 0000000000..893fc125af --- /dev/null +++ b/replica-lib/src/triedb/server/service.rs @@ -0,0 +1,239 @@ +use evm_state::{BlockNum, StorageSecondary}; +use futures_util::FutureExt; +use solana_ledger::blockstore::Blockstore; +use std::net::SocketAddr; +use std::sync::Arc; +use std::thread::{Builder, JoinHandle}; +use std::time::Duration; +use tokio::sync::oneshot::{self, Receiver, Sender}; + +use tonic::{self, transport}; + +use log::{error, info}; + +use crate::triedb::error::{evm_height, RangeJsonInitError}; +use crate::triedb::{server, EvmHeightIndex, ReadRange}; + +use self::helpers::{dispatch_sources, maybe_init_bigtable}; + +use super::config::Config; +use super::{proto, UsedStorage}; + +use proto::app_grpc::backend_server::BackendServer; +use thiserror::Error; + +pub(super) mod helpers; +/// The service wraps the Rpc to make it runnable in the tokio runtime +/// and handles start and stop of the service. +pub struct Service { + server_addr: SocketAddr, + server: BackendServer, + runtime: Option, + storage_clone: UsedStorage, +} + +pub struct RunningService { + thread: JoinHandle<()>, + server_handle: BackendServer, + _exit_signal_sender: Sender<()>, +} + +const SECONDARY_CATCH_UP_SECONDS: u64 = 7; + +#[allow(clippy::result_unit_err)] +impl Service { + pub fn new( + server_addr: SocketAddr, + block_threshold: evm_state::BlockNum, + storage: UsedStorage, + range: Box, + runtime: tokio::runtime::Runtime, + block_storage: Box, + ) -> Service { + runtime.block_on(async { + let result = range.get().await; + log::info!("check range at startup : {:?}", result); + }); + + Self { + server_addr, + server: super::Server::new(storage.clone(), range, block_threshold, block_storage), + runtime: Some(runtime), + storage_clone: storage, + } + } + + pub fn into_thread(self) -> std::io::Result { + let (exit_signal_sender, exit_signal_receiver) = oneshot::channel::<()>(); + let server_handle = self.server.clone(); + let thread = Builder::new() + .name("velas-state-rpc-runtime".to_string()) + .spawn(move || { + self.block_on(exit_signal_receiver); + })?; + // TODO: register _exit_signal_sender send into Ctrl-C handler + Ok(RunningService { + thread, + _exit_signal_sender: exit_signal_sender, + server_handle, + }) + } + + // Start TriedbReplServer in a Tokio runtime + fn block_on(mut self, exit_signal: Receiver<()>) { + let runtime = self + .runtime + .take() + .expect("invariant broken: runtime should be moved out only once"); + let result = runtime.block_on(self.run(&runtime, exit_signal)); + + match result { + Ok(_) => { + info!("TriedbReplServer finished"); + } + Err(err) => { + error!("TriedbReplServer finished in error: {:}?", err); + } + } + } + + async fn catch_up_secondary_background(storage: Option) { + if let Some(storage) = storage { + loop { + match storage.try_catch_up() { + Ok(..) => { + log::warn!("successfully synced up secondary rocksdb with primary"); + } + Err(err) => { + log::error!( + "problem with syncing up secondary rocksdb with primary {:?}", + err + ); + } + } + + tokio::time::sleep(Duration::new(SECONDARY_CATCH_UP_SECONDS, 0)).await; + } + } + } + // Runs tonic_server implementation with a provided configuration + async fn run( + self, + runtime: &tokio::runtime::Runtime, + exit_signal: Receiver<()>, + ) -> Result<(), tonic::transport::Error> { + info!( + "Running triedb replica server at the endpoint: {:?}", + self.server_addr + ); + let secondary_storage = match self.storage_clone { + UsedStorage::WritableWithGC(..) => None, + UsedStorage::ReadOnlyNoGC(storage) => Some(storage), + }; + let bg_secondary_jh = runtime.spawn(Self::catch_up_secondary_background(secondary_storage)); + + let res = transport::Server::builder() + .add_service(self.server) + .serve_with_shutdown(self.server_addr, exit_signal.map(drop)) + .await; + + match bg_secondary_jh.await { + Ok(..) => {} + Err(err) => { + log::error!("catch up with primary task panicked!!! {:?}", err); + } + } + + res + } +} + +#[derive(Debug, Error)] +pub enum RunError { + #[error("io {0}")] + Io(#[from] std::io::Error), + #[error("thread join {0:?}")] + Thread(Box), +} + +#[derive(Debug, Error)] +pub enum DispatchSourcesError { + #[error("empty json file arg")] + EmptyJsonFileArg, + #[error("range init json {0}")] + RangeInit(#[from] RangeJsonInitError), + #[error("bigtable blockstore not initialized")] + BigtableNonInit, + #[error("solana blockstore not initialized")] + SolanaBlockstoreNonInit, +} + +#[derive(Debug, Error)] +pub enum StartError { + #[error("evm height {0}")] + EvmHeight(#[from] evm_height::Error), + + #[error("dispatch sources error {0}")] + DispatchSources(#[from] DispatchSourcesError), + #[error("run error {0}")] + Run(#[from] RunError), +} + +impl RunningService { + pub fn start( + bind_address: SocketAddr, + + config: Config, + used_storage: server::UsedStorage, + runtime: tokio::runtime::Runtime, + solana_blockstore: Option>, + ) -> Result { + log::info!("starting triedb replica server, {:#?}", config); + + let bigtable_blockstore = maybe_init_bigtable(config.clone(), &runtime)?; + + let max_diff_gap = config.max_diff_height_gap; + let (range, blockstore) = dispatch_sources(config, bigtable_blockstore, solana_blockstore)?; + + let service = + RunningService::start_internal(bind_address, range, used_storage, runtime, blockstore, max_diff_gap)?; + Ok(service) + } + + fn start_internal( + bind_address: SocketAddr, + range: Box, + storage: server::UsedStorage, + runtime: tokio::runtime::Runtime, + block_storage: Box, + max_diff_height_gap: usize, + ) -> Result { + log::info!("starting the thread"); + if max_diff_height_gap < CURSES_MAX_HEIGHT_GAP { + log::error!("\"evm-state-rpc-max-height-dif\" param specified too low: {}", max_diff_height_gap); + } + let service = server::Service::new( + bind_address, + max_diff_height_gap as BlockNum, + storage, + range, + runtime, + block_storage, + ) + .into_thread()?; + Ok(service) + } + pub fn join(self) -> Result<(), RunError> { + self.server_handle.join().map_err(|err| { + let str = format!("server handle join {:?}", err); + RunError::Thread(str.into()) + })?; + self.thread.join().map_err(|err| { + let str = format!("repr of thread join err {:?}", err); + RunError::Thread(str.into()) + })?; + Ok(()) + } +} + +const CURSES_MAX_HEIGHT_GAP: usize = 10_000; diff --git a/replica-lib/src/triedb/server/service/helpers.rs b/replica-lib/src/triedb/server/service/helpers.rs new file mode 100644 index 0000000000..b82fbee5f1 --- /dev/null +++ b/replica-lib/src/triedb/server/service/helpers.rs @@ -0,0 +1,131 @@ +use std::{sync::Arc, thread, time::Duration}; + +use evm_state::BlockNum; +use solana_ledger::blockstore::Blockstore; + +use crate::triedb::{ + error::evm_height, + range::RangeJSON, + server::config::{Config, HeightIndexSource, RangeSource}, + CachedRootsLedgerStorage, EvmHeightIndex, ReadRange, +}; + +use super::DispatchSourcesError; + +pub(super) fn maybe_init_bigtable( + config: Config, + runtime: &tokio::runtime::Runtime, +) -> Result, evm_height::Error> { + let bigtable = match (config.range_source, config.height_index_source) { + (RangeSource::BigtableBlockstore, _) | (_, HeightIndexSource::BigtableBlockstore) => { + let result = init_bigtable(runtime, config.bigtable_length_hint)?; + Some(result) + } + _ => None, + }; + Ok(bigtable) +} + +fn init_bigtable( + runtime: &tokio::runtime::Runtime, + bigtable_length_hint: BlockNum, +) -> Result { + + log::warn!("init bigtable called"); + let bigtable_blockstore = runtime.block_on(async { + let bigtable_blockstore = solana_storage_bigtable::LedgerStorage::new( + false, + Some(std::time::Duration::new(20, 0)), + None, + ) + .await; + + let bigtable_blockstore = match bigtable_blockstore { + Err(err) => return Err(evm_height::Error::from(err)), + Ok(bigtable_blockstore) => bigtable_blockstore, + }; + let bigtable_blockstore = + CachedRootsLedgerStorage::new(bigtable_blockstore, bigtable_length_hint); + match bigtable_blockstore.get_last_available_block().await { + Err(err) => { + log::error!("ledger storage sanity check failed {:#?}", err); + return Err(err); + } + Ok(height) => { + log::info!("ledger storage sanity check done : last height {}", height); + } + } + Ok(bigtable_blockstore) + })?; + Ok(bigtable_blockstore) +} + +type DispatchResult = Result<(Box, Box), DispatchSourcesError>; + +const SECONDARY_CATCH_UP_SECONDS: u64 = 40; + +fn spin_off_sync_up_thread(solana_blockstore: Arc) { + let _jh = std::thread::spawn(move || loop { + match solana_blockstore.try_catch_up_with_primary() { + Ok(true) => { + log::warn!("successfully synced up secondary solana_blockstore with primary"); + } + Err(err) => { + log::error!( + "problem with syncing up secondary solana_blockstore with primary {:?}", + err + ); + } + _ => {} + } + + thread::sleep(Duration::new(SECONDARY_CATCH_UP_SECONDS, 0)); + }); +} + +pub(super) fn dispatch_sources( + config: Config, + bigtable_blockstore: Option, + solana_blockstore: Option>, +) -> DispatchResult { + let mut sol_blockstore_selected = false; + let range: Box = match config.range_source { + RangeSource::JSON { file } => { + let file = file.ok_or(DispatchSourcesError::EmptyJsonFileArg)?; + let range = RangeJSON::new(file, None)?; + Box::new(range) + } + RangeSource::BigtableBlockstore => { + let bigtable_blockstore = bigtable_blockstore + .clone() + .ok_or(DispatchSourcesError::BigtableNonInit)?; + Box::new(bigtable_blockstore) + } + + RangeSource::SolanaBlockstore => { + let solana_blockstore = solana_blockstore + .clone() + .ok_or(DispatchSourcesError::SolanaBlockstoreNonInit)?; + spin_off_sync_up_thread(solana_blockstore.clone()); + sol_blockstore_selected = true; + Box::new(solana_blockstore) + } + }; + let index: Box = match config.height_index_source { + HeightIndexSource::BigtableBlockstore => { + let bigtable_blockstore = + bigtable_blockstore.ok_or(DispatchSourcesError::BigtableNonInit)?; + Box::new(bigtable_blockstore) + } + + HeightIndexSource::SolanaBlockstore => { + let solana_blockstore = + solana_blockstore.ok_or(DispatchSourcesError::SolanaBlockstoreNonInit)?; + if !sol_blockstore_selected { + spin_off_sync_up_thread(solana_blockstore.clone()); + } + Box::new(solana_blockstore) + } + }; + Ok((range, index)) +} diff --git a/replica-node/Cargo.toml b/replica-node/Cargo.toml index 788bcf6706..f0c11ffdee 100644 --- a/replica-node/Cargo.toml +++ b/replica-node/Cargo.toml @@ -9,11 +9,22 @@ license = "Apache-2.0" homepage = "https://solana.com/" documentation = "https://docs.rs/solana-validator" +[[bin]] +name = "triedb_replica" +path = "src/bin/triedb.rs" + +[[bin]] +name = "triedb_replica_client" +path = "src/bin/triedb_client.rs" + [dependencies] clap = "2.33.1" +regex = "1" crossbeam-channel = "0.5" log = "0.4.14" rand = "0.7.0" +etcommon-hexutil = "0.2.4" +evm-state = { path = "../evm-utils/evm-state" } solana-clap-utils = { path = "../clap-utils", version = "=1.9.29" } solana-download-utils = { path = "../download-utils", version = "=1.9.29" } solana-genesis-utils = { path = "../genesis-utils", version = "=1.9.29" } @@ -26,9 +37,19 @@ solana-replica-lib = { path = "../replica-lib", version = "=1.9.29" } solana-runtime = { path = "../runtime", version = "=1.9.29" } solana-sdk = { path = "../sdk", version = "=1.9.29" } solana-send-transaction-service = { path = "../send-transaction-service", version = "=1.9.29" } +solana-storage-bigtable = { path = "../storage-bigtable", version = "=1.9.29" } solana-streamer = { path = "../streamer", version = "=1.9.29" } solana-version = { path = "../version", version = "=0.6.3" } velas-validator = { path = "../validator", version = "=1.9.29" } +# To run triedb_repl_client +tokio = { version = "1.14.1", features = ["full"] } +tonic = { version = "0.8.1", features = ["tls", "transport", "gzip"] } + + +thiserror = "1.0.39" + +futures = "0.3.26" +env_logger = "0.9" [dev-dependencies] serial_test = "0.5.1" diff --git a/replica-node/src/bin/triedb.rs b/replica-node/src/bin/triedb.rs new file mode 100644 index 0000000000..34579844f3 --- /dev/null +++ b/replica-node/src/bin/triedb.rs @@ -0,0 +1,220 @@ +//! The main AccountsDb replication node responsible for replicating +//! AccountsDb information from peer a validator or another replica-node. + +#![allow(clippy::integer_arithmetic)] + +use std::{ + net::{AddrParseError, SocketAddr}, + str::FromStr, + sync::Arc, +}; + +use solana_ledger::{blockstore::Blockstore, blockstore_db::AccessType}; +use solana_replica_lib::triedb::{ + error::{evm_height, RangeJsonInitError}, + server::{RunError, RunningService, StartError, UsedStorage}, + {Config, HeightIndexSource, ParseError, RangeSource}, +}; + +use { + clap::{crate_description, crate_name, App, AppSettings, Arg}, + std::{env, path::PathBuf}, +}; + +use evm_state::Storage; +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum Error { + #[error(transparent)] + Storage(#[from] evm_state::storage::Error), + #[error(transparent)] + AddrParse(#[from] AddrParseError), + #[error(transparent)] + RangeInit(#[from] RangeJsonInitError), + #[error(transparent)] + Io(#[from] std::io::Error), + #[error("evm height {0}")] + EvmHeight(#[from] evm_height::Error), + #[error("blockstore {0}")] + Blockstore(#[from] solana_ledger::blockstore::BlockstoreError), + + #[error(transparent)] + Run(#[from] RunError), + #[error("config parse {0}")] + ConfigParse(#[from] ParseError), + #[error(transparent)] + Start(#[from] StartError), + #[error(transparent)] + RangeSource(Box), +} + +pub fn main() -> Result<(), Error> { + let matches = App::new(crate_name!()) + .about(crate_description!()) + .version(solana_version::version!()) + .setting(AppSettings::VersionlessSubcommands) + .setting(AppSettings::InferSubcommands) + .arg( + Arg::with_name("evm_state") + .short("e") + .long("evm-state") + .value_name("DIR") + .takes_value(true) + .required(true) + .help("Use DIR as ledger location"), + ) + .arg( + Arg::with_name("gc_enabled") + .long("gc") + .required(false) + .takes_value(false) + .help("whether to open evm_state_db with gc_enabled"), + ) + .arg( + Arg::with_name("secondary_mode") + .long("secondary") + .required(false) + .takes_value(false) + .help("whether to open evm_state_db in secondary mode"), + ) + .arg( + Arg::with_name("bind_address") + .long("bind-address") + .value_name("HOST:PORT") + .takes_value(true) + .validator(solana_net_utils::is_host_port) + .required(true) + .help("IP:PORT address to bind the state gRPC server"), + ) + .arg( + Arg::with_name("range_source") + .long("range-source") + .value_name("STRING") + .takes_value(true) + .possible_values(&["json", "bigtable", "solana_blockstore"]) + .required(true) + .help("source of range data"), + ) + .arg( + Arg::with_name("height_index_source") + .long("height-index-source") + .value_name("STRING") + .takes_value(true) + .possible_values(&["bigtable", "solana_blockstore"]) + .required(true) + .help("source of evm height index data"), + ) + .arg( + Arg::with_name("range_file") + .long("range-file") + .value_name("FILE") + .takes_value(true) + .required(false) + .required_if("range_source", "json") + .help("FILE with json of `RangeJSON` serialization"), + ) + .arg( + Arg::with_name("bigtable_length_hint") + .long("bigtable-length-hint") + .value_name("NUMBER") + .takes_value(true) + .required(false) + .help("NUMBER of last block hint"), + ) + .arg( + Arg::with_name("blockstore_path") + .long("blockstore-path") + .value_name("DIR") + .takes_value(true) + .required(false) + .required_ifs(&[ + ("range_source", "solana_blockstore"), + ("height_index_source", "solana_blockstore"), + ]) + .help("PATH of blockstore local storage for range and/or state root index"), + ) + .arg( + Arg::with_name("max_height_diff") + .long("max-height-diff") + .value_name("NUM") + .takes_value(true) + .required(false) + .help("NUM of maximum height difference"), + ) + .get_matches(); + + let _ = env_logger::Builder::from_default_env().try_init(); + + let evm_state = PathBuf::from(matches.value_of("evm_state").unwrap()); + log::info!("{:?}", evm_state); + + let socket_addr = matches.value_of("bind_address").unwrap(); + let secondary_mode = matches.is_present("secondary_mode"); + + let state_rpc_bind_address: SocketAddr = socket_addr.parse()?; + + let gc_enabled = matches.is_present("gc_enabled"); + + let used_storage = if secondary_mode { + UsedStorage::ReadOnlyNoGC(Storage::open_secondary_persistent(evm_state, gc_enabled)?) + } else { + UsedStorage::WritableWithGC(Storage::open_persistent( + evm_state, gc_enabled, // enable gc + )?) + }; + + let runtime = tokio::runtime::Builder::new_multi_thread() + .worker_threads(10) + .thread_name("velas-state-rpc-worker") + .enable_all() + .build()?; + + let blockstore_path = matches.value_of("blockstore_path"); + + let config = Config::parse_standalone(&matches)?; + + // fence + + let solana_blockstore = init_solana_blockstore( + config.range_source.clone(), + config.height_index_source.clone(), + blockstore_path, + )?; + + let service = RunningService::start( + state_rpc_bind_address, + config, + used_storage, + runtime, + solana_blockstore, + )?; + + service.join().map_err(|err| RunError::Thread(err.into()))?; + Ok(()) +} + +fn init_solana_blockstore( + range_source: RangeSource, + height_index_source: HeightIndexSource, + blockstore_path: Option<&str>, +) -> Result>, Error> { + let solana_blockstore = match (range_source, height_index_source) { + (RangeSource::SolanaBlockstore, _) | (_, HeightIndexSource::SolanaBlockstore) => { + log::warn!("init solana_blockstore called"); + let blockstore_path = blockstore_path.expect("blockstore_path is empty"); + + let path = PathBuf::from_str(blockstore_path).unwrap(); + let solana_blockstore = solana_ledger::blockstore::Blockstore::open_with_access_type( + path.as_ref(), + AccessType::TryPrimaryThenSecondary, + None, + false, + ) + .map(Arc::new)?; + Some(solana_blockstore) + } + _ => None, + }; + Ok(solana_blockstore) +} diff --git a/replica-node/src/bin/triedb_client.rs b/replica-node/src/bin/triedb_client.rs new file mode 100644 index 0000000000..2fba6d7643 --- /dev/null +++ b/replica-node/src/bin/triedb_client.rs @@ -0,0 +1,260 @@ +use std::net::{AddrParseError, SocketAddr}; +use std::num::ParseIntError; +use std::path::PathBuf; +use std::str::FromStr; + +use solana_replica_lib::triedb::error::evm_height; +use solana_replica_lib::triedb::{client::Client, range::RangeJSON}; +use solana_replica_lib::triedb::{CachedRootsLedgerStorage, DB_SEMAPHORE_PERMITS_PER_LARGE_DIFF}; + +use clap::{crate_description, crate_name, App, AppSettings, Arg, ArgMatches}; +use evm_state::Storage; +use thiserror::Error; + +#[derive(Debug)] +struct ParsedArgs { + state_rpc_address: String, + timeout_seconds: u64, + max_height_gap: usize, + evm_state: PathBuf, + coarse_range_file: String, + fine_range_file: String, + request_workers: u32, + db_workers: u32, +} + +#[derive(Error, Debug)] +enum Error { + #[error("address parse {0}")] + AddrParse(#[from] AddrParseError), + #[error("integer parse {0}")] + IntParse(#[from] ParseIntError), + #[error("evm height sanity check {0}")] + EvmHeightSanityCheck(#[from] evm_height::Error), + #[error("storage error {0}")] + Storage(#[from] evm_state::storage::Error), + #[error("range init {0}")] + RangeInit(#[from] solana_replica_lib::triedb::error::RangeJsonInitError), + #[error("solana storage bigtable {0}")] + StorageBigtable(#[from] solana_storage_bigtable::Error), + #[error("connect error {0}")] + Connect(#[from] tonic::transport::Error), + #[error("db workers param specified too low : actual {0}, min {1}")] + DbWorkersTooLow(u32, u32), +} +const MAX_HEIGHT_DIFF_DEFAULT: &str = "700000"; +const TIMEOUT_SECONDS_DEFAULT: &str = "60"; + +impl ParsedArgs { + fn parse(matches: ArgMatches) -> Result { + let state_rpc_address = matches.value_of("state_rpc_address").unwrap(); + + let secure_flag = matches.is_present("tls"); + let secure_flag = if secure_flag { "s" } else { "" }; + + let state_rpc_address = { + SocketAddr::from_str(state_rpc_address)?; + + format!("http{}://{}", secure_flag, state_rpc_address) + }; + + let evm_state = PathBuf::from(matches.value_of("evm_state").unwrap()); + let range_file = matches.value_of("range_file").unwrap().to_string(); + let rangemap_file = matches.value_of("rangemap_file").unwrap().to_string(); + let db_workers = matches.value_of("db_workers").unwrap().parse().unwrap(); + let request_workers = matches + .value_of("request_workers") + .unwrap() + .parse() + .unwrap(); + + let max_height_gap: usize = matches + .value_of("max_height_diff") + .unwrap_or(MAX_HEIGHT_DIFF_DEFAULT) + .parse()?; + + let timeout_seconds: u64 = matches + .value_of("grpc_timeout_sec") + .unwrap_or(TIMEOUT_SECONDS_DEFAULT) + .parse()?; + + Ok(Self { + state_rpc_address, + timeout_seconds, + max_height_gap, + evm_state, + coarse_range_file: range_file, + fine_range_file: rangemap_file, + db_workers, + request_workers, + }) + } + + fn build(self) -> Result { + log::info!("building ClientOpts {:#?}", self); + + let gc_enabled = true; + let storage = Storage::open_persistent(self.evm_state, gc_enabled)?; + + let range = RangeJSON::new(self.coarse_range_file, Some(self.fine_range_file))?; + if self.db_workers < DB_SEMAPHORE_PERMITS_PER_LARGE_DIFF { + return Err(Error::DbWorkersTooLow( + self.db_workers, + DB_SEMAPHORE_PERMITS_PER_LARGE_DIFF, + )); + } + Ok(ClientOpts { + state_rpc_address: self.state_rpc_address, + timeout_seconds: self.timeout_seconds, + max_height_gap: self.max_height_gap, + storage, + range, + request_workers: self.request_workers, + db_workers: self.db_workers, + }) + } +} + +pub struct ClientOpts { + state_rpc_address: String, + timeout_seconds: u64, + max_height_gap: usize, + storage: Storage, + range: RangeJSON, + request_workers: u32, + db_workers: u32, +} + +#[tokio::main(flavor = "multi_thread", worker_threads = 10)] +async fn main() -> Result<(), Error> { + let matches = App::new(crate_name!()) + .about(crate_description!()) + .version(solana_version::version!()) + .setting(AppSettings::VersionlessSubcommands) + .setting(AppSettings::InferSubcommands) + .arg( + Arg::with_name("evm_state") + .short("e") + .long("evm-state") + .value_name("DIR") + .takes_value(true) + .required(true) + .help("Use DIR as ledger location"), + ) + .arg( + Arg::with_name("state_rpc_address") + .long("state-rpc-address") + .value_name("HOST:PORT") + .multiple(false) + // .multiple(true) + // .number_of_values(1) + .takes_value(true) + .validator(solana_net_utils::is_host_port) + .required(true) + .help("IP:PORT address of the state gRPC server to connect to"), + ) + .arg( + Arg::with_name("tls") + .long("tls") + .takes_value(false) + .help("Use https instead of http"), + ) + .arg( + Arg::with_name("range_file") + .long("range-file") + .value_name("FILE") + .takes_value(true) + .required(true) + // replica-lib/src/triedb/range.rs + .help("FILE with json of coarse `RangeJSON` serialization"), + ) + .arg( + Arg::with_name("rangemap_file") + .long("rangemap-file") + .value_name("FILE") + .takes_value(true) + .required(true) + // replica-lib/src/triedb/range.rs + .help("FILE with json of fine `RangeJSON` serialization"), + ) + .arg( + Arg::with_name("request_workers") + .long("request-workers") + .value_name("NUM") + .takes_value(true) + .default_value("50") + // replica-lib/src/triedb/range.rs + .help("NUM of parallel grpc requests' workers"), + ) + .arg( + Arg::with_name("db_workers") + .long("db-workers") + .value_name("NUM") + .takes_value(true) + .default_value("50") + // replica-lib/src/triedb/range.rs + .help("NUM of parallel db workers"), + ) + .arg( + Arg::with_name("grpc_timeout_sec") + .long("grpc-timeout-sec") + .value_name("SEC") + .takes_value(true) + // replica-lib/src/triedb/range.rs + .help("grpc timeout SEC"), + ) + .arg( + Arg::with_name("max_height_diff") + .long("max-height-diff") + .value_name("NUM") + .hidden(true) + .takes_value(true) + // replica-lib/src/triedb/range.rs + .help("NUM of maximum height diff attempted"), + ) + .get_matches(); + + let _ = env_logger::Builder::from_default_env().try_init(); + log::info!("cwd start {}", std::env::current_dir().unwrap().display()); + let client_opts = ParsedArgs::parse(matches)?; + let client_opts = client_opts.build()?; + let mut client = connect(client_opts).await?; + + client.sync().await; + + // fortunately, horizon is unreachable + Ok(()) +} + +async fn connect(client_opts: ClientOpts) -> Result, Error> { + let block_storage = solana_storage_bigtable::LedgerStorage::new( + false, + Some(std::time::Duration::new(20, 0)), + None, + ) + .await?; + + let block_storage = CachedRootsLedgerStorage::new( + block_storage, + MAINNET_HINT_DEFAULT.parse().expect("parse hint"), + ); + + let client = async { + Client::connect( + client_opts.state_rpc_address, + client_opts.timeout_seconds, + client_opts.range, + client_opts.storage, + block_storage, + client_opts.request_workers, + client_opts.db_workers, + client_opts.max_height_gap, + ) + .await + } + .await?; + + Ok(client) +} + +const MAINNET_HINT_DEFAULT: &str = "62184801"; diff --git a/sdk/src/genesis_config.rs b/sdk/src/genesis_config.rs index 0a2b805eef..4dc24486a4 100644 --- a/sdk/src/genesis_config.rs +++ b/sdk/src/genesis_config.rs @@ -30,7 +30,6 @@ use { fmt, fs::{File, OpenOptions}, io::Write, - mem, path::{Path, PathBuf}, str::FromStr, time::{SystemTime, UNIX_EPOCH}, @@ -263,9 +262,9 @@ impl GenesisConfig { } if chunk.is_empty() { - return None + None } else { - return Some(Ok(chunk)) + Some(Ok(chunk)) } }); diff --git a/validator/Cargo.toml b/validator/Cargo.toml index 230a901a53..ca2a5d27a6 100644 --- a/validator/Cargo.toml +++ b/validator/Cargo.toml @@ -48,6 +48,8 @@ solana-streamer = { path = "../streamer", version = "=1.9.29" } solana-test-validator = { path = "../test-validator", version = "=1.9.29" } solana-version = { path = "../version", version = "=0.6.3" } solana-vote-program = { path = "../programs/vote", version = "=1.9.29" } + +tokio = { version = "1.14.1", features = ["full"] } symlink = "0.1.0" evm-state = { path = "../evm-utils/evm-state" } diff --git a/validator/src/main.rs b/validator/src/main.rs index 503cc74b77..d41e1b9e83 100644 --- a/validator/src/main.rs +++ b/validator/src/main.rs @@ -598,6 +598,41 @@ pub fn main() { .takes_value(true) .help("Use DIR as evm-state archive location"), ) + .arg( + Arg::with_name("evm_state_rpc_port") + .long("evm-state-rpc-port") + .value_name("PORT") + .takes_value(true) + .requires("evm_state_archive_path") + .requires("evm_height_index_source") + .validator(velas_validator::port_validator) + .help("Enable evm state rpc on this port"), + ) + .arg( + Arg::with_name("evm_height_index_source") + .long("evm-height-index-source") + .value_name("STRING") + .takes_value(true) + .possible_values(&["bigtable", "solana_blockstore"]) + .required(false) + .help("source of evm height index data"), + ) + .arg( + Arg::with_name("bigtable_evm_blockstore_length_hint") + .long("bigtable-evm-blockstore-length-hint") + .value_name("NUMBER") + .takes_value(true) + .required(false) + .help("NUMBER of last evm block hint"), + ) + .arg( + Arg::with_name("evm_state_rpc_max_height_diff") + .long("evm-state-rpc-max-height-diff") + .value_name("NUM") + .takes_value(true) + .required(false) + .help("NUM of maximum height difference"), + ) .arg( Arg::with_name("evm_state_path") .long("evm-state") @@ -2159,6 +2194,27 @@ pub fn main() { bind_address }; + let (evm_state_rpc_addr, evm_state_rpc_config): (Option, Option) = match evm_state_archive { + Some(..) => { + let addr = value_t!(matches, "evm_state_rpc_port", u16).ok().map(|rpc_port| { + SocketAddr::new(rpc_bind_address, rpc_port) + }); + + let config = match solana_replica_lib::triedb::Config::parse_validator(&matches) { + Ok(config) => Some(config), + Err(err) => { + + error!("parse evm_state_rpc_config: {:#?}", err); + None + } + + }; + (addr, config) + }, + None => (None,None) + + }; + let contact_debug_interval = value_t_or_exit!(matches, "contact_debug_interval", u64); let account_indexes = process_account_indexes(&matches); @@ -2366,6 +2422,7 @@ pub fn main() { .ok() .map(Duration::from_secs), }, + evm_state_rpc_config, accountsdb_repl_service_config, geyser_plugin_config_files, rpc_addrs: value_t!(matches, "rpc_port", u16).ok().map(|rpc_port| { @@ -2377,6 +2434,7 @@ pub fn main() { // https://github.com/solana-labs/solana/issues/12250 ) }), + evm_state_rpc_addr, pubsub_config: PubSubConfig { enable_block_subscription: matches.is_present("rpc_pubsub_enable_block_subscription"), enable_vote_subscription: matches.is_present("rpc_pubsub_enable_vote_subscription"), From ad422ce686630f347b49e0457fd0bc35dad79b79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dj8yf0=CE=BCl?= Date: Wed, 26 Apr 2023 11:07:08 +0300 Subject: [PATCH 06/11] chore(replica-lib): remove rlp dependency, fix accumulated clippy --- Cargo.lock | 1 - evm-utils/evm-state/src/transactions.rs | 2 +- evm-utils/evm-state/src/types.rs | 4 ++-- replica-lib/Cargo.toml | 1 - replica-lib/src/triedb/client/sync/bootstrap/helpers.rs | 3 +-- 5 files changed, 4 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e118a88943..8e59a37faf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7379,7 +7379,6 @@ dependencies = [ "primitive-types 0.8.0", "prost 0.11.9", "rangemap", - "rlp", "rocksdb", "serde", "serde_json", diff --git a/evm-utils/evm-state/src/transactions.rs b/evm-utils/evm-state/src/transactions.rs index ae8f4aada6..14855107f0 100644 --- a/evm-utils/evm-state/src/transactions.rs +++ b/evm-utils/evm-state/src/transactions.rs @@ -469,7 +469,7 @@ impl<'de> Decodable<'de> for UnsignedTransaction { return Err(fastrlp::DecodeError::UnexpectedString); } let payload_view = &mut &buf[..h.payload_length]; - let cnt = fastrlp::count(*payload_view)?; + let cnt = fastrlp::count(payload_view)?; if cnt!= 6 { return Err(fastrlp::DecodeError::ListLengthMismatch { expected: 6, got: cnt }); } diff --git a/evm-utils/evm-state/src/types.rs b/evm-utils/evm-state/src/types.rs index 66b752e058..19afe0792b 100644 --- a/evm-utils/evm-state/src/types.rs +++ b/evm-utils/evm-state/src/types.rs @@ -222,7 +222,7 @@ impl<'de> Decodable<'de> for Account { return Err(fastrlp::DecodeError::UnexpectedString); } let payload_view = &mut &buf[..h.payload_length]; - let cnt = fastrlp::count(*payload_view)?; + let cnt = fastrlp::count(payload_view)?; if cnt!= 4 { return Err(fastrlp::DecodeError::ListLengthMismatch { expected: 4, got: cnt }); } @@ -599,7 +599,7 @@ pub(super) mod transaction_roots { return Err(fastrlp::DecodeError::UnexpectedString); } let payload_view = &mut &buf[..h.payload_length]; - let cnt = fastrlp::count(*payload_view)?; + let cnt = fastrlp::count(payload_view)?; if cnt!= 4 { return Err(fastrlp::DecodeError::ListLengthMismatch { expected: 4, got: cnt }); } diff --git a/replica-lib/Cargo.toml b/replica-lib/Cargo.toml index e306e0ed51..e0cdf3954a 100644 --- a/replica-lib/Cargo.toml +++ b/replica-lib/Cargo.toml @@ -26,7 +26,6 @@ clap = "2.33.1" sha3 = "0.9.1" -rlp = "0.5.0" tokio = { version = "1.14.1", features = ["full", "time"] } tonic = { version = "0.8.1", features = ["tls", "transport", "gzip"] } diff --git a/replica-lib/src/triedb/client/sync/bootstrap/helpers.rs b/replica-lib/src/triedb/client/sync/bootstrap/helpers.rs index bad16c4a50..90393ac257 100644 --- a/replica-lib/src/triedb/client/sync/bootstrap/helpers.rs +++ b/replica-lib/src/triedb/client/sync/bootstrap/helpers.rs @@ -1,8 +1,7 @@ use evm_state::{storage::account_extractor, H256}; -use rlp::Rlp; use sha3::{Digest, Keccak256}; -use triedb::{gc::ReachableHashes, merkle::MerkleNode}; +use triedb::gc::ReachableHashes; use crate::triedb::{error::client, MAX_CHUNK_HASHES}; From 27aa165d08e9064d5fc91a0cac8b4dba9e1cddd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dj8yf0=CE=BCl?= <26653921+dj8yfo@users.noreply.github.com> Date: Wed, 26 Apr 2023 21:42:35 +0300 Subject: [PATCH 07/11] [ur] feat(ledger, evm-utils/evm-state) rust rocksdb orthodox (#441) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(evm-utils/evm-state): remove first part of features of unorthodox rust-rocksdb [ ] revert `rust-rocksdb` to orthodox version effort └── [✓] first revert effort with inner traits made visible ├── [✓] link everything to tag where stuff wasn't available ├── [✓] [issue orthodox rust-rocksdb v1](https://github.com/velas/velas-chain/issues/432) │ └── [✓] define new trait `VelasDBCommon` │ ├── [✓] method `pub fn flush(&self) -> Result<(), Error> {` │ └── [✓] `pub fn cancel_all_background_work(&self, wait: bool) {` └── [✓] remove `HACK` annotations * fix(ledger,evm-utils/evm-state): bump rocksdb to v0.20.1 [orthodox] * chore(**/*): update triedb tag --------- --- Cargo.lock | 77 +++++++----- evm-utils/evm-state/Cargo.toml | 3 +- evm-utils/evm-state/src/storage/mod.rs | 159 +++++++++++++++++++++---- ledger/Cargo.toml | 3 +- ledger/src/blockstore_db.rs | 2 +- replica-lib/Cargo.toml | 4 +- replica-node/src/bin/triedb_client.rs | 1 + 7 files changed, 190 insertions(+), 59 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8e59a37faf..93e10be1b0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -259,9 +259,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "axum" -version = "0.6.16" +version = "0.6.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "113713495a32dd0ab52baf5c10044725aa3aec00b31beda84218e469029b72a3" +checksum = "b70caf9f1b0c045f7da350636435b775a9733adf2df56e8aa2a29210fbc335d4" dependencies = [ "async-trait", "axum-core", @@ -409,9 +409,9 @@ dependencies = [ [[package]] name = "bindgen" -version = "0.60.1" +version = "0.64.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "062dddbc1ba4aca46de6338e2bf87771414c335f7b2f2036e8f3e9befebf88e6" +checksum = "c4243e6031260db77ede97ad86c27e501d646a27ab57b59a574f725d98ab1fb4" dependencies = [ "bitflags", "cexpr", @@ -424,6 +424,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", + "syn 1.0.109", ] [[package]] @@ -889,9 +890,9 @@ dependencies = [ [[package]] name = "clap" -version = "3.2.23" +version = "3.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5" +checksum = "eef2b3ded6a26dfaec672a742c93c8cf6b689220324da509ec5caa20de55dc83" dependencies = [ "atty", "bitflags", @@ -1151,7 +1152,7 @@ dependencies = [ "atty", "cast 0.3.0", "ciborium", - "clap 3.2.23", + "clap 3.2.24", "criterion-plot", "itertools", "lazy_static", @@ -2152,7 +2153,7 @@ dependencies = [ [[package]] name = "fastrlp" version = "0.3.0" -source = "git+https://github.com/velas/fastrlp?tag=second_release_candidate#f4e921c54f7669e157b2e7e8f5385eed54e105cc" +source = "git+https://github.com/velas/fastrlp?tag=second_release_candidate#7a967beb99c5627b90013a3ba0b4b74577797bc4" dependencies = [ "arrayvec 0.7.2", "auto_impl 1.0.1", @@ -2167,7 +2168,7 @@ dependencies = [ [[package]] name = "fastrlp-derive" version = "0.2.0" -source = "git+https://github.com/velas/fastrlp?tag=second_release_candidate#f4e921c54f7669e157b2e7e8f5385eed54e105cc" +source = "git+https://github.com/velas/fastrlp?tag=second_release_candidate#7a967beb99c5627b90013a3ba0b4b74577797bc4" dependencies = [ "bytes 1.4.0", "proc-macro2 1.0.56", @@ -3102,7 +3103,7 @@ checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" dependencies = [ "hermit-abi 0.3.1", "io-lifetimes 1.0.10", - "rustix 0.37.14", + "rustix 0.37.15", "windows-sys 0.48.0", ] @@ -3387,8 +3388,9 @@ checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb" [[package]] name = "librocksdb-sys" -version = "0.8.0+7.4.4" -source = "git+https://github.com/velas/rust-rocksdb#7330656ddd0ef00aadd623faccbdb809e1b98062" +version = "0.10.0+7.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fe4d5874f5ff2bc616e55e8c6086d478fcda13faf9495768a4aa1c22042d30b" dependencies = [ "bindgen", "bzip2-sys", @@ -3396,6 +3398,7 @@ dependencies = [ "glob", "libc", "libz-sys", + "lz4-sys", ] [[package]] @@ -3530,6 +3533,16 @@ dependencies = [ "hashbrown 0.11.2", ] +[[package]] +name = "lz4-sys" +version = "1.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57d27b317e207b10f69f5e75494119e391a96f48861ae870d1da6edac98ca900" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "matches" version = "0.1.10" @@ -3929,9 +3942,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.51" +version = "0.10.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97ea2d98598bf9ada7ea6ee8a30fb74f9156b63bbe495d64ec2b87c269d2dda3" +checksum = "01b8574602df80f7b85fdfc5392fa884a4e3b3f4f35402c070ab34c3d3f78d56" dependencies = [ "bitflags", "cfg-if 1.0.0", @@ -3970,9 +3983,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.86" +version = "0.9.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "992bac49bdbab4423199c654a5515bd2a6c6a23bf03f2dd3bdb7e5ae6259bc69" +checksum = "8e17f59264b2809d77ae94f0e1ebabc434773f370d6ca667bd223ea10e06cc7e" dependencies = [ "cc", "libc", @@ -5081,7 +5094,7 @@ dependencies = [ name = "rbpf-cli" version = "1.9.29" dependencies = [ - "clap 3.2.23", + "clap 3.2.24", "serde", "serde_json", "solana-bpf-loader-program", @@ -5298,8 +5311,9 @@ dependencies = [ [[package]] name = "rocksdb" -version = "0.19.0" -source = "git+https://github.com/velas/rust-rocksdb#7330656ddd0ef00aadd623faccbdb809e1b98062" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "015439787fce1e75d55f279078d33ff14b4af5d93d995e8838ee4631301c8a99" dependencies = [ "libc", "librocksdb-sys", @@ -5373,9 +5387,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.14" +version = "0.37.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b864d3c18a5785a05953adeed93e2dca37ed30f18e69bba9f30079d51f363f" +checksum = "a0661814f891c57c930a610266415528da53c4933e6dea5fb350cbfe048a9ece" dependencies = [ "bitflags", "errno 0.3.1", @@ -5481,9 +5495,9 @@ dependencies = [ [[package]] name = "scale-info" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cfdffd972d76b22f3d7f81c8be34b2296afd3a25e0a547bd9abe340a4dbbe97" +checksum = "dfdef77228a4c05dc94211441595746732131ad7f6530c6c18f045da7b7ab937" dependencies = [ "bitvec 1.0.1", "cfg-if 1.0.0", @@ -5494,9 +5508,9 @@ dependencies = [ [[package]] name = "scale-info-derive" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61fa974aea2d63dd18a4ec3a49d59af9f34178c73a4f56d2f18205628d00681e" +checksum = "53012eae69e5aa5c14671942a5dd47de59d4cdcff8532a6dd0e081faf1119482" dependencies = [ "proc-macro-crate 1.3.1", "proc-macro2 1.0.56", @@ -7393,7 +7407,7 @@ dependencies = [ "tokio", "tonic 0.8.3", "tonic-build 0.8.4", - "triedb 0.5.0 (git+https://github.com/velas/triedb?tag=optimal_children_expose_error)", + "triedb 0.5.0 (git+https://github.com/velas/triedb?tag=rocksdb-v0.20.1-orth)", ] [[package]] @@ -8369,7 +8383,7 @@ dependencies = [ "cfg-if 1.0.0", "fastrand", "redox_syscall 0.3.5", - "rustix 0.37.14", + "rustix 0.37.15", "windows-sys 0.45.0", ] @@ -9009,11 +9023,10 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "cf9cf6a813d3f40c88b0b6b6f29a5c95c6cdbf97c1f9cc53fb820200f5ad814d" dependencies = [ - "cfg-if 1.0.0", "log 0.4.17", "pin-project-lite", "tracing-attributes", @@ -9126,7 +9139,7 @@ checksum = "0de5f738ceab88e2491a94ddc33c3feeadfa95fedc60363ef110845df12f3878" [[package]] name = "triedb" version = "0.5.0" -source = "git+https://github.com/velas/triedb?tag=fast_rlp#4897a7febd6808523879aa4b41e87aa3a091c8ec" +source = "git+https://github.com/velas/triedb?tag=fast_rlp#a0019f6073a081bc9f177b4b7fb41362fb5d6649" dependencies = [ "anyhow", "backtrace", @@ -9150,7 +9163,7 @@ dependencies = [ [[package]] name = "triedb" version = "0.5.0" -source = "git+https://github.com/velas/triedb?tag=optimal_children_expose_error#6cef9352ebda60189a5cd4c9a424fb6dcb5e37ee" +source = "git+https://github.com/velas/triedb?tag=rocksdb-v0.20.1-orth#48ad76f5c1491234840676d2721cc5287462f3d3" dependencies = [ "anyhow", "bincode", diff --git a/evm-utils/evm-state/Cargo.toml b/evm-utils/evm-state/Cargo.toml index 7ce1e710b9..bcbc70d45d 100644 --- a/evm-utils/evm-state/Cargo.toml +++ b/evm-utils/evm-state/Cargo.toml @@ -9,7 +9,8 @@ evm = { git = "https://github.com/velas/evm", tag = "v0.35-with-traces", feature secp256k1 = { version = "0.19.0", features = ["recovery", "global-context"] } # force rand version, because 0.6.5 break compatibility with secp256k1 rand2 = { version = "=0.6.1", package = "rand" } -rocksdb = { git = "https://github.com/velas/rust-rocksdb", version = "0.19.0", default-features = false } +rocksdb = { package = "rocksdb", version = "0.20.1", default-features = false } + # rocksdb = { version = "0.16.0", default-features = false } triedb = { git = "https://github.com/velas/triedb", tag = "fast_rlp", features = ["rocksdb"] } # triedb = { path = "../../../triedb", features = ["rocksdb"] } diff --git a/evm-utils/evm-state/src/storage/mod.rs b/evm-utils/evm-state/src/storage/mod.rs index fdbcc4d276..ae67436c74 100644 --- a/evm-utils/evm-state/src/storage/mod.rs +++ b/evm-utils/evm-state/src/storage/mod.rs @@ -17,9 +17,9 @@ use log::*; use rlp::{Decodable as DecodableOld, Encodable as EncodableOld}; use rocksdb::{ backup::{BackupEngine, BackupEngineOptions, RestoreOptions}, - db::{DBInner, DBWithThreadModeInner}, ColumnFamily, ColumnFamilyDescriptor, Env, IteratorMode, OptimisticTransactionDB, - OptimisticTransactionDBInner, Options, ReadOptions, + DBWithThreadMode, + Options, ReadOptions, AsColumnFamilyRef, DBIteratorWithThreadMode, DBAccess, DBPinnableSlice, }; use serde::{de::DeserializeOwned, Serialize}; use tempfile::TempDir; @@ -96,16 +96,17 @@ impl AsRef for Location { } } -pub struct Storage +pub struct Storage where - D: DBInner, + D: VelasDBCommon, { pub(crate) db: Arc>, // Location should be second field, because of drop order in Rust. location: Location, gc_enabled: bool, } -impl Clone for Storage { + +impl Clone for Storage { fn clone(&self) -> Self { Self { db: Arc::clone(&self.db), @@ -115,7 +116,7 @@ impl Clone for Storage { } } -impl std::fmt::Debug for Storage { +impl std::fmt::Debug for Storage { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("Storage") .field("db", &self.db) @@ -199,13 +200,13 @@ impl Descriptors { impl Storage where - D: DBInner, + D: VelasDBCommon, { pub fn gc_enabled(&self) -> bool { self.gc_enabled } - pub fn db(&self) -> &rocksdb::DBCommon { + pub fn db(&self) -> &D { (*self.db).borrow() } @@ -254,11 +255,12 @@ where } } -type ReadOnlyDb = rocksdb::DBWithThreadMode; +type RocksWithThreadMode = DBWithThreadMode; -pub type StorageSecondary = Storage; +pub type StorageSecondary = Storage; impl StorageSecondary { + pub fn open_secondary_persistent>(path: P, gc_enabled: bool) -> Result { Self::open(Location::Persisent(path.as_ref().to_owned()), gc_enabled) } @@ -270,7 +272,7 @@ impl StorageSecondary { pub fn rocksdb_trie_handle( &self, - ) -> SyncRocksHandle { + ) -> SyncRocksHandle { SyncRocksHandle::new(RocksDatabaseHandle::new(self.db())) } @@ -293,7 +295,7 @@ impl StorageSecondary { temporarily cause the performance of another db use (like by validator) to degrade" ); - ReadOnlyDb::open_cf_as_secondary( + RocksWithThreadMode::open_cf_as_secondary( &db_opts, path.as_ref(), secondary_path.as_path(), @@ -309,7 +311,9 @@ impl StorageSecondary { } } -impl Storage { +impl Storage { + + pub fn open_persistent>(path: P, gc_enabled: bool) -> Result { Self::open(Location::Persisent(path.as_ref().to_owned()), gc_enabled) } @@ -372,7 +376,9 @@ impl Storage { path.display(), target.display() ); - let mut engine = BackupEngine::open(&BackupEngineOptions::default(), path)?; + let opts = BackupEngineOptions::new(path)?; + let env = Env::new()?; + let mut engine = BackupEngine::open(&opts, &env)?; engine.restore_from_latest_backup(target, target, &RestoreOptions::default())?; Ok(()) @@ -694,7 +700,10 @@ impl Storage { let backup_dir = backup_dir.unwrap_or_else(|| self.location.as_ref().join(BACKUP_SUBDIR)); info!("EVM Backup storage data into {}", backup_dir.display()); - let mut engine = BackupEngine::open(&BackupEngineOptions::default(), &backup_dir)?; + let opts = BackupEngineOptions::new(&backup_dir)?; + let env = Env::new()?; + + let mut engine = BackupEngine::open(&opts, &env)?; if engine.get_backup_info().len() > HARD_BACKUPS_COUNT { // TODO: measure engine.purge_old_backups(HARD_BACKUPS_COUNT)?; @@ -810,19 +819,127 @@ impl<'a> RootCleanup<'a> { } } -impl Borrow for Storage { +impl Borrow for Storage { fn borrow(&self) -> &DB { self.db() } } +pub trait VelasDBCommon: DBAccess + std::fmt::Debug + Sized { + + fn flush(&self) -> Result<(), rocksdb::Error> ; + fn cancel_all_background_work(&self, wait: bool) ; + + fn iterator_cf<'a: 'b, 'b>( + &'a self, + cf_handle: &impl AsColumnFamilyRef, + mode: IteratorMode, + ) -> DBIteratorWithThreadMode<'b, Self> ; + + fn get_pinned_cf>( + &self, + cf: &impl AsColumnFamilyRef, + key: K, + ) -> Result, rocksdb::Error> ; + + fn put_cf(&self, cf: &impl AsColumnFamilyRef, key: K, value: V) -> Result<(), rocksdb::Error> + where + K: AsRef<[u8]>, + V: AsRef<[u8]>; + + fn cf_handle(&self, name: &str) -> Option<&ColumnFamily> ; + +} + +impl VelasDBCommon for rocksdb::DBWithThreadMode { + + fn flush(&self) -> Result<(), rocksdb::Error> { + self.flush() + } + + fn cancel_all_background_work(&self, wait: bool) { + self.cancel_all_background_work(wait) + } + + fn iterator_cf<'a: 'b, 'b>( + &'a self, + cf_handle: &impl AsColumnFamilyRef, + mode: IteratorMode, + ) -> DBIteratorWithThreadMode<'b, Self> { + self.iterator_cf(cf_handle, mode) + } + fn get_pinned_cf>( + &self, + cf: &impl AsColumnFamilyRef, + key: K, + ) -> Result, rocksdb::Error> { + self.get_pinned_cf(cf, key) + + } + + fn put_cf(&self, cf: &impl AsColumnFamilyRef, key: K, value: V) -> Result<(), rocksdb::Error> + where + K: AsRef<[u8]>, + V: AsRef<[u8]> { + self.put_cf(cf, key, value) + + } + + fn cf_handle(&self, name: &str) -> Option<&ColumnFamily> { + self.cf_handle(name) + } + +} + +impl VelasDBCommon for OptimisticTransactionDB { + fn flush(&self) -> Result<(), rocksdb::Error> { + self.flush() + } + + fn cancel_all_background_work(&self, wait: bool) { + self.cancel_all_background_work(wait) + } + + fn iterator_cf<'a: 'b, 'b>( + &'a self, + cf_handle: &impl AsColumnFamilyRef, + mode: IteratorMode, + ) -> DBIteratorWithThreadMode<'b, Self> { + self.iterator_cf(cf_handle, mode) + } + + fn get_pinned_cf>( + &self, + cf: &impl AsColumnFamilyRef, + key: K, + ) -> Result, rocksdb::Error> { + self.get_pinned_cf(cf, key) + + } + + fn put_cf(&self, cf: &impl AsColumnFamilyRef, key: K, value: V) -> Result<(), rocksdb::Error> + where + K: AsRef<[u8]>, + V: AsRef<[u8]> { + self.put_cf(cf, key, value) + + } + + fn cf_handle(&self, name: &str) -> Option<&ColumnFamily> { + self.cf_handle(name) + } + + + +} + #[derive(AsRef, Deref)] // Hack to close rocksdb background threads. And flush database. -pub struct DbWithClose(rocksdb::DBCommon); +pub struct DbWithClose(D); impl Drop for DbWithClose where - D: rocksdb::db::DBInner, + D: VelasDBCommon, { fn drop(&mut self) { if let Err(e) = self.flush() { @@ -832,7 +949,7 @@ where } } -impl std::fmt::Debug for DbWithClose { +impl std::fmt::Debug for DbWithClose { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("DbWithClose") .field("0", &self.0) @@ -888,7 +1005,7 @@ impl SubStorage for TransactionHashesPerBlock { impl Storage where - D: DBInner, + D: VelasDBCommon, { pub fn get(&self, key: S::Key) -> Option { let cf = self.cf::(); @@ -947,7 +1064,7 @@ pub fn default_db_opts() -> Result { let mut opts = Options::default(); opts.create_if_missing(true); opts.create_missing_column_families(true); - let mut env = Env::default()?; + let mut env = Env::new()?; env.join_all_threads(); opts.set_env(&env); Ok(opts) diff --git a/ledger/Cargo.toml b/ledger/Cargo.toml index 2de348dd00..db1a1254fe 100644 --- a/ledger/Cargo.toml +++ b/ledger/Cargo.toml @@ -61,8 +61,7 @@ parking_lot = "0.12.1" # version = "0.16.0" default-features = false features = ["lz4"] -git = "https://github.com/velas/rust-rocksdb" -version = "0.19.0" +version = "0.20.1" [dev-dependencies] assert_matches = "1.5.0" diff --git a/ledger/src/blockstore_db.rs b/ledger/src/blockstore_db.rs index 49d672cf8f..56af48e789 100644 --- a/ledger/src/blockstore_db.rs +++ b/ledger/src/blockstore_db.rs @@ -1773,7 +1773,7 @@ fn get_db_options(access_type: &AccessType) -> Options { // A good value for this is the number of cores on the machine options.increase_parallelism(num_cpus::get() as i32); - let mut env = rocksdb::Env::default().unwrap(); + let mut env = rocksdb::Env::new().unwrap(); // While a compaction is ongoing, all the background threads // could be used by the compaction. This can stall writes which diff --git a/replica-lib/Cargo.toml b/replica-lib/Cargo.toml index e0cdf3954a..8a0f6f41c8 100644 --- a/replica-lib/Cargo.toml +++ b/replica-lib/Cargo.toml @@ -38,9 +38,9 @@ derivative="2.2" evm-state = { path = "../evm-utils/evm-state" } evm-rpc = { path = "../evm-utils/evm-rpc" } primitive-types = "0.8.0" -rocksdb = { git = "https://github.com/velas/rust-rocksdb", version = "0.19.0", default-features = false } +rocksdb = { package = "rocksdb", version = "0.20.1", default-features = false } -triedb = { git = "https://github.com/velas/triedb", tag = "optimal_children_expose_error", features = ["rocksdb"] } +triedb = { git = "https://github.com/velas/triedb", tag = "rocksdb-v0.20.1-orth", features = ["rocksdb"] } rangemap = { version = "1.3.0", features = ["serde1"]} diff --git a/replica-node/src/bin/triedb_client.rs b/replica-node/src/bin/triedb_client.rs index 2fba6d7643..d0ef045f26 100644 --- a/replica-node/src/bin/triedb_client.rs +++ b/replica-node/src/bin/triedb_client.rs @@ -90,6 +90,7 @@ impl ParsedArgs { }) } + fn build(self) -> Result { log::info!("building ClientOpts {:#?}", self); From ac2ca59880daab8601c4527ae99ed6f6a64f5fd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dj8yf0=CE=BCl?= Date: Wed, 26 Apr 2023 22:39:33 +0300 Subject: [PATCH 08/11] feat(evm-utils/evm-state): connect to fast_rlp feature of triedb, part 3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ ] merge [pull request: < fast-rlp >](https://github.com/velas/velas-chain/pull/443) ├── [ ] merge [pull request: < triedb | fast-rlp >](https://github.com/velas/triedb/pull/51) └── [ ] make minimal changes to make velas-chain compile with both libs used ├── [✓] __evm-utils/evm-state/src/types.rs__: │ ├── [✓] `Account` │ │ ├── [✓] `Encodable` stub, `Decodable` stub │ │ ├── [✓] actual impl │ │ │ └── [✓] roundtrip test │ │ └── [✓] move old impl to #[cfg(test)] │ └── [✓] `EthereumReceipt` │ ├── [✓] `Encodable` stub, `Decodable` stub │ ├── [✓] roundtrip test │ ├── [✓] move old impl to #[cfg(test)] │ └── [✓] nested │ ├── [✓] `ethbloom::Bloom` │ │ ├── [✓] `Encodable` stub, `Decodable` stub │ │ ├── [✓] nested │ │ └── [✓] roundtrip test │ └── [✓] `ethereum::Log` │ ├── [✓] `Encodable` stub, `Decodable` stub │ ├── [✓] nested │ └── [✓] roundtrip test └── [ ] __evm-utils/evm-state/src/transactions.rs__: └── [ ] `TransactionInReceipt` ├── [✓] `Encodable` stub, `Decodable` stub ├── [ ] roundtrip test ├── [ ] move old impl to #[cfg(test)] └── [ ] nested ├── [ ] `Transaction` │ ├── [ ] `Encodable` stub, `Decodable` stub │ ├── [ ] roundtrip test │ ├── [ ] move old impl to #[cfg(test)] │ └── [ ] nested │ └── [✓] `TransactionAction` │ ├── [✓] `Encodable` stub, `Decodable` stub │ └── [✓] nested └── [✓] `UnsignedTransactionWithCaller` ├── [✓] `Encodable` stub, `Decodable` stub ├── [✓] roundtrip test ├── [ ] move old impl to #[cfg(test)] └── [ ] nested └── [✓] `UnsignedTransaction` ├── [✓] `Encodable` stub, `Decodable` stub ├── [✓] roundtrip test ├── [✓] move old impl to #[cfg(test)] ├── [✓] return derived `Encodable`, `Decodable` impl └── [✓] nested └── [✓] `TransactionAction` ├── [✓] `Encodable` stub, `Decodable` stub ├── [✓] roundtrip test └── [ ] move old impl to #[cfg(test)] --- Cargo.lock | 29 +-- .../evm-state/src/rlp_roundtrip_tests.rs | 85 ++++++- evm-utils/evm-state/src/transactions.rs | 210 ++++++++++++------ replica-lib/Cargo.toml | 2 +- .../triedb/client/sync/bootstrap/helpers.rs | 2 +- 5 files changed, 237 insertions(+), 91 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 93e10be1b0..f4aa819900 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2101,7 +2101,7 @@ dependencies = [ "snafu", "tempfile", "thiserror", - "triedb 0.5.0 (git+https://github.com/velas/triedb?tag=fast_rlp)", + "triedb", ] [[package]] @@ -6999,7 +6999,7 @@ dependencies = [ "solana-vote-program", "tikv-jemallocator", "tokio", - "triedb 0.5.0 (git+https://github.com/velas/triedb?tag=fast_rlp)", + "triedb", ] [[package]] @@ -7407,7 +7407,7 @@ dependencies = [ "tokio", "tonic 0.8.3", "tonic-build 0.8.4", - "triedb 0.5.0 (git+https://github.com/velas/triedb?tag=rocksdb-v0.20.1-orth)", + "triedb", ] [[package]] @@ -7794,7 +7794,7 @@ dependencies = [ "solana-sdk", "solana-transaction-status", "tonic-build 0.8.4", - "triedb 0.5.0 (git+https://github.com/velas/triedb?tag=fast_rlp)", + "triedb", ] [[package]] @@ -9160,27 +9160,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "triedb" -version = "0.5.0" -source = "git+https://github.com/velas/triedb?tag=rocksdb-v0.20.1-orth#48ad76f5c1491234840676d2721cc5287462f3d3" -dependencies = [ - "anyhow", - "bincode", - "dashmap 4.0.2", - "derivative", - "etcommon-hexutil", - "log 0.4.17", - "primitive-types 0.11.1", - "rayon", - "rlp", - "rocksdb", - "serde", - "sha3 0.9.1", - "termtree", - "thiserror", -] - [[package]] name = "triehash" version = "0.8.4" diff --git a/evm-utils/evm-state/src/rlp_roundtrip_tests.rs b/evm-utils/evm-state/src/rlp_roundtrip_tests.rs index 1d4ab62b99..3bd0737816 100644 --- a/evm-utils/evm-state/src/rlp_roundtrip_tests.rs +++ b/evm-utils/evm-state/src/rlp_roundtrip_tests.rs @@ -1,4 +1,4 @@ -use crate::{transaction_roots::EthereumReceipt, TransactionAction, UnsignedTransaction}; +use crate::{transaction_roots::EthereumReceipt, TransactionAction, UnsignedTransaction, UnsignedTransactionWithCaller}; use super::types::Account; @@ -151,6 +151,7 @@ fn test_check_tranaaction_action_roundtrip() { check_roundtrip!(ta2 => TransactionAction); } + #[test] fn test_check_unsigned_transaction_roundtrip() { let ta2 = TransactionAction::Call(H160([56; 20])); @@ -177,4 +178,86 @@ fn test_check_unsigned_transaction_roundtrip() { }; check_roundtrip!(ut1 => UnsignedTransaction); +} + +#[test] +fn test_check_unsigned_transaction_with_caller_roundtrip1() { + let ta = TransactionAction::Call(H160([56; 20])); + + let ut = UnsignedTransaction { + nonce: U256([46;4]), + gas_price: U256([543; 4]), + gas_limit: U256([342;4]), + action: ta, + value: U256([20000; 4]), + input: vec![34, 45, 12, 123, 243], + }; + + let ut_c = UnsignedTransactionWithCaller { + unsigned_tx: ut, + caller: H160([23; 20]), + chain_id: 24, + signed_compatible: true, + + }; + let old_rlp_raw: Vec; + let rlp_raw; + { + old_rlp_raw = encode_old(&ut_c).to_vec(); + dbg!(hexutil::to_hex(&old_rlp_raw)); + let rlp = Rlp::new(&old_rlp_raw); + let decoded_node: UnsignedTransactionWithCaller = UnsignedTransactionWithCaller::decode_old(&rlp, true).unwrap(); + assert_eq!(decoded_node, ut_c); + } + { + rlp_raw = encode(&ut_c); + dbg!(hexutil::to_hex(&rlp_raw)); + let decoded_node: UnsignedTransactionWithCaller = UnsignedTransactionWithCaller::decode(&mut rlp_raw.as_ref(), true).unwrap(); + assert_eq!(decoded_node, ut_c); + } + + { + assert_eq!(old_rlp_raw, rlp_raw); + } +} + +#[test] +fn test_check_unsigned_transaction_with_caller_roundtrip2() { + let ta = TransactionAction::Create; + + let ut = UnsignedTransaction { + nonce: U256([46;4]), + gas_price: U256([543; 4]), + gas_limit: U256([342;4]), + action: ta, + value: U256([23000;4]), + input: vec![34, 45, 12, 123, 243], + }; + + let ut_c = UnsignedTransactionWithCaller { + unsigned_tx: ut, + caller: H160([23; 20]), + chain_id: 24, + signed_compatible: false, + + }; + let old_rlp_raw: Vec; + let rlp_raw; + { + old_rlp_raw = encode_old(&ut_c).to_vec(); + dbg!(hexutil::to_hex(&old_rlp_raw)); + let rlp = Rlp::new(&old_rlp_raw); + let decoded_node: UnsignedTransactionWithCaller = UnsignedTransactionWithCaller::decode_old(&rlp, false).unwrap(); + assert_eq!(decoded_node, ut_c); + } + { + rlp_raw = encode(&ut_c); + dbg!(hexutil::to_hex(&rlp_raw)); + let decoded_node: UnsignedTransactionWithCaller = UnsignedTransactionWithCaller::decode(&mut rlp_raw.as_ref(), false).unwrap(); + assert_eq!(decoded_node, ut_c); + } + + { + assert_eq!(old_rlp_raw, rlp_raw); + } } \ No newline at end of file diff --git a/evm-utils/evm-state/src/transactions.rs b/evm-utils/evm-state/src/transactions.rs index 14855107f0..a0075ab828 100644 --- a/evm-utils/evm-state/src/transactions.rs +++ b/evm-utils/evm-state/src/transactions.rs @@ -1,5 +1,5 @@ use borsh::{BorshDeserialize, BorshSchema, BorshSerialize}; -use bytes::{BufMut, Buf}; +use bytes::BufMut; use evm::{backend::Log, ExitReason, ExitRevert}; use primitive_types::{H160, H256, U256}; use rlp::{Decodable as DecodableOld, DecoderError, Encodable as EncodableOld, Rlp, RlpStream}; @@ -131,6 +131,7 @@ impl Transaction { )] +#[derive(Decodable, Encodable)] pub struct UnsignedTransaction { pub nonce: U256, pub gas_price: U256, @@ -430,65 +431,6 @@ impl DecodableOld for UnsignedTransaction { } } -impl Encodable for UnsignedTransaction { - fn encode(&self,out: &mut dyn BufMut) { - - let len = self.nonce.length() + self.gas_price.length() + - self.gas_limit.length() + self.action.length() + self.value.length() + self.input.length(); - fastrlp::Header { - list: true, - payload_length: len, - }.encode(out); - self.nonce.encode(out); - self.gas_price.encode(out); - self.gas_limit.encode(out); - self.action.encode(out); - self.value.encode(out); - self.input.encode(out); - } - - fn length(&self) -> usize { - - let len = self.nonce.length() + self.gas_price.length() + - self.gas_limit.length() + self.action.length() + self.value.length() + self.input.length(); - fastrlp::Header { - list: true, - payload_length: len, - } - .length() - + len - - } -} - - -impl<'de> Decodable<'de> for UnsignedTransaction { - fn decode(buf: &mut &'de [u8]) -> Result { - let h = fastrlp::Header::decode(buf)?; - if !h.list { - return Err(fastrlp::DecodeError::UnexpectedString); - } - let payload_view = &mut &buf[..h.payload_length]; - let cnt = fastrlp::count(payload_view)?; - if cnt!= 6 { - return Err(fastrlp::DecodeError::ListLengthMismatch { expected: 6, got: cnt }); - } - - let nonce = fastrlp::Decodable::decode(payload_view)?; - let gas_price = fastrlp::Decodable::decode(payload_view)?; - let gas_limit = fastrlp::Decodable::decode(payload_view)?; - let action = fastrlp::Decodable::decode(payload_view)?; - let value = fastrlp::Decodable::decode(payload_view)?; - let input: &[u8] = fastrlp::Decodable::decode(payload_view)?; - buf.advance(h.payload_length); - Ok(Self { - nonce, gas_price, gas_limit, action, value, input: input.to_vec(), - }) - } -} - - - impl From for UnsignedTransaction { fn from(val: Transaction) -> UnsignedTransaction { UnsignedTransaction { @@ -562,10 +504,10 @@ impl DecodableOld for TransactionInReceipt { fn decode(rlp: &Rlp<'_>) -> Result { let items = rlp.item_count()?; Ok(match items { - 8 => TransactionInReceipt::Unsigned(UnsignedTransactionWithCaller::decode(rlp, false)?), + 8 => TransactionInReceipt::Unsigned(UnsignedTransactionWithCaller::decode_old(rlp, false)?), 9 => { if rlp.val_at::(8) == Ok(0x1u8) { - TransactionInReceipt::Unsigned(UnsignedTransactionWithCaller::decode( + TransactionInReceipt::Unsigned(UnsignedTransactionWithCaller::decode_old( rlp, true, )?) } else { @@ -615,6 +557,96 @@ impl EncodableOld for UnsignedTransactionWithCaller { } } +impl Encodable for UnsignedTransactionWithCaller { + + fn encode(&self,out: &mut dyn BufMut) { + let chain_id = self.chain_id; + if self.signed_compatible { + let len = self.unsigned_tx.nonce.length() + + self.unsigned_tx.gas_price.length() + + self.unsigned_tx.gas_limit.length() + + self.unsigned_tx.action.length()+ + self.unsigned_tx.value.length()+ + self.unsigned_tx.input.length()+ + chain_id.length() + + self.caller.length() + + UNSIGNED_TX_MARKER.length(); + fastrlp::Header { + list: true, + payload_length: len, + }.encode(out); + self.unsigned_tx.nonce.encode(out); + self.unsigned_tx.gas_price.encode(out); + self.unsigned_tx.gas_limit.encode(out); + self.unsigned_tx.action.encode(out); + self.unsigned_tx.value.encode(out); + self.unsigned_tx.input.encode(out); + chain_id.encode(out); + self.caller.encode(out); + UNSIGNED_TX_MARKER.encode(out); + } else { + let len = self.unsigned_tx.nonce.length() + + self.unsigned_tx.gas_price.length() + + self.unsigned_tx.gas_limit.length() + + self.unsigned_tx.action.length()+ + self.unsigned_tx.value.length()+ + self.unsigned_tx.input.length()+ + self.caller.length() + + chain_id.length(); + fastrlp::Header { + list: true, + payload_length: len, + }.encode(out); + self.unsigned_tx.nonce.encode(out); + self.unsigned_tx.gas_price.encode(out); + self.unsigned_tx.gas_limit.encode(out); + self.unsigned_tx.action.encode(out); + self.unsigned_tx.value.encode(out); + self.unsigned_tx.input.encode(out); + self.caller.encode(out); + chain_id.encode(out); + + } + + } + fn length(&self) -> usize { + let chain_id = self.chain_id; + if self.signed_compatible { + let len = self.unsigned_tx.nonce.length() + + self.unsigned_tx.gas_price.length() + + self.unsigned_tx.gas_limit.length() + + self.unsigned_tx.action.length()+ + self.unsigned_tx.value.length()+ + self.unsigned_tx.input.length()+ + chain_id.length() + + self.caller.length() + + UNSIGNED_TX_MARKER.length(); + fastrlp::Header { + list: true, + payload_length: len, + } + .length() + + len + } else { + let len = self.unsigned_tx.nonce.length() + + self.unsigned_tx.gas_price.length() + + self.unsigned_tx.gas_limit.length() + + self.unsigned_tx.action.length()+ + self.unsigned_tx.value.length()+ + self.unsigned_tx.input.length()+ + self.caller.length() + + chain_id.length(); + fastrlp::Header { + list: true, + payload_length: len, + } + .length() + + len + + } + } +} + impl UnsignedTransactionWithCaller { pub fn tx_id_hash(&self) -> H256 { // old transaction hash was calculated with different rlp structure, use signing_hash to be compatible @@ -625,7 +657,7 @@ impl UnsignedTransactionWithCaller { self.rlp_append(&mut stream); H256::from_slice(Keccak256::digest(stream.as_raw()).as_slice()) } - fn decode(rlp: &Rlp<'_>, signed_compatible: bool) -> Result { + pub(super) fn decode_old(rlp: &Rlp<'_>, signed_compatible: bool) -> Result { let nonce = rlp.val_at(0)?; let gas_price = rlp.val_at(1)?; let gas_limit = rlp.val_at(2)?; @@ -664,6 +696,58 @@ impl UnsignedTransactionWithCaller { }) } } + + pub(super) fn decode(buf: &mut &[u8], signed_compatible: bool) -> Result { + let h = fastrlp::Header::decode(buf)?; + if !h.list { + return Err(fastrlp::DecodeError::UnexpectedString); + } + let payload_view = &mut &buf[..h.payload_length]; + let cnt = fastrlp::count(payload_view)?; + let expected_cnt = if signed_compatible { + 9 + } else { + 8 + }; + + if cnt!= expected_cnt { + return Err(fastrlp::DecodeError::ListLengthMismatch { expected: expected_cnt, got: cnt }); + } + let nonce = fastrlp::Decodable::decode(payload_view)?; + let gas_price = fastrlp::Decodable::decode(payload_view)?; + let gas_limit = fastrlp::Decodable::decode(payload_view)?; + let action = fastrlp::Decodable::decode(payload_view)?; + let value = fastrlp::Decodable::decode(payload_view)?; + let input = fastrlp::Decodable::decode(payload_view)?; + let (chain_id, caller) = if signed_compatible { + let chain_id = fastrlp::Decodable::decode(payload_view)?; + let caller = fastrlp::Decodable::decode(payload_view)?; + let _marker: u8 = fastrlp::Decodable::decode(payload_view)?; + debug_assert_eq!(_marker, UNSIGNED_TX_MARKER); + debug_assert!(payload_view.is_empty()); + (chain_id, caller) + } else { + let caller = fastrlp::Decodable::decode(payload_view)?; + let chain_id = fastrlp::Decodable::decode(payload_view)?; + debug_assert!(payload_view.is_empty()); + (chain_id, caller) + + }; + + Ok(Self { + unsigned_tx: UnsignedTransaction { + nonce, + gas_price, + gas_limit, + action, + value, + input, + }, + caller, + chain_id, + signed_compatible, + }) + } } // TODO: Work on logs and state_root. diff --git a/replica-lib/Cargo.toml b/replica-lib/Cargo.toml index 8a0f6f41c8..bf3f477d7f 100644 --- a/replica-lib/Cargo.toml +++ b/replica-lib/Cargo.toml @@ -40,7 +40,7 @@ evm-rpc = { path = "../evm-utils/evm-rpc" } primitive-types = "0.8.0" rocksdb = { package = "rocksdb", version = "0.20.1", default-features = false } -triedb = { git = "https://github.com/velas/triedb", tag = "rocksdb-v0.20.1-orth", features = ["rocksdb"] } +triedb = { git = "https://github.com/velas/triedb", tag = "fast_rlp", features = ["rocksdb"] } rangemap = { version = "1.3.0", features = ["serde1"]} diff --git a/replica-lib/src/triedb/client/sync/bootstrap/helpers.rs b/replica-lib/src/triedb/client/sync/bootstrap/helpers.rs index 90393ac257..a7942d60b9 100644 --- a/replica-lib/src/triedb/client/sync/bootstrap/helpers.rs +++ b/replica-lib/src/triedb/client/sync/bootstrap/helpers.rs @@ -20,7 +20,7 @@ fn map_node_to_next_layer( parent: &((H256, bool), Vec), ) -> Result, triedb::Error> { let ((_hash, direct), node) = parent; - let node = MerkleNode::decode(&Rlp::new(node))?; + let node = triedb::rlp::decode(node)?; let (direct_childs, indirect_childs) = if *direct { ReachableHashes::collect(&node, account_extractor).childs() From 6d03e8a57759b9d70fdfecde3fb4c1ce2dcbc8ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dj8yf0=CE=BCl?= Date: Thu, 27 Apr 2023 16:54:21 +0300 Subject: [PATCH 09/11] feat(evm-utils/evm-state): connect to fast_rlp feature part 4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ ] merge [pull request: < fast-rlp >](https://github.com/velas/velas-chain/pull/443) ├── [ ] merge [pull request: < triedb | fast-rlp >](https://github.com/velas/triedb/pull/51) └── [✓] make minimal changes to make velas-chain compile with both libs used ├── [✓] __evm-utils/evm-state/src/types.rs__: │ ├── [✓] `Account` │ │ ├── [✓] `Encodable` stub, `Decodable` stub │ │ ├── [✓] actual impl │ │ │ └── [✓] roundtrip test │ │ └── [✓] move old impl to #[cfg(test)] │ └── [✓] `EthereumReceipt` │ ├── [✓] `Encodable` stub, `Decodable` stub │ ├── [✓] roundtrip test │ ├── [✓] move old impl to #[cfg(test)] │ └── [✓] nested │ ├── [✓] `ethbloom::Bloom` │ │ ├── [✓] `Encodable` stub, `Decodable` stub │ │ ├── [✓] nested │ │ └── [✓] roundtrip test │ └── [✓] `ethereum::Log` │ ├── [✓] `Encodable` stub, `Decodable` stub │ ├── [✓] nested │ └── [✓] roundtrip test └── [✓] __evm-utils/evm-state/src/transactions.rs__: └── [✓] `TransactionInReceipt` ├── [✓] `Encodable` stub, `Decodable` stub ├── [✓] roundtrip test │ └── [✓] split roundtrip test in 3 ├── [✓] move old impl to #[cfg(test)] └── [✓] nested ├── [✓] `Transaction` │ ├── [✓] `Encodable` stub, `Decodable` stub │ ├── [✓] roundtrip test │ ├── [✓] move old impl to #[cfg(test)] │ └── [✓] nested │ └── [✓] `TransactionAction` │ ├── [✓] `Encodable` stub, `Decodable` stub │ ├── [✓] nested │ └── [ ] move old impl to #[cfg(test)] └── [✓] `UnsignedTransactionWithCaller` ├── [✓] `Encodable` stub, `Decodable` stub ├── [✓] roundtrip test ├── [✓] move old impl to #[cfg(test)] └── [✓] nested └── [✓] `UnsignedTransaction` ├── [✓] `Encodable` stub, `Decodable` stub ├── [✓] roundtrip test ├── [✓] move old impl to #[cfg(test)] ├── [✓] return derived `Encodable`, `Decodable` impl └── [✓] nested └── [✓] `TransactionAction` ├── [✓] `Encodable` stub, `Decodable` stub ├── [✓] roundtrip test └── [ ] move old impl to #[cfg(test)] --- .../evm-state/src/rlp_roundtrip_tests.rs | 150 ++++++++++++++++- evm-utils/evm-state/src/transactions.rs | 157 ++++++++++++++++-- storage-proto/src/convert.rs | 6 +- 3 files changed, 298 insertions(+), 15 deletions(-) diff --git a/evm-utils/evm-state/src/rlp_roundtrip_tests.rs b/evm-utils/evm-state/src/rlp_roundtrip_tests.rs index 3bd0737816..1c367b0ce8 100644 --- a/evm-utils/evm-state/src/rlp_roundtrip_tests.rs +++ b/evm-utils/evm-state/src/rlp_roundtrip_tests.rs @@ -1,4 +1,4 @@ -use crate::{transaction_roots::EthereumReceipt, TransactionAction, UnsignedTransaction, UnsignedTransactionWithCaller}; +use crate::{transaction_roots::EthereumReceipt, TransactionAction, UnsignedTransaction, UnsignedTransactionWithCaller, Transaction, TransactionSignature, TransactionInReceipt}; use super::types::Account; @@ -260,4 +260,150 @@ fn test_check_unsigned_transaction_with_caller_roundtrip2() { { assert_eq!(old_rlp_raw, rlp_raw); } -} \ No newline at end of file +} + +#[test] +fn test_check_transaction_roundtrip() { + + let ta1 = TransactionAction::Create; + let tx1 = Transaction{ + nonce: U256([72; 4]), + gas_price: U256([3213;4]), + gas_limit: U256([4324; 4]), + action: ta1, + value: U256([7732; 4]), + signature: TransactionSignature { + v: 88979, + r: H256([34; 32]), + s: H256([78; 32]), + }, + input: vec![32, 31, 0, 34, 76, 173], + + }; + + check_roundtrip!(tx1 => Transaction); + + let ta2 = TransactionAction::Call(H160([56; 20])); + let tx2 = Transaction{ + nonce: U256([79; 4]), + gas_price: U256([3013;4]), + gas_limit: U256([4124; 4]), + action: ta2, + value: U256([7832; 4]), + signature: TransactionSignature { + v: 88979, + r: H256([38; 32]), + s: H256([76; 32]), + }, + input: vec![32, 31, 0, 34, 76, 173], + + }; + + check_roundtrip!(tx2 => Transaction); + +} + +#[test] +fn test_check_transaction_in_receipt_roundtrip1() { + + let ta = TransactionAction::Create; + let tx = Transaction{ + nonce: U256([72; 4]), + gas_price: U256([3213;4]), + gas_limit: U256([4324; 4]), + action: ta, + value: U256([7732; 4]), + signature: TransactionSignature { + v: 88979, + r: H256([34; 32]), + s: H256([78; 32]), + }, + input: vec![32, 31, 0, 34, 76, 173], + + }; + + let tx_in_rec1 = TransactionInReceipt::Signed(tx); + + check_roundtrip!(tx_in_rec1 => TransactionInReceipt); + +} + +#[test] +fn test_check_transaction_in_receipt_roundtrip2() { + let ta = TransactionAction::Create; + + let ut = UnsignedTransaction { + nonce: U256([46;4]), + gas_price: U256([543; 4]), + gas_limit: U256([342;4]), + action: ta, + value: U256([23000;4]), + input: vec![34, 45, 12, 123, 243], + }; + + let ut_c = UnsignedTransactionWithCaller { + unsigned_tx: ut, + caller: H160([23; 20]), + chain_id: 24, + signed_compatible: false, + + }; + + let tx_in_rec2 = TransactionInReceipt::Unsigned(ut_c); + + + check_roundtrip!(tx_in_rec2 => TransactionInReceipt); +} + +#[test] +fn test_check_transaction_in_receipt_roundtrip3() { + let ta2 = TransactionAction::Call(H160([56; 20])); + + let ut2 = UnsignedTransaction { + nonce: U256([46;4]), + gas_price: U256([543; 4]), + gas_limit: U256([342;4]), + action: ta2, + value: U256([20000; 4]), + input: vec![34, 45, 12, 123, 243], + }; + + let ut_c2 = UnsignedTransactionWithCaller { + unsigned_tx: ut2, + caller: H160([23; 20]), + chain_id: 24, + signed_compatible: true, + + }; + let tx_in_rec3 = TransactionInReceipt::Unsigned(ut_c2); + + check_roundtrip!(tx_in_rec3 => TransactionInReceipt); + +} + +#[test] +fn test_check_unsigned_transaction_with_caller_tx_id_hash() { + let ta2 = TransactionAction::Call(H160([56; 20])); + + let ut2 = UnsignedTransaction { + nonce: U256([46;4]), + gas_price: U256([543; 4]), + gas_limit: U256([342;4]), + action: ta2, + value: U256([20000; 4]), + input: vec![34, 45, 12, 123, 243], + }; + + let ut_c2 = UnsignedTransactionWithCaller { + unsigned_tx: ut2, + caller: H160([23; 20]), + chain_id: 24, + signed_compatible: true, + + }; + + let old = ut_c2.tx_id_hash_old(); + let new = ut_c2.tx_id_hash(); + + assert_eq!(old, new); +} diff --git a/evm-utils/evm-state/src/transactions.rs b/evm-utils/evm-state/src/transactions.rs index a0075ab828..ae238bf4b4 100644 --- a/evm-utils/evm-state/src/transactions.rs +++ b/evm-utils/evm-state/src/transactions.rs @@ -1,5 +1,5 @@ use borsh::{BorshDeserialize, BorshSchema, BorshSerialize}; -use bytes::BufMut; +use bytes::{BufMut, Buf, BytesMut}; use evm::{backend::Log, ExitReason, ExitRevert}; use primitive_types::{H160, H256, U256}; use rlp::{Decodable as DecodableOld, DecoderError, Encodable as EncodableOld, Rlp, RlpStream}; @@ -129,8 +129,6 @@ impl Transaction { Serialize, Deserialize, )] - - #[derive(Decodable, Encodable)] pub struct UnsignedTransaction { pub nonce: U256, @@ -359,7 +357,6 @@ impl<'de> Decodable<'de> for TransactionAction { fn decode(buf: &mut &'de [u8]) -> Result { let mut buf_view = *buf; let h = fastrlp::Header::decode(&mut buf_view)?; - dbg!("header : {:?}", &h); if h.payload_length == 0 { let _h = fastrlp::Header::decode(buf)?; return Ok(Self::Create); @@ -385,6 +382,74 @@ impl EncodableOld for Transaction { } } +impl Encodable for Transaction { + fn encode(&self,out: &mut dyn BufMut) { + + let len = self.nonce.length() + self.gas_price.length() + + self.gas_limit.length() + self.action.length() + + self.value.length() + self.input.length() + + self.signature.v.length() + self.signature.r.length() + self.signature.s.length() ; + fastrlp::Header { + list: true, + payload_length: len, + }.encode(out); + self.nonce.encode(out); + self.gas_price.encode(out); + self.gas_limit.encode(out); + self.action.encode(out); + self.value.encode(out); + self.input.encode(out); + self.signature.v.encode(out); + self.signature.r.encode(out); + self.signature.s.encode(out); + } + + fn length(&self) -> usize { + + let len = self.nonce.length() + self.gas_price.length() + + self.gas_limit.length() + self.action.length() + + self.value.length() + self.input.length() + + self.signature.v.length() + self.signature.r.length() + self.signature.s.length() ; + fastrlp::Header { + list: true, + payload_length: len, + } + .length() + + len + + } +} + +impl<'de> Decodable<'de> for Transaction { + fn decode(buf: &mut &'de [u8]) -> Result { + let h = fastrlp::Header::decode(buf)?; + if !h.list { + return Err(fastrlp::DecodeError::UnexpectedString); + } + let payload_view = &mut &buf[..h.payload_length]; + let cnt = fastrlp::count(payload_view)?; + if cnt!= 9 { + return Err(fastrlp::DecodeError::ListLengthMismatch { expected: 9, got: cnt }); + } + + let nonce = fastrlp::Decodable::decode(payload_view)?; + let gas_price = fastrlp::Decodable::decode(payload_view)?; + let gas_limit = fastrlp::Decodable::decode(payload_view)?; + let action = fastrlp::Decodable::decode(payload_view)?; + let value = fastrlp::Decodable::decode(payload_view)?; + let input= fastrlp::Decodable::decode(payload_view)?; + let v= fastrlp::Decodable::decode(payload_view)?; + let r = fastrlp::Decodable::decode(payload_view)?; + let s = fastrlp::Decodable::decode(payload_view)?; + buf.advance(h.payload_length); + Ok(Self { + nonce, gas_price, gas_limit, action, value, input, + signature: TransactionSignature { v, r, s}, + }) + } +} + +#[cfg(test)] impl DecodableOld for Transaction { fn decode(rlp: &Rlp<'_>) -> Result { Ok(Self { @@ -462,19 +527,75 @@ impl TransactionInReceipt { impl Encodable for TransactionInReceipt { fn encode(&self,out: &mut dyn BufMut) { - unimplemented!(); + match self { + TransactionInReceipt::Signed(tx) => { + tx.encode(out); + }, + TransactionInReceipt::Unsigned(tx) => { + tx.encode(out); + }, + } } fn length(&self) -> usize { - unimplemented!(); - + match self { + TransactionInReceipt::Signed(tx) => { + tx.length() + }, + TransactionInReceipt::Unsigned(tx) => { + tx.length() + }, + } } } +pub fn consume(buf: &mut &[u8]) -> Result<(), triedb::rlp::decode::DecodeError> { + let h = fastrlp::Header::decode(buf)?; + + buf.advance(h.payload_length); + Ok(()) + + +} impl<'de> Decodable<'de> for TransactionInReceipt { fn decode(buf: &mut &'de [u8]) -> Result { - unimplemented!(); + let mut count_view = *buf; + let h = fastrlp::Header::decode(&mut count_view)?; + if !h.list { + return Err(fastrlp::DecodeError::UnexpectedString); + } + let count_view = &mut &count_view[..h.payload_length]; + let cnt = fastrlp::count(count_view)?; + + let res = match cnt { + 8 => { + TransactionInReceipt::Unsigned(UnsignedTransactionWithCaller::decode(buf, false)?) + }, + 9 => { + for _repeat in 0..8 { + consume(count_view)?; + } + let res: Result = fastrlp::Decodable::decode(count_view); + match (count_view.is_empty(), res) { + (true, Ok(UNSIGNED_TX_MARKER)) => { + TransactionInReceipt::Unsigned(UnsignedTransactionWithCaller::decode(buf, true)?) + }, + _ => { + TransactionInReceipt::Signed(::decode(buf)?) + } + + } + + }, + _ => return Err(fastrlp::DecodeError::Custom( + "list len must be either 8 or 9 for TransactionInReceipt" + ) ), + + }; + Ok(res) } } + +#[cfg(test)] impl EncodableOld for TransactionInReceipt { fn rlp_append(&self, s: &mut RlpStream) { match self { @@ -500,6 +621,7 @@ impl From for TransactionInReceipt { } } +#[cfg(test)] impl DecodableOld for TransactionInReceipt { fn decode(rlp: &Rlp<'_>) -> Result { let items = rlp.item_count()?; @@ -511,7 +633,7 @@ impl DecodableOld for TransactionInReceipt { rlp, true, )?) } else { - TransactionInReceipt::Signed(Transaction::decode(rlp)?) + TransactionInReceipt::Signed(::decode(rlp)?) } } _ => return Err(DecoderError::RlpInvalidLength), @@ -529,6 +651,7 @@ pub struct UnsignedTransactionWithCaller { pub signed_compatible: bool, } +#[cfg(test)] impl EncodableOld for UnsignedTransactionWithCaller { fn rlp_append(&self, s: &mut RlpStream) { let chain_id = self.chain_id; @@ -648,7 +771,9 @@ impl Encodable for UnsignedTransactionWithCaller { } impl UnsignedTransactionWithCaller { - pub fn tx_id_hash(&self) -> H256 { + + #[cfg(test)] + pub fn tx_id_hash_old(&self) -> H256 { // old transaction hash was calculated with different rlp structure, use signing_hash to be compatible if !self.signed_compatible { return self.unsigned_tx.signing_hash(Some(self.chain_id)); @@ -657,6 +782,18 @@ impl UnsignedTransactionWithCaller { self.rlp_append(&mut stream); H256::from_slice(Keccak256::digest(stream.as_raw()).as_slice()) } + pub fn tx_id_hash(&self) -> H256 { + + if !self.signed_compatible { + return self.unsigned_tx.signing_hash(Some(self.chain_id)); + } + let mut buf = BytesMut::with_capacity(1024); + self.encode(&mut buf); + + H256::from_slice(Keccak256::digest(buf.as_ref()).as_slice()) + + } + #[cfg(test)] pub(super) fn decode_old(rlp: &Rlp<'_>, signed_compatible: bool) -> Result { let nonce = rlp.val_at(0)?; let gas_price = rlp.val_at(1)?; diff --git a/storage-proto/src/convert.rs b/storage-proto/src/convert.rs index 0f0c8b1d4b..bef72ef79e 100644 --- a/storage-proto/src/convert.rs +++ b/storage-proto/src/convert.rs @@ -1097,9 +1097,9 @@ impl TryFrom for evm_state::TransactionInRe impl From for generated_evm::Transaction { fn from(tx: evm_state::Transaction) -> Self { - let bytes = rlp::encode(&tx); + let bytes = triedb::rlp::encode(&tx); Self { - rlp_encoded_body: bytes.to_vec(), + rlp_encoded_body: bytes, } } } @@ -1107,7 +1107,7 @@ impl From for generated_evm::Transaction { impl TryFrom for evm_state::Transaction { type Error = &'static str; fn try_from(tx: generated_evm::Transaction) -> Result { - rlp::decode(&tx.rlp_encoded_body).map_err(|_| "Failed to deserialize rlp tx body") + triedb::rlp::decode(&tx.rlp_encoded_body).map_err(|_| "Failed to deserialize rlp tx body") } } From 542e3a07efb1a32d9e10fec56bd49fd500877777 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dj8yf0=CE=BCl?= Date: Fri, 28 Apr 2023 00:55:09 +0300 Subject: [PATCH 10/11] fix(evm-utils/evm-state): fix decoding error --- evm-utils/evm-state/src/transactions.rs | 5 +++-- evm-utils/evm-state/src/types.rs | 4 ++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/evm-utils/evm-state/src/transactions.rs b/evm-utils/evm-state/src/transactions.rs index ae238bf4b4..2cacb180f5 100644 --- a/evm-utils/evm-state/src/transactions.rs +++ b/evm-utils/evm-state/src/transactions.rs @@ -441,6 +441,7 @@ impl<'de> Decodable<'de> for Transaction { let v= fastrlp::Decodable::decode(payload_view)?; let r = fastrlp::Decodable::decode(payload_view)?; let s = fastrlp::Decodable::decode(payload_view)?; + debug_assert!(payload_view.is_empty()); buf.advance(h.payload_length); Ok(Self { nonce, gas_price, gas_limit, action, value, input, @@ -861,15 +862,15 @@ impl UnsignedTransactionWithCaller { let caller = fastrlp::Decodable::decode(payload_view)?; let _marker: u8 = fastrlp::Decodable::decode(payload_view)?; debug_assert_eq!(_marker, UNSIGNED_TX_MARKER); - debug_assert!(payload_view.is_empty()); (chain_id, caller) } else { let caller = fastrlp::Decodable::decode(payload_view)?; let chain_id = fastrlp::Decodable::decode(payload_view)?; - debug_assert!(payload_view.is_empty()); (chain_id, caller) }; + debug_assert!(payload_view.is_empty()); + buf.advance(h.payload_length); Ok(Self { unsigned_tx: UnsignedTransaction { diff --git a/evm-utils/evm-state/src/types.rs b/evm-utils/evm-state/src/types.rs index 19afe0792b..ace06ad8ff 100644 --- a/evm-utils/evm-state/src/types.rs +++ b/evm-utils/evm-state/src/types.rs @@ -231,6 +231,8 @@ impl<'de> Decodable<'de> for Account { let balance = fastrlp::Decodable::decode(payload_view)?; let storage_root= fastrlp::Decodable::decode(payload_view)?; let code_hash = fastrlp::Decodable::decode(payload_view)?; + + debug_assert!(payload_view.is_empty()); buf.advance(h.payload_length); Ok(Self { nonce, balance, storage_root, code_hash, @@ -608,6 +610,8 @@ pub(super) mod transaction_roots { let gas_used = fastrlp::Decodable::decode(payload_view)?; let log_bloom= fastrlp::Decodable::decode(payload_view)?; let logs = fastrlp::Decodable::decode(payload_view)?; + + debug_assert!(payload_view.is_empty()); buf.advance(h.payload_length); Ok(Self { status, gas_used, log_bloom, logs, From 245c4b0f67454c0d65f120db512ce8a749657975 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dj8yf0=CE=BCl?= Date: Fri, 28 Apr 2023 23:29:52 +0300 Subject: [PATCH 11/11] chore(evm-state): some roundtrip tests rlp <-> fast_rlp --- .../evm-state/src/rlp_roundtrip_tests.rs | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/evm-utils/evm-state/src/rlp_roundtrip_tests.rs b/evm-utils/evm-state/src/rlp_roundtrip_tests.rs index 1c367b0ce8..c3160f38f9 100644 --- a/evm-utils/evm-state/src/rlp_roundtrip_tests.rs +++ b/evm-utils/evm-state/src/rlp_roundtrip_tests.rs @@ -1,3 +1,5 @@ +use std::convert::TryInto; + use crate::{transaction_roots::EthereumReceipt, TransactionAction, UnsignedTransaction, UnsignedTransactionWithCaller, Transaction, TransactionSignature, TransactionInReceipt}; use super::types::Account; @@ -381,6 +383,31 @@ fn test_check_transaction_in_receipt_roundtrip3() { } +#[test] +fn test_check_transaction_in_receipt_roundtrip4() { + + let ta = TransactionAction::Call(H160([10; 20])); + let tx = Transaction{ + nonce: U256([72; 4]), + gas_price: U256([3213;4]), + gas_limit: U256([4324; 4]), + action: ta, + value: U256([7732; 4]), + signature: TransactionSignature { + v: 88979, + r: H256([34; 32]), + s: H256([78; 32]), + }, + input: vec![32, 31, 0, 34, 76, 173], + + }; + + let tx_in_rec1 = TransactionInReceipt::Signed(tx); + + check_roundtrip!(tx_in_rec1 => TransactionInReceipt); + +} + #[test] fn test_check_unsigned_transaction_with_caller_tx_id_hash() { let ta2 = TransactionAction::Call(H160([56; 20])); @@ -407,3 +434,64 @@ fn test_check_unsigned_transaction_with_caller_tx_id_hash() { assert_eq!(old, new); } + + +#[test] +fn test_check_transaction_in_receipt_roundtrip5() { + let ta_inner = hexutil::read_hex("5c44f6325198ac3d4007727211040311e9e6a1f0").unwrap(); + let r_inner = hexutil::read_hex("ed30d3b0afdffef99887e8fcba2de50f3b390286ae2047588ceb1b989ae52dbd").unwrap(); + let s_inner = hexutil::read_hex("1aa5f7e761f7866ee87381e6e1d8efbcdb02daa7f752c3c0478854da0eafc170").unwrap(); + let ta = TransactionAction::Call(H160(ta_inner.try_into().unwrap())); + + let tx = Transaction{ + nonce: U256::from_dec_str("2787").unwrap(), + gas_price: U256::from_dec_str("3000000000").unwrap(), + gas_limit: U256::from_dec_str("45348").unwrap(), + action: ta, + value: U256::from_dec_str("0").unwrap(), + signature: TransactionSignature { + v: 247, + r: H256(r_inner.try_into().unwrap()), + s: H256(s_inner.try_into().unwrap()), + }, + input: vec![162, 44, 180, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 126, 29, 14, 117, 75, 59, 62, 29, 25, 113, 208, 49, 29, 132, 62, 179, 181, 26, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], + + }; + + let tx_in_rec1 = TransactionInReceipt::Signed(tx); + + check_roundtrip!(tx_in_rec1 => TransactionInReceipt); + +} + +#[test] +fn test_check_transaction_in_receipt_roundtrip6() { + let ta_inner = hexutil::read_hex("c848e8767a209ec1538f7bc8a5d849ea521443dc").unwrap(); + + let r_inner = hexutil::read_hex("e8f46e259e3f8586a25a0f6037e13dbeb59123d7faa7a65e8d8c9edf6338433e").unwrap(); + let s_inner = hexutil::read_hex("7316d2aaacdb75a1d25b12d3843fd30e16d11aecf68974f0c96f6d33299b6cf6").unwrap(); + let ta = TransactionAction::Call(H160(ta_inner.try_into().unwrap())); + + let tx = Transaction{ + nonce: U256::from_dec_str("975723").unwrap(), + gas_price: U256::from_dec_str("5000000000").unwrap(), + gas_limit: U256::from_dec_str("700000").unwrap(), + action: ta, + value: U256::from_dec_str("0").unwrap(), + signature: TransactionSignature { + v: 248, + r: H256(r_inner.try_into().unwrap()), + s: H256(s_inner.try_into().unwrap()), + }, + input: vec![70, + 65, + 37, + 125], + + }; + + let tx_in_rec1 = TransactionInReceipt::Signed(tx); + + check_roundtrip!(tx_in_rec1 => TransactionInReceipt); + +} \ No newline at end of file