Compare commits

..

201 Commits

Author SHA1 Message Date
Marek Kotewicz
70389b2888 Merge pull request #922 from ethcore/beta-staging
Master to beta v1.0.2
2016-04-11 16:42:09 +02:00
debris
8f63f6d32a fixed transaction deadlock 2016-04-11 14:39:01 +02:00
debris
f02f99cd3f fixed eth_getLogs 2016-04-11 14:38:18 +02:00
Gav Wood
bbbd6f01fc --unlock is comma-delimited. 2016-04-11 14:37:10 +02:00
debris
ddbce9f014 removed empty lines 2016-04-11 14:36:27 +02:00
debris
423c5e87da fixed eth_getLogs 2016-04-11 14:36:16 +02:00
NikVolf
a15d2882d0 removing lower-level defaults 2016-04-11 14:36:02 +02:00
NikVolf
6d5809757f create provided custom dir for keys if none 2016-04-11 14:35:55 +02:00
Gav Wood
e179b0e0c2 Merge pull request #908 from ethcore/beta-staging
Master to beta 1.0.2
2016-04-09 10:18:41 -07:00
arkpar
37eb0fb04e Use new json RPC server 2016-04-09 13:31:34 +02:00
Tomasz Drwięga
32b0a80a18 Removing Option from setup_rpc_server method return type 2016-04-09 13:29:13 +02:00
Tomasz Drwięga
9df9937922 Fixing compilation with rpc feature disabled 2016-04-09 13:29:06 +02:00
debris
eae66568a9 fixed #895 2016-04-09 13:28:55 +02:00
Tomasz Drwięga
ece348d173 Avoid signalling readiness when app is about to be closed 2016-04-09 13:28:43 +02:00
arkpar
cc0c54a45c Propagate transaction queue 2016-04-09 13:28:37 +02:00
Tomasz Drwięga
3f139116b2 Reverting order of shutdown event 2016-04-09 13:26:14 +02:00
Tomasz Drwięga
771e3998a9 Updating rpc comments 2016-04-09 13:26:08 +02:00
Tomasz Drwięga
03fbde9723 More descriptive message when closing 2016-04-09 13:26:00 +02:00
Tomasz Drwięga
3303aa73ff Tracing shutdown and changed order of IoManager shutdown process 2016-04-09 13:25:54 +02:00
Tomasz Drwięga
8367be6992 Rewriting messages 2016-04-09 13:25:46 +02:00
Tomasz Drwięga
e6237ed05e Removing additional thread from JSON-RPC 2016-04-09 13:25:39 +02:00
Tomasz Drwięga
0abdcedc03 Additional logging and error messages 2016-04-09 13:25:28 +02:00
Tomasz Drwięga
59a735e2c4 Removing match on constant 2016-04-09 13:25:20 +02:00
arkpar
bf24355480 Fixed eth_call nonce and gas handling 2016-04-09 13:25:16 +02:00
NikVolf
4ed15931af replacing /home/nikky also 2016-04-09 13:21:18 +02:00
NikVolf
c5553c1f21 passing key path to all invocations 2016-04-09 13:19:09 +02:00
debris
33d633eed1 fixed #875 and added tests for eth_sendTransaction 2016-04-09 13:16:40 +02:00
Nikolay Volf
a3a0de096d replace add with or 2016-04-09 13:10:20 +02:00
Tomasz Drwięga
aed708ffd8 More descriptive expectations to transaction queue consistency. 2016-04-09 13:09:55 +02:00
Tomasz Drwięga
66d3d7ec11 Fixing typo in bigint 2016-04-09 13:09:45 +02:00
Nikolay Volf
8503aeb2df [ci skip] update misleading cli help msg for author 2016-04-09 13:09:06 +02:00
arkpar
a7ebc1dd25 Handle geth keys with lowercase crypto key 2016-04-09 13:08:52 +02:00
Robert Habermeier
584d89f964 Find geth data store cross-platform.
Fixes #869
2016-04-09 13:08:40 +02:00
arkpar
4aeaab3a2f Fixed bootnode URL and error message 2016-04-09 13:08:03 +02:00
NikVolf
9750a31336 replace popcnt with mov 2016-04-09 13:07:48 +02:00
debris
404005cc93 fixed #855 2016-04-09 13:06:51 +02:00
Gav Wood
9b5bd37dc5 Merge pull request #905 from ethcore/sync-beta
Imporved sync error handling
2016-04-08 17:43:42 -07:00
arkpar
f96e5bc0d5 v1.0.2 2016-04-06 16:15:36 +02:00
arkpar
444c9c4375 Track import errors and restart sync 2016-04-06 16:15:31 +02:00
Gav Wood
2a2c24855c Fix build. 2016-03-28 21:19:28 +02:00
Gav Wood
712302391c Use sensible gas price. 2016-03-28 20:42:23 +02:00
Gav Wood
3023d76a46 Publish locally-made transactions to peers. 2016-03-28 19:43:49 +02:00
Gav Wood
f60d74b231 Merge pull request #844 from ethcore/sync-beta
Full sync restart on bad block
2016-03-28 15:49:39 +02:00
arkpar
3e192ab486 Full restart on bad block 2016-03-28 13:05:59 +02:00
Gav Wood
fe313677b3 Merge pull request #845 from ethcore/beta-staging
Merge fixes from master to beta
2016-03-28 10:00:50 +02:00
arkpar
20f3f356e5 v1.0.1 2016-03-28 02:25:12 +02:00
NikVolf
b9141b830b test for pending 2016-03-28 02:19:29 +02:00
NikVolf
a938385692 checking tx queue 2016-03-28 02:19:19 +02:00
debris
c9ac0392d8 tests for deserialization of issue #835 2016-03-28 02:18:50 +02:00
NikVolf
02dfc8632e fix test 2016-03-28 02:17:32 +02:00
NikVolf
ac2a62707a in cli call 2016-03-28 02:17:28 +02:00
NikVolf
6f78523bf0 unlimited unlock 2016-03-28 02:15:12 +02:00
Gav Wood
5dbbf9db13 Allow passwords on multiple lines in --password files. 2016-03-28 02:13:47 +02:00
Gav Wood
0d6ffa2a97 Minor refactor. 2016-03-28 02:13:47 +02:00
Gav Wood
3afb6370f9 Unlock accounts on CLI. 2016-03-28 02:13:47 +02:00
Gav Wood
dad4bfecdf Merge pull request #828 from ethcore/optionalblocknumberinrpc
Make BlockNumber optional, fix eth_call
2016-03-26 23:29:45 +01:00
Gav Wood
902b44c94f Remove info!s. 2016-03-26 13:44:42 +01:00
Gav Wood
54bf237e4f Fix backport. 2016-03-26 13:31:04 +01:00
Gav Wood
f835ce8253 Fix eth_call so it doesn't need the secret of the sender. 2016-03-26 13:30:50 +01:00
Gav Wood
4d04668c48 Make BlockNumber optional. 2016-03-26 12:35:15 +01:00
Arkadiy Paronyan
b4d95089d4 Merge pull request #826 from ethcore/web3sha3-beta
Web3sha3 beta
2016-03-26 12:08:30 +01:00
Gav Wood
cca30f964e Update web3.rs
[ci-skip]
2016-03-26 11:22:29 +01:00
NikVolf
f11cc80561 wiki test 2016-03-26 11:22:23 +01:00
NikVolf
4f71fd5d4d avoid copy 2016-03-26 11:22:13 +01:00
NikVolf
0340466f5f web3_sha3 2016-03-26 11:22:06 +01:00
Nikolay Volf
8847819b31 Merge pull request #821 from ethcore/netidfix-beta
Use network id for the web3_net_version return.
2016-03-26 04:01:53 +04:00
Gav Wood
ca91fd5e76 Use network id for the web3_net_version return. 2016-03-26 00:22:09 +01:00
Arkadiy Paronyan
df2619a37d Merge pull request #806 from ethcore/tracegetwork-beta
Fix mining from spinning
2016-03-24 17:34:07 +01:00
arkpar
4840371635 Fixed test 2016-03-24 17:07:54 +01:00
Gav Wood
68e4156143 Don't care if engaged in sync since it's typically doing so. 2016-03-24 14:29:54 +00:00
Gav Wood
83f812b176 Fix logic. agaib. 2016-03-24 14:24:58 +00:00
Gav Wood
36c5525e3f Fix logic error. 2016-03-24 14:15:55 +00:00
Gav Wood
78b5c12cf9 Fix mining. 2016-03-24 14:13:43 +00:00
Gav Wood
0564e7c168 Fix compile. 2016-03-24 14:00:15 +00:00
Gav Wood
7a4e91d26d Add tracing. 2016-03-24 14:00:09 +00:00
Tomasz Drwięga
ec26827f58 Fixing future-current transactions clash 2016-03-23 14:45:02 +01:00
arkpar
01b71bf9ba Merge with master 2016-03-22 22:09:44 +01:00
Gav Wood
42040438ed Fix author reporting. num_cpus for JSONRPC threads. 2016-03-22 21:58:28 +01:00
Gav Wood
799828b51e Increase threads to 4. 2016-03-22 21:58:28 +01:00
debris
f78e8c3a38 fixed eth_call, eth_sendTransaction and eth_estimateGas 2016-03-22 21:58:28 +01:00
debris
4f242996d1 uncle 2016-03-22 21:58:28 +01:00
debris
daecf5db3e removed outdated comment 2016-03-22 21:58:28 +01:00
debris
9a09f52679 implemented eth_sendRawTransaction 2016-03-22 21:58:28 +01:00
debris
841a996fa6 test for eth_getTransactionReceipt 2016-03-22 21:58:28 +01:00
Alexander Orlov
ff99ccaf82 complete getting started steps for OS X
You get 
`multirust: no default toolchain configured` 
when 
`multirust default stable`
is not executed.
2016-03-22 21:58:28 +01:00
arkpar
60f2aadb8e Prettier version wo git dir; Use rustc compile time version 2016-03-22 21:53:29 +01:00
Tomasz Drwięga
c143b1b783 Validating senders balance before importing transaction to queue 2016-03-22 21:52:28 +01:00
Tomasz Drwięga
2377d46c59 Speeding up build 2016-03-22 21:44:58 +01:00
Arkadiy Paronyan
10d361aec5 Merge pull request #796 from ethcore/beta-staging
Merge master to beta
2016-03-22 20:55:57 +01:00
arkpar
bf4e4df4c8 Fixed sync tests 2016-03-21 18:51:22 +01:00
arkpar
3b766f01f2 Fixed rpc tests 2016-03-21 18:07:07 +01:00
arkpar
2aa3864d67 Merge with master 2016-03-21 15:55:46 +01:00
debris
04082d1514 client implementation of transaction receipt 2016-03-21 00:05:45 +01:00
debris
85fa07728c LocalizedReceipt 2016-03-21 00:05:45 +01:00
Tomasz Drwięga
a36ac996a0 Avoiding possible overflow when block number gets smaller. 2016-03-21 00:05:45 +01:00
Tomasz Drwięga
6e666ecac7 Fixing ethminer doctest 2016-03-21 00:05:45 +01:00
Tomasz Drwięga
08dc83205c Flipping sealing_enabled flag after no requests for sealing_block for some time 2016-03-21 00:05:43 +01:00
Gav Wood
bff142828d JSONRPC interface defaults to local.
Please enter the commit message for your changes. Lines starting
2016-03-21 00:04:55 +01:00
Gav Wood
6d1ae888ca Listen on all interfaces for JSONRPC by default. 2016-03-21 00:04:55 +01:00
debris
d5cc2c9e67 implemented rpc eth_estimateGas method, added tests for rpc eth_call and eth_estimateGas 2016-03-21 00:04:55 +01:00
debris
048dba7ef3 fixed indentation 2016-03-21 00:04:55 +01:00
debris
280c5e8a99 implementation of eth_estimateGas 2016-03-21 00:04:55 +01:00
debris
1257ad2993 fixes after merge 2016-03-21 00:04:55 +01:00
debris
5c72e60b14 implemented eth_call 2016-03-21 00:04:55 +01:00
debris
aa6b6e477c added output to execution result 2016-03-21 00:04:55 +01:00
Gav Wood
245ef854dd Allow 0x prefix for --author. 2016-03-21 00:04:55 +01:00
debris
c2cffd1e06 improvements to build, updated dependencies, moved rpctest to its own submodule 2016-03-21 00:04:53 +01:00
debris
ddab958e61 fixed missing import 2016-03-20 23:56:57 +01:00
debris
a10160bd56 use ethjson module to load chain json tests 2016-03-20 23:56:57 +01:00
debris
49be60e984 test ethjson module on travis 2016-03-20 23:56:57 +01:00
debris
2b8a151b82 fixed failing eth rpc tests 2016-03-20 23:56:57 +01:00
debris
9bcc6c9e69 next batch of rpc fixes, 103 still failing 2016-03-20 23:56:57 +01:00
debris
0fc605face rpc tests, now 421 passing / 116 failing 2016-03-20 23:56:57 +01:00
debris
8f1618687c fixed parsing blockchain file, added default account to rpc tests 2016-03-20 23:56:57 +01:00
debris
cb246c26c0 fixed invalid json files 2016-03-20 23:56:56 +01:00
debris
086e45671b removed warnings by adding missing documentation 2016-03-20 23:56:56 +01:00
debris
f3ad643b69 pricing { linear: {} } 2016-03-20 23:56:56 +01:00
debris
c5a4993e39 fixed failing builin test 2016-03-20 23:56:56 +01:00
debris
32cc0bddf6 fixed od builting parsing 2016-03-20 23:56:56 +01:00
debris
d87286c5c3 updated rpc helpers docs 2016-03-20 23:56:56 +01:00
debris
ac3acdef71 linear -> pricing 2016-03-20 23:56:56 +01:00
debris
dffa9bcef6 fixed compilation with --release flag 2016-03-20 23:56:56 +01:00
debris
9ce75a173e fixed name of rpctest executable in rpctest --help 2016-03-20 23:56:56 +01:00
debris
755faf37e3 running rpc tests 2016-03-20 23:56:56 +01:00
debris
de21fef868 new way of loading PodState 2016-03-20 23:56:56 +01:00
debris
39aa02ed26 moved ethcores spec to its own module, added genesis 2016-03-20 23:56:54 +01:00
debris
7a0dfec115 added genesis method to ethjson blockchain 2016-03-20 23:54:53 +01:00
debris
1fa019d92a ethjson spec submodule 2016-03-20 23:54:53 +01:00
debris
7105ed3f61 rpctest executable 2016-03-20 23:54:53 +01:00
Tomasz Drwięga
2f411c93fd Removing update_seal when new transactions arrives 2016-03-20 23:54:53 +01:00
Tomasz Drwięga
808f959a94 Common error handling 2016-03-20 23:54:51 +01:00
Tomasz Drwięga
2aae862330 Updating sealing when new transactions are received 2016-03-20 23:54:24 +01:00
Tomasz Drwięga
b18a7bde9a Updating gas_limit in test_client generated blocks 2016-03-20 23:53:23 +01:00
Tomasz Drwięga
a0cdf5c420 Ignoring transactions slightly above gas_limit 2016-03-20 23:53:21 +01:00
Tomasz Drwięga
b3dd72ab0a BlockGasLimit taken from push_transaction result 2016-03-20 23:52:58 +01:00
Tomasz Drwięga
4d984ead4f Fixing compilation 2016-03-20 23:52:58 +01:00
Tomasz Drwięga
fbc85e31c2 Refactoring removing invalid transactions from queue 2016-03-20 23:52:58 +01:00
Tomasz Drwięga
177d26a25e Stop adding transactions right after we know that no other will make it to block. 2016-03-20 23:52:58 +01:00
Tomasz Drwięga
1f363b22fc Removing invalid transactions from queue 2016-03-20 23:52:58 +01:00
Tomasz Drwięga
5aed421fa3 Removing allow dead_code 2016-03-20 23:52:58 +01:00
Tomasz Drwięga
f4df9c8dfd Fixing warnings 2016-03-20 23:52:58 +01:00
Tomasz Drwięga
144385e67d Bumping clippy 2016-03-20 23:52:56 +01:00
Tomasz Drwięga
9b6abb5861 Attempting to add all transactions to mined block 2016-03-20 23:52:31 +01:00
arkpar
6c81f1fb74 Prettier version wo git dir; Use rustc compile time version 2016-03-20 23:52:29 +01:00
Nikolay Volf
7371beb26c get rid of the function 2016-03-20 23:52:00 +01:00
Nikolay Volf
7acdc80b27 propagation is out 2016-03-20 23:51:59 +01:00
Nikolay Volf
3847f8a9fc no flag also 2016-03-20 23:51:58 +01:00
Tomasz Drwięga
56e977b425 Fixing doctest 2016-03-20 23:51:22 +01:00
Tomasz Drwięga
2f8e6be2ea Adding missing commas 2016-03-20 23:51:22 +01:00
Tomasz Drwięga
180debb260 Reverting check if block queue is empty 2016-03-20 23:51:22 +01:00
Tomasz Drwięga
b79c7f05c0 Increasing balance in tests 2016-03-20 23:51:22 +01:00
Tomasz Drwięga
d17c629b71 Full transaction cost 2016-03-20 23:51:22 +01:00
Tomasz Drwięga
4be4a1c151 Fixing sync test 2016-03-20 23:51:22 +01:00
Tomasz Drwięga
b0d7d48391 Adding test 2016-03-20 23:51:22 +01:00
Tomasz Drwięga
164cd268ad Fixing build 2016-03-20 23:51:22 +01:00
Tomasz Drwięga
3a16ef19c1 Removing unused import 2016-03-20 23:51:22 +01:00
Tomasz Drwięga
74ea9cc74c Validating senders balance before importing transaction to queue 2016-03-20 23:51:22 +01:00
Tomasz Drwięga
2e88183df4 Removing printlns 2016-03-20 23:51:22 +01:00
Tomasz Drwięga
fca8eb5810 Importing transactions from hashset. Notifying about every block 2016-03-20 23:51:22 +01:00
Tomasz Drwięga
df4b326cb3 Adding missing space 2016-03-20 23:51:22 +01:00
Tomasz Drwięga
4db397ecb1 Renaming status fields to something more descriptive. 2016-03-20 23:51:20 +01:00
Tomasz Drwięga
e767fd88f6 Returning number of transactions pending in block not queue 2016-03-20 23:50:59 +01:00
Tomasz Drwięga
fae7039fda Disabling benches and beta tests 2016-03-20 23:50:59 +01:00
Tomasz Drwięga
69d6f3ed3e Enabling fast finish 2016-03-20 23:50:59 +01:00
Tomasz Drwięga
4292e75dca More cleaning 2016-03-20 23:50:59 +01:00
Tomasz Drwięga
2b4640c94c Cleaning 2016-03-20 23:50:59 +01:00
Tomasz Drwięga
42a6954ec9 Speeding up build 2016-03-20 23:50:57 +01:00
Nikolay Volf
114bab66c4 overhaul to flag 2016-03-20 23:50:31 +01:00
Nikolay Volf
13d0d6d006 adding helper can_sync 2016-03-20 23:50:31 +01:00
debris
c15e78cd95 tests for loading test json files 2016-03-20 23:50:31 +01:00
debris
24993b8d4e finished blockchain test deserialization 2016-03-20 23:50:31 +01:00
debris
69d89583ca proper blockchain json parsing 2016-03-20 23:50:29 +01:00
Arkadiy Paronyan
3c8fb60cbd Update install-parity.sh 2016-03-20 23:49:34 +01:00
arkpar
9f8a131fa4 restart sync on getting old unknown header 2016-03-20 23:49:34 +01:00
Nikolay Volf
31f4a214a9 adding message from client to sync and disabling sending transactions to the queue while syncing 2016-03-20 23:49:34 +01:00
Gav Wood
81f8f939b9 Update sync_provider.rs 2016-03-20 23:49:34 +01:00
Nikolay Volf
28e4847b59 tests 2016-03-20 23:49:34 +01:00
Nikolay Volf
30ecff3959 checking queue also 2016-03-20 23:49:34 +01:00
Nikolay Volf
8add773b12 [ci skip] grammar fix 2016-03-20 23:49:34 +01:00
Nikolay Volf
c20e761051 adding check for a sync 2016-03-20 23:49:34 +01:00
arkpar
35be0e9943 Indent 2016-03-17 19:40:08 +01:00
arkpar
3bf0a00ba4 Prettier version wo git dir; Use rustc compile time version 2016-03-17 19:39:54 +01:00
arkpar
570d2c21d3 Merge branch 'sync' into beta 2016-03-15 19:44:15 +01:00
arkpar
b9fc5bdda0 Merge remote-tracking branch 'origin/transaction_queue_race' into beta 2016-03-15 12:56:30 +01:00
arkpar
1964ed7eb3 Merge remote-tracking branch 'origin/sync' into beta 2016-03-15 12:56:17 +01:00
arkpar
60bcab3e48 Merge remote-tracking branch 'origin/docker' into beta 2016-03-14 19:13:07 +01:00
arkpar
ebb7699da2 Merge remote-tracking branch 'origin/pv63-receipts' into beta 2016-03-14 18:58:23 +01:00
arkpar
78821bb935 Merge remote-tracking branch 'origin/unclesminingfix' into beta 2016-03-14 18:56:27 +01:00
arkpar
e8a21116f7 missing mut 2016-03-14 15:50:45 +01:00
Gav Wood
9f81b07224 Lock reports to avoid out of order badness. 2016-03-14 15:50:32 +01:00
arkpar
8eeda2b1a3 Fixed handshake leak 2016-03-14 15:50:03 +01:00
Arkadiy Paronyan
0087568c16 Merge pull request #712 from ethcore/beta-version
Version 1.0 in beta
2016-03-14 14:56:44 +01:00
arkpar
75a11ba9be Merge remote-tracking branch 'origin/targetgaslimit' into beta 2016-03-14 14:05:38 +01:00
Nikolay Volf
4ac9807bc1 fixing tests for beta 2016-03-14 11:12:15 +01:00
arkpar
1c26ffa208 Merge branch 'network' into beta 2016-03-14 11:11:36 +01:00
arkpar
f8b18d5d7b Merge remote-tracking branch 'origin/rpc-personal-tests' into beta 2016-03-14 10:30:22 +01:00
arkpar
b327e79b42 Merge remote-tracking branch 'origin/fixing_warnings' into beta 2016-03-14 10:28:38 +01:00
arkpar
8e2f35856a Merge remote-tracking branch 'origin/docoptclean' into beta 2016-03-14 10:26:59 +01:00
arkpar
a029551b0b Merge branch 'build' into beta 2016-03-14 09:56:44 +01:00
arkpar
320581a3e4 Merge branch 'fix-discovery' into beta 2016-03-14 01:33:41 +01:00
arkpar
f77b4119da Version 1.0 2016-03-14 01:01:15 +01:00
460 changed files with 13409 additions and 63519 deletions

View File

@@ -33,15 +33,17 @@ env:
global:
# GH_TOKEN
- secure: bumJASbZSU8bxJ0EyPUJmu16AiV9EXOpyOj86Jlq/Ty9CfwGqsSXt96uDyE+OUJf34RUFQMsw0nk37/zC4lcn6kqk2wpuH3N/o85Zo/cVZY/NusBWLQqtT5VbYWsV+u2Ua4Tmmsw8yVYQhYwU2ZOejNpflL+Cs9XGgORp1L+/gMRMC2y5Se6ZhwnKPQlRJ8LGsG1dzjQULxzADIt3/zuspNBS8a2urJwlHfGMkvHDoUWCviP/GXoSqw3TZR7FmKyxE19I8n9+iSvm9+oZZquvcgfUxMHn8Gq/b44UbPvjtFOg2yam4xdWXF/RyWCHdc/R9EHorSABeCbefIsm+zcUF3/YQxwpSxM4IZEeH2rTiC7dcrsKw3XsO16xFQz5YI5Bay+CT/wTdMmJd7DdYz7Dyf+pOvcM9WOf/zorxYWSBOMYy0uzbusU2iyIghQ82s7E/Ahg+WARtPgkuTLSB5aL1oCTBKHqQscMr7lo5Ti6RpWLxEdTQMBznc+bMr+6dEtkEcG9zqc6cE9XX+ox3wTU6+HVMfQ1ltCntJ4UKcw3A6INEbw9wgocQa812CIASQ2fE+SCAbz6JxBjIAlFUnD1lUB7S8PdMPwn9plfQgKQ2A5YZqg6FnBdf0rQXIJYxQWKHXj/rBHSUCT0tHACDlzTA+EwWggvkP5AGIxRxm8jhw=
- TARGETS="-p ethkey -p ethstore -p ethash -p ethcore-util -p ethcore -p ethsync -p ethcore-rpc -p parity -p ethjson -p ethcore-dapps -p ethcore-signer"
- CVER=5
- NUM_JOBS=1
# - TARGETS="-p ethash -p ethcore-util -p ethcore -p ethsync -p ethcore-rpc -p parity -p ethminer"
- TARGETS="-p ethcore-util"
- ARCHIVE_SUFFIX="-${TRAVIS_OS_NAME}-${TRAVIS_TAG}"
- KCOV_FEATURES=""
- KCOV_CMD="./kcov-master/tmp/usr/local/bin/kcov --exclude-pattern /usr/,/.cargo,/root/.multirust,src/tests,util/json-tests,util/src/network/tests,sync/src/tests,ethcore/src/tests,ethcore/src/evm/tests,ethstore/tests target/kcov"
- KCOV_CMD="./kcov-master/tmp/usr/local/bin/kcov --exclude-pattern /usr/,/.cargo,/root/.multirust,src/tests,util/json-tests,util/src/network/tests,sync/src/tests,ethcore/src/tests,ethcore/src/evm/tests target/kcov"
- RUN_TESTS="false"
- RUN_COVERAGE="false"
- RUN_BUILD="false"
- RUN_BENCHES="false"
- RUST_BACKTRACE="1"
cache:
apt: true
directories:
@@ -55,6 +57,8 @@ addons:
- libdw-dev
script:
- echo "$TRAVIS_BUILD_DIR/target"
- ls "$TRAVIS_BUILD_DIR/target"
- if [ "$RUN_TESTS" = "true" ]; then cargo test --release --verbose ${FEATURES} ${TARGETS}; fi
- if [ "$RUN_BENCHES" = "true" ]; then cargo bench --no-run ${FEATURES} ${TARGETS}; fi
- if [ "$RUN_BUILD" = "true" ]; then cargo build --release --verbose ${FEATURES}; fi
@@ -65,16 +69,12 @@ after_success: |
wget https://github.com/SimonKagstrom/kcov/archive/master.tar.gz &&
tar xzf master.tar.gz && mkdir kcov-master/build && cd kcov-master/build && cmake .. && make && make install DESTDIR=../tmp && cd ../.. &&
cargo test --no-run ${KCOV_FEATURES} ${TARGETS} &&
$KCOV_CMD target/debug/deps/ethkey-* &&
$KCOV_CMD target/debug/deps/ethstore-* &&
$KCOV_CMD target/debug/deps/ethcore_util-* &&
$KCOV_CMD target/debug/deps/ethash-* &&
$KCOV_CMD target/debug/deps/ethcore-* &&
$KCOV_CMD target/debug/deps/ethsync-* &&
$KCOV_CMD target/debug/deps/ethcore_rpc-* &&
$KCOV_CMD target/debug/deps/ethcore_dapps-* &&
$KCOV_CMD target/debug/deps/ethcore_signer-* &&
$KCOV_CMD target/debug/deps/ethjson-* &&
$KCOV_CMD target/debug/deps/ethminer-* &&
$KCOV_CMD target/debug/parity-* &&
[ $TRAVIS_BRANCH = master ] &&
[ $TRAVIS_PULL_REQUEST = false ] &&
@@ -95,14 +95,9 @@ deploy:
tags: true
notifications:
webhooks:
urls:
- https://hooks.slack.com/services/${SLACK_WEBHOOK}
on_success: always
on_failure: always
on_start: never
notifications:
slack:
rooms:
- ethcore:4EGxt9WP6AS7uX4JKXSfR9vi#chatops
webhooks:
urls:
- https://hooks.slack.com/services/${SLACK_WEBHOOK}
on_success: always
on_failure: always
on_start: never

980
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,15 +1,13 @@
[package]
description = "Ethcore client."
name = "parity"
version = "1.2.0"
version = "1.0.2"
license = "GPL-3.0"
authors = ["Ethcore <admin@ethcore.io>"]
build = "build.rs"
[build-dependencies]
rustc_version = "0.1"
syntex = "*"
ethcore-ipc-codegen = { path = "ipc/codegen" }
[dependencies]
log = "0.3"
@@ -17,41 +15,24 @@ env_logger = "0.3"
rustc-serialize = "0.3"
docopt = "0.6"
time = "0.1"
ctrlc = { git = "https://github.com/ethcore/rust-ctrlc.git" }
ctrlc = { git = "https://github.com/tomusdrw/rust-ctrlc.git" }
fdlimit = { path = "util/fdlimit" }
daemonize = "0.2"
num_cpus = "0.2"
number_prefix = "0.2"
rpassword = "0.2.1"
clippy = { version = "0.0.77", optional = true}
rpassword = "0.1"
clippy = { version = "0.0.54", optional = true }
ethcore = { path = "ethcore" }
ethcore-util = { path = "util" }
ethsync = { path = "sync" }
ethminer = { path = "miner" }
ethcore-devtools = { path = "devtools" }
ethcore-rpc = { path = "rpc", optional = true }
ethcore-signer = { path = "signer", optional = true }
ethcore-dapps = { path = "dapps", optional = true }
semver = "0.2"
ethcore-ipc-nano = { path = "ipc/nano" }
ethcore-ipc = { path = "ipc/rpc" }
json-ipc-server = { git = "https://github.com/ethcore/json-ipc-server.git" }
ansi_term = "0.7"
[target.'cfg(windows)'.dependencies]
winapi = "0.2"
[target.'cfg(not(windows))'.dependencies]
daemonize = "0.2"
[dependencies.hyper]
version = "0.8"
default-features = false
[features]
default = ["rpc", "dapps", "ethcore-signer"]
default = ["rpc"]
rpc = ["ethcore-rpc"]
dapps = ["ethcore-dapps"]
dev = ["clippy", "ethcore/dev", "ethcore-util/dev", "ethsync/dev", "ethcore-rpc/dev",
"ethcore-dapps/dev", "ethcore-signer/dev"]
dev = ["clippy", "ethcore/dev", "ethcore-util/dev", "ethsync/dev", "ethcore-rpc/dev", "ethminer/dev"]
travis-beta = ["ethcore/json-tests"]
travis-nightly = ["ethcore/json-tests", "dev"]
@@ -60,5 +41,5 @@ path = "parity/main.rs"
name = "parity"
[profile.release]
debug = true
debug = false
lto = false

View File

@@ -1,5 +1,4 @@
# [Parity](https://ethcore.io/parity.html)
### Fast, light, and robust Ethereum implementation
# ethcore
[![Build Status][travis-image]][travis-url] [![Coverage Status][coveralls-image]][coveralls-url] [![Join the chat at https://gitter.im/trogdoro/xiki][gitter-image]][gitter-url] [![GPLv3][license-image]][license-url]
@@ -12,77 +11,30 @@
[license-image]: https://img.shields.io/badge/license-GPL%20v3-green.svg
[license-url]: http://www.gnu.org/licenses/gpl-3.0.en.html
[Internal Documentation](http://ethcore.github.io/parity/ethcore/index.html)
[Documentation](http://ethcore.github.io/parity/ethcore/index.html)
----
### Building from source
## About Parity
Parity's goal is to be the fastest, lightest, and most secure Ethereum client. We are developing Parity using the sophisticated and
cutting-edge Rust programming language. Parity is licensed under the GPLv3, and can be used for all your Ethereum needs.
By default, Parity will run a JSONRPC server on `127.0.0.1:8545`. This is fully configurable and supports a number
of RPC APIs.
Parity also runs a server for running decentralized apps, or "Dapps", on `http://127.0.0.1:8080`.
This includes a few useful Dapps, including Ethereum Wallet, Maker OTC, and a node status page.
In a near-future release, it will be easy to install Dapps and use them through this web interface.
If you run into an issue while using parity, feel free to file one in this repository
or hop on our [gitter chat room]([gitter-url]) to ask a question. We are glad to help!
Parity's current release is 1.1. You can download it at https://ethcore.io/parity.html or follow the instructions
below to build from source.
----
## Build dependencies
Parity is fully compatible with Stable Rust.
We recommend installing Rust through [rustup](https://www.rustup.rs/). If you don't already have rustup, you can install it like this:
- Linux and OSX:
```bash
$ curl https://sh.rustup.rs -sSf | sh
```
- Windows
Make sure you have Visual Studio 2015 with C++ support installed. Next, download and run the rustup installer from
https://static.rust-lang.org/rustup/dist/x86_64-pc-windows-msvc/rustup-init.exe, start "VS2015 x64 Native Tools Command Prompt", and use the following command to install and set up the msvc toolchain:
```
$ rustup default stable-x86_64-pc-windows-msvc
```
Once you have rustup, install parity or download and build from source
----
## Quick install
First (if you don't already have it) get multirust:
- Linux:
```bash
cargo install --git https://github.com/ethcore/parity.git parity
curl -sf https://raw.githubusercontent.com/brson/multirust/master/quick-install.sh | sudo sh -s -- --yes
```
----
- OSX with Homebrew:
```bash
brew update && brew install multirust
multirust default stable
```
## Build from source
Then, download and build Parity:
```bash
# download Parity code
$ git clone https://github.com/ethcore/parity
$ cd parity
git clone https://github.com/ethcore/parity
cd parity
# build in release mode
$ cargo build --release
cargo build --release
```
This will produce an executable in the `./target/release` subdirectory.
To get started, just run
```bash
$ ./target/release/parity
```
and parity will begin syncing the Ethereum blockchain.

View File

@@ -1,29 +0,0 @@
environment:
matrix:
- TARGET: x86_64-pc-windows-msvc
install:
- git submodule update --init --recursive
- ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-1.9.0-x86_64-pc-windows-msvc.exe"
- ps: Start-FileDownload "https://github.com/ethcore/win-build/raw/master/SimpleFC.dll" -FileName nsis\SimpleFC.dll
- ps: Start-FileDownload "https://github.com/ethcore/win-build/raw/master/vc_redist.x64.exe" -FileName nsis\vc_redist.x64.exe
- rust-1.9.0-x86_64-pc-windows-msvc.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust"
- SET PATH=%PATH%;C:\Program Files (x86)\Rust\bin;C:\Program Files (x86)\NSIS
- rustc -V
- cargo -V
build: off
test_script:
- cargo test --verbose --release
after_test:
- cargo build --verbose --release
- makensis.exe nsis\installer.nsi
artifacts:
- path: nsis\installer.exe
name: Windows Installer (x86_64)
cache:
- target
- C:\users\appveyor\.cargo -> appveyor.yml

View File

@@ -15,35 +15,11 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
extern crate rustc_version;
extern crate syntex;
extern crate ethcore_ipc_codegen as codegen;
use std::env;
use std::path::Path;
use rustc_version::{version_meta, Channel};
fn main() {
if let Channel::Nightly = version_meta().channel {
println!("cargo:rustc-cfg=nightly");
}
let out_dir = env::var_os("OUT_DIR").unwrap();
// ipc pass
{
let src = Path::new("parity/hypervisor/service.rs.in");
let dst = Path::new(&out_dir).join("hypervisor_service_ipc.rs");
let mut registry = syntex::Registry::new();
codegen::register(&mut registry);
registry.expand("", &src, &dst).unwrap();
}
// serialization pass
{
let src = Path::new(&out_dir).join("hypervisor_service_ipc.rs");
let dst = Path::new(&out_dir).join("hypervisor_service_cg.rs");
let mut registry = syntex::Registry::new();
codegen::register(&mut registry);
registry.expand("", &src, &dst).unwrap();
}
}

12
cov.sh
View File

@@ -16,28 +16,22 @@ if ! type kcov > /dev/null; then
fi
cargo test \
-p ethkey \
-p ethstore \
-p ethash \
-p ethcore-util \
-p ethcore \
-p ethsync \
-p ethcore-rpc \
-p parity \
-p ethcore-signer \
-p ethcore-dapps \
-p ethminer \
--no-run || exit $?
rm -rf target/coverage
mkdir -p target/coverage
EXCLUDE="~/.multirust,rocksdb,secp256k1,src/tests,util/json-tests,util/src/network/tests,sync/src/tests,ethcore/src/tests,ethcore/src/evm/tests,ethstore/tests"
kcov --exclude-pattern $EXCLUDE --include-pattern src --verify target/coverage target/debug/deps/ethkey-*
kcov --exclude-pattern $EXCLUDE --include-pattern src --verify target/coverage target/debug/deps/ethstore-*
EXCLUDE="~/.multirust,rocksdb,secp256k1,src/tests,util/json-tests,util/src/network/tests,sync/src/tests,ethcore/src/tests,ethcore/src/evm/tests"
kcov --exclude-pattern $EXCLUDE --include-pattern src --verify target/coverage target/debug/deps/ethcore-*
kcov --exclude-pattern $EXCLUDE --include-pattern src --verify target/coverage target/debug/deps/ethash-*
kcov --exclude-pattern $EXCLUDE --include-pattern src --verify target/coverage target/debug/deps/ethcore_util-*
kcov --exclude-pattern $EXCLUDE --include-pattern src --verify target/coverage target/debug/deps/ethsync-*
kcov --exclude-pattern $EXCLUDE --include-pattern src --verify target/coverage target/debug/deps/ethcore_rpc-*
kcov --exclude-pattern $EXCLUDE --include-pattern src --verify target/coverage target/debug/deps/ethcore_signer-*
kcov --exclude-pattern $EXCLUDE --include-pattern src --verify target/coverage target/debug/deps/ethcore_dapps-*
kcov --exclude-pattern $EXCLUDE --include-pattern src --verify target/coverage target/debug/deps/ethminer-*
xdg-open target/coverage/index.html

View File

@@ -1,41 +0,0 @@
[package]
description = "Parity Dapps crate"
name = "ethcore-dapps"
version = "1.2.0"
license = "GPL-3.0"
authors = ["Ethcore <admin@ethcore.io"]
build = "build.rs"
[lib]
[dependencies]
log = "0.3"
jsonrpc-core = "2.0"
jsonrpc-http-server = { git = "https://github.com/ethcore/jsonrpc-http-server.git" }
hyper = { default-features = false, git = "https://github.com/ethcore/hyper" }
url = "1.0"
rustc-serialize = "0.3"
serde = "0.7.0"
serde_json = "0.7.0"
serde_macros = { version = "0.7.0", optional = true }
ethcore-rpc = { path = "../rpc" }
ethcore-util = { path = "../util" }
parity-dapps = { git = "https://github.com/ethcore/parity-dapps-rs.git", version = "0.3" }
# List of apps
parity-dapps-status = { git = "https://github.com/ethcore/parity-dapps-status-rs.git", version = "0.5.0" }
parity-dapps-builtins = { git = "https://github.com/ethcore/parity-dapps-builtins-rs.git", version = "0.5.0" }
parity-dapps-wallet = { git = "https://github.com/ethcore/parity-dapps-wallet-rs.git", version = "0.6.0", optional = true }
parity-dapps-dao = { git = "https://github.com/ethcore/parity-dapps-dao-rs.git", version = "0.4.0", optional = true }
parity-dapps-makerotc = { git = "https://github.com/ethcore/parity-dapps-makerotc-rs.git", version = "0.3.0", optional = true }
mime_guess = { version = "1.6.1" }
clippy = { version = "0.0.77", optional = true}
[build-dependencies]
serde_codegen = { version = "0.7.0", optional = true }
syntex = "*"
[features]
default = ["serde_codegen", "extra-dapps"]
extra-dapps = ["parity-dapps-wallet"]
nightly = ["serde_macros"]
dev = ["clippy", "ethcore-rpc/dev", "ethcore-util/dev"]

View File

@@ -1,45 +0,0 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
#[cfg(not(feature = "serde_macros"))]
mod inner {
extern crate syntex;
extern crate serde_codegen;
use std::env;
use std::path::Path;
pub fn main() {
let out_dir = env::var_os("OUT_DIR").unwrap();
let src = Path::new("./src/api/mod.rs.in");
let dst = Path::new(&out_dir).join("mod.rs");
let mut registry = syntex::Registry::new();
serde_codegen::register(&mut registry);
registry.expand("", &src, &dst).unwrap();
}
}
#[cfg(feature = "serde_macros")]
mod inner {
pub fn main() {}
}
fn main() {
inner::main();
}

View File

@@ -1,69 +0,0 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::sync::Arc;
use endpoint::{Endpoint, Endpoints, EndpointInfo, Handler, EndpointPath};
use api::response::as_json;
pub struct RestApi {
endpoints: Arc<Endpoints>,
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct App {
pub id: String,
pub name: String,
pub description: String,
pub version: String,
pub author: String,
#[serde(rename="iconUrl")]
pub icon_url: String,
}
impl App {
fn from_info(id: &str, info: &EndpointInfo) -> Self {
App {
id: id.to_owned(),
name: info.name.to_owned(),
description: info.description.to_owned(),
version: info.version.to_owned(),
author: info.author.to_owned(),
icon_url: info.icon_url.to_owned(),
}
}
}
impl RestApi {
pub fn new(endpoints: Arc<Endpoints>) -> Box<Endpoint> {
Box::new(RestApi {
endpoints: endpoints
})
}
fn list_apps(&self) -> Vec<App> {
self.endpoints.iter().filter_map(|(ref k, ref e)| {
e.info().map(|ref info| App::from_info(k, info))
}).collect()
}
}
impl Endpoint for RestApi {
fn to_handler(&self, _path: EndpointPath) -> Box<Handler> {
as_json(&self.list_apps())
}
}

View File

@@ -1,28 +0,0 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! REST API
#![warn(missing_docs)]
#![cfg_attr(feature="nightly", feature(custom_derive, custom_attribute, plugin))]
#![cfg_attr(feature="nightly", plugin(serde_macros, clippy))]
#[cfg(feature = "serde_macros")]
include!("mod.rs.in");
#[cfg(not(feature = "serde_macros"))]
include!(concat!(env!("OUT_DIR"), "/mod.rs"));

View File

@@ -1,21 +0,0 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
mod api;
mod response;
pub use self::api::RestApi;
pub use self::api::App;

View File

@@ -1,23 +0,0 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use serde::Serialize;
use serde_json;
use endpoint::{ContentHandler, Handler};
pub fn as_json<T : Serialize>(val: &T) -> Box<Handler> {
Box::new(ContentHandler::new(serde_json::to_string(val).unwrap(), "application/json".to_owned()))
}

View File

@@ -1,116 +0,0 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use serde_json;
use std::io;
use std::io::Read;
use std::fs;
use std::path::PathBuf;
use page::LocalPageEndpoint;
use endpoint::{Endpoints, EndpointInfo};
use api::App;
struct LocalDapp {
id: String,
path: PathBuf,
info: EndpointInfo,
}
fn local_dapps(dapps_path: String) -> Vec<LocalDapp> {
let files = fs::read_dir(dapps_path.as_str());
if let Err(e) = files {
warn!(target: "dapps", "Unable to load local dapps from: {}. Reason: {:?}", dapps_path, e);
return vec![];
}
let files = files.expect("Check is done earlier");
files.map(|dir| {
let entry = try!(dir);
let file_type = try!(entry.file_type());
// skip files
if file_type.is_file() {
return Err(io::Error::new(io::ErrorKind::NotFound, "Not a file"));
}
// take directory name and path
entry.file_name().into_string()
.map(|name| (name, entry.path()))
.map_err(|e| {
info!(target: "dapps", "Unable to load dapp: {:?}. Reason: {:?}", entry.path(), e);
io::Error::new(io::ErrorKind::NotFound, "Invalid name")
})
})
.filter_map(|m| {
if let Err(ref e) = m {
debug!(target: "dapps", "Ignoring local dapp: {:?}", e);
}
m.ok()
})
.map(|(name, path)| {
// try to get manifest file
let info = read_manifest(&name, path.clone());
LocalDapp {
id: name,
path: path,
info: info,
}
})
.collect()
}
fn read_manifest(name: &str, mut path: PathBuf) -> EndpointInfo {
path.push("manifest.json");
fs::File::open(path.clone())
.map_err(|e| format!("{:?}", e))
.and_then(|mut f| {
// Reat file
let mut s = String::new();
try!(f.read_to_string(&mut s).map_err(|e| format!("{:?}", e)));
// Try to deserialize manifest
serde_json::from_str::<App>(&s).map_err(|e| format!("{:?}", e))
})
.map(|app| EndpointInfo {
name: app.name,
description: app.description,
version: app.version,
author: app.author,
icon_url: app.icon_url,
})
.unwrap_or_else(|e| {
warn!(target: "dapps", "Cannot read manifest file at: {:?}. Error: {:?}", path, e);
EndpointInfo {
name: name.into(),
description: name.into(),
version: "0.0.0".into(),
author: "?".into(),
icon_url: "icon.png".into(),
}
})
}
pub fn local_endpoints(dapps_path: String) -> Endpoints {
let mut pages = Endpoints::new();
for dapp in local_dapps(dapps_path) {
pages.insert(
dapp.id,
Box::new(LocalPageEndpoint::new(dapp.path, dapp.info))
);
}
pages
}

View File

@@ -1,87 +0,0 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use endpoint::{Endpoints, Endpoint};
use page::PageEndpoint;
use proxypac::ProxyPac;
use parity_dapps::WebApp;
mod fs;
extern crate parity_dapps_status;
extern crate parity_dapps_builtins;
pub const DAPPS_DOMAIN : &'static str = ".parity";
pub const RPC_PATH : &'static str = "rpc";
pub const API_PATH : &'static str = "api";
pub const UTILS_PATH : &'static str = "parity-utils";
pub fn main_page() -> &'static str {
"/home/"
}
pub fn utils() -> Box<Endpoint> {
Box::new(PageEndpoint::with_prefix(parity_dapps_builtins::App::default(), UTILS_PATH.to_owned()))
}
pub fn all_endpoints(dapps_path: String) -> Endpoints {
// fetch fs dapps at first to avoid overwriting builtins
let mut pages = fs::local_endpoints(dapps_path);
// Home page needs to be safe embed
// because we use Cross-Origin LocalStorage.
// TODO [ToDr] Account naming should be moved to parity.
pages.insert("home".into(), Box::new(
PageEndpoint::new_safe_to_embed(parity_dapps_builtins::App::default())
));
pages.insert("proxy".into(), ProxyPac::boxed());
insert::<parity_dapps_status::App>(&mut pages, "parity");
insert::<parity_dapps_status::App>(&mut pages, "status");
// Optional dapps
wallet_page(&mut pages);
daodapp_page(&mut pages);
makerotc_page(&mut pages);
pages
}
#[cfg(feature = "parity-dapps-wallet")]
fn wallet_page(pages: &mut Endpoints) {
extern crate parity_dapps_wallet;
insert::<parity_dapps_wallet::App>(pages, "wallet");
}
#[cfg(not(feature = "parity-dapps-wallet"))]
fn wallet_page(_pages: &mut Endpoints) {}
#[cfg(feature = "parity-dapps-dao")]
fn daodapp_page(pages: &mut Endpoints) {
extern crate parity_dapps_dao;
insert::<parity_dapps_dao::App>(pages, "dao");
}
#[cfg(not(feature = "parity-dapps-dao"))]
fn daodapp_page(_pages: &mut Endpoints) {}
#[cfg(feature = "parity-dapps-makerotc")]
fn makerotc_page(pages: &mut Endpoints) {
extern crate parity_dapps_makerotc;
insert::<parity_dapps_makerotc::App>(pages, "makerotc");
}
#[cfg(not(feature = "parity-dapps-makerotc"))]
fn makerotc_page(_pages: &mut Endpoints) {}
fn insert<T : WebApp + Default + 'static>(pages: &mut Endpoints, id: &str) {
pages.insert(id.to_owned(), Box::new(PageEndpoint::new(T::default())));
}

View File

@@ -1,99 +0,0 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! URL Endpoint traits
use hyper::status::StatusCode;
use hyper::{header, server, Decoder, Encoder, Next};
use hyper::net::HttpStream;
use std::io::Write;
use std::collections::BTreeMap;
#[derive(Debug, PartialEq, Default, Clone)]
pub struct EndpointPath {
pub app_id: String,
pub host: String,
pub port: u16,
}
#[derive(Debug, PartialEq, Clone)]
pub struct EndpointInfo {
pub name: String,
pub description: String,
pub version: String,
pub author: String,
pub icon_url: String,
}
pub trait Endpoint : Send + Sync {
fn info(&self) -> Option<&EndpointInfo> { None }
fn to_handler(&self, path: EndpointPath) -> Box<server::Handler<HttpStream>>;
}
pub type Endpoints = BTreeMap<String, Box<Endpoint>>;
pub type Handler = server::Handler<HttpStream>;
pub struct ContentHandler {
content: String,
mimetype: String,
write_pos: usize,
}
impl ContentHandler {
pub fn new(content: String, mimetype: String) -> Self {
ContentHandler {
content: content,
mimetype: mimetype,
write_pos: 0
}
}
}
impl server::Handler<HttpStream> for ContentHandler {
fn on_request(&mut self, _request: server::Request) -> Next {
Next::write()
}
fn on_request_readable(&mut self, _decoder: &mut Decoder<HttpStream>) -> Next {
Next::write()
}
fn on_response(&mut self, res: &mut server::Response) -> Next {
res.set_status(StatusCode::Ok);
res.headers_mut().set(header::ContentType(self.mimetype.parse().unwrap()));
Next::write()
}
fn on_response_writable(&mut self, encoder: &mut Encoder<HttpStream>) -> Next {
let bytes = self.content.as_bytes();
if self.write_pos == bytes.len() {
return Next::end();
}
match encoder.write(&bytes[self.write_pos..]) {
Ok(bytes) => {
self.write_pos += bytes;
Next::write()
},
Err(e) => match e.kind() {
::std::io::ErrorKind::WouldBlock => Next::write(),
_ => Next::end()
},
}
}
}

View File

@@ -1,170 +0,0 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Ethcore Webapplications for Parity
//! ```
//! extern crate jsonrpc_core;
//! extern crate ethcore_dapps;
//!
//! use std::sync::Arc;
//! use jsonrpc_core::IoHandler;
//! use ethcore_dapps::*;
//!
//! struct SayHello;
//! impl MethodCommand for SayHello {
//! fn execute(&self, _params: Params) -> Result<Value, Error> {
//! Ok(Value::String("hello".to_string()))
//! }
//! }
//!
//! fn main() {
//! let io = IoHandler::new();
//! io.add_method("say_hello", SayHello);
//! let _server = Server::start_unsecure_http(
//! &"127.0.0.1:3030".parse().unwrap(),
//! Arc::new(io)
//! );
//! }
//! ```
//!
#![warn(missing_docs)]
#![cfg_attr(feature="nightly", plugin(clippy))]
#[macro_use]
extern crate log;
extern crate url;
extern crate hyper;
extern crate serde;
extern crate serde_json;
extern crate jsonrpc_core;
extern crate jsonrpc_http_server;
extern crate parity_dapps;
extern crate ethcore_rpc;
extern crate mime_guess;
mod endpoint;
mod apps;
mod page;
mod router;
mod rpc;
mod api;
mod proxypac;
use std::sync::{Arc, Mutex};
use std::net::SocketAddr;
use std::collections::HashMap;
use jsonrpc_core::{IoHandler, IoDelegate};
use router::auth::{Authorization, NoAuth, HttpBasicAuth};
use ethcore_rpc::Extendable;
static DAPPS_DOMAIN : &'static str = ".parity";
/// Webapps HTTP+RPC server build.
pub struct ServerBuilder {
dapps_path: String,
handler: Arc<IoHandler>,
}
impl Extendable for ServerBuilder {
fn add_delegate<D: Send + Sync + 'static>(&self, delegate: IoDelegate<D>) {
self.handler.add_delegate(delegate);
}
}
impl ServerBuilder {
/// Construct new dapps server
pub fn new(dapps_path: String) -> Self {
ServerBuilder {
dapps_path: dapps_path,
handler: Arc::new(IoHandler::new())
}
}
/// Asynchronously start server with no authentication,
/// returns result with `Server` handle on success or an error.
pub fn start_unsecure_http(&self, addr: &SocketAddr) -> Result<Server, ServerError> {
Server::start_http(addr, NoAuth, self.handler.clone(), self.dapps_path.clone())
}
/// Asynchronously start server with `HTTP Basic Authentication`,
/// return result with `Server` handle on success or an error.
pub fn start_basic_auth_http(&self, addr: &SocketAddr, username: &str, password: &str) -> Result<Server, ServerError> {
Server::start_http(addr, HttpBasicAuth::single_user(username, password), self.handler.clone(), self.dapps_path.clone())
}
}
/// Webapps HTTP server.
pub struct Server {
server: Option<hyper::server::Listening>,
panic_handler: Arc<Mutex<Option<Box<Fn() -> () + Send>>>>,
}
impl Server {
fn start_http<A: Authorization + 'static>(addr: &SocketAddr, authorization: A, handler: Arc<IoHandler>, dapps_path: String) -> Result<Server, ServerError> {
let panic_handler = Arc::new(Mutex::new(None));
let authorization = Arc::new(authorization);
let endpoints = Arc::new(apps::all_endpoints(dapps_path));
let special = Arc::new({
let mut special = HashMap::new();
special.insert(router::SpecialEndpoint::Rpc, rpc::rpc(handler, panic_handler.clone()));
special.insert(router::SpecialEndpoint::Api, api::RestApi::new(endpoints.clone()));
special.insert(router::SpecialEndpoint::Utils, apps::utils());
special
});
try!(hyper::Server::http(addr))
.handle(move |_| router::Router::new(
apps::main_page(),
endpoints.clone(),
special.clone(),
authorization.clone(),
))
.map(|l| Server {
server: Some(l),
panic_handler: panic_handler,
})
.map_err(ServerError::from)
}
/// Set callback for panics.
pub fn set_panic_handler<F>(&self, handler: F) where F : Fn() -> () + Send + 'static {
*self.panic_handler.lock().unwrap() = Some(Box::new(handler));
}
}
impl Drop for Server {
fn drop(&mut self) {
self.server.take().unwrap().close()
}
}
/// Webapp Server startup error
#[derive(Debug)]
pub enum ServerError {
/// Wrapped `std::io::Error`
IoError(std::io::Error),
/// Other `hyper` error
Other(hyper::error::Error),
}
impl From<hyper::error::Error> for ServerError {
fn from(err: hyper::error::Error) -> Self {
match err {
hyper::error::Error::Io(e) => ServerError::IoError(e),
e => ServerError::Other(e),
}
}
}

View File

@@ -1,154 +0,0 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use page::handler;
use std::sync::Arc;
use endpoint::{Endpoint, EndpointInfo, EndpointPath, Handler};
use parity_dapps::{WebApp, File, Info};
pub struct PageEndpoint<T : WebApp + 'static> {
/// Content of the files
pub app: Arc<T>,
/// Prefix to strip from the path (when `None` deducted from `app_id`)
pub prefix: Option<String>,
/// Safe to be loaded in frame by other origin. (use wisely!)
safe_to_embed: bool,
info: EndpointInfo,
}
impl<T: WebApp + 'static> PageEndpoint<T> {
/// Creates new `PageEndpoint` for builtin (compile time) Dapp.
pub fn new(app: T) -> Self {
let info = app.info();
PageEndpoint {
app: Arc::new(app),
prefix: None,
safe_to_embed: false,
info: EndpointInfo::from(info),
}
}
/// Create new `PageEndpoint` and specify prefix that should be removed before looking for a file.
/// It's used only for special endpoints (i.e. `/parity-utils/`)
/// So `/parity-utils/inject.js` will be resolved to `/inject.js` is prefix is set.
pub fn with_prefix(app: T, prefix: String) -> Self {
let info = app.info();
PageEndpoint {
app: Arc::new(app),
prefix: Some(prefix),
safe_to_embed: false,
info: EndpointInfo::from(info),
}
}
/// Creates new `PageEndpoint` which can be safely used in iframe
/// even from different origin. It might be dangerous (clickjacking).
/// Use wisely!
pub fn new_safe_to_embed(app: T) -> Self {
let info = app.info();
PageEndpoint {
app: Arc::new(app),
prefix: None,
safe_to_embed: true,
info: EndpointInfo::from(info),
}
}
}
impl<T: WebApp> Endpoint for PageEndpoint<T> {
fn info(&self) -> Option<&EndpointInfo> {
Some(&self.info)
}
fn to_handler(&self, path: EndpointPath) -> Box<Handler> {
Box::new(handler::PageHandler {
app: BuiltinDapp::new(self.app.clone()),
prefix: self.prefix.clone(),
path: path,
file: None,
safe_to_embed: self.safe_to_embed,
})
}
}
impl From<Info> for EndpointInfo {
fn from(info: Info) -> Self {
EndpointInfo {
name: info.name.into(),
description: info.description.into(),
author: info.author.into(),
icon_url: info.icon_url.into(),
version: info.version.into(),
}
}
}
struct BuiltinDapp<T: WebApp + 'static> {
app: Arc<T>,
}
impl<T: WebApp + 'static> BuiltinDapp<T> {
fn new(app: Arc<T>) -> Self {
BuiltinDapp {
app: app,
}
}
}
impl<T: WebApp + 'static> handler::Dapp for BuiltinDapp<T> {
type DappFile = BuiltinDappFile<T>;
fn file(&self, path: &str) -> Option<Self::DappFile> {
self.app.file(path).map(|_| {
BuiltinDappFile {
app: self.app.clone(),
path: path.into(),
write_pos: 0,
}
})
}
}
struct BuiltinDappFile<T: WebApp + 'static> {
app: Arc<T>,
path: String,
write_pos: usize,
}
impl<T: WebApp + 'static> BuiltinDappFile<T> {
fn file(&self) -> &File {
self.app.file(&self.path).expect("Check is done when structure is created.")
}
}
impl<T: WebApp + 'static> handler::DappFile for BuiltinDappFile<T> {
fn content_type(&self) -> &str {
self.file().content_type
}
fn is_drained(&self) -> bool {
self.write_pos == self.file().content.len()
}
fn next_chunk(&mut self) -> &[u8] {
&self.file().content[self.write_pos..]
}
fn bytes_written(&mut self, bytes: usize) {
self.write_pos += bytes;
}
}

View File

@@ -1,207 +0,0 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::io::Write;
use hyper::header;
use hyper::server;
use hyper::uri::RequestUri;
use hyper::net::HttpStream;
use hyper::status::StatusCode;
use hyper::{Decoder, Encoder, Next};
use endpoint::EndpointPath;
/// Represents a file that can be sent to client.
/// Implementation should keep track of bytes already sent internally.
pub trait DappFile: Send {
/// Returns a content-type of this file.
fn content_type(&self) -> &str;
/// Checks if all bytes from that file were written.
fn is_drained(&self) -> bool;
/// Fetch next chunk to write to the client.
fn next_chunk(&mut self) -> &[u8];
/// How many files have been written to the client.
fn bytes_written(&mut self, bytes: usize);
}
/// Dapp as a (dynamic) set of files.
pub trait Dapp: Send + 'static {
/// File type
type DappFile: DappFile;
/// Returns file under given path.
fn file(&self, path: &str) -> Option<Self::DappFile>;
}
/// A handler for a single webapp.
/// Resolves correct paths and serves as a plumbing code between
/// hyper server and dapp.
pub struct PageHandler<T: Dapp> {
/// A Dapp.
pub app: T,
/// File currently being served (or `None` if file does not exist).
pub file: Option<T::DappFile>,
/// Optional prefix to strip from path.
pub prefix: Option<String>,
/// Requested path.
pub path: EndpointPath,
/// Flag indicating if the file can be safely embeded (put in iframe).
pub safe_to_embed: bool,
}
impl<T: Dapp> PageHandler<T> {
fn extract_path(&self, path: &str) -> String {
let app_id = &self.path.app_id;
let prefix = "/".to_owned() + self.prefix.as_ref().unwrap_or(app_id);
let prefix_with_slash = prefix.clone() + "/";
let query_pos = path.find('?').unwrap_or_else(|| path.len());
// Index file support
match path == "/" || path == &prefix || path == &prefix_with_slash {
true => "index.html".to_owned(),
false => if path.starts_with(&prefix_with_slash) {
path[prefix_with_slash.len()..query_pos].to_owned()
} else if path.starts_with("/") {
path[1..query_pos].to_owned()
} else {
path[0..query_pos].to_owned()
}
}
}
}
impl<T: Dapp> server::Handler<HttpStream> for PageHandler<T> {
fn on_request(&mut self, req: server::Request) -> Next {
self.file = match *req.uri() {
RequestUri::AbsolutePath(ref path) => {
self.app.file(&self.extract_path(path))
},
RequestUri::AbsoluteUri(ref url) => {
self.app.file(&self.extract_path(url.path()))
},
_ => None,
};
Next::write()
}
fn on_request_readable(&mut self, _decoder: &mut Decoder<HttpStream>) -> Next {
Next::write()
}
fn on_response(&mut self, res: &mut server::Response) -> Next {
if let Some(ref f) = self.file {
res.set_status(StatusCode::Ok);
res.headers_mut().set(header::ContentType(f.content_type().parse().unwrap()));
if !self.safe_to_embed {
res.headers_mut().set_raw("X-Frame-Options", vec![b"SAMEORIGIN".to_vec()]);
}
Next::write()
} else {
res.set_status(StatusCode::NotFound);
Next::write()
}
}
fn on_response_writable(&mut self, encoder: &mut Encoder<HttpStream>) -> Next {
match self.file {
None => Next::end(),
Some(ref f) if f.is_drained() => Next::end(),
Some(ref mut f) => match encoder.write(f.next_chunk()) {
Ok(bytes) => {
f.bytes_written(bytes);
Next::write()
},
Err(e) => match e.kind() {
::std::io::ErrorKind::WouldBlock => Next::write(),
_ => Next::end(),
},
}
}
}
}
#[cfg(test)]
mod test {
use super::*;
pub struct TestWebAppFile;
impl DappFile for TestWebAppFile {
fn content_type(&self) -> &str {
unimplemented!()
}
fn is_drained(&self) -> bool {
unimplemented!()
}
fn next_chunk(&mut self) -> &[u8] {
unimplemented!()
}
fn bytes_written(&mut self, _bytes: usize) {
unimplemented!()
}
}
#[derive(Default)]
pub struct TestWebapp;
impl Dapp for TestWebapp {
type DappFile = TestWebAppFile;
fn file(&self, _path: &str) -> Option<Self::DappFile> {
None
}
}
}
#[test]
fn should_extract_path_with_appid() {
// given
let path1 = "/";
let path2= "/test.css";
let path3 = "/app/myfile.txt";
let path4 = "/app/myfile.txt?query=123";
let page_handler = PageHandler {
app: test::TestWebapp,
prefix: None,
path: EndpointPath {
app_id: "app".to_owned(),
host: "".to_owned(),
port: 8080
},
file: None,
safe_to_embed: true,
};
// when
let res1 = page_handler.extract_path(path1);
let res2 = page_handler.extract_path(path2);
let res3 = page_handler.extract_path(path3);
let res4 = page_handler.extract_path(path4);
// then
assert_eq!(&res1, "index.html");
assert_eq!(&res2, "test.css");
assert_eq!(&res3, "myfile.txt");
assert_eq!(&res4, "myfile.txt");
}

View File

@@ -1,118 +0,0 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use mime_guess;
use std::io::{Seek, Read, SeekFrom};
use std::fs;
use std::path::PathBuf;
use page::handler;
use endpoint::{Endpoint, EndpointInfo, EndpointPath, Handler};
pub struct LocalPageEndpoint {
path: PathBuf,
info: EndpointInfo,
}
impl LocalPageEndpoint {
pub fn new(path: PathBuf, info: EndpointInfo) -> Self {
LocalPageEndpoint {
path: path,
info: info,
}
}
}
impl Endpoint for LocalPageEndpoint {
fn info(&self) -> Option<&EndpointInfo> {
Some(&self.info)
}
fn to_handler(&self, path: EndpointPath) -> Box<Handler> {
Box::new(handler::PageHandler {
app: LocalDapp::new(self.path.clone()),
prefix: None,
path: path,
file: None,
safe_to_embed: false,
})
}
}
struct LocalDapp {
path: PathBuf,
}
impl LocalDapp {
fn new(path: PathBuf) -> Self {
LocalDapp {
path: path
}
}
}
impl handler::Dapp for LocalDapp {
type DappFile = LocalFile;
fn file(&self, file_path: &str) -> Option<Self::DappFile> {
let mut path = self.path.clone();
for part in file_path.split('/') {
path.push(part);
}
// Check if file exists
fs::File::open(path.clone()).ok().map(|file| {
let content_type = mime_guess::guess_mime_type(path);
let len = file.metadata().ok().map_or(0, |meta| meta.len());
LocalFile {
content_type: content_type.to_string(),
buffer: [0; 4096],
file: file,
pos: 0,
len: len,
}
})
}
}
struct LocalFile {
content_type: String,
buffer: [u8; 4096],
file: fs::File,
len: u64,
pos: u64,
}
impl handler::DappFile for LocalFile {
fn content_type(&self) -> &str {
&self.content_type
}
fn is_drained(&self) -> bool {
self.pos == self.len
}
fn next_chunk(&mut self) -> &[u8] {
let _ = self.file.seek(SeekFrom::Start(self.pos));
if let Ok(n) = self.file.read(&mut self.buffer) {
&self.buffer[0..n]
} else {
&self.buffer[0..0]
}
}
fn bytes_written(&mut self, bytes: usize) {
self.pos += bytes as u64;
}
}

View File

@@ -1,24 +0,0 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
mod builtin;
mod local;
mod handler;
pub use self::local::LocalPageEndpoint;
pub use self::builtin::PageEndpoint;

View File

@@ -1,48 +0,0 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Serving ProxyPac file
use endpoint::{Endpoint, Handler, ContentHandler, EndpointPath};
use apps::DAPPS_DOMAIN;
pub struct ProxyPac;
impl ProxyPac {
pub fn boxed() -> Box<Endpoint> {
Box::new(ProxyPac)
}
}
impl Endpoint for ProxyPac {
fn to_handler(&self, path: EndpointPath) -> Box<Handler> {
let content = format!(
r#"
function FindProxyForURL(url, host) {{
if (shExpMatch(host, "*{0}"))
{{
return "PROXY {1}:{2}";
}}
return "DIRECT";
}}
"#,
DAPPS_DOMAIN, path.host, path.port);
Box::new(ContentHandler::new(content, "application/javascript".to_owned()))
}
}

View File

@@ -1,161 +0,0 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! HTTP Authorization implementations
use std::io::Write;
use std::collections::HashMap;
use hyper::{header, server, Decoder, Encoder, Next};
use hyper::net::HttpStream;
use hyper::status::StatusCode;
/// Authorization result
pub enum Authorized {
/// Authorization was successful.
Yes,
/// Unsuccessful authorization. Handler for further work is returned.
No(Box<server::Handler<HttpStream>>),
}
/// Authorization interface
pub trait Authorization : Send + Sync {
/// Checks if authorization is valid.
fn is_authorized(&self, req: &server::Request)-> Authorized;
}
/// HTTP Basic Authorization handler
pub struct HttpBasicAuth {
users: HashMap<String, String>,
}
/// No-authorization implementation (authorization disabled)
pub struct NoAuth;
impl Authorization for NoAuth {
fn is_authorized(&self, _req: &server::Request)-> Authorized {
Authorized::Yes
}
}
impl Authorization for HttpBasicAuth {
fn is_authorized(&self, req: &server::Request) -> Authorized {
let auth = self.check_auth(&req);
match auth {
Access::Denied => {
Authorized::No(Box::new(UnauthorizedHandler { write_pos: 0 }))
},
Access::AuthRequired => {
Authorized::No(Box::new(AuthRequiredHandler))
},
Access::Granted => {
Authorized::Yes
},
}
}
}
#[derive(Debug)]
enum Access {
Granted,
Denied,
AuthRequired,
}
impl HttpBasicAuth {
/// Creates `HttpBasicAuth` instance with only one user.
pub fn single_user(username: &str, password: &str) -> Self {
let mut users = HashMap::new();
users.insert(username.to_owned(), password.to_owned());
HttpBasicAuth {
users: users
}
}
fn is_authorized(&self, username: &str, password: &str) -> bool {
self.users.get(&username.to_owned()).map_or(false, |pass| pass == password)
}
fn check_auth(&self, req: &server::Request) -> Access {
match req.headers().get::<header::Authorization<header::Basic>>() {
Some(&header::Authorization(
header::Basic { ref username, password: Some(ref password) }
)) if self.is_authorized(username, password) => Access::Granted,
Some(_) => Access::Denied,
None => Access::AuthRequired,
}
}
}
pub struct UnauthorizedHandler {
write_pos: usize,
}
impl server::Handler<HttpStream> for UnauthorizedHandler {
fn on_request(&mut self, _request: server::Request) -> Next {
Next::write()
}
fn on_request_readable(&mut self, _decoder: &mut Decoder<HttpStream>) -> Next {
Next::write()
}
fn on_response(&mut self, res: &mut server::Response) -> Next {
res.set_status(StatusCode::Unauthorized);
Next::write()
}
fn on_response_writable(&mut self, encoder: &mut Encoder<HttpStream>) -> Next {
let response = "Unauthorized".as_bytes();
if self.write_pos == response.len() {
return Next::end();
}
match encoder.write(&response[self.write_pos..]) {
Ok(bytes) => {
self.write_pos += bytes;
Next::write()
},
Err(e) => match e.kind() {
::std::io::ErrorKind::WouldBlock => Next::write(),
_ => Next::end()
},
}
}
}
pub struct AuthRequiredHandler;
impl server::Handler<HttpStream> for AuthRequiredHandler {
fn on_request(&mut self, _request: server::Request) -> Next {
Next::write()
}
fn on_request_readable(&mut self, _decoder: &mut Decoder<HttpStream>) -> Next {
Next::write()
}
fn on_response(&mut self, res: &mut server::Response) -> Next {
res.set_status(StatusCode::Unauthorized);
res.headers_mut().set_raw("WWW-Authenticate", vec![b"Basic realm=\"Parity\"".to_vec()]);
Next::write()
}
fn on_response_writable(&mut self, _encoder: &mut Encoder<HttpStream>) -> Next {
Next::end()
}
}

View File

@@ -1,255 +0,0 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Router implementation
//! Processes request handling authorization and dispatching it to proper application.
mod url;
mod redirect;
pub mod auth;
use DAPPS_DOMAIN;
use std::sync::Arc;
use std::collections::HashMap;
use url::Host;
use hyper;
use hyper::{server, uri, header};
use hyper::{Next, Encoder, Decoder};
use hyper::net::HttpStream;
use apps;
use endpoint::{Endpoint, Endpoints, EndpointPath};
use self::url::Url;
use self::auth::{Authorization, Authorized};
use self::redirect::Redirection;
/// Special endpoints are accessible on every domain (every dapp)
#[derive(Debug, PartialEq, Hash, Eq)]
pub enum SpecialEndpoint {
Rpc,
Api,
Utils,
None,
}
pub struct Router<A: Authorization + 'static> {
main_page: &'static str,
endpoints: Arc<Endpoints>,
special: Arc<HashMap<SpecialEndpoint, Box<Endpoint>>>,
authorization: Arc<A>,
handler: Box<server::Handler<HttpStream>>,
}
impl<A: Authorization + 'static> server::Handler<HttpStream> for Router<A> {
fn on_request(&mut self, req: server::Request) -> Next {
// Check authorization
let auth = self.authorization.is_authorized(&req);
// Choose proper handler depending on path / domain
self.handler = match auth {
Authorized::No(handler) => handler,
Authorized::Yes => {
let url = extract_url(&req);
let endpoint = extract_endpoint(&url);
match endpoint {
// First check special endpoints
(ref path, ref endpoint) if self.special.contains_key(endpoint) => {
self.special.get(endpoint).unwrap().to_handler(path.clone().unwrap_or_default())
},
// Then delegate to dapp
(Some(ref path), _) if self.endpoints.contains_key(&path.app_id) => {
self.endpoints.get(&path.app_id).unwrap().to_handler(path.clone())
},
// Redirection to main page
_ if *req.method() == hyper::method::Method::Get => {
Redirection::new(self.main_page)
},
// RPC by default
_ => {
self.special.get(&SpecialEndpoint::Rpc).unwrap().to_handler(EndpointPath::default())
}
}
}
};
// Delegate on_request to proper handler
self.handler.on_request(req)
}
/// This event occurs each time the `Request` is ready to be read from.
fn on_request_readable(&mut self, decoder: &mut Decoder<HttpStream>) -> Next {
self.handler.on_request_readable(decoder)
}
/// This event occurs after the first time this handled signals `Next::write()`.
fn on_response(&mut self, response: &mut server::Response) -> Next {
self.handler.on_response(response)
}
/// This event occurs each time the `Response` is ready to be written to.
fn on_response_writable(&mut self, encoder: &mut Encoder<HttpStream>) -> Next {
self.handler.on_response_writable(encoder)
}
}
impl<A: Authorization> Router<A> {
pub fn new(
main_page: &'static str,
endpoints: Arc<Endpoints>,
special: Arc<HashMap<SpecialEndpoint, Box<Endpoint>>>,
authorization: Arc<A>) -> Self {
let handler = special.get(&SpecialEndpoint::Rpc).unwrap().to_handler(EndpointPath::default());
Router {
main_page: main_page,
endpoints: endpoints,
special: special,
authorization: authorization,
handler: handler,
}
}
}
fn extract_url(req: &server::Request) -> Option<Url> {
match *req.uri() {
uri::RequestUri::AbsoluteUri(ref url) => {
match Url::from_generic_url(url.clone()) {
Ok(url) => Some(url),
_ => None,
}
},
uri::RequestUri::AbsolutePath(ref path) => {
// Attempt to prepend the Host header (mandatory in HTTP/1.1)
let url_string = match req.headers().get::<header::Host>() {
Some(ref host) => {
format!("http://{}:{}{}", host.hostname, host.port.unwrap_or(80), path)
},
None => return None,
};
match Url::parse(&url_string) {
Ok(url) => Some(url),
_ => None,
}
},
_ => None,
}
}
fn extract_endpoint(url: &Option<Url>) -> (Option<EndpointPath>, SpecialEndpoint) {
fn special_endpoint(url: &Url) -> SpecialEndpoint {
if url.path.len() <= 1 {
return SpecialEndpoint::None;
}
match url.path[0].as_ref() {
apps::RPC_PATH => SpecialEndpoint::Rpc,
apps::API_PATH => SpecialEndpoint::Api,
apps::UTILS_PATH => SpecialEndpoint::Utils,
_ => SpecialEndpoint::None,
}
}
match *url {
Some(ref url) => match url.host {
Host::Domain(ref domain) if domain.ends_with(DAPPS_DOMAIN) => {
let len = domain.len() - DAPPS_DOMAIN.len();
let id = domain[0..len].to_owned();
(Some(EndpointPath {
app_id: id,
host: domain.clone(),
port: url.port,
}), special_endpoint(url))
},
_ if url.path.len() > 1 => {
let id = url.path[0].clone();
(Some(EndpointPath {
app_id: id.clone(),
host: format!("{}", url.host),
port: url.port,
}), special_endpoint(url))
},
_ => (None, special_endpoint(url)),
},
_ => (None, SpecialEndpoint::None)
}
}
#[test]
fn should_extract_endpoint() {
assert_eq!(extract_endpoint(&None), (None, SpecialEndpoint::None));
// With path prefix
assert_eq!(
extract_endpoint(&Url::parse("http://localhost:8080/status/index.html").ok()),
(Some(EndpointPath {
app_id: "status".to_owned(),
host: "localhost".to_owned(),
port: 8080,
}), SpecialEndpoint::None)
);
// With path prefix
assert_eq!(
extract_endpoint(&Url::parse("http://localhost:8080/rpc/").ok()),
(Some(EndpointPath {
app_id: "rpc".to_owned(),
host: "localhost".to_owned(),
port: 8080,
}), SpecialEndpoint::Rpc)
);
assert_eq!(
extract_endpoint(&Url::parse("http://my.status.parity/parity-utils/inject.js").ok()),
(Some(EndpointPath {
app_id: "my.status".to_owned(),
host: "my.status.parity".to_owned(),
port: 80,
}), SpecialEndpoint::Utils)
);
// By Subdomain
assert_eq!(
extract_endpoint(&Url::parse("http://my.status.parity/test.html").ok()),
(Some(EndpointPath {
app_id: "my.status".to_owned(),
host: "my.status.parity".to_owned(),
port: 80,
}), SpecialEndpoint::None)
);
// RPC by subdomain
assert_eq!(
extract_endpoint(&Url::parse("http://my.status.parity/rpc/").ok()),
(Some(EndpointPath {
app_id: "my.status".to_owned(),
host: "my.status.parity".to_owned(),
port: 80,
}), SpecialEndpoint::Rpc)
);
// API by subdomain
assert_eq!(
extract_endpoint(&Url::parse("http://my.status.parity/api/").ok()),
(Some(EndpointPath {
app_id: "my.status".to_owned(),
host: "my.status.parity".to_owned(),
port: 80,
}), SpecialEndpoint::Api)
);
}

View File

@@ -1,55 +0,0 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! HTTP Redirection hyper handler
use hyper::{header, server, Decoder, Encoder, Next};
use hyper::net::HttpStream;
use hyper::status::StatusCode;
pub struct Redirection {
to_url: &'static str
}
impl Redirection {
pub fn new(url: &'static str) -> Box<Self> {
Box::new(Redirection {
to_url: url
})
}
}
impl server::Handler<HttpStream> for Redirection {
fn on_request(&mut self, _request: server::Request) -> Next {
Next::write()
}
fn on_request_readable(&mut self, _decoder: &mut Decoder<HttpStream>) -> Next {
Next::write()
}
fn on_response(&mut self, res: &mut server::Response) -> Next {
res.set_status(StatusCode::MovedPermanently);
res.headers_mut().set(header::Location(self.to_url.to_owned()));
Next::write()
}
fn on_response_writable(&mut self, _encoder: &mut Encoder<HttpStream>) -> Next {
Next::end()
}
}

View File

@@ -1,145 +0,0 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! HTTP/HTTPS URL type. Based on URL type from Iron library.
use url::Host;
use url::{self};
/// HTTP/HTTPS URL type for Iron.
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct Url {
/// Raw url of url
pub raw: url::Url,
/// The host field of the URL, probably a domain.
pub host: Host,
/// The connection port.
pub port: u16,
/// The URL path, the resource to be accessed.
///
/// A *non-empty* vector encoding the parts of the URL path.
/// Empty entries of `""` correspond to trailing slashes.
pub path: Vec<String>,
/// The URL username field, from the userinfo section of the URL.
///
/// `None` if the `@` character was not part of the input OR
/// if a blank username was provided.
/// Otherwise, a non-empty string.
pub username: Option<String>,
/// The URL password field, from the userinfo section of the URL.
///
/// `None` if the `@` character was not part of the input OR
/// if a blank password was provided.
/// Otherwise, a non-empty string.
pub password: Option<String>,
}
impl Url {
/// Create a URL from a string.
///
/// The input must be a valid URL with a special scheme for this to succeed.
///
/// HTTP and HTTPS are special schemes.
///
/// See: http://url.spec.whatwg.org/#special-scheme
pub fn parse(input: &str) -> Result<Url, String> {
// Parse the string using rust-url, then convert.
match url::Url::parse(input) {
Ok(raw_url) => Url::from_generic_url(raw_url),
Err(e) => Err(format!("{}", e))
}
}
/// Create a `Url` from a `rust-url` `Url`.
pub fn from_generic_url(raw_url: url::Url) -> Result<Url, String> {
// Map empty usernames to None.
let username = match raw_url.username() {
"" => None,
username => Some(username.to_owned())
};
// Map empty passwords to None.
let password = match raw_url.password() {
Some(password) if !password.is_empty() => Some(password.to_owned()),
_ => None,
};
let port = try!(raw_url.port_or_known_default().ok_or_else(|| format!("Unknown port for scheme: `{}`", raw_url.scheme())));
let host = try!(raw_url.host().ok_or_else(|| "Valid host, because only data:, mailto: protocols does not have host.".to_owned())).to_owned();
let path = try!(raw_url.path_segments().ok_or_else(|| "Valid path segments. In HTTP we won't get cannot-be-a-base URLs".to_owned()))
.map(|part| part.to_owned()).collect();
Ok(Url {
port: port,
host: host,
path: path,
raw: raw_url,
username: username,
password: password,
})
}
}
#[cfg(test)]
mod test {
use super::Url;
#[test]
fn test_default_port() {
assert_eq!(Url::parse("http://example.com/wow").unwrap().port, 80u16);
assert_eq!(Url::parse("https://example.com/wow").unwrap().port, 443u16);
}
#[test]
fn test_explicit_port() {
assert_eq!(Url::parse("http://localhost:3097").unwrap().port, 3097u16);
}
#[test]
fn test_empty_username() {
assert!(Url::parse("http://@example.com").unwrap().username.is_none());
assert!(Url::parse("http://:password@example.com").unwrap().username.is_none());
}
#[test]
fn test_not_empty_username() {
let user = Url::parse("http://john:pass@example.com").unwrap().username;
assert_eq!(user.unwrap(), "john");
let user = Url::parse("http://john:@example.com").unwrap().username;
assert_eq!(user.unwrap(), "john");
}
#[test]
fn test_empty_password() {
assert!(Url::parse("http://michael@example.com").unwrap().password.is_none());
assert!(Url::parse("http://:@example.com").unwrap().password.is_none());
}
#[test]
fn test_not_empty_password() {
let pass = Url::parse("http://michael:pass@example.com").unwrap().password;
assert_eq!(pass.unwrap(), "pass");
let pass = Url::parse("http://:pass@example.com").unwrap().password;
assert_eq!(pass.unwrap(), "pass");
}
}

View File

@@ -1,41 +0,0 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::sync::{Arc, Mutex};
use jsonrpc_core::IoHandler;
use jsonrpc_http_server::{ServerHandler, PanicHandler, AccessControlAllowOrigin};
use endpoint::{Endpoint, EndpointPath, Handler};
pub fn rpc(handler: Arc<IoHandler>, panic_handler: Arc<Mutex<Option<Box<Fn() -> () + Send>>>>) -> Box<Endpoint> {
Box::new(RpcEndpoint {
handler: handler,
panic_handler: panic_handler,
cors_domain: vec![AccessControlAllowOrigin::Null],
})
}
struct RpcEndpoint {
handler: Arc<IoHandler>,
panic_handler: Arc<Mutex<Option<Box<Fn() -> () + Send>>>>,
cors_domain: Vec<AccessControlAllowOrigin>,
}
impl Endpoint for RpcEndpoint {
fn to_handler(&self, _path: EndpointPath) -> Box<Handler> {
let panic_handler = PanicHandler { handler: self.panic_handler.clone() };
Box::new(ServerHandler::new(self.handler.clone(), self.cors_domain.clone(), panic_handler))
}
}

View File

@@ -1,26 +0,0 @@
[package]
description = "Ethcore Database"
homepage = "http://ethcore.io"
license = "GPL-3.0"
name = "ethcore-db"
version = "1.2.0"
authors = ["Ethcore <admin@ethcore.io>"]
build = "build.rs"
[build-dependencies]
syntex = "*"
ethcore-ipc-codegen = { path = "../ipc/codegen" }
[dependencies]
clippy = { version = "0.0.77", optional = true}
ethcore-devtools = { path = "../devtools" }
ethcore-ipc = { path = "../ipc/rpc" }
rocksdb = { git = "https://github.com/ethcore/rust-rocksdb" }
semver = "0.2"
ethcore-ipc-nano = { path = "../ipc/nano" }
nanomsg = { git = "https://github.com/ethcore/nanomsg.rs.git" }
crossbeam = "0.2"
ethcore-util = { path = "../util" }
[features]
dev = ["clippy"]

View File

@@ -1,43 +0,0 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
extern crate syntex;
extern crate ethcore_ipc_codegen as codegen;
use std::env;
use std::path::Path;
pub fn main() {
let out_dir = env::var_os("OUT_DIR").unwrap();
// ipc pass
{
let src = Path::new("src/lib.rs.in");
let dst = Path::new(&out_dir).join("lib.intermediate.rs.in");
let mut registry = syntex::Registry::new();
codegen::register(&mut registry);
registry.expand("", &src, &dst).unwrap();
}
// binary serialization pass
{
let src = Path::new(&out_dir).join("lib.intermediate.rs.in");
let dst = Path::new(&out_dir).join("lib.rs");
let mut registry = syntex::Registry::new();
codegen::register(&mut registry);
registry.expand("", &src, &dst).unwrap();
}
}

View File

@@ -1,573 +0,0 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Ethcore rocksdb ipc service
use traits::*;
use rocksdb::{DB, Writable, WriteBatch, IteratorMode, DBIterator,
IndexType, Options, DBCompactionStyle, BlockBasedOptions, Direction};
use std::sync::{RwLock, Arc};
use std::convert::From;
use ipc::IpcConfig;
use std::mem;
use ipc::binary::BinaryConvertError;
use std::collections::{VecDeque, HashMap, BTreeMap};
impl From<String> for Error {
fn from(s: String) -> Error {
Error::RocksDb(s)
}
}
enum WriteCacheEntry {
Remove,
Write(Vec<u8>),
}
pub struct WriteCache {
entries: HashMap<Vec<u8>, WriteCacheEntry>,
preferred_len: usize,
}
const FLUSH_BATCH_SIZE: usize = 4096;
impl WriteCache {
fn new(cache_len: usize) -> WriteCache {
WriteCache {
entries: HashMap::new(),
preferred_len: cache_len,
}
}
fn write(&mut self, key: Vec<u8>, val: Vec<u8>) {
self.entries.insert(key, WriteCacheEntry::Write(val));
}
fn remove(&mut self, key: Vec<u8>) {
self.entries.insert(key, WriteCacheEntry::Remove);
}
fn get(&self, key: &Vec<u8>) -> Option<Vec<u8>> {
self.entries.get(key).and_then(
|vec_ref| match vec_ref {
&WriteCacheEntry::Write(ref val) => Some(val.clone()),
&WriteCacheEntry::Remove => None
})
}
/// WriteCache should be locked for this
fn flush(&mut self, db: &DB, amount: usize) -> Result<(), Error> {
let batch = WriteBatch::new();
let mut removed_so_far = 0;
while removed_so_far < amount {
if self.entries.len() == 0 { break; }
let removed_key = {
let (key, cache_entry) = self.entries.iter().nth(0)
.expect("if entries.len == 0, we should have break in the loop, still we got here somehow");
match *cache_entry {
WriteCacheEntry::Write(ref val) => {
try!(batch.put(&key, val));
},
WriteCacheEntry::Remove => {
try!(batch.delete(&key));
},
}
key.clone()
};
self.entries.remove(&removed_key);
removed_so_far = removed_so_far + 1;
}
if removed_so_far > 0 {
try!(db.write(batch));
}
Ok(())
}
/// flushes until cache is empty
fn flush_all(&mut self, db: &DB) -> Result<(), Error> {
while !self.is_empty() { try!(self.flush(db, FLUSH_BATCH_SIZE)); }
Ok(())
}
fn is_empty(&self) -> bool {
self.entries.is_empty()
}
fn try_shrink(&mut self, db: &DB) -> Result<(), Error> {
if self.entries.len() > self.preferred_len {
try!(self.flush(db, FLUSH_BATCH_SIZE));
}
Ok(())
}
}
pub struct Database {
db: RwLock<Option<DB>>,
/// Iterators - dont't use between threads!
iterators: RwLock<BTreeMap<IteratorHandle, DBIterator>>,
write_cache: RwLock<WriteCache>,
}
unsafe impl Send for Database {}
unsafe impl Sync for Database {}
impl Database {
pub fn new() -> Database {
Database {
db: RwLock::new(None),
iterators: RwLock::new(BTreeMap::new()),
write_cache: RwLock::new(WriteCache::new(DEFAULT_CACHE_LEN)),
}
}
pub fn flush(&self) -> Result<(), Error> {
let mut cache_lock = self.write_cache.write().unwrap();
let db_lock = self.db.read().unwrap();
if db_lock.is_none() { return Ok(()); }
let db = db_lock.as_ref().unwrap();
try!(cache_lock.try_shrink(&db));
Ok(())
}
pub fn flush_all(&self) -> Result<(), Error> {
let mut cache_lock = self.write_cache.write().unwrap();
let db_lock = self.db.read().unwrap();
if db_lock.is_none() { return Ok(()); }
let db = db_lock.as_ref().expect("we should have exited with Ok(()) on the previous step");
try!(cache_lock.flush_all(&db));
Ok(())
}
}
impl Drop for Database {
fn drop(&mut self) {
self.flush().unwrap();
}
}
#[derive(Ipc)]
impl DatabaseService for Database {
fn open(&self, config: DatabaseConfig, path: String) -> Result<(), Error> {
let mut db = self.db.write().unwrap();
if db.is_some() { return Err(Error::AlreadyOpen); }
let mut opts = Options::new();
opts.set_max_open_files(256);
opts.create_if_missing(true);
opts.set_use_fsync(false);
opts.set_compaction_style(DBCompactionStyle::DBUniversalCompaction);
if let Some(size) = config.prefix_size {
let mut block_opts = BlockBasedOptions::new();
block_opts.set_index_type(IndexType::HashSearch);
opts.set_block_based_table_factory(&block_opts);
opts.set_prefix_extractor_fixed_size(size);
}
*db = Some(try!(DB::open(&opts, &path)));
Ok(())
}
/// Opens database in the specified path with the default config
fn open_default(&self, path: String) -> Result<(), Error> {
self.open(DatabaseConfig::default(), path)
}
fn close(&self) -> Result<(), Error> {
try!(self.flush_all());
let mut db = self.db.write().unwrap();
if db.is_none() { return Err(Error::IsClosed); }
*db = None;
Ok(())
}
fn put(&self, key: &[u8], value: &[u8]) -> Result<(), Error> {
let mut cache_lock = self.write_cache.write().unwrap();
cache_lock.write(key.to_vec(), value.to_vec());
Ok(())
}
fn delete(&self, key: &[u8]) -> Result<(), Error> {
let mut cache_lock = self.write_cache.write().unwrap();
cache_lock.remove(key.to_vec());
Ok(())
}
fn write(&self, transaction: DBTransaction) -> Result<(), Error> {
let mut cache_lock = self.write_cache.write().unwrap();
let mut writes = transaction.writes.borrow_mut();
for kv in writes.drain(..) {
cache_lock.write(kv.key, kv.value);
}
let mut removes = transaction.removes.borrow_mut();
for k in removes.drain(..) {
cache_lock.remove(k);
}
Ok(())
}
fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Error> {
{
let key_vec = key.to_vec();
let cache_hit = self.write_cache.read().unwrap().get(&key_vec);
if cache_hit.is_some() {
return Ok(Some(cache_hit.expect("cache_hit.is_some() = true, still there is none somehow here")))
}
}
let db_lock = self.db.read().unwrap();
let db = try!(db_lock.as_ref().ok_or(Error::IsClosed));
match try!(db.get(key)) {
Some(db_vec) => {
Ok(Some(db_vec.to_vec()))
},
None => Ok(None),
}
}
fn get_by_prefix(&self, prefix: &[u8]) -> Result<Option<Vec<u8>>, Error> {
let db_lock = self.db.read().unwrap();
let db = try!(db_lock.as_ref().ok_or(Error::IsClosed));
let mut iter = db.iterator(IteratorMode::From(prefix, Direction::Forward));
match iter.next() {
// TODO: use prefix_same_as_start read option (not availabele in C API currently)
Some((k, v)) => if k[0 .. prefix.len()] == prefix[..] { Ok(Some(v.to_vec())) } else { Ok(None) },
_ => Ok(None)
}
}
fn is_empty(&self) -> Result<bool, Error> {
let db_lock = self.db.read().unwrap();
let db = try!(db_lock.as_ref().ok_or(Error::IsClosed));
Ok(db.iterator(IteratorMode::Start).next().is_none())
}
fn iter(&self) -> Result<IteratorHandle, Error> {
let db_lock = self.db.read().unwrap();
let db = try!(db_lock.as_ref().ok_or(Error::IsClosed));
let mut iterators = self.iterators.write().unwrap();
let next_iterator = iterators.keys().last().unwrap_or(&0) + 1;
iterators.insert(next_iterator, db.iterator(IteratorMode::Start));
Ok(next_iterator)
}
fn iter_next(&self, handle: IteratorHandle) -> Option<KeyValue>
{
let mut iterators = self.iterators.write().unwrap();
let mut iterator = match iterators.get_mut(&handle) {
Some(some_iterator) => some_iterator,
None => { return None; },
};
iterator.next().and_then(|(some_key, some_val)| {
Some(KeyValue {
key: some_key.to_vec(),
value: some_val.to_vec(),
})
})
}
fn dispose_iter(&self, handle: IteratorHandle) -> Result<(), Error> {
let mut iterators = self.iterators.write().unwrap();
iterators.remove(&handle);
Ok(())
}
}
// TODO : put proper at compile-time
impl IpcConfig for Database {}
/// Database iterator
pub struct DatabaseIterator {
client: Arc<DatabaseClient<::nanomsg::Socket>>,
handle: IteratorHandle,
}
impl Iterator for DatabaseIterator {
type Item = (Vec<u8>, Vec<u8>);
fn next(&mut self) -> Option<Self::Item> {
self.client.iter_next(self.handle).and_then(|kv| Some((kv.key, kv.value)))
}
}
impl Drop for DatabaseIterator {
fn drop(&mut self) {
self.client.dispose_iter(self.handle).unwrap();
}
}
#[cfg(test)]
mod test {
use super::Database;
use traits::*;
use devtools::*;
#[test]
fn can_be_created() {
let db = Database::new();
assert!(db.is_empty().is_err());
}
#[test]
fn can_be_open_empty() {
let db = Database::new();
let path = RandomTempPath::create_dir();
db.open_default(path.as_str().to_owned()).unwrap();
assert!(db.is_empty().is_ok());
}
#[test]
fn can_store_key() {
let db = Database::new();
let path = RandomTempPath::create_dir();
db.open_default(path.as_str().to_owned()).unwrap();
db.put("xxx".as_bytes(), "1".as_bytes()).unwrap();
db.flush_all().unwrap();
assert!(!db.is_empty().unwrap());
}
#[test]
fn can_retrieve() {
let db = Database::new();
let path = RandomTempPath::create_dir();
db.open_default(path.as_str().to_owned()).unwrap();
db.put("xxx".as_bytes(), "1".as_bytes()).unwrap();
db.close().unwrap();
db.open_default(path.as_str().to_owned()).unwrap();
assert_eq!(db.get("xxx".as_bytes()).unwrap().unwrap(), "1".as_bytes().to_vec());
}
}
#[cfg(test)]
mod write_cache_tests {
use super::Database;
use traits::*;
use devtools::*;
#[test]
fn cache_write_flush() {
let db = Database::new();
let path = RandomTempPath::create_dir();
db.open_default(path.as_str().to_owned()).unwrap();
db.put("100500".as_bytes(), "1".as_bytes()).unwrap();
db.delete("100500".as_bytes()).unwrap();
db.flush_all().unwrap();
let val = db.get("100500".as_bytes()).unwrap();
assert!(val.is_none());
}
}
#[cfg(test)]
mod client_tests {
use super::{DatabaseClient, Database};
use traits::*;
use devtools::*;
use nanoipc;
use std::sync::Arc;
use std::sync::atomic::{Ordering, AtomicBool};
use crossbeam;
use run_worker;
fn init_worker(addr: &str) -> nanoipc::Worker<Database> {
let mut worker = nanoipc::Worker::<Database>::new(&Arc::new(Database::new()));
worker.add_duplex(addr).unwrap();
worker
}
#[test]
fn can_call_handshake() {
let url = "ipc:///tmp/parity-db-ipc-test-10.ipc";
let worker_should_exit = Arc::new(AtomicBool::new(false));
let worker_is_ready = Arc::new(AtomicBool::new(false));
let c_worker_should_exit = worker_should_exit.clone();
let c_worker_is_ready = worker_is_ready.clone();
::std::thread::spawn(move || {
let mut worker = init_worker(url);
while !c_worker_should_exit.load(Ordering::Relaxed) {
worker.poll();
c_worker_is_ready.store(true, Ordering::Relaxed);
}
});
while !worker_is_ready.load(Ordering::Relaxed) { }
let client = nanoipc::init_duplex_client::<DatabaseClient<_>>(url).unwrap();
let hs = client.handshake();
worker_should_exit.store(true, Ordering::Relaxed);
assert!(hs.is_ok());
}
#[test]
fn can_open_db() {
let url = "ipc:///tmp/parity-db-ipc-test-20.ipc";
let path = RandomTempPath::create_dir();
let worker_should_exit = Arc::new(AtomicBool::new(false));
let worker_is_ready = Arc::new(AtomicBool::new(false));
let c_worker_should_exit = worker_should_exit.clone();
let c_worker_is_ready = worker_is_ready.clone();
::std::thread::spawn(move || {
let mut worker = init_worker(url);
while !c_worker_should_exit.load(Ordering::Relaxed) {
worker.poll();
c_worker_is_ready.store(true, Ordering::Relaxed);
}
});
while !worker_is_ready.load(Ordering::Relaxed) { }
let client = nanoipc::init_duplex_client::<DatabaseClient<_>>(url).unwrap();
client.open_default(path.as_str().to_owned()).unwrap();
assert!(client.is_empty().unwrap());
worker_should_exit.store(true, Ordering::Relaxed);
}
#[test]
fn can_put() {
let url = "ipc:///tmp/parity-db-ipc-test-30.ipc";
let path = RandomTempPath::create_dir();
crossbeam::scope(move |scope| {
let stop = Arc::new(AtomicBool::new(false));
run_worker(scope, stop.clone(), url);
let client = nanoipc::init_client::<DatabaseClient<_>>(url).unwrap();
client.open_default(path.as_str().to_owned()).unwrap();
client.put("xxx".as_bytes(), "1".as_bytes()).unwrap();
client.close().unwrap();
stop.store(true, Ordering::Relaxed);
});
}
#[test]
fn can_put_and_read() {
let url = "ipc:///tmp/parity-db-ipc-test-40.ipc";
let path = RandomTempPath::create_dir();
crossbeam::scope(move |scope| {
let stop = Arc::new(AtomicBool::new(false));
run_worker(scope, stop.clone(), url);
let client = nanoipc::init_client::<DatabaseClient<_>>(url).unwrap();
client.open_default(path.as_str().to_owned()).unwrap();
client.put("xxx".as_bytes(), "1".as_bytes()).unwrap();
client.close().unwrap();
client.open_default(path.as_str().to_owned()).unwrap();
assert_eq!(client.get("xxx".as_bytes()).unwrap().unwrap(), "1".as_bytes().to_vec());
stop.store(true, Ordering::Relaxed);
});
}
#[test]
fn can_read_empty() {
let url = "ipc:///tmp/parity-db-ipc-test-45.ipc";
let path = RandomTempPath::create_dir();
crossbeam::scope(move |scope| {
let stop = Arc::new(AtomicBool::new(false));
run_worker(scope, stop.clone(), url);
let client = nanoipc::init_client::<DatabaseClient<_>>(url).unwrap();
client.open_default(path.as_str().to_owned()).unwrap();
assert!(client.get("xxx".as_bytes()).unwrap().is_none());
stop.store(true, Ordering::Relaxed);
});
}
#[test]
fn can_commit_client_transaction() {
let url = "ipc:///tmp/parity-db-ipc-test-60.ipc";
let path = RandomTempPath::create_dir();
crossbeam::scope(move |scope| {
let stop = Arc::new(AtomicBool::new(false));
run_worker(scope, stop.clone(), url);
let client = nanoipc::init_client::<DatabaseClient<_>>(url).unwrap();
client.open_default(path.as_str().to_owned()).unwrap();
let transaction = DBTransaction::new();
transaction.put("xxx".as_bytes(), "1".as_bytes());
client.write(transaction).unwrap();
client.close().unwrap();
client.open_default(path.as_str().to_owned()).unwrap();
assert_eq!(client.get("xxx".as_bytes()).unwrap().unwrap(), "1".as_bytes().to_vec());
stop.store(true, Ordering::Relaxed);
});
}
#[test]
fn key_write_read_ipc() {
let url = "ipc:///tmp/parity-db-ipc-test-70.ipc";
let path = RandomTempPath::create_dir();
crossbeam::scope(|scope| {
let stop = StopGuard::new();
run_worker(&scope, stop.share(), url);
let client = nanoipc::init_client::<DatabaseClient<_>>(url).unwrap();
client.open_default(path.as_str().to_owned()).unwrap();
let mut batch = Vec::new();
for _ in 0..100 {
batch.push((random_str(256).as_bytes().to_vec(), random_str(256).as_bytes().to_vec()));
batch.push((random_str(256).as_bytes().to_vec(), random_str(2048).as_bytes().to_vec()));
batch.push((random_str(2048).as_bytes().to_vec(), random_str(2048).as_bytes().to_vec()));
batch.push((random_str(2048).as_bytes().to_vec(), random_str(256).as_bytes().to_vec()));
}
for &(ref k, ref v) in batch.iter() {
client.put(k, v).unwrap();
}
client.close().unwrap();
client.open_default(path.as_str().to_owned()).unwrap();
for &(ref k, ref v) in batch.iter() {
assert_eq!(v, &client.get(k).unwrap().unwrap());
}
});
}
}

View File

@@ -1,20 +0,0 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Database ipc service
#![allow(dead_code, unused_assignments, unused_variables)] // codegen issues
include!(concat!(env!("OUT_DIR"), "/lib.rs"));

View File

@@ -1,89 +0,0 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
extern crate ethcore_ipc as ipc;
extern crate rocksdb;
extern crate ethcore_devtools as devtools;
extern crate semver;
extern crate ethcore_ipc_nano as nanoipc;
extern crate nanomsg;
extern crate crossbeam;
extern crate ethcore_util as util;
pub mod database;
pub mod traits;
pub use traits::{DatabaseService, DBTransaction, Error};
pub use database::{Database, DatabaseClient, DatabaseIterator};
use std::sync::Arc;
use std::sync::atomic::*;
use std::path::PathBuf;
pub type DatabaseNanoClient = DatabaseClient<::nanomsg::Socket>;
pub type DatabaseConnection = nanoipc::GuardedSocket<DatabaseNanoClient>;
#[derive(Debug)]
pub enum ServiceError {
Io(std::io::Error),
Socket(nanoipc::SocketError),
}
impl std::convert::From<std::io::Error> for ServiceError {
fn from(io_error: std::io::Error) -> ServiceError { ServiceError::Io(io_error) }
}
impl std::convert::From<nanoipc::SocketError> for ServiceError {
fn from(socket_error: nanoipc::SocketError) -> ServiceError { ServiceError::Socket(socket_error) }
}
pub fn blocks_service_url(db_path: &str) -> Result<String, std::io::Error> {
let mut path = PathBuf::from(db_path);
try!(::std::fs::create_dir_all(db_path));
path.push("blocks.ipc");
Ok(format!("ipc://{}", path.to_str().unwrap()))
}
pub fn extras_service_url(db_path: &str) -> Result<String, ::std::io::Error> {
let mut path = PathBuf::from(db_path);
try!(::std::fs::create_dir_all(db_path));
path.push("extras.ipc");
Ok(format!("ipc://{}", path.to_str().unwrap()))
}
pub fn blocks_client(db_path: &str) -> Result<DatabaseConnection, ServiceError> {
let url = try!(blocks_service_url(db_path));
let client = try!(nanoipc::init_client::<DatabaseClient<_>>(&url));
Ok(client)
}
pub fn extras_client(db_path: &str) -> Result<DatabaseConnection, ServiceError> {
let url = try!(extras_service_url(db_path));
let client = try!(nanoipc::init_client::<DatabaseClient<_>>(&url));
Ok(client)
}
// for tests
pub fn run_worker(scope: &crossbeam::Scope, stop: Arc<AtomicBool>, socket_path: &str) {
let socket_path = socket_path.to_owned();
scope.spawn(move || {
let mut worker = nanoipc::Worker::new(&Arc::new(Database::new()));
worker.add_reqrep(&socket_path).unwrap();
while !stop.load(Ordering::Relaxed) {
worker.poll();
}
});
}

View File

@@ -1,132 +0,0 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Ethcore database trait
use std::mem;
use ipc::binary::BinaryConvertError;
use std::collections::VecDeque;
use std::cell::RefCell;
pub type IteratorHandle = u32;
pub const DEFAULT_CACHE_LEN: usize = 12288;
#[derive(Binary)]
pub struct KeyValue {
pub key: Vec<u8>,
pub value: Vec<u8>,
}
#[derive(Debug, Binary)]
pub enum Error {
AlreadyOpen,
IsClosed,
RocksDb(String),
TransactionUnknown,
IteratorUnknown,
UncommitedTransactions,
}
/// Database configuration
#[derive(Binary)]
pub struct DatabaseConfig {
/// Optional prefix size in bytes. Allows lookup by partial key.
pub prefix_size: Option<usize>,
/// write cache length
pub cache: usize,
}
impl Default for DatabaseConfig {
fn default() -> DatabaseConfig {
DatabaseConfig {
prefix_size: None,
cache: DEFAULT_CACHE_LEN,
}
}
}
impl DatabaseConfig {
fn with_prefix(prefix: usize) -> DatabaseConfig {
DatabaseConfig {
prefix_size: Some(prefix),
cache: DEFAULT_CACHE_LEN,
}
}
}
pub trait DatabaseService : Sized {
/// Opens database in the specified path
fn open(&self, config: DatabaseConfig, path: String) -> Result<(), Error>;
/// Opens database in the specified path with the default config
fn open_default(&self, path: String) -> Result<(), Error>;
/// Closes database
fn close(&self) -> Result<(), Error>;
/// Insert a key-value pair in the transaction. Any existing value value will be overwritten.
fn put(&self, key: &[u8], value: &[u8]) -> Result<(), Error>;
/// Delete value by key.
fn delete(&self, key: &[u8]) -> Result<(), Error>;
/// Get value by key.
fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Error>;
/// Get value by partial key. Prefix size should match configured prefix size.
fn get_by_prefix(&self, prefix: &[u8]) -> Result<Option<Vec<u8>>, Error>;
/// Check if there is anything in the database.
fn is_empty(&self) -> Result<bool, Error>;
/// Get handle to iterate through keys
fn iter(&self) -> Result<IteratorHandle, Error>;
/// Next key-value for the the given iterator
fn iter_next(&self, iterator: IteratorHandle) -> Option<KeyValue>;
/// Dispose iteration that is no longer needed
fn dispose_iter(&self, handle: IteratorHandle) -> Result<(), Error>;
/// Write client transaction
fn write(&self, transaction: DBTransaction) -> Result<(), Error>;
}
#[derive(Binary)]
pub struct DBTransaction {
pub writes: RefCell<Vec<KeyValue>>,
pub removes: RefCell<Vec<Vec<u8>>>,
}
impl DBTransaction {
pub fn new() -> DBTransaction {
DBTransaction {
writes: RefCell::new(Vec::new()),
removes: RefCell::new(Vec::new()),
}
}
pub fn put(&self, key: &[u8], value: &[u8]) {
let mut brw = self.writes.borrow_mut();
brw.push(KeyValue { key: key.to_vec(), value: value.to_vec() });
}
pub fn delete(&self, key: &[u8]) {
let mut brw = self.removes.borrow_mut();
brw.push(key.to_vec());
}
}

View File

@@ -3,7 +3,7 @@ description = "Ethcore development/test/build tools"
homepage = "http://ethcore.io"
license = "GPL-3.0"
name = "ethcore-devtools"
version = "1.2.0"
version = "1.0.0"
authors = ["Ethcore <admin@ethcore.io>"]
[dependencies]

1
devtools/README.md Normal file
View File

@@ -0,0 +1 @@
# ethcore dev tools

View File

@@ -20,9 +20,5 @@
extern crate rand;
pub mod random_path;
pub mod test_socket;
pub mod stop_guard;
pub use random_path::*;
pub use test_socket::*;
pub use stop_guard::*;

View File

@@ -26,11 +26,7 @@ pub struct RandomTempPath {
}
pub fn random_filename() -> String {
random_str(8)
}
pub fn random_str(len: usize) -> String {
(0..len).map(|_| ((random::<f32>() * 26.0) as u8 + 97) as char).collect()
(0..8).map(|_| ((random::<f32>() * 26.0) as u8 + 97) as char).collect()
}
impl RandomTempPath {
@@ -58,18 +54,12 @@ impl RandomTempPath {
pub fn as_str(&self) -> &str {
self.path.to_str().unwrap()
}
pub fn new_in(&self, name: &str) -> String {
let mut path = self.path.clone();
path.push(name);
path.to_str().unwrap().to_owned()
}
}
impl Drop for RandomTempPath {
fn drop(&mut self) {
if let Err(e) = fs::remove_dir_all(self.as_path()) {
panic!("Failed to remove temp directory. Here's what prevented this from happening: ({})", e);
panic!("failed to remove temp directory, probably something failed to destroyed ({})", e);
}
}
}

View File

@@ -1,45 +0,0 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Stop guard mod
use std::sync::Arc;
use std::sync::atomic::*;
/// Stop guard that will set a stop flag on drop
pub struct StopGuard {
flag: Arc<AtomicBool>,
}
impl StopGuard {
/// Create a stop guard
pub fn new() -> StopGuard {
StopGuard {
flag: Arc::new(AtomicBool::new(false))
}
}
/// Share stop guard between the threads
pub fn share(&self) -> Arc<AtomicBool> {
self.flag.clone()
}
}
impl Drop for StopGuard {
fn drop(&mut self) {
self.flag.store(true, Ordering::Relaxed)
}
}

View File

@@ -1,94 +0,0 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::io::*;
use std::cmp;
pub struct TestSocket {
pub read_buffer: Vec<u8>,
pub write_buffer: Vec<u8>,
pub cursor: usize,
pub buf_size: usize,
}
impl Default for TestSocket {
fn default() -> Self {
TestSocket::new()
}
}
impl TestSocket {
pub fn new() -> Self {
TestSocket {
read_buffer: vec![],
write_buffer: vec![],
cursor: 0,
buf_size: 0,
}
}
pub fn new_buf(buf_size: usize) -> TestSocket {
TestSocket {
read_buffer: vec![],
write_buffer: vec![],
cursor: 0,
buf_size: buf_size,
}
}
pub fn new_ready(data: Vec<u8>) -> TestSocket {
TestSocket {
read_buffer: data,
write_buffer: vec![],
cursor: 0,
buf_size: 0,
}
}
}
impl Read for TestSocket {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let end_position = cmp::min(self.read_buffer.len(), self.cursor+buf.len());
let len = cmp::max(end_position - self.cursor, 0);
match len {
0 => Ok(0),
_ => {
for i in self.cursor..end_position {
buf[i-self.cursor] = self.read_buffer[i];
}
self.cursor = self.cursor + buf.len();
Ok(len)
}
}
}
}
impl Write for TestSocket {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
if self.buf_size == 0 || buf.len() < self.buf_size {
self.write_buffer.extend(buf.iter().cloned());
Ok(buf.len())
}
else {
self.write_buffer.extend(buf.iter().take(self.buf_size).cloned());
Ok(self.buf_size)
}
}
fn flush(&mut self) -> Result<()> {
unimplemented!();
}
}

5
doc.sh
View File

@@ -2,13 +2,10 @@
# generate documentation only for partiy and ethcore libraries
cargo doc --no-deps --verbose \
-p ethkey \
-p ethstore \
-p ethash \
-p ethcore-util \
-p ethcore \
-p ethsync \
-p ethcore-rpc \
-p ethcore-signer \
-p ethcore-dapps \
-p parity \
-p ethminer

View File

@@ -1,25 +0,0 @@
FROM centos:latest
WORKDIR /build
# install tools and dependencies
RUN yum -y update&& \
yum install -y git make gcc-c++ gcc file
# install rustup
RUN curl -sSf https://static.rust-lang.org/rustup.sh -o rustup.sh &&\
ls&&\
sh rustup.sh -s -- --disable-sudo
# show backtraces
ENV RUST_BACKTRACE 1
ENV CXX g++
ENV CC gcc
RUN rustc -vV && \
cargo -V && \
gcc -v &&\
g++ -v
# git clone parity
RUN git clone https://github.com/ethcore/parity && \
cd parity&&\
ls -a&&\
cargo build --release --verbose && \
ls /build/parity/target/release/parity && \
file /build/parity/target/release/parity && \
RUN file /build/parity/target/release/parity

View File

@@ -1,50 +0,0 @@
FROM ubuntu:14.04
WORKDIR /build
# install tools and dependencies
RUN apt-get -y update && \
apt-get install -y --force-yes --no-install-recommends \
curl git make g++ gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf \
libc6-dev-armhf-cross wget file ca-certificates \
binutils-arm-linux-gnueabihf \
&& \
apt-get clean
# install rustup
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y
# rustup directory
ENV PATH /root/.cargo/bin:$PATH
ENV RUST_TARGETS="arm-unknown-linux-gnueabihf"
# multirust add arm--linux-gnuabhf toolchain
RUN rustup target add stable arm-unknown-linux-gnueabihf
# show backtraces
ENV RUST_BACKTRACE 1
# set compilers
ENV CXX arm-linux-gnueabihf-g++
ENV CC arm-linux-gnueabihf-gcc
# build parity
RUN git clone https://github.com/ethcore/parity && \
cd parity && \
git checkout master && \
wget https://github.com/nix-rust/nix/archive/v0.5.0.tar.gz && \
tar -xf v0.5.0.tar.gz && \
rm -rf v0.5.0.tar.gz && \
wget https://github.com/thkaw/mio/archive/v0.5.x.tar.gz && \
tar -xf v0.5.x.tar.gz && \
rm -rf v0.5.x.tar.gz && \
mkdir -p .cargo && \
echo 'paths = ["nix-0.5.0","mio-0.5.x"]\n\
[target.arm-unknown-linux-gnueabihf]\n\
linker = "arm-linux-gnueabihf-gcc"\n'\
>>.cargo/config && \
cat .cargo/config && \
rustc -vV && \
cargo -V && \
cargo build --target arm-unknown-linux-gnueabihf --release --verbose && \
ls /build/parity/target/arm-unknown-linux-gnueabihf/release/parity && \
file /build/parity/target/arm-unknown-linux-gnueabihf/release/parity && \
/usr/bin/arm-linux-gnueabihf-strip /build/parity/target/arm-unknown-linux-gnueabihf/release/parity
RUN file /build/parity/target/arm-unknown-linux-gnueabihf/release/parity

View File

@@ -27,11 +27,11 @@ RUN git clone https://github.com/debris/evmjit && \
mkdir build && cd build && \
cmake .. && make && make install && cd
# install rustup
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y
# install multirust
RUN curl -sf https://raw.githubusercontent.com/brson/multirust/master/blastoff.sh | sh -s -- --yes
# rustup directory
ENV PATH /root/.cargo/bin:$PATH
# export rust LIBRARY_PATH
ENV LIBRARY_PATH /usr/local/lib
# show backtraces
ENV RUST_BACKTRACE 1

View File

@@ -27,11 +27,11 @@ RUN git clone https://github.com/debris/evmjit && \
mkdir build && cd build && \
cmake .. && make && make install && cd
# install rustup
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y
# install multirust
RUN curl -sf https://raw.githubusercontent.com/brson/multirust/master/blastoff.sh | sh -s -- --yes
# rustup directory
ENV PATH /root/.cargo/bin:$PATH
# export rust LIBRARY_PATH
ENV LIBRARY_PATH /usr/local/lib
# show backtraces
ENV RUST_BACKTRACE 1

View File

@@ -8,11 +8,11 @@ RUN apt-get update && \
git \
make
# install rustup
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y
# install multirust
RUN curl -sf https://raw.githubusercontent.com/brson/multirust/master/blastoff.sh | sh -s -- --yes
# rustup directory
ENV PATH /root/.cargo/bin:$PATH
# export rust LIBRARY_PATH
ENV LIBRARY_PATH /usr/local/lib
# show backtraces
ENV RUST_BACKTRACE 1

View File

@@ -1,6 +1,6 @@
[package]
name = "ethash"
version = "1.2.0"
version = "1.0.0"
authors = ["arkpar <arkadiy@ethcore.io"]
[lib]

View File

@@ -20,14 +20,12 @@
// TODO: fix endianess for big endian
use primal::is_prime;
use std::cell::Cell;
use std::sync::Mutex;
use std::mem;
use std::ptr;
use sha3;
use std::slice;
use std::path::PathBuf;
use std::io::{self, Read, Write};
use std::io::{Read, Write, self};
use std::fs::{self, File};
pub const ETHASH_EPOCH_LENGTH: u64 = 30000;
@@ -44,14 +42,14 @@ const NODE_WORDS: usize = 64 / 4;
const NODE_BYTES: usize = 64;
const MIX_WORDS: usize = ETHASH_MIX_BYTES / 4;
const MIX_NODES: usize = MIX_WORDS / NODE_WORDS;
const FNV_PRIME: u32 = 0x01000193;
const FNV_PRIME: u32 = 0x01000193;
/// Computation result
pub struct ProofOfWork {
/// Difficulty boundary
pub value: H256,
/// Mix
pub mix_hash: H256,
pub mix_hash: H256
}
struct Node {
@@ -87,7 +85,6 @@ pub type H256 = [u8; 32];
pub struct Light {
block_number: u64,
cache: Vec<Node>,
seed_compute: Mutex<SeedHashCompute>,
}
/// Light cache structur
@@ -104,17 +101,17 @@ impl Light {
light_compute(self, header_hash, nonce)
}
pub fn file_path(seed_hash: H256) -> PathBuf {
pub fn file_path(block_number: u64) -> PathBuf {
let mut home = ::std::env::home_dir().unwrap();
home.push(".ethash");
home.push("light");
let seed_hash = get_seedhash(block_number);
home.push(to_hex(&seed_hash));
home
}
pub fn from_file(block_number: u64) -> io::Result<Light> {
let seed_compute = SeedHashCompute::new();
let path = Light::file_path(seed_compute.get_seedhash(block_number));
let path = Light::file_path(block_number);
let mut file = try!(File::open(path));
let cache_size = get_cache_size(block_number);
@@ -129,13 +126,11 @@ impl Light {
Ok(Light {
cache: nodes,
block_number: block_number,
seed_compute: Mutex::new(seed_compute),
})
}
pub fn to_file(&self) -> io::Result<()> {
let seed_compute = self.seed_compute.lock().unwrap();
let path = Light::file_path(seed_compute.get_seedhash(self.block_number));
let path = Light::file_path(self.block_number);
try!(fs::create_dir_all(path.parent().unwrap()));
let mut file = try!(File::create(path));
@@ -146,51 +141,6 @@ impl Light {
}
}
pub struct SeedHashCompute {
prev_epoch: Cell<u64>,
prev_seedhash: Cell<H256>,
}
impl SeedHashCompute {
#[inline]
pub fn new() -> SeedHashCompute {
SeedHashCompute {
prev_epoch: Cell::new(0),
prev_seedhash: Cell::new([0u8; 32]),
}
}
#[inline]
fn reset_cache(&self) {
self.prev_epoch.set(0);
self.prev_seedhash.set([0u8; 32]);
}
#[inline]
pub fn get_seedhash(&self, block_number: u64) -> H256 {
let epoch = block_number / ETHASH_EPOCH_LENGTH;
if epoch < self.prev_epoch.get() {
// can't build on previous hash if requesting an older block
self.reset_cache();
}
if epoch > self.prev_epoch.get() {
let seed_hash = SeedHashCompute::resume_compute_seedhash(self.prev_seedhash.get(), self.prev_epoch.get(), epoch);
self.prev_seedhash.set(seed_hash);
self.prev_epoch.set(epoch);
}
self.prev_seedhash.get()
}
#[inline]
pub fn resume_compute_seedhash(mut hash: H256, start_epoch: u64, end_epoch: u64) -> H256 {
for _ in start_epoch..end_epoch {
unsafe { sha3::sha3_256(hash[..].as_mut_ptr(), 32, hash[..].as_ptr(), 32) };
}
hash
}
}
#[inline]
fn fnv_hash(x: u32, y: u32) -> u32 {
return x.wrapping_mul(FNV_PRIME) ^ y;
@@ -203,24 +153,34 @@ fn sha3_512(input: &[u8], output: &mut [u8]) {
#[inline]
fn get_cache_size(block_number: u64) -> usize {
let mut sz: u64 = CACHE_BYTES_INIT + CACHE_BYTES_GROWTH * (block_number / ETHASH_EPOCH_LENGTH);
sz = sz - NODE_BYTES as u64;
while !is_prime(sz / NODE_BYTES as u64) {
sz = sz - 2 * NODE_BYTES as u64;
}
sz as usize
let mut sz: u64 = CACHE_BYTES_INIT + CACHE_BYTES_GROWTH * (block_number / ETHASH_EPOCH_LENGTH);
sz = sz - NODE_BYTES as u64;
while !is_prime(sz / NODE_BYTES as u64) {
sz = sz - 2 * NODE_BYTES as u64;
}
sz as usize
}
#[inline]
fn get_data_size(block_number: u64) -> usize {
let mut sz: u64 = DATASET_BYTES_INIT + DATASET_BYTES_GROWTH * (block_number / ETHASH_EPOCH_LENGTH);
sz = sz - ETHASH_MIX_BYTES as u64;
while !is_prime(sz / ETHASH_MIX_BYTES as u64) {
sz = sz - 2 * ETHASH_MIX_BYTES as u64;
}
sz as usize
let mut sz: u64 = DATASET_BYTES_INIT + DATASET_BYTES_GROWTH * (block_number / ETHASH_EPOCH_LENGTH);
sz = sz - ETHASH_MIX_BYTES as u64;
while !is_prime(sz / ETHASH_MIX_BYTES as u64) {
sz = sz - 2 * ETHASH_MIX_BYTES as u64;
}
sz as usize
}
#[inline]
/// Given the `block_number`, determine the seed hash for Ethash.
pub fn get_seedhash(block_number: u64) -> H256 {
let epochs = block_number / ETHASH_EPOCH_LENGTH;
let mut ret: H256 = [0u8; 32];
for _ in 0..epochs {
unsafe { sha3::sha3_256(ret[..].as_mut_ptr(), 32, ret[..].as_ptr(), 32) };
}
ret
}
/// Difficulty quick check for POW preverification
///
@@ -251,12 +211,12 @@ pub fn light_compute(light: &Light, header_hash: &H256, nonce: u64) -> ProofOfWo
hash_compute(light, full_size, header_hash, nonce)
}
fn hash_compute(light: &Light, full_size: usize, header_hash: &H256, nonce: u64) -> ProofOfWork {
fn hash_compute(light: &Light, full_size: usize, header_hash: &H256, nonce: u64) -> ProofOfWork {
if full_size % MIX_WORDS != 0 {
panic!("Unaligned full size");
}
// pack hash and nonce together into first 40 bytes of s_mix
let mut s_mix: [Node; MIX_NODES + 1] = [Node::default(), Node::default(), Node::default()];
let mut s_mix: [Node; MIX_NODES + 1] = [ Node::default(), Node::default(), Node::default() ];
unsafe { ptr::copy_nonoverlapping(header_hash.as_ptr(), s_mix.get_unchecked_mut(0).bytes.as_mut_ptr(), 32) };
unsafe { ptr::copy_nonoverlapping(mem::transmute(&nonce), s_mix.get_unchecked_mut(0).bytes[32..].as_mut_ptr(), 8) };
@@ -297,7 +257,7 @@ fn hash_compute(light: &Light, full_size: usize, header_hash: &H256, nonce: u64)
ptr::copy_nonoverlapping(mix.get_unchecked_mut(0).bytes.as_ptr(), buf[64..].as_mut_ptr(), 32);
ptr::copy_nonoverlapping(mix.get_unchecked_mut(0).bytes.as_ptr(), mix_hash.as_mut_ptr(), 32);
let mut value: H256 = [0u8; 32];
sha3::sha3_256(value.as_mut_ptr(), value.len(), buf.as_ptr(), buf.len());
sha3::sha3_256(value.as_mut_ptr(), value.len(), buf.as_ptr(), buf.len());
ProofOfWork {
mix_hash: mix_hash,
value: value,
@@ -327,9 +287,7 @@ fn calculate_dag_item(node_index: u32, light: &Light) -> Node {
}
fn light_new(block_number: u64) -> Light {
let seed_compute = SeedHashCompute::new();
let seedhash = seed_compute.get_seedhash(block_number);
let seedhash = get_seedhash(block_number);
let cache_size = get_cache_size(block_number);
if cache_size % NODE_BYTES != 0 {
@@ -350,7 +308,7 @@ fn light_new(block_number: u64) -> Light {
let idx = *nodes.get_unchecked_mut(i).as_words().get_unchecked(0) as usize % num_nodes;
let mut data = nodes.get_unchecked((num_nodes - 1 + i) % num_nodes).clone();
for w in 0..NODE_WORDS {
*data.as_words_mut().get_unchecked_mut(w) ^= *nodes.get_unchecked(idx).as_words().get_unchecked(w);
*data.as_words_mut().get_unchecked_mut(w) ^= *nodes.get_unchecked(idx).as_words().get_unchecked(w) ;
}
sha3_512(&data.bytes, &mut nodes.get_unchecked_mut(i).bytes);
}
@@ -360,11 +318,10 @@ fn light_new(block_number: u64) -> Light {
Light {
cache: nodes,
block_number: block_number,
seed_compute: Mutex::new(seed_compute),
}
}
static CHARS: &'static [u8] = b"0123456789abcdef";
static CHARS: &'static[u8] = b"0123456789abcdef";
fn to_hex(bytes: &[u8]) -> String {
let mut v = Vec::with_capacity(bytes.len() * 2);
for &byte in bytes.iter() {
@@ -372,7 +329,9 @@ fn to_hex(bytes: &[u8]) -> String {
v.push(CHARS[(byte & 0xf) as usize]);
}
unsafe { String::from_utf8_unchecked(v) }
unsafe {
String::from_utf8_unchecked(v)
}
}
#[test]
@@ -402,8 +361,8 @@ fn test_get_data_size() {
#[test]
fn test_difficulty_test() {
let hash = [0xf5, 0x7e, 0x6f, 0x3a, 0xcf, 0xc0, 0xdd, 0x4b, 0x5b, 0xf2, 0xbe, 0xe4, 0x0a, 0xb3, 0x35, 0x8a, 0xa6, 0x87, 0x73, 0xa8, 0xd0, 0x9f, 0x5e, 0x59, 0x5e, 0xab, 0x55, 0x94, 0x05, 0x52, 0x7d, 0x72];
let mix_hash = [0x1f, 0xff, 0x04, 0xce, 0xc9, 0x41, 0x73, 0xfd, 0x59, 0x1e, 0x3d, 0x89, 0x60, 0xce, 0x6b, 0xdf, 0x8b, 0x19, 0x71, 0x04, 0x8c, 0x71, 0xff, 0x93, 0x7b, 0xb2, 0xd3, 0x2a, 0x64, 0x31, 0xab, 0x6d];
let hash = [0xf5, 0x7e, 0x6f, 0x3a, 0xcf, 0xc0, 0xdd, 0x4b, 0x5b, 0xf2, 0xbe, 0xe4, 0x0a, 0xb3, 0x35, 0x8a, 0xa6, 0x87, 0x73, 0xa8, 0xd0, 0x9f, 0x5e, 0x59, 0x5e, 0xab, 0x55, 0x94, 0x05, 0x52, 0x7d, 0x72];
let mix_hash = [0x1f, 0xff, 0x04, 0xce, 0xc9, 0x41, 0x73, 0xfd, 0x59, 0x1e, 0x3d, 0x89, 0x60, 0xce, 0x6b, 0xdf, 0x8b, 0x19, 0x71, 0x04, 0x8c, 0x71, 0xff, 0x93, 0x7b, 0xb2, 0xd3, 0x2a, 0x64, 0x31, 0xab, 0x6d ];
let nonce = 0xd7b3ac70a301a249;
let boundary_good = [0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3e, 0x9b, 0x6c, 0x69, 0xbc, 0x2c, 0xe2, 0xa2, 0x4a, 0x8e, 0x95, 0x69, 0xef, 0xc7, 0xd7, 0x1b, 0x33, 0x35, 0xdf, 0x36, 0x8c, 0x9a, 0xe9, 0x7e, 0x53, 0x84];
assert_eq!(quick_get_difficulty(&hash, nonce, &mix_hash)[..], boundary_good[..]);
@@ -413,8 +372,8 @@ fn test_difficulty_test() {
#[test]
fn test_light_compute() {
let hash = [0xf5, 0x7e, 0x6f, 0x3a, 0xcf, 0xc0, 0xdd, 0x4b, 0x5b, 0xf2, 0xbe, 0xe4, 0x0a, 0xb3, 0x35, 0x8a, 0xa6, 0x87, 0x73, 0xa8, 0xd0, 0x9f, 0x5e, 0x59, 0x5e, 0xab, 0x55, 0x94, 0x05, 0x52, 0x7d, 0x72];
let mix_hash = [0x1f, 0xff, 0x04, 0xce, 0xc9, 0x41, 0x73, 0xfd, 0x59, 0x1e, 0x3d, 0x89, 0x60, 0xce, 0x6b, 0xdf, 0x8b, 0x19, 0x71, 0x04, 0x8c, 0x71, 0xff, 0x93, 0x7b, 0xb2, 0xd3, 0x2a, 0x64, 0x31, 0xab, 0x6d];
let hash = [0xf5, 0x7e, 0x6f, 0x3a, 0xcf, 0xc0, 0xdd, 0x4b, 0x5b, 0xf2, 0xbe, 0xe4, 0x0a, 0xb3, 0x35, 0x8a, 0xa6, 0x87, 0x73, 0xa8, 0xd0, 0x9f, 0x5e, 0x59, 0x5e, 0xab, 0x55, 0x94, 0x05, 0x52, 0x7d, 0x72];
let mix_hash = [0x1f, 0xff, 0x04, 0xce, 0xc9, 0x41, 0x73, 0xfd, 0x59, 0x1e, 0x3d, 0x89, 0x60, 0xce, 0x6b, 0xdf, 0x8b, 0x19, 0x71, 0x04, 0x8c, 0x71, 0xff, 0x93, 0x7b, 0xb2, 0xd3, 0x2a, 0x64, 0x31, 0xab, 0x6d ];
let boundary = [0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3e, 0x9b, 0x6c, 0x69, 0xbc, 0x2c, 0xe2, 0xa2, 0x4a, 0x8e, 0x95, 0x69, 0xef, 0xc7, 0xd7, 0x1b, 0x33, 0x35, 0xdf, 0x36, 0x8c, 0x9a, 0xe9, 0x7e, 0x53, 0x84];
let nonce = 0xd7b3ac70a301a249;
// difficulty = 0x085657254bd9u64;
@@ -423,34 +382,3 @@ fn test_light_compute() {
assert_eq!(result.mix_hash[..], mix_hash[..]);
assert_eq!(result.value[..], boundary[..]);
}
#[test]
fn test_seed_compute_once() {
let seed_compute = SeedHashCompute::new();
let hash = [241, 175, 44, 134, 39, 121, 245, 239, 228, 236, 43, 160, 195, 152, 46, 7, 199, 5, 253, 147, 241, 206, 98, 43, 3, 104, 17, 40, 192, 79, 106, 162];
assert_eq!(seed_compute.get_seedhash(486382), hash);
}
#[test]
fn test_seed_compute_zero() {
let seed_compute = SeedHashCompute::new();
assert_eq!(seed_compute.get_seedhash(0), [0u8; 32]);
}
#[test]
fn test_seed_compute_after_older() {
let seed_compute = SeedHashCompute::new();
// calculating an older value first shouldn't affect the result
let _ = seed_compute.get_seedhash(50000);
let hash = [241, 175, 44, 134, 39, 121, 245, 239, 228, 236, 43, 160, 195, 152, 46, 7, 199, 5, 253, 147, 241, 206, 98, 43, 3, 104, 17, 40, 192, 79, 106, 162];
assert_eq!(seed_compute.get_seedhash(486382), hash);
}
#[test]
fn test_seed_compute_after_newer() {
let seed_compute = SeedHashCompute::new();
// calculating an newer value first shouldn't affect the result
let _ = seed_compute.get_seedhash(972764);
let hash = [241, 175, 44, 134, 39, 121, 245, 239, 228, 236, 43, 160, 195, 152, 46, 7, 199, 5, 253, 147, 241, 206, 98, 43, 3, 104, 17, 40, 192, 79, 106, 162];
assert_eq!(seed_compute.get_seedhash(486382), hash);
}

View File

@@ -24,7 +24,7 @@ mod compute;
use std::mem;
use compute::Light;
pub use compute::{ETHASH_EPOCH_LENGTH, H256, ProofOfWork, SeedHashCompute, quick_get_difficulty};
pub use compute::{get_seedhash, quick_get_difficulty, H256, ProofOfWork, ETHASH_EPOCH_LENGTH};
use std::sync::{Arc, Mutex};
@@ -76,7 +76,7 @@ impl EthashManager {
lights.recent.clone()
}
_ => None,
},
}
};
match light {
None => {
@@ -95,7 +95,7 @@ impl EthashManager {
lights.prev = mem::replace(&mut lights.recent, Some(light.clone()));
light
}
Some(light) => light,
Some(light) => light
}
};
light.compute(header_hash, nonce)

View File

@@ -3,13 +3,8 @@ description = "Ethcore library"
homepage = "http://ethcore.io"
license = "GPL-3.0"
name = "ethcore"
version = "1.2.0"
version = "1.0.2"
authors = ["Ethcore <admin@ethcore.io>"]
build = "build.rs"
[build-dependencies]
syntex = "*"
"ethcore-ipc-codegen" = { path = "../ipc/codegen" }
[dependencies]
log = "0.3"
@@ -22,15 +17,11 @@ ethcore-util = { path = "../util" }
evmjit = { path = "../evmjit", optional = true }
ethash = { path = "../ethash" }
num_cpus = "0.2"
clippy = { version = "0.0.77", optional = true}
crossbeam = "0.2.9"
lazy_static = "0.2"
clippy = { version = "0.0.54", optional = true }
crossbeam = "0.1.5"
lazy_static = "0.1"
ethcore-devtools = { path = "../devtools" }
ethjson = { path = "../json" }
bloomchain = "0.1"
"ethcore-ipc" = { path = "../ipc/rpc" }
rayon = "0.3.1"
ethstore = { path = "../ethstore" }
[features]
jit = ["evmjit"]

View File

@@ -1,33 +0,0 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
extern crate syntex;
extern crate ethcore_ipc_codegen as codegen;
use std::env;
use std::path::Path;
fn main() {
let out_dir = env::var_os("OUT_DIR").unwrap();
// serialization pass
{
let src = Path::new("src/types/mod.rs.in");
let dst = Path::new(&out_dir).join("types.rs");
let mut registry = syntex::Registry::new();
codegen::register(&mut registry);
registry.expand("", &src, &dst).unwrap();
}
}

View File

@@ -1,33 +1,24 @@
{
"name": "Frontier/Homestead",
"engine": {
"Ethash": {
"params": {
"gasLimitBoundDivisor": "0x0400",
"minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"frontierCompatibilityModeLimit": "0x118c30",
"daoRescueSoftFork": false
}
}
},
"engineName": "Ethash",
"params": {
"accountStartNonce": "0x00",
"frontierCompatibilityModeLimit": "0x118c30",
"maximumExtraDataSize": "0x20",
"tieBreakingGas": false,
"minGasLimit": "0x1388",
"gasLimitBoundDivisor": "0x0400",
"minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"networkID" : "0x1"
},
"genesis": {
"seal": {
"ethereum": {
"nonce": "0x0000000000000042",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
},
"nonce": "0x0000000000000042",
"difficulty": "0x400000000",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"author": "0x0000000000000000000000000000000000000000",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",

File diff suppressed because it is too large Load Diff

View File

@@ -1,33 +1,24 @@
{
"name": "Frontier (Test)",
"engine": {
"Ethash": {
"params": {
"gasLimitBoundDivisor": "0x0400",
"minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"frontierCompatibilityModeLimit": "0x118c30",
"daoRescueSoftFork": false
}
}
},
"engineName": "Ethash",
"params": {
"accountStartNonce": "0x00",
"frontierCompatibilityModeLimit": "0x118c30",
"maximumExtraDataSize": "0x20",
"tieBreakingGas": false,
"minGasLimit": "0x1388",
"gasLimitBoundDivisor": "0x0400",
"minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"networkID" : "0x1"
},
"genesis": {
"seal": {
"ethereum": {
"nonce": "0x0000000000000042",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
},
"nonce": "0x0000000000000042",
"difficulty": "0x400000000",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"author": "0x0000000000000000000000000000000000000000",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",

View File

@@ -1,43 +0,0 @@
{
"name": "Frontier (Test)",
"engine": {
"Ethash": {
"params": {
"gasLimitBoundDivisor": "0x0400",
"minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"frontierCompatibilityModeLimit": "0x118c30",
"daoRescueSoftFork": true
}
}
},
"params": {
"accountStartNonce": "0x00",
"maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388",
"networkID" : "0x1"
},
"genesis": {
"seal": {
"ethereum": {
"nonce": "0x0000000000000042",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
},
"difficulty": "0x400000000",
"author": "0x0000000000000000000000000000000000000000",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa",
"gasLimit": "0x1388"
},
"accounts": {
"0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
"0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
"0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
"0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }
}
}

View File

@@ -1,33 +1,24 @@
{
"name": "Frontier (Test)",
"engine": {
"Ethash": {
"params": {
"gasLimitBoundDivisor": "0x0400",
"minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"frontierCompatibilityModeLimit": "0xffffffffffffffff",
"daoRescueSoftFork": false
}
}
},
"engineName": "Ethash",
"params": {
"accountStartNonce": "0x00",
"frontierCompatibilityModeLimit": "0xffffffffffffffff",
"maximumExtraDataSize": "0x20",
"tieBreakingGas": false,
"minGasLimit": "0x1388",
"gasLimitBoundDivisor": "0x0400",
"minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"networkID" : "0x1"
},
"genesis": {
"seal": {
"ethereum": {
"nonce": "0x0000000000000042",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
},
"nonce": "0x0000000000000042",
"difficulty": "0x400000000",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"author": "0x0000000000000000000000000000000000000000",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",

View File

@@ -1,33 +1,24 @@
{
"name": "Homestead (Test)",
"engine": {
"Ethash": {
"params": {
"gasLimitBoundDivisor": "0x0400",
"minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"frontierCompatibilityModeLimit": 0,
"daoRescueSoftFork": false
}
}
},
"engineName": "Ethash",
"params": {
"accountStartNonce": "0x00",
"frontierCompatibilityModeLimit": 0,
"maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388",
"tieBreakingGas": false,
"gasLimitBoundDivisor": "0x0400",
"minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"networkID" : "0x1"
},
"genesis": {
"seal": {
"ethereum": {
"nonce": "0x0000000000000042",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
},
"nonce": "0x0000000000000042",
"difficulty": "0x400000000",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"author": "0x0000000000000000000000000000000000000000",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",

View File

@@ -1,43 +0,0 @@
{
"name": "Homestead (Test)",
"engine": {
"Ethash": {
"params": {
"gasLimitBoundDivisor": "0x0400",
"minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"frontierCompatibilityModeLimit": 0,
"daoRescueSoftFork": true
}
}
},
"params": {
"accountStartNonce": "0x00",
"maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388",
"networkID" : "0x1"
},
"genesis": {
"seal": {
"ethereum": {
"nonce": "0x0000000000000042",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
},
"difficulty": "0x400000000",
"author": "0x0000000000000000000000000000000000000000",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa",
"gasLimit": "0x1388"
},
"accounts": {
"0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
"0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
"0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
"0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }
}
}

View File

@@ -1,33 +1,24 @@
{
"name": "Morden",
"engine": {
"Ethash": {
"params": {
"gasLimitBoundDivisor": "0x0400",
"minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar": "",
"frontierCompatibilityModeLimit": "0x789b0",
"daoRescueSoftFork": false
}
}
},
"engineName": "Ethash",
"params": {
"accountStartNonce": "0x0100000",
"frontierCompatibilityModeLimit": "0x789b0",
"maximumExtraDataSize": "0x20",
"tieBreakingGas": false,
"minGasLimit": "0x1388",
"gasLimitBoundDivisor": "0x0400",
"minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar": "",
"networkID" : "0x2"
},
"genesis": {
"seal": {
"ethereum": {
"nonce": "0x00006d6f7264656e",
"mixHash": "0x00000000000000000000000000000000000000647572616c65787365646c6578"
}
},
"nonce": "0x00006d6f7264656e",
"difficulty": "0x20000",
"mixHash": "0x00000000000000000000000000000000000000647572616c65787365646c6578",
"author": "0x0000000000000000000000000000000000000000",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
@@ -35,8 +26,7 @@
"gasLimit": "0x2fefd8"
},
"nodes": [
"enode://e731347db0521f3476e6bbbb83375dcd7133a1601425ebd15fd10f3835fd4c304fba6282087ca5a0deeafadf0aa0d4fd56c3323331901c1f38bd181c283e3e35@128.199.55.137:30303",
"enode://ceb5c0f85eb994dbe9693bf46d99b03f6b838d17cc74e68d5eb003171ff39e5f120b17f965b267c319303f94d80b9d994b77062fb1486d76ce95d9f3d8fe1cb4@46.101.122.141:30303"
"enode://b1217cbaa440e35ed471157123fe468e19e8b5ad5bedb4b1fdbcbdab6fb2f5ed3e95dd9c24a22a79fdb2352204cea207df27d92bfd21bfd41545e8b16f637499@104.44.138.37:30303"
],
"accounts": {
"0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },

View File

@@ -1,33 +1,24 @@
{
"name": "Olympic",
"engine": {
"Ethash": {
"params": {
"gasLimitBoundDivisor": "0x0400",
"minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800",
"durationLimit": "0x08",
"blockReward": "0x14D1120D7B160000",
"registrar": "5e70c0bbcd5636e0f9f9316e9f8633feb64d4050",
"frontierCompatibilityModeLimit": "0xffffffffffffffff",
"daoRescueSoftFork": false
}
}
},
"engineName": "Ethash",
"params": {
"accountStartNonce": "0x00",
"frontierCompatibilityModeLimit": "0xffffffffffffffff",
"maximumExtraDataSize": "0x0400",
"tieBreakingGas": false,
"minGasLimit": "125000",
"gasLimitBoundDivisor": "0x0400",
"minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800",
"durationLimit": "0x08",
"blockReward": "0x14D1120D7B160000",
"registrar": "5e70c0bbcd5636e0f9f9316e9f8633feb64d4050",
"networkID" : "0x0"
},
"genesis": {
"seal": {
"ethereum": {
"nonce": "0x000000000000002a",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
},
"nonce": "0x000000000000002a",
"difficulty": "0x20000",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"author": "0x0000000000000000000000000000000000000000",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",

View File

@@ -1,33 +0,0 @@
{
"name": "Morden",
"engine": {
"Null": null
},
"params": {
"accountStartNonce": "0x0",
"maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388",
"networkID" : "0x2"
},
"genesis": {
"seal": {
"ethereum": {
"nonce": "0x00006d6f7264656e",
"mixHash": "0x00000000000000000000000000000000000000647572616c65787365646c6578"
}
},
"difficulty": "0x20000",
"author": "0x0000000000000000000000000000000000000000",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x",
"gasLimit": "0x2fefd8"
},
"accounts": {
"0000000000000000000000000000000000000001": { "balance": "1", "nonce": "0", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
"0000000000000000000000000000000000000002": { "balance": "1", "nonce": "0", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
"0000000000000000000000000000000000000003": { "balance": "1", "nonce": "0", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
"0000000000000000000000000000000000000004": { "balance": "1", "nonce": "0", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
"9cce34f7ab185c7aba1b7c8140d620b4bda941d6": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "0" }
}
}

View File

@@ -1,22 +1,24 @@
{
"name": "Morden",
"engine": {
"Null": null
},
"engineName": "NullEngine",
"params": {
"accountStartNonce": "0x0100000",
"frontierCompatibilityModeLimit": "0xfffa2990",
"maximumExtraDataSize": "0x20",
"tieBreakingGas": false,
"minGasLimit": "0x1388",
"gasLimitBoundDivisor": "0x0400",
"minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar": "",
"networkID" : "0x2"
},
"genesis": {
"seal": {
"ethereum": {
"nonce": "0x00006d6f7264656e",
"mixHash": "0x00000000000000000000000000000000000000647572616c65787365646c6578"
}
},
"nonce": "0x00006d6f7264656e",
"difficulty": "0x20000",
"mixHash": "0x00000000000000000000000000000000000000647572616c65787365646c6578",
"author": "0x0000000000000000000000000000000000000000",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",

View File

@@ -1,39 +0,0 @@
{
"name": "TestAuthority",
"engine": {
"BasicAuthority": {
"params": {
"gasLimitBoundDivisor": "0x0400",
"durationLimit": "0x0d",
"authorities" : ["0x9cce34f7ab185c7aba1b7c8140d620b4bda941d6"]
}
}
},
"params": {
"accountStartNonce": "0x0100000",
"maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388",
"networkID" : "0x69"
},
"genesis": {
"seal": {
"generic": {
"fields": 1,
"rlp": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa"
}
},
"difficulty": "0x20000",
"author": "0x0000000000000000000000000000000000000000",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x",
"gasLimit": "0x2fefd8"
},
"accounts": {
"0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
"0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
"0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
"0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
"9cce34f7ab185c7aba1b7c8140d620b4bda941d6": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" }
}
}

View File

@@ -51,6 +51,8 @@ impl Account {
}
}
#[cfg(test)]
#[cfg(feature = "json-tests")]
/// General constructor.
pub fn from_pod(pod: PodAccount) -> Account {
Account {
@@ -116,12 +118,7 @@ impl Account {
/// Get (and cache) the contents of the trie's storage at `key`.
pub fn storage_at(&self, db: &AccountDB, key: &H256) -> H256 {
self.storage_overlay.borrow_mut().entry(key.clone()).or_insert_with(||{
let db = SecTrieDB::new(db, &self.storage_root)
.expect("Account storage_root initially set to zero (valid) and only altered by SecTrieDBMut. \
SecTrieDBMut would not set it to an invalid state root. Therefore the root is valid and DB creation \
using it will not fail.");
(Filth::Clean, H256::from(db.get(key.bytes()).map_or(U256::zero(), |v| -> U256 {decode(v)})))
(Filth::Clean, H256::from(SecTrieDB::new(db, &self.storage_root).get(key.bytes()).map_or(U256::zero(), |v| -> U256 {decode(v)})))
}).1.clone()
}
@@ -141,7 +138,7 @@ impl Account {
/// get someone who knows to call `note_code`.
pub fn code(&self) -> Option<&[u8]> {
match self.code_hash {
Some(c) if c == SHA3_EMPTY && self.code_cache.is_empty() => Some(&self.code_cache),
Some(c) if c == SHA3_EMPTY && self.code_cache.is_empty() => Some(&self.code_cache),
Some(_) if !self.code_cache.is_empty() => Some(&self.code_cache),
None => Some(&self.code_cache),
_ => None,
@@ -166,16 +163,16 @@ impl Account {
!self.code_cache.is_empty() || (self.code_cache.is_empty() && self.code_hash == Some(SHA3_EMPTY))
}
/// Provide a database to get `code_hash`. Should not be called if it is a contract without code.
/// Provide a database to lookup `code_hash`. Should not be called if it is a contract without code.
pub fn cache_code(&mut self, db: &AccountDB) -> bool {
// TODO: fill out self.code_cache;
trace!("Account::cache_code: ic={}; self.code_hash={:?}, self.code_cache={}", self.is_cached(), self.code_hash, self.code_cache.pretty());
self.is_cached() ||
match self.code_hash {
Some(ref h) => match db.get(h) {
Some(ref h) => match db.lookup(h) {
Some(x) => { self.code_cache = x.to_vec(); true },
_ => {
warn!("Failed reverse get of {}", h);
warn!("Failed reverse lookup of {}", h);
false
},
},
@@ -209,10 +206,7 @@ impl Account {
/// Commit the `storage_overlay` to the backing DB and update `storage_root`.
pub fn commit_storage(&mut self, db: &mut AccountDBMut) {
let mut t = SecTrieDBMut::from_existing(db, &mut self.storage_root)
.expect("Account storage_root initially set to zero (valid) and only altered by SecTrieDBMut. \
SecTrieDBMut would not set it to an invalid state root. Therefore the root is valid and DB creation \
using it will not fail.");
let mut t = SecTrieDBMut::from_existing(db, &mut self.storage_root);
for (k, &mut (ref mut f, ref mut v)) in self.storage_overlay.borrow_mut().iter_mut() {
if f == &Filth::Dirty {
// cast key and value to trait type,
@@ -267,7 +261,7 @@ mod tests {
let mut db = MemoryDB::new();
let mut db = AccountDBMut::new(&mut db, &Address::new());
let rlp = {
let mut a = Account::new_contract(69.into(), 0.into());
let mut a = Account::new_contract(x!(69), x!(0));
a.set_storage(H256::from(&U256::from(0x00u64)), H256::from(&U256::from(0x1234u64)));
a.commit_storage(&mut db);
a.init_code(vec![]);
@@ -287,7 +281,7 @@ mod tests {
let mut db = AccountDBMut::new(&mut db, &Address::new());
let rlp = {
let mut a = Account::new_contract(69.into(), 0.into());
let mut a = Account::new_contract(x!(69), x!(0));
a.init_code(vec![0x55, 0x44, 0xffu8]);
a.commit_code(&mut db);
a.rlp()
@@ -302,10 +296,10 @@ mod tests {
#[test]
fn commit_storage() {
let mut a = Account::new_contract(69.into(), 0.into());
let mut a = Account::new_contract(x!(69), x!(0));
let mut db = MemoryDB::new();
let mut db = AccountDBMut::new(&mut db, &Address::new());
a.set_storage(0.into(), 0x1234.into());
a.set_storage(x!(0), x!(0x1234));
assert_eq!(a.storage_root(), None);
a.commit_storage(&mut db);
assert_eq!(a.storage_root().unwrap().hex(), "c57e1afb758b07f8d2c8f13a3b6e44fa5ff94ab266facc5a4fd3f062426e50b2");
@@ -313,21 +307,21 @@ mod tests {
#[test]
fn commit_remove_commit_storage() {
let mut a = Account::new_contract(69.into(), 0.into());
let mut a = Account::new_contract(x!(69), x!(0));
let mut db = MemoryDB::new();
let mut db = AccountDBMut::new(&mut db, &Address::new());
a.set_storage(0.into(), 0x1234.into());
a.set_storage(x!(0), x!(0x1234));
a.commit_storage(&mut db);
a.set_storage(1.into(), 0x1234.into());
a.set_storage(x!(1), x!(0x1234));
a.commit_storage(&mut db);
a.set_storage(1.into(), 0.into());
a.set_storage(x!(1), x!(0));
a.commit_storage(&mut db);
assert_eq!(a.storage_root().unwrap().hex(), "c57e1afb758b07f8d2c8f13a3b6e44fa5ff94ab266facc5a4fd3f062426e50b2");
}
#[test]
fn commit_code() {
let mut a = Account::new_contract(69.into(), 0.into());
let mut a = Account::new_contract(x!(69), x!(0));
let mut db = MemoryDB::new();
let mut db = AccountDBMut::new(&mut db, &Address::new());
a.init_code(vec![0x55, 0x44, 0xffu8]);
@@ -348,6 +342,7 @@ mod tests {
#[test]
fn new_account() {
use rustc_serialize::hex::ToHex;
let a = Account::new(U256::from(69u8), U256::from(0u8), HashMap::new(), Bytes::new());
assert_eq!(a.rlp().to_hex(), "f8448045a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470");
@@ -359,6 +354,7 @@ mod tests {
#[test]
fn create_account() {
use rustc_serialize::hex::ToHex;
let a = Account::new(U256::from(69u8), U256::from(0u8), HashMap::new(), Bytes::new());
assert_eq!(a.rlp().to_hex(), "f8448045a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470");

View File

@@ -20,7 +20,7 @@ impl<'db> AccountDB<'db> {
pub fn new(db: &'db HashDB, address: &Address) -> AccountDB<'db> {
AccountDB {
db: db,
address: address.into(),
address: x!(address),
}
}
}
@@ -30,18 +30,18 @@ impl<'db> HashDB for AccountDB<'db>{
unimplemented!()
}
fn get(&self, key: &H256) -> Option<&[u8]> {
fn lookup(&self, key: &H256) -> Option<&[u8]> {
if key == &SHA3_NULL_RLP {
return Some(&NULL_RLP_STATIC);
}
self.db.get(&combine_key(&self.address, key))
self.db.lookup(&combine_key(&self.address, key))
}
fn contains(&self, key: &H256) -> bool {
fn exists(&self, key: &H256) -> bool {
if key == &SHA3_NULL_RLP {
return true;
}
self.db.contains(&combine_key(&self.address, key))
self.db.exists(&combine_key(&self.address, key))
}
fn insert(&mut self, _value: &[u8]) -> H256 {
@@ -52,7 +52,7 @@ impl<'db> HashDB for AccountDB<'db>{
unimplemented!()
}
fn remove(&mut self, _key: &H256) {
fn kill(&mut self, _key: &H256) {
unimplemented!()
}
}
@@ -67,7 +67,7 @@ impl<'db> AccountDBMut<'db> {
pub fn new(db: &'db mut HashDB, address: &Address) -> AccountDBMut<'db> {
AccountDBMut {
db: db,
address: address.into(),
address: x!(address),
}
}
@@ -82,18 +82,18 @@ impl<'db> HashDB for AccountDBMut<'db>{
unimplemented!()
}
fn get(&self, key: &H256) -> Option<&[u8]> {
fn lookup(&self, key: &H256) -> Option<&[u8]> {
if key == &SHA3_NULL_RLP {
return Some(&NULL_RLP_STATIC);
}
self.db.get(&combine_key(&self.address, key))
self.db.lookup(&combine_key(&self.address, key))
}
fn contains(&self, key: &H256) -> bool {
fn exists(&self, key: &H256) -> bool {
if key == &SHA3_NULL_RLP {
return true;
}
self.db.contains(&combine_key(&self.address, key))
self.db.exists(&combine_key(&self.address, key))
}
fn insert(&mut self, value: &[u8]) -> H256 {
@@ -114,12 +114,12 @@ impl<'db> HashDB for AccountDBMut<'db>{
self.db.emplace(key, value.to_vec())
}
fn remove(&mut self, key: &H256) {
fn kill(&mut self, key: &H256) {
if key == &SHA3_NULL_RLP {
return;
}
let key = combine_key(&self.address, key);
self.db.remove(&key)
self.db.kill(&key)
}
}

View File

@@ -17,48 +17,10 @@
//! Diff between two accounts.
use util::*;
#[cfg(test)]
use pod_account::*;
#[derive(Debug, PartialEq, Eq, Clone)]
/// Diff type for specifying a change (or not).
pub enum Diff<T> where T: Eq {
/// Both sides are the same.
Same,
/// Left (pre, source) side doesn't include value, right side (post, destination) does.
Born(T),
/// Both sides include data; it chaged value between them.
Changed(T, T),
/// Left (pre, source) side does include value, right side (post, destination) does not.
Died(T),
}
impl<T> Diff<T> where T: Eq {
/// Construct new object with given `pre` and `post`.
pub fn new(pre: T, post: T) -> Self { if pre == post { Diff::Same } else { Diff::Changed(pre, post) } }
/// Get the before value, if there is one.
pub fn pre(&self) -> Option<&T> { match *self { Diff::Died(ref x) | Diff::Changed(ref x, _) => Some(x), _ => None } }
/// Get the after value, if there is one.
pub fn post(&self) -> Option<&T> { match *self { Diff::Born(ref x) | Diff::Changed(_, ref x) => Some(x), _ => None } }
/// Determine whether there was a change or not.
pub fn is_same(&self) -> bool { match *self { Diff::Same => true, _ => false }}
}
#[derive(Debug, PartialEq, Eq, Clone)]
/// Account diff.
pub struct AccountDiff {
/// Change in balance, allowed to be `Diff::Same`.
pub balance: Diff<U256>,
/// Change in nonce, allowed to be `Diff::Same`.
pub nonce: Diff<U256>, // Allowed to be Same
/// Change in code, allowed to be `Diff::Same`.
pub code: Diff<Bytes>, // Allowed to be Same
/// Change in storage, values are not allowed to be `Diff::Same`.
pub storage: BTreeMap<H256, Diff<H256>>,
}
#[derive(Debug, PartialEq, Eq, Clone)]
#[derive(Debug,Clone,PartialEq,Eq)]
/// Change in existance type.
// TODO: include other types of change.
pub enum Existance {
@@ -81,6 +43,19 @@ impl fmt::Display for Existance {
}
}
#[derive(Debug,Clone,PartialEq,Eq)]
/// Account diff.
pub struct AccountDiff {
/// Change in balance, allowed to be `Diff::Same`.
pub balance: Diff<U256>,
/// Change in nonce, allowed to be `Diff::Same`.
pub nonce: Diff<U256>, // Allowed to be Same
/// Change in code, allowed to be `Diff::Same`.
pub code: Diff<Bytes>, // Allowed to be Same
/// Change in storage, values are not allowed to be `Diff::Same`.
pub storage: BTreeMap<H256, Diff<H256>>,
}
impl AccountDiff {
/// Get `Existance` projection.
pub fn existance(&self) -> Existance {
@@ -90,6 +65,47 @@ impl AccountDiff {
_ => Existance::Alive,
}
}
#[cfg(test)]
/// Determine difference between two optionally existant `Account`s. Returns None
/// if they are the same.
pub fn diff_pod(pre: Option<&PodAccount>, post: Option<&PodAccount>) -> Option<AccountDiff> {
match (pre, post) {
(None, Some(x)) => Some(AccountDiff {
balance: Diff::Born(x.balance),
nonce: Diff::Born(x.nonce),
code: Diff::Born(x.code.clone()),
storage: x.storage.iter().map(|(k, v)| (k.clone(), Diff::Born(v.clone()))).collect(),
}),
(Some(x), None) => Some(AccountDiff {
balance: Diff::Died(x.balance),
nonce: Diff::Died(x.nonce),
code: Diff::Died(x.code.clone()),
storage: x.storage.iter().map(|(k, v)| (k.clone(), Diff::Died(v.clone()))).collect(),
}),
(Some(pre), Some(post)) => {
let storage: Vec<_> = pre.storage.keys().merge(post.storage.keys())
.filter(|k| pre.storage.get(k).unwrap_or(&H256::new()) != post.storage.get(k).unwrap_or(&H256::new()))
.collect();
let r = AccountDiff {
balance: Diff::new(pre.balance, post.balance),
nonce: Diff::new(pre.nonce, post.nonce),
code: Diff::new(pre.code.clone(), post.code.clone()),
storage: storage.into_iter().map(|k|
(k.clone(), Diff::new(
pre.storage.get(&k).cloned().unwrap_or_else(H256::new),
post.storage.get(&k).cloned().unwrap_or_else(H256::new)
))).collect(),
};
if r.balance.is_same() && r.nonce.is_same() && r.code.is_same() && r.storage.is_empty() {
None
} else {
Some(r)
}
},
_ => None,
}
}
}
// TODO: refactor into something nicer.

View File

@@ -1,272 +0,0 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Account management.
use std::fmt;
use std::sync::RwLock;
use std::collections::HashMap;
use util::{Address as H160, H256, H520};
use ethstore::{SecretStore, Error as SSError, SafeAccount, EthStore};
use ethstore::dir::{KeyDirectory};
use ethstore::ethkey::{Address as SSAddress, Message as SSMessage, Secret as SSSecret, Random, Generator};
/// Type of unlock.
#[derive(Clone)]
enum Unlock {
/// If account is unlocked temporarily, it should be locked after first usage.
Temp,
/// Account unlocked permantently can always sign message.
/// Use with caution.
Perm,
}
/// Data associated with account.
#[derive(Clone)]
struct AccountData {
unlock: Unlock,
password: String,
}
/// `AccountProvider` errors.
#[derive(Debug)]
pub enum Error {
/// Returned when account is not unlocked.
NotUnlocked,
/// Returned when signing fails.
SStore(SSError),
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match *self {
Error::NotUnlocked => write!(f, "Account is locked"),
Error::SStore(ref e) => write!(f, "{}", e),
}
}
}
impl From<SSError> for Error {
fn from(e: SSError) -> Self {
Error::SStore(e)
}
}
macro_rules! impl_bridge_type {
($name: ident, $size: expr, $core: ident, $store: ident) => {
/// Primitive
pub struct $name([u8; $size]);
impl From<[u8; $size]> for $name {
fn from(s: [u8; $size]) -> Self {
$name(s)
}
}
impl From<$core> for $name {
fn from(s: $core) -> Self {
$name(s.0)
}
}
impl From<$store> for $name {
fn from(s: $store) -> Self {
$name(s.into())
}
}
impl Into<$core> for $name {
fn into(self) -> $core {
$core(self.0)
}
}
impl Into<$store> for $name {
fn into(self) -> $store {
$store::from(self.0)
}
}
}
}
impl_bridge_type!(Secret, 32, H256, SSSecret);
impl_bridge_type!(Message, 32, H256, SSMessage);
impl_bridge_type!(Address, 20, H160, SSAddress);
struct NullDir;
impl KeyDirectory for NullDir {
fn load(&self) -> Result<Vec<SafeAccount>, SSError> {
Ok(vec![])
}
fn insert(&self, _account: SafeAccount) -> Result<(), SSError> {
Ok(())
}
fn remove(&self, _address: &SSAddress) -> Result<(), SSError> {
Ok(())
}
}
/// Account management.
/// Responsible for unlocking accounts.
pub struct AccountProvider {
unlocked: RwLock<HashMap<SSAddress, AccountData>>,
sstore: Box<SecretStore>,
}
impl AccountProvider {
/// Creates new account provider.
pub fn new(sstore: Box<SecretStore>) -> Self {
AccountProvider {
unlocked: RwLock::new(HashMap::new()),
sstore: sstore,
}
}
/// Creates not disk backed provider.
pub fn transient_provider() -> Self {
AccountProvider {
unlocked: RwLock::new(HashMap::new()),
sstore: Box::new(EthStore::open(Box::new(NullDir)).unwrap())
}
}
/// Creates new random account.
pub fn new_account(&self, password: &str) -> Result<H160, Error> {
let secret = Random.generate().unwrap().secret().clone();
let address = try!(self.sstore.insert_account(secret, password));
Ok(Address::from(address).into())
}
/// Inserts new account into underlying store.
/// Does not unlock account!
pub fn insert_account<S>(&self, secret: S, password: &str) -> Result<H160, Error> where Secret: From<S> {
let s = Secret::from(secret);
let address = try!(self.sstore.insert_account(s.into(), password));
Ok(Address::from(address).into())
}
/// Returns addresses of all accounts.
pub fn accounts(&self) -> Vec<H160> {
self.sstore.accounts().into_iter().map(|a| H160(a.into())).collect()
}
/// Helper method used for unlocking accounts.
fn unlock_account<A>(&self, account: A, password: String, unlock: Unlock) -> Result<(), Error> where Address: From<A> {
let a = Address::from(account);
let account = a.into();
// verify password by signing dump message
// result may be discarded
let _ = try!(self.sstore.sign(&account, &password, &Default::default()));
// check if account is already unlocked pernamently, if it is, do nothing
{
let unlocked = self.unlocked.read().unwrap();
if let Some(data) = unlocked.get(&account) {
if let Unlock::Perm = data.unlock {
return Ok(())
}
}
}
let data = AccountData {
unlock: unlock,
password: password,
};
let mut unlocked = self.unlocked.write().unwrap();
unlocked.insert(account, data);
Ok(())
}
/// Unlocks account permanently.
pub fn unlock_account_permanently<A>(&self, account: A, password: String) -> Result<(), Error> where Address: From<A> {
self.unlock_account(account, password, Unlock::Perm)
}
/// Unlocks account temporarily (for one signing).
pub fn unlock_account_temporarily<A>(&self, account: A, password: String) -> Result<(), Error> where Address: From<A> {
self.unlock_account(account, password, Unlock::Temp)
}
/// Checks if given account is unlocked
pub fn is_unlocked<A>(&self, account: A) -> bool where Address: From<A> {
let account = Address::from(account).into();
let unlocked = self.unlocked.read().unwrap();
unlocked.get(&account).is_some()
}
/// Signs the message. Account must be unlocked.
pub fn sign<A, M>(&self, account: A, message: M) -> Result<H520, Error> where Address: From<A>, Message: From<M> {
let account = Address::from(account).into();
let message = Message::from(message).into();
let data = {
let unlocked = self.unlocked.read().unwrap();
try!(unlocked.get(&account).ok_or(Error::NotUnlocked)).clone()
};
if let Unlock::Temp = data.unlock {
let mut unlocked = self.unlocked.write().unwrap();
unlocked.remove(&account).expect("data exists: so key must exist: qed");
}
let signature = try!(self.sstore.sign(&account, &data.password, &message));
Ok(H520(signature.into()))
}
/// Unlocks an account, signs the message, and locks it again.
pub fn sign_with_password<A, M>(&self, account: A, password: String, message: M) -> Result<H520, Error> where Address: From<A>, Message: From<M> {
let account = Address::from(account).into();
let message = Message::from(message).into();
let signature = try!(self.sstore.sign(&account, &password, &message));
Ok(H520(signature.into()))
}
}
#[cfg(test)]
mod tests {
use super::AccountProvider;
use ethstore::ethkey::{Generator, Random};
#[test]
fn unlock_account_temp() {
let kp = Random.generate().unwrap();
let ap = AccountProvider::transient_provider();
assert!(ap.insert_account(kp.secret().clone(), "test").is_ok());
assert!(ap.unlock_account_temporarily(kp.address(), "test1".into()).is_err());
assert!(ap.unlock_account_temporarily(kp.address(), "test".into()).is_ok());
assert!(ap.sign(kp.address(), [0u8; 32]).is_ok());
assert!(ap.sign(kp.address(), [0u8; 32]).is_err());
}
#[test]
fn unlock_account_perm() {
let kp = Random.generate().unwrap();
let ap = AccountProvider::transient_provider();
assert!(ap.insert_account(kp.secret().clone(), "test").is_ok());
assert!(ap.unlock_account_permanently(kp.address(), "test1".into()).is_err());
assert!(ap.unlock_account_permanently(kp.address(), "test".into()).is_ok());
assert!(ap.sign(kp.address(), [0u8; 32]).is_ok());
assert!(ap.sign(kp.address(), [0u8; 32]).is_ok());
assert!(ap.unlock_account_temporarily(kp.address(), "test".into()).is_ok());
assert!(ap.sign(kp.address(), [0u8; 32]).is_ok());
assert!(ap.sign(kp.address(), [0u8; 32]).is_ok());
}
}

View File

@@ -16,7 +16,6 @@
//! Evm input params.
use common::*;
use ethjson;
/// Transaction value
#[derive(Clone, Debug)]
@@ -27,15 +26,6 @@ pub enum ActionValue {
Apparent(U256)
}
impl ActionValue {
/// Returns action value as U256.
pub fn value(&self) -> U256 {
match *self {
ActionValue::Transfer(x) | ActionValue::Apparent(x) => x
}
}
}
// TODO: should be a trait, possible to avoid cloning everything from a Transaction(/View).
/// Action (call/create) input params. Everything else should be specified in Externalities.
#[derive(Clone, Debug)]
@@ -77,19 +67,3 @@ impl Default for ActionParams {
}
}
}
impl From<ethjson::vm::Transaction> for ActionParams {
fn from(t: ethjson::vm::Transaction) -> Self {
ActionParams {
code_address: Address::new(),
address: t.address.into(),
sender: t.sender.into(),
origin: t.origin.into(),
code: Some(t.code.into()),
data: Some(t.data.into()),
gas: t.gas.into(),
gas_price: t.gas_price.into(),
value: ActionValue::Transfer(t.value.into()),
}
}
}

View File

@@ -1,262 +0,0 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! A blockchain engine that supports a basic, non-BFT proof-of-authority.
use common::*;
use account_provider::AccountProvider;
use block::*;
use spec::{CommonParams, Spec};
use engine::*;
use evm::Schedule;
use ethjson;
/// `BasicAuthority` params.
#[derive(Debug, PartialEq)]
pub struct BasicAuthorityParams {
/// Gas limit divisor.
pub gas_limit_bound_divisor: U256,
/// Block duration.
pub duration_limit: u64,
/// Valid signatories.
pub authorities: HashSet<Address>,
}
impl From<ethjson::spec::BasicAuthorityParams> for BasicAuthorityParams {
fn from(p: ethjson::spec::BasicAuthorityParams) -> Self {
BasicAuthorityParams {
gas_limit_bound_divisor: p.gas_limit_bound_divisor.into(),
duration_limit: p.duration_limit.into(),
authorities: p.authorities.into_iter().map(Into::into).collect::<HashSet<_>>(),
}
}
}
/// Engine using `BasicAuthority` proof-of-work consensus algorithm, suitable for Ethereum
/// mainnet chains in the Olympic, Frontier and Homestead eras.
pub struct BasicAuthority {
params: CommonParams,
our_params: BasicAuthorityParams,
builtins: BTreeMap<Address, Builtin>,
}
impl BasicAuthority {
/// Create a new instance of BasicAuthority engine
pub fn new(params: CommonParams, our_params: BasicAuthorityParams, builtins: BTreeMap<Address, Builtin>) -> Self {
BasicAuthority {
params: params,
our_params: our_params,
builtins: builtins,
}
}
}
impl Engine for BasicAuthority {
fn name(&self) -> &str { "BasicAuthority" }
fn version(&self) -> SemanticVersion { SemanticVersion::new(1, 0, 0) }
// One field - the signature
fn seal_fields(&self) -> usize { 1 }
fn params(&self) -> &CommonParams { &self.params }
fn builtins(&self) -> &BTreeMap<Address, Builtin> { &self.builtins }
/// Additional engine-specific information for the user/developer concerning `header`.
fn extra_info(&self, _header: &Header) -> HashMap<String, String> { hash_map!["signature".to_owned() => "TODO".to_owned()] }
fn schedule(&self, _env_info: &EnvInfo) -> Schedule {
Schedule::new_homestead()
}
fn populate_from_parent(&self, header: &mut Header, parent: &Header, gas_floor_target: U256) {
header.difficulty = parent.difficulty;
header.gas_limit = {
let gas_limit = parent.gas_limit;
let bound_divisor = self.our_params.gas_limit_bound_divisor;
if gas_limit < gas_floor_target {
min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into())
} else {
max(gas_floor_target, gas_limit - gas_limit / bound_divisor + 1.into())
}
};
header.note_dirty();
// info!("ethash: populate_from_parent #{}: difficulty={} and gas_limit={}", header.number, header.difficulty, header.gas_limit);
}
/// Apply the block reward on finalisation of the block.
/// This assumes that all uncles are valid uncles (i.e. of at least one generation before the current).
fn on_close_block(&self, _block: &mut ExecutedBlock) {}
/// Attempt to seal the block internally.
///
/// This operation is synchronous and may (quite reasonably) not be available, in which `false` will
/// be returned.
fn generate_seal(&self, block: &ExecutedBlock, accounts: Option<&AccountProvider>) -> Option<Vec<Bytes>> {
if let Some(ap) = accounts {
let header = block.header();
let message = header.bare_hash();
// account should be pernamently unlocked, otherwise sealing will fail
if let Ok(signature) = ap.sign(*block.header().author(), message) {
return Some(vec![encode(&signature).to_vec()]);
} else {
trace!(target: "basicauthority", "generate_seal: FAIL: accounts secret key unavailable");
}
} else {
trace!(target: "basicauthority", "generate_seal: FAIL: accounts not provided");
}
None
}
fn verify_block_basic(&self, header: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> {
// check the seal fields.
// TODO: pull this out into common code.
if header.seal.len() != self.seal_fields() {
return Err(From::from(BlockError::InvalidSealArity(
Mismatch { expected: self.seal_fields(), found: header.seal.len() }
)));
}
Ok(())
}
fn verify_block_unordered(&self, header: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> {
// check the signature is legit.
let sig = try!(UntrustedRlp::new(&header.seal[0]).as_val::<H520>());
let signer = Address::from(try!(ec::recover(&sig, &header.bare_hash())).sha3());
if !self.our_params.authorities.contains(&signer) {
return try!(Err(BlockError::InvalidSeal));
}
Ok(())
}
fn verify_block_family(&self, header: &Header, parent: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> {
// we should not calculate difficulty for genesis blocks
if header.number() == 0 {
return Err(From::from(BlockError::RidiculousNumber(OutOfBounds { min: Some(1), max: None, found: header.number() })));
}
// Check difficulty is correct given the two timestamps.
if header.difficulty() != parent.difficulty() {
return Err(From::from(BlockError::InvalidDifficulty(Mismatch { expected: *parent.difficulty(), found: *header.difficulty() })))
}
let gas_limit_divisor = self.our_params.gas_limit_bound_divisor;
let min_gas = parent.gas_limit - parent.gas_limit / gas_limit_divisor;
let max_gas = parent.gas_limit + parent.gas_limit / gas_limit_divisor;
if header.gas_limit <= min_gas || header.gas_limit >= max_gas {
return Err(From::from(BlockError::InvalidGasLimit(OutOfBounds { min: Some(min_gas), max: Some(max_gas), found: header.gas_limit })));
}
Ok(())
}
fn verify_transaction_basic(&self, t: &SignedTransaction, _header: &Header) -> result::Result<(), Error> {
try!(t.check_low_s());
Ok(())
}
fn verify_transaction(&self, t: &SignedTransaction, _header: &Header) -> Result<(), Error> {
t.sender().map(|_|()) // Perform EC recovery and cache sender
}
}
impl Header {
/// Get the none field of the header.
pub fn signature(&self) -> H520 {
decode(&self.seal()[0])
}
}
/// Create a new test chain spec with `BasicAuthority` consensus engine.
pub fn new_test_authority() -> Spec { Spec::load(include_bytes!("../res/test_authority.json")) }
#[cfg(test)]
mod tests {
use super::*;
use common::*;
use block::*;
use tests::helpers::*;
use account_provider::AccountProvider;
#[test]
fn has_valid_metadata() {
let engine = new_test_authority().engine;
assert!(!engine.name().is_empty());
assert!(engine.version().major >= 1);
}
#[test]
fn can_return_schedule() {
let engine = new_test_authority().engine;
let schedule = engine.schedule(&EnvInfo {
number: 10000000,
author: 0.into(),
timestamp: 0,
difficulty: 0.into(),
last_hashes: vec![],
dao_rescue_block_gas_limit: None,
gas_used: 0.into(),
gas_limit: 0.into(),
});
assert!(schedule.stack_limit > 0);
}
#[test]
fn can_do_seal_verification_fail() {
let engine = new_test_authority().engine;
let header: Header = Header::default();
let verify_result = engine.verify_block_basic(&header, None);
match verify_result {
Err(Error::Block(BlockError::InvalidSealArity(_))) => {},
Err(_) => { panic!("should be block seal-arity mismatch error (got {:?})", verify_result); },
_ => { panic!("Should be error, got Ok"); },
}
}
#[test]
fn can_do_signature_verification_fail() {
let engine = new_test_authority().engine;
let mut header: Header = Header::default();
header.set_seal(vec![rlp::encode(&Signature::zero()).to_vec()]);
let verify_result = engine.verify_block_unordered(&header, None);
match verify_result {
Err(Error::Util(UtilError::Crypto(CryptoError::InvalidSignature))) => {},
Err(_) => { panic!("should be block difficulty error (got {:?})", verify_result); },
_ => { panic!("Should be error, got Ok"); },
}
}
#[test]
fn can_generate_seal() {
let tap = AccountProvider::transient_provider();
let addr = tap.insert_account("".sha3(), "").unwrap();
tap.unlock_account_permanently(addr, "".into()).unwrap();
let spec = new_test_authority();
let engine = &spec.engine;
let genesis_header = spec.genesis_header();
let mut db_result = get_temp_journal_db();
let mut db = db_result.take();
spec.ensure_db_good(db.as_hashdb_mut());
let last_hashes = vec![genesis_header.hash()];
let vm_factory = Default::default();
let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, None, addr, 3141562.into(), vec![]).unwrap();
let b = b.close_and_lock();
let seal = engine.generate_seal(b.block(), Some(&tap)).unwrap();
assert!(b.try_seal(engine.deref(), seal).is_ok());
}
}

View File

@@ -22,10 +22,9 @@ use common::*;
use engine::*;
use state::*;
use verification::PreverifiedBlock;
use trace::Trace;
use evm::Factory as EvmFactory;
/// A block, encoded as it is on the block chain.
// TODO: rename to Block
#[derive(Default, Debug, Clone)]
pub struct Block {
/// The header of this block.
@@ -38,7 +37,23 @@ pub struct Block {
impl Block {
/// Returns true if the given bytes form a valid encoding of a block in RLP.
// TODO: implement Decoder for this and have this use that.
pub fn is_good(b: &[u8]) -> bool {
/*
let urlp = UntrustedRlp::new(&b);
if !urlp.is_list() || urlp.item_count() != 3 || urlp.size() != b.len() { return false; }
if urlp.val_at::<Header>(0).is_err() { return false; }
if !urlp.at(1).unwrap().is_list() { return false; }
if urlp.at(1).unwrap().iter().find(|i| i.as_val::<Transaction>().is_err()).is_some() {
return false;
}
if !urlp.at(2).unwrap().is_list() { return false; }
if urlp.at(2).unwrap().iter().find(|i| i.as_val::<Header>().is_err()).is_some() {
return false;
}
true*/
UntrustedRlp::new(b).as_val::<Block>().is_ok()
}
}
@@ -61,34 +76,19 @@ impl Decodable for Block {
}
/// Internal type for a block's common elements.
#[derive(Clone)]
// TODO: rename to ExecutedBlock
// TODO: use BareBlock
#[derive(Debug)]
pub struct ExecutedBlock {
base: Block,
receipts: Vec<Receipt>,
transactions_set: HashSet<H256>,
state: State,
traces: Option<Vec<Trace>>,
}
/// A set of references to `ExecutedBlock` fields that are publicly accessible.
pub struct BlockRefMut<'a> {
/// Block header.
pub header: &'a mut Header,
/// Block transactions.
pub transactions: &'a Vec<SignedTransaction>,
/// Block uncles.
pub uncles: &'a Vec<Header>,
/// Transaction receipts.
pub receipts: &'a Vec<Receipt>,
/// State.
pub state: &'a mut State,
/// Traces.
pub traces: &'a Option<Vec<Trace>>,
}
/// A set of immutable references to `ExecutedBlock` fields that are publicly accessible.
pub struct BlockRef<'a> {
/// Block header.
pub header: &'a Header,
/// Block transactions.
@@ -98,49 +98,26 @@ pub struct BlockRef<'a> {
/// Transaction receipts.
pub receipts: &'a Vec<Receipt>,
/// State.
pub state: &'a State,
/// Traces.
pub traces: &'a Option<Vec<Trace>>,
pub state: &'a mut State,
}
impl ExecutedBlock {
/// Create a new block from the given `state`.
fn new(state: State, tracing: bool) -> ExecutedBlock {
ExecutedBlock {
base: Default::default(),
receipts: Default::default(),
transactions_set: Default::default(),
state: state,
traces: if tracing {Some(Vec::new())} else {None},
}
}
fn new(state: State) -> ExecutedBlock { ExecutedBlock { base: Default::default(), receipts: Default::default(), transactions_set: Default::default(), state: state } }
/// Get a structure containing individual references to all public fields.
pub fn fields_mut(&mut self) -> BlockRefMut {
pub fn fields(&mut self) -> BlockRefMut {
BlockRefMut {
header: &mut self.base.header,
header: &self.base.header,
transactions: &self.base.transactions,
uncles: &self.base.uncles,
state: &mut self.state,
receipts: &self.receipts,
traces: &self.traces,
}
}
/// Get a structure containing individual references to all public fields.
pub fn fields(&self) -> BlockRef {
BlockRef {
header: &self.base.header,
transactions: &self.base.transactions,
uncles: &self.base.uncles,
state: &self.state,
receipts: &self.receipts,
traces: &self.traces,
}
}
}
/// Trait for a object that is a `ExecutedBlock`.
/// Trait for a object that is_a `ExecutedBlock`.
pub trait IsBlock {
/// Get the block associated with this object.
fn block(&self) -> &ExecutedBlock;
@@ -157,9 +134,6 @@ pub trait IsBlock {
/// Get all information on receipts in this block.
fn receipts(&self) -> &Vec<Receipt> { &self.block().receipts }
/// Get all information concerning transaction tracing in this block.
fn traces(&self) -> &Option<Vec<Trace>> { &self.block().traces }
/// Get all uncles in this block.
fn uncles(&self) -> &Vec<Header> { &self.block().base.uncles }
}
@@ -175,63 +149,33 @@ impl IsBlock for ExecutedBlock {
pub struct OpenBlock<'x> {
block: ExecutedBlock,
engine: &'x Engine,
vm_factory: &'x EvmFactory,
last_hashes: LastHashes,
dao_rescue_block_gas_limit: Option<U256>,
}
/// Just like `OpenBlock`, except that we've applied `Engine::on_close_block`, finished up the non-seal header fields,
/// Just like OpenBlock, except that we've applied `Engine::on_close_block`, finished up the non-seal header fields,
/// and collected the uncles.
///
/// There is no function available to push a transaction.
#[derive(Clone)]
pub struct ClosedBlock {
block: ExecutedBlock,
uncle_bytes: Bytes,
last_hashes: LastHashes,
dao_rescue_block_gas_limit: Option<U256>,
unclosed_state: State,
}
/// Just like `ClosedBlock` except that we can't reopen it and it's faster.
///
/// We actually store the post-`Engine::on_close_block` state, unlike in `ClosedBlock` where it's the pre.
#[derive(Clone)]
pub struct LockedBlock {
block: ExecutedBlock,
uncle_bytes: Bytes,
}
/// A block that has a valid seal.
///
/// The block's header has valid seal arguments. The block cannot be reversed into a `ClosedBlock` or `OpenBlock`.
/// The block's header has valid seal arguments. The block cannot be reversed into a ClosedBlock or OpenBlock.
pub struct SealedBlock {
block: ExecutedBlock,
uncle_bytes: Bytes,
}
impl<'x> OpenBlock<'x> {
#[cfg_attr(feature="dev", allow(too_many_arguments))]
/// Create a new `OpenBlock` ready for transaction pushing.
pub fn new(
engine: &'x Engine,
vm_factory: &'x EvmFactory,
tracing: bool,
db: Box<JournalDB>,
parent: &Header,
last_hashes: LastHashes,
dao_rescue_block_gas_limit: Option<U256>,
author: Address,
gas_floor_target: U256,
extra_data: Bytes,
) -> Result<Self, Error> {
let state = try!(State::from_existing(db, parent.state_root().clone(), engine.account_start_nonce()));
/// Create a new OpenBlock ready for transaction pushing.
pub fn new(engine: &'x Engine, db: Box<JournalDB>, parent: &Header, last_hashes: LastHashes, author: Address, gas_floor_target: U256, extra_data: Bytes) -> Self {
let mut r = OpenBlock {
block: ExecutedBlock::new(state, tracing),
block: ExecutedBlock::new(State::from_existing(db, parent.state_root().clone(), engine.account_start_nonce())),
engine: engine,
vm_factory: vm_factory,
last_hashes: last_hashes,
dao_rescue_block_gas_limit: dao_rescue_block_gas_limit,
};
r.block.base.header.parent_hash = parent.hash();
@@ -243,7 +187,7 @@ impl<'x> OpenBlock<'x> {
engine.populate_from_parent(&mut r.block.base.header, parent, gas_floor_target);
engine.on_new_block(&mut r.block);
Ok(r)
r
}
/// Alter the author for the block.
@@ -288,7 +232,6 @@ impl<'x> OpenBlock<'x> {
/// Get the environment info concerning this block.
pub fn env_info(&self) -> EnvInfo {
// TODO: memoise.
const SOFT_FORK_BLOCK: u64 = 1775000;
EnvInfo {
number: self.block.base.header.number,
author: self.block.base.header.author.clone(),
@@ -297,7 +240,6 @@ impl<'x> OpenBlock<'x> {
last_hashes: self.last_hashes.clone(), // TODO: should be a reference.
gas_used: self.block.receipts.last().map_or(U256::zero(), |r| r.gas_used),
gas_limit: self.block.base.header.gas_limit.clone(),
dao_rescue_block_gas_limit: if self.block.base.header.number == SOFT_FORK_BLOCK { Some(self.block.base.header.gas_limit) } else { self.dao_rescue_block_gas_limit },
}
}
@@ -305,31 +247,22 @@ impl<'x> OpenBlock<'x> {
///
/// If valid, it will be executed, and archived together with the receipt.
pub fn push_transaction(&mut self, t: SignedTransaction, h: Option<H256>) -> Result<&Receipt, Error> {
if self.block.transactions_set.contains(&t.hash()) {
return Err(From::from(TransactionError::AlreadyImported));
}
let env_info = self.env_info();
// info!("env_info says gas_used={}", env_info.gas_used);
match self.block.state.apply(&env_info, self.engine, self.vm_factory, &t, self.block.traces.is_some()) {
Ok(outcome) => {
match self.block.state.apply(&env_info, self.engine, &t) {
Ok(receipt) => {
self.block.transactions_set.insert(h.unwrap_or_else(||t.hash()));
self.block.base.transactions.push(t);
let t = outcome.trace;
self.block.traces.as_mut().map(|traces| traces.push(t.expect("self.block.traces.is_some(): so we must be tracing: qed")));
self.block.receipts.push(outcome.receipt);
self.block.receipts.push(receipt);
Ok(&self.block.receipts.last().unwrap())
}
Err(x) => Err(From::from(x))
}
}
/// Turn this into a `ClosedBlock`. A `BlockChain` must be provided in order to figure out the uncles.
/// Turn this into a `ClosedBlock`. A BlockChain must be provided in order to figure out the uncles.
pub fn close(self) -> ClosedBlock {
let mut s = self;
let unclosed_state = s.block.state.clone();
s.engine.on_close_block(&mut s.block);
s.block.base.header.transactions_root = ordered_trie_root(s.block.base.transactions.iter().map(|ref e| e.rlp_bytes().to_vec()).collect());
let uncle_bytes = s.block.base.uncles.iter().fold(RlpStream::new_list(s.block.base.uncles.len()), |mut s, u| {s.append_raw(&u.rlp(Seal::With), 1); s} ).out();
@@ -343,29 +276,6 @@ impl<'x> OpenBlock<'x> {
ClosedBlock {
block: s.block,
uncle_bytes: uncle_bytes,
last_hashes: s.last_hashes,
dao_rescue_block_gas_limit: s.dao_rescue_block_gas_limit,
unclosed_state: unclosed_state,
}
}
/// Turn this into a `LockedBlock`. A BlockChain must be provided in order to figure out the uncles.
pub fn close_and_lock(self) -> LockedBlock {
let mut s = self;
s.engine.on_close_block(&mut s.block);
s.block.base.header.transactions_root = ordered_trie_root(s.block.base.transactions.iter().map(|ref e| e.rlp_bytes().to_vec()).collect());
let uncle_bytes = s.block.base.uncles.iter().fold(RlpStream::new_list(s.block.base.uncles.len()), |mut s, u| {s.append_raw(&u.rlp(Seal::With), 1); s} ).out();
s.block.base.header.uncles_hash = uncle_bytes.sha3();
s.block.base.header.state_root = s.block.state.root().clone();
s.block.base.header.receipts_root = ordered_trie_root(s.block.receipts.iter().map(|ref r| r.rlp_bytes().to_vec()).collect());
s.block.base.header.log_bloom = s.block.receipts.iter().fold(LogBloom::zero(), |mut b, r| {b = &b | &r.log_bloom; b}); //TODO: use |= operator
s.block.base.header.gas_used = s.block.receipts.last().map_or(U256::zero(), |r| r.gas_used);
s.block.base.header.note_dirty();
LockedBlock {
block: s.block,
uncle_bytes: uncle_bytes,
}
}
}
@@ -378,41 +288,10 @@ impl<'x> IsBlock for ClosedBlock {
fn block(&self) -> &ExecutedBlock { &self.block }
}
impl<'x> IsBlock for LockedBlock {
fn block(&self) -> &ExecutedBlock { &self.block }
}
impl ClosedBlock {
/// Get the hash of the header without seal arguments.
pub fn hash(&self) -> H256 { self.header().rlp_sha3(Seal::Without) }
/// Turn this into a `LockedBlock`, unable to be reopened again.
pub fn lock(self) -> LockedBlock {
LockedBlock {
block: self.block,
uncle_bytes: self.uncle_bytes,
}
}
/// Given an engine reference, reopen the `ClosedBlock` into an `OpenBlock`.
pub fn reopen<'a>(self, engine: &'a Engine, vm_factory: &'a EvmFactory) -> OpenBlock<'a> {
// revert rewards (i.e. set state back at last transaction's state).
let mut block = self.block;
block.state = self.unclosed_state;
OpenBlock {
block: block,
engine: engine,
vm_factory: vm_factory,
last_hashes: self.last_hashes,
dao_rescue_block_gas_limit: self.dao_rescue_block_gas_limit,
}
}
}
impl LockedBlock {
/// Get the hash of the header without seal arguments.
pub fn hash(&self) -> H256 { self.header().rlp_sha3(Seal::Without) }
/// Provide a valid seal in order to turn this into a `SealedBlock`.
///
/// NOTE: This does not check the validity of `seal` with the engine.
@@ -428,7 +307,7 @@ impl LockedBlock {
/// Provide a valid seal in order to turn this into a `SealedBlock`.
/// This does check the validity of `seal` with the engine.
/// Returns the `ClosedBlock` back again if the seal is no good.
pub fn try_seal(self, engine: &Engine, seal: Vec<Bytes>) -> Result<SealedBlock, LockedBlock> {
pub fn try_seal(self, engine: &Engine, seal: Vec<Bytes>) -> Result<SealedBlock, ClosedBlock> {
let mut s = self;
s.block.base.header.set_seal(seal);
match engine.verify_block_seal(&s.block.base.header) {
@@ -460,82 +339,40 @@ impl IsBlock for SealedBlock {
}
/// Enact the block given by block header, transactions and uncles
#[cfg_attr(feature="dev", allow(too_many_arguments))]
pub fn enact(
header: &Header,
transactions: &[SignedTransaction],
uncles: &[Header],
engine: &Engine,
tracing: bool,
db: Box<JournalDB>,
parent: &Header,
last_hashes: LastHashes,
dao_rescue_block_gas_limit: Option<U256>,
vm_factory: &EvmFactory
) -> Result<LockedBlock, Error> {
pub fn enact(header: &Header, transactions: &[SignedTransaction], uncles: &[Header], engine: &Engine, db: Box<JournalDB>, parent: &Header, last_hashes: LastHashes) -> Result<ClosedBlock, Error> {
{
if ::log::max_log_level() >= ::log::LogLevel::Trace {
let s = try!(State::from_existing(db.boxed_clone(), parent.state_root().clone(), engine.account_start_nonce()));
let s = State::from_existing(db.spawn(), parent.state_root().clone(), engine.account_start_nonce());
trace!("enact(): root={}, author={}, author_balance={}\n", s.root(), header.author(), s.balance(&header.author()));
}
}
let mut b = try!(OpenBlock::new(engine, vm_factory, tracing, db, parent, last_hashes, dao_rescue_block_gas_limit, header.author().clone(), 3141562.into(), header.extra_data().clone()));
let mut b = OpenBlock::new(engine, db, parent, last_hashes, header.author().clone(), x!(3141562), header.extra_data().clone());
b.set_difficulty(*header.difficulty());
b.set_gas_limit(*header.gas_limit());
b.set_timestamp(header.timestamp());
for t in transactions { try!(b.push_transaction(t.clone(), None)); }
for u in uncles { try!(b.push_uncle(u.clone())); }
Ok(b.close_and_lock())
Ok(b.close())
}
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header
#[cfg_attr(feature="dev", allow(too_many_arguments))]
pub fn enact_bytes(
block_bytes: &[u8],
engine: &Engine,
tracing: bool,
db: Box<JournalDB>,
parent: &Header,
last_hashes: LastHashes,
dao_rescue_block_gas_limit: Option<U256>,
vm_factory: &EvmFactory
) -> Result<LockedBlock, Error> {
pub fn enact_bytes(block_bytes: &[u8], engine: &Engine, db: Box<JournalDB>, parent: &Header, last_hashes: LastHashes) -> Result<ClosedBlock, Error> {
let block = BlockView::new(block_bytes);
let header = block.header();
enact(&header, &block.transactions(), &block.uncles(), engine, tracing, db, parent, last_hashes, dao_rescue_block_gas_limit, vm_factory)
enact(&header, &block.transactions(), &block.uncles(), engine, db, parent, last_hashes)
}
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header
#[cfg_attr(feature="dev", allow(too_many_arguments))]
pub fn enact_verified(
block: &PreverifiedBlock,
engine: &Engine,
tracing: bool,
db: Box<JournalDB>,
parent: &Header,
last_hashes: LastHashes,
dao_rescue_block_gas_limit: Option<U256>,
vm_factory: &EvmFactory
) -> Result<LockedBlock, Error> {
pub fn enact_verified(block: &PreverifiedBlock, engine: &Engine, db: Box<JournalDB>, parent: &Header, last_hashes: LastHashes) -> Result<ClosedBlock, Error> {
let view = BlockView::new(&block.bytes);
enact(&block.header, &block.transactions, &view.uncles(), engine, tracing, db, parent, last_hashes, dao_rescue_block_gas_limit, vm_factory)
enact(&block.header, &block.transactions, &view.uncles(), engine, db, parent, last_hashes)
}
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header. Seal the block aferwards
#[cfg_attr(feature="dev", allow(too_many_arguments))]
pub fn enact_and_seal(
block_bytes: &[u8],
engine: &Engine,
tracing: bool,
db: Box<JournalDB>,
parent: &Header,
last_hashes: LastHashes,
dao_rescue_block_gas_limit: Option<U256>,
vm_factory: &EvmFactory
) -> Result<SealedBlock, Error> {
pub fn enact_and_seal(block_bytes: &[u8], engine: &Engine, db: Box<JournalDB>, parent: &Header, last_hashes: LastHashes) -> Result<SealedBlock, Error> {
let header = BlockView::new(block_bytes).header_view();
Ok(try!(try!(enact_bytes(block_bytes, engine, tracing, db, parent, last_hashes, dao_rescue_block_gas_limit, vm_factory)).seal(engine, header.seal())))
Ok(try!(try!(enact_bytes(block_bytes, engine, db, parent, last_hashes)).seal(engine, header.seal())))
}
#[cfg(test)]
@@ -543,43 +380,39 @@ mod tests {
use tests::helpers::*;
use super::*;
use common::*;
use engine::*;
#[test]
fn open_block() {
use spec::*;
let spec = Spec::new_test();
let engine = &spec.engine;
let genesis_header = spec.genesis_header();
let engine = Spec::new_test().to_engine().unwrap();
let genesis_header = engine.spec().genesis_header();
let mut db_result = get_temp_journal_db();
let mut db = db_result.take();
spec.ensure_db_good(db.as_hashdb_mut());
engine.spec().ensure_db_good(db.as_hashdb_mut());
let last_hashes = vec![genesis_header.hash()];
let vm_factory = Default::default();
let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, None, Address::zero(), 3141562.into(), vec![]).unwrap();
let b = b.close_and_lock();
let b = OpenBlock::new(engine.deref(), db, &genesis_header, last_hashes, Address::zero(), x!(3141562), vec![]);
let b = b.close();
let _ = b.seal(engine.deref(), vec![]);
}
#[test]
fn enact_block() {
use spec::*;
let spec = Spec::new_test();
let engine = &spec.engine;
let genesis_header = spec.genesis_header();
let engine = Spec::new_test().to_engine().unwrap();
let genesis_header = engine.spec().genesis_header();
let mut db_result = get_temp_journal_db();
let mut db = db_result.take();
spec.ensure_db_good(db.as_hashdb_mut());
let vm_factory = Default::default();
let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, vec![genesis_header.hash()], None, Address::zero(), 3141562.into(), vec![]).unwrap()
.close_and_lock().seal(engine.deref(), vec![]).unwrap();
engine.spec().ensure_db_good(db.as_hashdb_mut());
let b = OpenBlock::new(engine.deref(), db, &genesis_header, vec![genesis_header.hash()], Address::zero(), x!(3141562), vec![]).close().seal(engine.deref(), vec![]).unwrap();
let orig_bytes = b.rlp_bytes();
let orig_db = b.drain();
let mut db_result = get_temp_journal_db();
let mut db = db_result.take();
spec.ensure_db_good(db.as_hashdb_mut());
let e = enact_and_seal(&orig_bytes, engine.deref(), false, db, &genesis_header, vec![genesis_header.hash()], None, &Default::default()).unwrap();
engine.spec().ensure_db_good(db.as_hashdb_mut());
let e = enact_and_seal(&orig_bytes, engine.deref(), db, &genesis_header, vec![genesis_header.hash()]).unwrap();
assert_eq!(e.rlp_bytes(), orig_bytes);
@@ -591,30 +424,28 @@ mod tests {
#[test]
fn enact_block_with_uncle() {
use spec::*;
let spec = Spec::new_test();
let engine = &spec.engine;
let genesis_header = spec.genesis_header();
let engine = Spec::new_test().to_engine().unwrap();
let genesis_header = engine.spec().genesis_header();
let mut db_result = get_temp_journal_db();
let mut db = db_result.take();
spec.ensure_db_good(db.as_hashdb_mut());
let vm_factory = Default::default();
let mut open_block = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, vec![genesis_header.hash()], None, Address::zero(), 3141562.into(), vec![]).unwrap();
engine.spec().ensure_db_good(db.as_hashdb_mut());
let mut open_block = OpenBlock::new(engine.deref(), db, &genesis_header, vec![genesis_header.hash()], Address::zero(), x!(3141562), vec![]);
let mut uncle1_header = Header::new();
uncle1_header.extra_data = b"uncle1".to_vec();
let mut uncle2_header = Header::new();
uncle2_header.extra_data = b"uncle2".to_vec();
open_block.push_uncle(uncle1_header).unwrap();
open_block.push_uncle(uncle2_header).unwrap();
let b = open_block.close_and_lock().seal(engine.deref(), vec![]).unwrap();
let b = open_block.close().seal(engine.deref(), vec![]).unwrap();
let orig_bytes = b.rlp_bytes();
let orig_db = b.drain();
let mut db_result = get_temp_journal_db();
let mut db = db_result.take();
spec.ensure_db_good(db.as_hashdb_mut());
let e = enact_and_seal(&orig_bytes, engine.deref(), false, db, &genesis_header, vec![genesis_header.hash()], None, &Default::default()).unwrap();
engine.spec().ensure_db_good(db.as_hashdb_mut());
let e = enact_and_seal(&orig_bytes, engine.deref(), db, &genesis_header, vec![genesis_header.hash()]).unwrap();
let bytes = e.rlp_bytes();
assert_eq!(bytes, orig_bytes);

View File

@@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! A queue of blocks. Sits between network or other I/O and the `BlockChain`.
//! A queue of blocks. Sits between network or other I/O and the BlockChain.
//! Sorts them ready for blockchain insertion.
use std::thread::{JoinHandle, self};
use std::sync::atomic::{AtomicBool, Ordering as AtomicOrdering};
@@ -89,7 +89,7 @@ impl BlockQueueInfo {
}
}
/// A queue of blocks. Sits between network or other I/O and the `BlockChain`.
/// A queue of blocks. Sits between network or other I/O and the BlockChain.
/// Sorts them ready for blockchain insertion.
pub struct BlockQueue {
panic_handler: Arc<PanicHandler>,
@@ -130,9 +130,7 @@ impl QueueSignal {
}
if self.signalled.compare_and_swap(false, true, AtomicOrdering::Relaxed) == false {
if let Err(e) = self.message_channel.send(UserMessage(SyncMessage::BlockVerified)) {
debug!("Error sending BlockVerified message: {:?}", e);
}
self.message_channel.send(UserMessage(SyncMessage::BlockVerified)).expect("Error sending BlockVerified message");
}
}
@@ -313,17 +311,17 @@ impl BlockQueue {
let h = header.hash();
{
if self.processing.read().unwrap().contains(&h) {
return Err(ImportError::AlreadyQueued.into());
return Err(x!(ImportError::AlreadyQueued));
}
let mut bad = self.verification.bad.lock().unwrap();
if bad.contains(&h) {
return Err(ImportError::KnownBad.into());
return Err(x!(ImportError::KnownBad));
}
if bad.contains(&header.parent_hash) {
bad.insert(h.clone());
return Err(ImportError::KnownBad.into());
return Err(x!(ImportError::KnownBad));
}
}
@@ -466,7 +464,7 @@ mod tests {
fn get_test_queue() -> BlockQueue {
let spec = get_test_spec();
let engine = spec.engine;
let engine = spec.to_engine().unwrap();
BlockQueue::new(BlockQueueConfig::default(), Arc::new(engine), IoChannel::disconnected())
}
@@ -474,7 +472,7 @@ mod tests {
fn can_be_created() {
// TODO better test
let spec = Spec::new_test();
let engine = spec.engine;
let engine = spec.to_engine().unwrap();
let _ = BlockQueue::new(BlockQueueConfig::default(), Arc::new(engine), IoChannel::disconnected());
}
@@ -535,7 +533,7 @@ mod tests {
#[test]
fn test_mem_limit() {
let spec = get_test_spec();
let engine = spec.engine;
let engine = spec.to_engine().unwrap();
let mut config = BlockQueueConfig::default();
config.max_mem_use = super::MIN_MEM_LIMIT; // empty queue uses about 15000
let queue = BlockQueue::new(config, Arc::new(engine), IoChannel::disconnected());

View File

@@ -17,8 +17,6 @@
use util::numbers::{U256,H256};
use header::BlockNumber;
use util::bytes::{FromRawBytesVariable, FromBytesError, ToBytesWithMap};
/// Brief info about inserted block.
#[derive(Clone)]
pub struct BlockInfo {
@@ -42,55 +40,12 @@ pub enum BlockLocation {
/// It's part of the fork which should become canon chain,
/// because it's total difficulty is higher than current
/// canon chain difficulty.
BranchBecomingCanonChain(BranchBecomingCanonChainData),
}
#[derive(Clone)]
pub struct BranchBecomingCanonChainData {
/// Hash of the newest common ancestor with old canon chain.
pub ancestor: H256,
/// Hashes of the blocks between ancestor and this block.
pub enacted: Vec<H256>,
/// Hashes of the blocks which were invalidated.
pub retracted: Vec<H256>,
}
impl FromRawBytesVariable for BranchBecomingCanonChainData {
fn from_bytes_variable(bytes: &[u8]) -> Result<BranchBecomingCanonChainData, FromBytesError> {
type Tuple = (Vec<H256>, Vec<H256>, H256);
let (enacted, retracted, ancestor) = try!(Tuple::from_bytes_variable(bytes));
Ok(BranchBecomingCanonChainData { ancestor: ancestor, enacted: enacted, retracted: retracted })
}
}
impl FromRawBytesVariable for BlockLocation {
fn from_bytes_variable(bytes: &[u8]) -> Result<BlockLocation, FromBytesError> {
match bytes[0] {
0 => Ok(BlockLocation::CanonChain),
1 => Ok(BlockLocation::Branch),
2 => Ok(BlockLocation::BranchBecomingCanonChain(
try!(BranchBecomingCanonChainData::from_bytes_variable(&bytes[1..bytes.len()])))),
_ => Err(FromBytesError::UnknownMarker)
}
}
}
impl ToBytesWithMap for BranchBecomingCanonChainData {
fn to_bytes_map(&self) -> Vec<u8> {
(&self.enacted, &self.retracted, &self.ancestor).to_bytes_map()
}
}
impl ToBytesWithMap for BlockLocation {
fn to_bytes_map(&self) -> Vec<u8> {
match *self {
BlockLocation::CanonChain => vec![0u8],
BlockLocation::Branch => vec![1u8],
BlockLocation::BranchBecomingCanonChain(ref data) => {
let mut bytes = (&data.enacted, &data.retracted, &data.ancestor).to_bytes_map();
bytes.insert(0, 2u8);
bytes
}
}
BranchBecomingCanonChain {
/// Hash of the newest common ancestor with old canon chain.
ancestor: H256,
/// Hashes of the blocks between ancestor and this block.
enacted: Vec<H256>,
/// Hashes of the blocks which were invalidated.
retracted: Vec<H256>,
}
}

View File

@@ -17,23 +17,40 @@
//! Blockchain database.
use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrder};
use bloomchain as bc;
use util::*;
use header::*;
use super::extras::*;
use extras::*;
use transaction::*;
use views::*;
use receipt::Receipt;
use blooms::{Bloom, BloomGroup};
use blockchain::block_info::{BlockInfo, BlockLocation, BranchBecomingCanonChainData};
use chainfilter::{ChainFilter, BloomIndex, FilterDataSource};
use blockchain::block_info::{BlockInfo, BlockLocation};
use blockchain::best_block::BestBlock;
use types::tree_route::TreeRoute;
use blockchain::bloom_indexer::BloomIndexer;
use blockchain::tree_route::TreeRoute;
use blockchain::update::ExtrasUpdate;
use blockchain::{CacheSize, ImportRoute, Config};
use db::{Writable, Readable, CacheUpdatePolicy};
use blockchain::{CacheSize, ImportRoute};
const LOG_BLOOMS_LEVELS: usize = 3;
const LOG_BLOOMS_ELEMENTS_PER_INDEX: usize = 16;
const BLOOM_INDEX_SIZE: usize = 16;
const BLOOM_LEVELS: u8 = 3;
/// Blockchain configuration.
#[derive(Debug)]
pub struct BlockChainConfig {
/// Preferred cache size in bytes.
pub pref_cache_size: usize,
/// Maximum cache size in bytes.
pub max_cache_size: usize,
}
impl Default for BlockChainConfig {
fn default() -> Self {
BlockChainConfig {
pref_cache_size: 1 << 14,
max_cache_size: 1 << 20,
}
}
}
/// Interface for querying blocks by hash and by number.
pub trait BlockProvider {
@@ -111,11 +128,7 @@ pub trait BlockProvider {
#[derive(Debug, Hash, Eq, PartialEq, Clone)]
enum CacheID {
Block(H256),
BlockDetails(H256),
BlockHashes(BlockNumber),
TransactionAddresses(H256),
BlocksBlooms(LogGroupPosition),
BlockReceipts(H256),
Extras(ExtrasIndex, H256),
}
struct CacheManager {
@@ -123,14 +136,6 @@ struct CacheManager {
in_use: HashSet<CacheID>,
}
impl bc::group::BloomGroupDatabase for BlockChain {
fn blooms_at(&self, position: &bc::group::GroupPosition) -> Option<bc::group::BloomGroup> {
let position = LogGroupPosition::from(position.clone());
self.note_used(CacheID::BlocksBlooms(position.clone()));
self.extras_db.read_with_cache(&self.blocks_blooms, &position).map(Into::into)
}
}
/// Structure providing fast access to blockchain data.
///
/// **Does not do input data verification.**
@@ -138,7 +143,6 @@ pub struct BlockChain {
// All locks must be captured in the order declared here.
pref_cache_size: AtomicUsize,
max_cache_size: AtomicUsize,
blooms_config: bc::Config,
best_block: RwLock<BestBlock>,
@@ -149,7 +153,8 @@ pub struct BlockChain {
block_details: RwLock<HashMap<H256, BlockDetails>>,
block_hashes: RwLock<HashMap<BlockNumber, H256>>,
transaction_addresses: RwLock<HashMap<H256, TransactionAddress>>,
blocks_blooms: RwLock<HashMap<LogGroupPosition, BloomGroup>>,
block_logs: RwLock<HashMap<H256, BlockLogBlooms>>,
blocks_blooms: RwLock<HashMap<H256, BlocksBlooms>>,
block_receipts: RwLock<HashMap<H256, BlockReceipts>>,
extras_db: Database,
@@ -157,14 +162,24 @@ pub struct BlockChain {
cache_man: RwLock<CacheManager>,
// blooms indexing
bloom_indexer: BloomIndexer,
insert_lock: Mutex<()>
}
impl FilterDataSource for BlockChain {
fn bloom_at_index(&self, bloom_index: &BloomIndex) -> Option<H2048> {
let location = self.bloom_indexer.location(bloom_index);
self.blocks_blooms(&location.hash).and_then(|blooms| blooms.blooms.into_iter().nth(location.index).cloned())
}
}
impl BlockProvider for BlockChain {
/// Returns true if the given block is known
/// (though not necessarily a part of the canon chain).
fn is_known(&self, hash: &H256) -> bool {
self.extras_db.exists_with_cache(&self.block_details, hash)
self.query_extras_exist(hash, &self.block_details)
}
/// Get raw block data
@@ -194,36 +209,28 @@ impl BlockProvider for BlockChain {
/// Get the familial details concerning a block.
fn block_details(&self, hash: &H256) -> Option<BlockDetails> {
self.note_used(CacheID::BlockDetails(hash.clone()));
self.extras_db.read_with_cache(&self.block_details, hash)
self.query_extras(hash, &self.block_details)
}
/// Get the hash of given block's number.
fn block_hash(&self, index: BlockNumber) -> Option<H256> {
self.note_used(CacheID::BlockHashes(index));
self.extras_db.read_with_cache(&self.block_hashes, &index)
self.query_extras(&index, &self.block_hashes)
}
/// Get the address of transaction with given hash.
fn transaction_address(&self, hash: &H256) -> Option<TransactionAddress> {
self.note_used(CacheID::TransactionAddresses(hash.clone()));
self.extras_db.read_with_cache(&self.transaction_addresses, hash)
self.query_extras(hash, &self.transaction_addresses)
}
/// Get receipts of block with given hash.
fn block_receipts(&self, hash: &H256) -> Option<BlockReceipts> {
self.note_used(CacheID::BlockReceipts(hash.clone()));
self.extras_db.read_with_cache(&self.block_receipts, hash)
self.query_extras(hash, &self.block_receipts)
}
/// Returns numbers of blocks containing given bloom.
fn blocks_with_bloom(&self, bloom: &H2048, from_block: BlockNumber, to_block: BlockNumber) -> Vec<BlockNumber> {
let range = from_block as bc::Number..to_block as bc::Number;
let chain = bc::group::BloomGroupChain::new(self.blooms_config, self);
chain.with_bloom(&range, &Bloom::from(bloom.clone()).into())
.into_iter()
.map(|b| b as BlockNumber)
.collect()
let filter = ChainFilter::new(self, self.bloom_indexer.index_size(), self.bloom_indexer.levels());
filter.blocks_with_bloom(bloom, from_block as usize, to_block as usize).into_iter().map(|b| b as BlockNumber).collect()
}
}
@@ -249,26 +256,16 @@ impl<'a> Iterator for AncestryIter<'a> {
impl BlockChain {
/// Create new instance of blockchain from given Genesis
pub fn new(config: Config, genesis: &[u8], path: &Path) -> BlockChain {
pub fn new(config: BlockChainConfig, genesis: &[u8], path: &Path) -> BlockChain {
// open extras db
let mut extras_path = path.to_path_buf();
extras_path.push("extras");
let extras_db = match config.db_cache_size {
None => Database::open_default(extras_path.to_str().unwrap()).unwrap(),
Some(cache_size) => Database::open(
&DatabaseConfig::with_cache(cache_size/2),
extras_path.to_str().unwrap()).unwrap(),
};
let extras_db = Database::open_default(extras_path.to_str().unwrap()).unwrap();
// open blocks db
let mut blocks_path = path.to_path_buf();
blocks_path.push("blocks");
let blocks_db = match config.db_cache_size {
None => Database::open_default(blocks_path.to_str().unwrap()).unwrap(),
Some(cache_size) => Database::open(
&DatabaseConfig::with_cache(cache_size/2),
blocks_path.to_str().unwrap()).unwrap(),
};
let blocks_db = Database::open_default(blocks_path.to_str().unwrap()).unwrap();
let mut cache_man = CacheManager{cache_usage: VecDeque::new(), in_use: HashSet::new()};
(0..COLLECTION_QUEUE_SIZE).foreach(|_| cache_man.cache_usage.push_back(HashSet::new()));
@@ -276,20 +273,18 @@ impl BlockChain {
let bc = BlockChain {
pref_cache_size: AtomicUsize::new(config.pref_cache_size),
max_cache_size: AtomicUsize::new(config.max_cache_size),
blooms_config: bc::Config {
levels: LOG_BLOOMS_LEVELS,
elements_per_index: LOG_BLOOMS_ELEMENTS_PER_INDEX,
},
best_block: RwLock::new(BestBlock::default()),
blocks: RwLock::new(HashMap::new()),
block_details: RwLock::new(HashMap::new()),
block_hashes: RwLock::new(HashMap::new()),
transaction_addresses: RwLock::new(HashMap::new()),
block_logs: RwLock::new(HashMap::new()),
blocks_blooms: RwLock::new(HashMap::new()),
block_receipts: RwLock::new(HashMap::new()),
extras_db: extras_db,
blocks_db: blocks_db,
cache_man: RwLock::new(cache_man),
bloom_indexer: BloomIndexer::new(BLOOM_INDEX_SIZE, BLOOM_LEVELS),
insert_lock: Mutex::new(()),
};
@@ -313,8 +308,8 @@ impl BlockChain {
bc.blocks_db.put(&hash, genesis).unwrap();
let batch = DBTransaction::new();
batch.write(&hash, &details);
batch.write(&header.number(), &hash);
batch.put_extras(&hash, &details);
batch.put_extras(&header.number(), &hash);
batch.put(b"best", &hash).unwrap();
bc.extras_db.write(batch).unwrap();
@@ -426,7 +421,6 @@ impl BlockChain {
}
}
#[cfg_attr(feature="dev", allow(similar_names))]
/// Inserts the block into backing cache database.
/// Expects the block to be valid and already verified.
/// If the block is already known, does nothing.
@@ -464,22 +458,28 @@ impl BlockChain {
batch.put(b"best", &update.info.hash).unwrap();
{
for hash in update.block_details.keys().cloned() {
self.note_used(CacheID::BlockDetails(hash));
}
let mut write_details = self.block_details.write().unwrap();
batch.extend_with_cache(write_details.deref_mut(), update.block_details, CacheUpdatePolicy::Overwrite);
for (hash, details) in update.block_details.into_iter() {
batch.put_extras(&hash, &details);
self.note_used(CacheID::Extras(ExtrasIndex::BlockDetails, hash.clone()));
write_details.insert(hash, details);
}
}
{
let mut write_receipts = self.block_receipts.write().unwrap();
batch.extend_with_cache(write_receipts.deref_mut(), update.block_receipts, CacheUpdatePolicy::Remove);
for (hash, receipt) in &update.block_receipts {
batch.put_extras(hash, receipt);
write_receipts.remove(hash);
}
}
{
let mut write_blocks_blooms = self.blocks_blooms.write().unwrap();
batch.extend_with_cache(write_blocks_blooms.deref_mut(), update.blocks_blooms, CacheUpdatePolicy::Remove);
for (bloom_hash, blocks_bloom) in &update.blocks_blooms {
batch.put_extras(bloom_hash, blocks_bloom);
write_blocks_blooms.remove(bloom_hash);
}
}
// These cached values must be updated last and togeterh
@@ -500,8 +500,15 @@ impl BlockChain {
}
}
batch.extend_with_cache(write_hashes.deref_mut(), update.block_hashes, CacheUpdatePolicy::Remove);
batch.extend_with_cache(write_txs.deref_mut(), update.transactions_addresses, CacheUpdatePolicy::Remove);
for (number, hash) in &update.block_hashes {
batch.put_extras(number, hash);
write_hashes.remove(number);
}
for (hash, tx_address) in &update.transactions_addresses {
batch.put_extras(hash, tx_address);
write_txs.remove(hash);
}
// update extras database
self.extras_db.write(batch).unwrap();
@@ -522,11 +529,6 @@ impl BlockChain {
/// Given a block's `parent`, find every block header which represents a valid possible uncle.
pub fn find_uncle_headers(&self, parent: &H256, uncle_generations: usize) -> Option<Vec<Header>> {
self.find_uncle_hashes(parent, uncle_generations).map(|v| v.into_iter().filter_map(|h| self.block_header(&h)).collect())
}
/// Given a block's `parent`, find every block hash which represents a valid possible uncle.
pub fn find_uncle_hashes(&self, parent: &H256, uncle_generations: usize) -> Option<Vec<H256>> {
if !self.is_known(parent) { return None; }
let mut excluded = HashSet::new();
@@ -538,13 +540,13 @@ impl BlockChain {
let mut ret = Vec::new();
for a in self.ancestry_iter(parent.clone()).unwrap().skip(1).take(uncle_generations) {
ret.extend(self.block_details(&a).unwrap().children.iter()
.filter(|h| !excluded.contains(h))
.filter_map(|h| if excluded.contains(h) { None } else { self.block_header(h) })
);
}
Some(ret)
}
/// Get inserted block info which is critical to prepare extras updates.
/// Get inserted block info which is critical to preapre extras updates.
fn block_info(&self, block_bytes: &[u8]) -> BlockInfo {
let block = BlockView::new(block_bytes);
let header = block.header_view();
@@ -573,11 +575,11 @@ impl BlockChain {
_ => {
let retracted = route.blocks.iter().take(route.index).cloned().collect::<Vec<H256>>();
BlockLocation::BranchBecomingCanonChain(BranchBecomingCanonChainData {
BlockLocation::BranchBecomingCanonChain {
ancestor: route.ancestor,
enacted: route.blocks.into_iter().skip(route.index).collect(),
retracted: retracted.into_iter().rev().collect(),
})
}
}
}
} else {
@@ -598,11 +600,11 @@ impl BlockChain {
BlockLocation::CanonChain => {
block_hashes.insert(number, info.hash.clone());
},
BlockLocation::BranchBecomingCanonChain(ref data) => {
let ancestor_number = self.block_number(&data.ancestor).unwrap();
BlockLocation::BranchBecomingCanonChain { ref ancestor, ref enacted, .. } => {
let ancestor_number = self.block_number(ancestor).unwrap();
let start_number = ancestor_number + 1;
for (index, hash) in data.enacted.iter().cloned().enumerate() {
for (index, hash) in enacted.iter().cloned().enumerate() {
block_hashes.insert(start_number + index as BlockNumber, hash);
}
@@ -677,38 +679,44 @@ impl BlockChain {
/// Later, BloomIndexer is used to map bloom location on filter layer (BloomIndex)
/// to bloom location in database (BlocksBloomLocation).
///
fn prepare_block_blooms_update(&self, block_bytes: &[u8], info: &BlockInfo) -> HashMap<LogGroupPosition, BloomGroup> {
fn prepare_block_blooms_update(&self, block_bytes: &[u8], info: &BlockInfo) -> HashMap<H256, BlocksBlooms> {
let block = BlockView::new(block_bytes);
let header = block.header_view();
let log_blooms = match info.location {
let modified_blooms = match info.location {
BlockLocation::Branch => HashMap::new(),
BlockLocation::CanonChain => {
let chain = bc::group::BloomGroupChain::new(self.blooms_config, self);
chain.insert(info.number as bc::Number, Bloom::from(header.log_bloom()).into())
ChainFilter::new(self, self.bloom_indexer.index_size(), self.bloom_indexer.levels())
.add_bloom(&header.log_bloom(), header.number() as usize)
},
BlockLocation::BranchBecomingCanonChain(ref data) => {
let ancestor_number = self.block_number(&data.ancestor).unwrap();
BlockLocation::BranchBecomingCanonChain { ref ancestor, ref enacted, .. } => {
let ancestor_number = self.block_number(ancestor).unwrap();
let start_number = ancestor_number + 1;
let range = start_number as bc::Number..self.best_block_number() as bc::Number;
let mut blooms: Vec<bc::Bloom> = data.enacted.iter()
let mut blooms: Vec<H2048> = enacted.iter()
.map(|hash| self.block(hash).unwrap())
.map(|bytes| BlockView::new(&bytes).header_view().log_bloom())
.map(Bloom::from)
.map(Into::into)
.collect();
blooms.push(Bloom::from(header.log_bloom()).into());
blooms.push(header.log_bloom());
let chain = bc::group::BloomGroupChain::new(self.blooms_config, self);
chain.replace(&range, blooms)
ChainFilter::new(self, self.bloom_indexer.index_size(), self.bloom_indexer.levels())
.reset_chain_head(&blooms, start_number as usize, self.best_block_number() as usize)
}
};
log_blooms.into_iter()
.map(|p| (From::from(p.0), From::from(p.1)))
.collect()
modified_blooms.into_iter()
.fold(HashMap::new(), | mut acc, (bloom_index, bloom) | {
{
let location = self.bloom_indexer.location(&bloom_index);
let mut blocks_blooms = acc
.entry(location.hash.clone())
.or_insert_with(|| self.blocks_blooms(&location.hash).unwrap_or_else(BlocksBlooms::new));
assert_eq!(self.bloom_indexer.index_size(), blocks_blooms.blooms.len());
blocks_blooms.blooms[location.index] = bloom;
}
acc
})
}
/// Get best block hash.
@@ -726,14 +734,54 @@ impl BlockChain {
self.best_block.read().unwrap().total_difficulty
}
/// Get block blooms.
fn blocks_blooms(&self, hash: &H256) -> Option<BlocksBlooms> {
self.query_extras(hash, &self.blocks_blooms)
}
fn query_extras<K, T>(&self, hash: &K, cache: &RwLock<HashMap<K, T>>) -> Option<T> where
T: Clone + Decodable + ExtrasIndexable,
K: ExtrasSliceConvertable + Eq + Hash + Clone {
{
let read = cache.read().unwrap();
if let Some(v) = read.get(hash) {
return Some(v.clone());
}
}
if let Some(h) = hash.as_h256() {
self.note_used(CacheID::Extras(T::extras_index(), h.clone()));
}
self.extras_db.get_extras(hash).map(| t: T | {
let mut write = cache.write().unwrap();
write.insert(hash.clone(), t.clone());
t
})
}
fn query_extras_exist<K, T>(&self, hash: &K, cache: &RwLock<HashMap<K, T>>) -> bool where
K: ExtrasSliceConvertable + Eq + Hash + Clone,
T: ExtrasIndexable {
{
let read = cache.read().unwrap();
if let Some(_) = read.get(hash) {
return true;
}
}
self.extras_db.extras_exists::<_, T>(hash)
}
/// Get current cache size.
pub fn cache_size(&self) -> CacheSize {
CacheSize {
blocks: self.blocks.read().unwrap().heap_size_of_children(),
block_details: self.block_details.read().unwrap().heap_size_of_children(),
transaction_addresses: self.transaction_addresses.read().unwrap().heap_size_of_children(),
block_logs: self.block_logs.read().unwrap().heap_size_of_children(),
blocks_blooms: self.blocks_blooms.read().unwrap().heap_size_of_children(),
block_receipts: self.block_receipts.read().unwrap().heap_size_of_children(),
block_receipts: self.block_receipts.read().unwrap().heap_size_of_children()
}
}
@@ -762,6 +810,7 @@ impl BlockChain {
let mut block_details = self.block_details.write().unwrap();
let mut block_hashes = self.block_hashes.write().unwrap();
let mut transaction_addresses = self.transaction_addresses.write().unwrap();
let mut block_logs = self.block_logs.write().unwrap();
let mut blocks_blooms = self.blocks_blooms.write().unwrap();
let mut block_receipts = self.block_receipts.write().unwrap();
let mut cache_man = self.cache_man.write().unwrap();
@@ -770,11 +819,12 @@ impl BlockChain {
cache_man.in_use.remove(&id);
match id {
CacheID::Block(h) => { blocks.remove(&h); },
CacheID::BlockDetails(h) => { block_details.remove(&h); }
CacheID::BlockHashes(h) => { block_hashes.remove(&h); }
CacheID::TransactionAddresses(h) => { transaction_addresses.remove(&h); }
CacheID::BlocksBlooms(h) => { blocks_blooms.remove(&h); }
CacheID::BlockReceipts(h) => { block_receipts.remove(&h); }
CacheID::Extras(ExtrasIndex::BlockDetails, h) => { block_details.remove(&h); },
CacheID::Extras(ExtrasIndex::TransactionAddress, h) => { transaction_addresses.remove(&h); },
CacheID::Extras(ExtrasIndex::BlockLogBlooms, h) => { block_logs.remove(&h); },
CacheID::Extras(ExtrasIndex::BlocksBlooms, h) => { blocks_blooms.remove(&h); },
CacheID::Extras(ExtrasIndex::BlockReceipts, h) => { block_receipts.remove(&h); },
_ => panic!(),
}
}
cache_man.cache_usage.push_front(HashSet::new());
@@ -786,6 +836,7 @@ impl BlockChain {
block_details.shrink_to_fit();
block_hashes.shrink_to_fit();
transaction_addresses.shrink_to_fit();
block_logs.shrink_to_fit();
blocks_blooms.shrink_to_fit();
block_receipts.shrink_to_fit();
}
@@ -798,12 +849,11 @@ impl BlockChain {
#[cfg(test)]
mod tests {
#![cfg_attr(feature="dev", allow(similar_names))]
use std::str::FromStr;
use rustc_serialize::hex::FromHex;
use util::hash::*;
use util::sha3::Hashable;
use blockchain::{BlockProvider, BlockChain, Config, ImportRoute};
use blockchain::{BlockProvider, BlockChain, BlockChainConfig, ImportRoute};
use tests::helpers::*;
use devtools::*;
use blockchain::generator::{ChainGenerator, ChainIterator, BlockFinalizer};
@@ -819,7 +869,7 @@ mod tests {
let first_hash = BlockView::new(&first).header_view().sha3();
let temp = RandomTempPath::new();
let bc = BlockChain::new(Config::default(), &genesis, temp.as_path());
let bc = BlockChain::new(BlockChainConfig::default(), &genesis, temp.as_path());
assert_eq!(bc.genesis_hash(), genesis_hash.clone());
assert_eq!(bc.best_block_number(), 0);
@@ -847,7 +897,7 @@ mod tests {
let genesis_hash = BlockView::new(&genesis).header_view().sha3();
let temp = RandomTempPath::new();
let bc = BlockChain::new(Config::default(), &genesis, temp.as_path());
let bc = BlockChain::new(BlockChainConfig::default(), &genesis, temp.as_path());
let mut block_hashes = vec![genesis_hash.clone()];
for _ in 0..10 {
@@ -879,7 +929,7 @@ mod tests {
let b5a = canon_chain.generate(&mut finalizer).unwrap();
let temp = RandomTempPath::new();
let bc = BlockChain::new(Config::default(), &genesis, temp.as_path());
let bc = BlockChain::new(BlockChainConfig::default(), &genesis, temp.as_path());
bc.insert_block(&b1a, vec![]);
bc.insert_block(&b1b, vec![]);
bc.insert_block(&b2a, vec![]);
@@ -920,7 +970,7 @@ mod tests {
let best_block_hash = b3a_hash.clone();
let temp = RandomTempPath::new();
let bc = BlockChain::new(Config::default(), &genesis, temp.as_path());
let bc = BlockChain::new(BlockChainConfig::default(), &genesis, temp.as_path());
let ir1 = bc.insert_block(&b1, vec![]);
let ir2 = bc.insert_block(&b2, vec![]);
let ir3b = bc.insert_block(&b3b, vec![]);
@@ -929,25 +979,21 @@ mod tests {
assert_eq!(ir1, ImportRoute {
enacted: vec![b1_hash],
retracted: vec![],
omitted: vec![],
});
assert_eq!(ir2, ImportRoute {
enacted: vec![b2_hash],
retracted: vec![],
omitted: vec![],
});
assert_eq!(ir3b, ImportRoute {
enacted: vec![b3b_hash],
retracted: vec![],
omitted: vec![],
});
assert_eq!(ir3a, ImportRoute {
enacted: vec![b3a_hash],
retracted: vec![b3b_hash],
omitted: vec![],
});
assert_eq!(bc.best_block_hash(), best_block_hash);
@@ -1025,14 +1071,14 @@ mod tests {
let temp = RandomTempPath::new();
{
let bc = BlockChain::new(Config::default(), &genesis, temp.as_path());
let bc = BlockChain::new(BlockChainConfig::default(), &genesis, temp.as_path());
assert_eq!(bc.best_block_hash(), genesis_hash);
bc.insert_block(&first, vec![]);
assert_eq!(bc.best_block_hash(), first_hash);
}
{
let bc = BlockChain::new(Config::default(), &genesis, temp.as_path());
let bc = BlockChain::new(BlockChainConfig::default(), &genesis, temp.as_path());
assert_eq!(bc.best_block_hash(), first_hash);
}
}
@@ -1085,7 +1131,7 @@ mod tests {
let b1_hash = H256::from_str("f53f268d23a71e85c7d6d83a9504298712b84c1a2ba220441c86eeda0bf0b6e3").unwrap();
let temp = RandomTempPath::new();
let bc = BlockChain::new(Config::default(), &genesis, temp.as_path());
let bc = BlockChain::new(BlockChainConfig::default(), &genesis, temp.as_path());
bc.insert_block(&b1, vec![]);
let transactions = bc.transactions(&b1_hash).unwrap();
@@ -1116,7 +1162,7 @@ mod tests {
let b2a = canon_chain.with_bloom(bloom_ba.clone()).generate(&mut finalizer).unwrap();
let temp = RandomTempPath::new();
let bc = BlockChain::new(Config::default(), &genesis, temp.as_path());
let bc = BlockChain::new(BlockChainConfig::default(), &genesis, temp.as_path());
let blocks_b1 = bc.blocks_with_bloom(&bloom_b1, 0, 5);
let blocks_b2 = bc.blocks_with_bloom(&bloom_b2, 0, 5);

View File

@@ -0,0 +1,102 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use util::numbers::H256;
use chainfilter::BloomIndex;
/// Represents location of block bloom in extras database.
#[derive(Debug, PartialEq)]
pub struct BlocksBloomLocation {
/// Unique hash of BlocksBloom
pub hash: H256,
/// Index within BlocksBloom
pub index: usize,
}
/// Should be used to localize blocks blooms in extras database.
pub struct BloomIndexer {
index_size: usize,
levels: u8,
}
impl BloomIndexer {
/// Plain constructor.
pub fn new(index_size: usize, levels: u8) -> Self {
BloomIndexer {
index_size: index_size,
levels: levels
}
}
/// Calculates bloom's position in database.
pub fn location(&self, bloom_index: &BloomIndex) -> BlocksBloomLocation {
use std::{mem, ptr};
let hash = unsafe {
let mut hash: H256 = mem::zeroed();
ptr::copy(&[bloom_index.index / self.index_size] as *const usize as *const u8, hash.as_mut_ptr(), 8);
hash[8] = bloom_index.level;
hash.reverse();
hash
};
BlocksBloomLocation {
hash: hash,
index: bloom_index.index % self.index_size
}
}
/// Returns index size.
pub fn index_size(&self) -> usize {
self.index_size
}
/// Returns number of cache levels.
pub fn levels(&self) -> u8 {
self.levels
}
}
#[cfg(test)]
mod tests {
use std::str::FromStr;
use util::hash::{H256, FixedHash};
use chainfilter::BloomIndex;
use blockchain::bloom_indexer::{BloomIndexer, BlocksBloomLocation};
#[test]
fn test_bloom_indexer() {
let bi = BloomIndexer::new(16, 3);
let index = BloomIndex::new(0, 0);
assert_eq!(bi.location(&index), BlocksBloomLocation {
hash: H256::new(),
index: 0
});
let index = BloomIndex::new(1, 0);
assert_eq!(bi.location(&index), BlocksBloomLocation {
hash: H256::from_str("0000000000000000000000000000000000000000000000010000000000000000").unwrap(),
index: 0
});
let index = BloomIndex::new(0, 299_999);
assert_eq!(bi.location(&index), BlocksBloomLocation {
hash: H256::from_str("000000000000000000000000000000000000000000000000000000000000493d").unwrap(),
index: 15
});
}
}

View File

@@ -23,6 +23,8 @@ pub struct CacheSize {
pub block_details: usize,
/// Transaction addresses cache size.
pub transaction_addresses: usize,
/// Logs cache size.
pub block_logs: usize,
/// Blooms cache size.
pub blocks_blooms: usize,
/// Block receipts size.
@@ -31,7 +33,5 @@ pub struct CacheSize {
impl CacheSize {
/// Total amount used by the cache.
pub fn total(&self) -> usize {
self.blocks + self.block_details + self.transaction_addresses + self.blocks_blooms + self.block_receipts
}
pub fn total(&self) -> usize { self.blocks + self.block_details + self.transaction_addresses + self.block_logs + self.blocks_blooms }
}

View File

@@ -1,39 +0,0 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Blockchain configuration.
/// Blockchain configuration.
#[derive(Debug)]
pub struct Config {
/// Preferred cache size in bytes.
pub pref_cache_size: usize,
/// Maximum cache size in bytes.
pub max_cache_size: usize,
/// Backing db cache_size
pub db_cache_size: Option<usize>,
}
impl Default for Config {
fn default() -> Self {
Config {
pref_cache_size: 1 << 14,
max_cache_size: 1 << 20,
db_cache_size: None,
}
}
}

View File

@@ -1,243 +0,0 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Blockchain DB extras.
use bloomchain;
use util::*;
use header::BlockNumber;
use receipt::Receipt;
use db::Key;
use blooms::{GroupPosition, BloomGroup};
/// Represents index of extra data in database
#[derive(Copy, Debug, Hash, Eq, PartialEq, Clone)]
pub enum ExtrasIndex {
/// Block details index
BlockDetails = 0,
/// Block hash index
BlockHash = 1,
/// Transaction address index
TransactionAddress = 2,
/// Block blooms index
BlocksBlooms = 3,
/// Block receipts index
BlockReceipts = 4,
}
fn with_index(hash: &H256, i: ExtrasIndex) -> H264 {
let mut result = H264::default();
result[0] = i as u8;
result.deref_mut()[1..].clone_from_slice(hash);
result
}
pub struct BlockNumberKey([u8; 5]);
impl Deref for BlockNumberKey {
type Target = [u8];
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl Key<H256> for BlockNumber {
type Target = BlockNumberKey;
fn key(&self) -> Self::Target {
let mut result = [0u8; 5];
result[0] = ExtrasIndex::BlockHash as u8;
result[1] = (self >> 24) as u8;
result[2] = (self >> 16) as u8;
result[3] = (self >> 8) as u8;
result[4] = *self as u8;
BlockNumberKey(result)
}
}
impl Key<BlockDetails> for H256 {
type Target = H264;
fn key(&self) -> H264 {
with_index(self, ExtrasIndex::BlockDetails)
}
}
pub struct LogGroupKey([u8; 6]);
impl Deref for LogGroupKey {
type Target = [u8];
fn deref(&self) -> &Self::Target {
&self.0
}
}
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
pub struct LogGroupPosition(GroupPosition);
impl From<bloomchain::group::GroupPosition> for LogGroupPosition {
fn from(position: bloomchain::group::GroupPosition) -> Self {
LogGroupPosition(From::from(position))
}
}
impl HeapSizeOf for LogGroupPosition {
fn heap_size_of_children(&self) -> usize {
self.0.heap_size_of_children()
}
}
impl Key<BloomGroup> for LogGroupPosition {
type Target = LogGroupKey;
fn key(&self) -> Self::Target {
let mut result = [0u8; 6];
result[0] = ExtrasIndex::BlocksBlooms as u8;
result[1] = self.0.level;
result[2] = (self.0.index >> 24) as u8;
result[3] = (self.0.index >> 16) as u8;
result[4] = (self.0.index >> 8) as u8;
result[5] = self.0.index as u8;
LogGroupKey(result)
}
}
impl Key<TransactionAddress> for H256 {
type Target = H264;
fn key(&self) -> H264 {
with_index(self, ExtrasIndex::TransactionAddress)
}
}
impl Key<BlockReceipts> for H256 {
type Target = H264;
fn key(&self) -> H264 {
with_index(self, ExtrasIndex::BlockReceipts)
}
}
/// Familial details concerning a block
#[derive(Debug, Clone)]
pub struct BlockDetails {
/// Block number
pub number: BlockNumber,
/// Total difficulty of the block and all its parents
pub total_difficulty: U256,
/// Parent block hash
pub parent: H256,
/// List of children block hashes
pub children: Vec<H256>
}
impl HeapSizeOf for BlockDetails {
fn heap_size_of_children(&self) -> usize {
self.children.heap_size_of_children()
}
}
impl Decodable for BlockDetails {
fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder {
let d = decoder.as_rlp();
let details = BlockDetails {
number: try!(d.val_at(0)),
total_difficulty: try!(d.val_at(1)),
parent: try!(d.val_at(2)),
children: try!(d.val_at(3)),
};
Ok(details)
}
}
impl Encodable for BlockDetails {
fn rlp_append(&self, s: &mut RlpStream) {
s.begin_list(4);
s.append(&self.number);
s.append(&self.total_difficulty);
s.append(&self.parent);
s.append(&self.children);
}
}
/// Represents address of certain transaction within block
#[derive(Clone)]
pub struct TransactionAddress {
/// Block hash
pub block_hash: H256,
/// Transaction index within the block
pub index: usize
}
impl HeapSizeOf for TransactionAddress {
fn heap_size_of_children(&self) -> usize { 0 }
}
impl Decodable for TransactionAddress {
fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder {
let d = decoder.as_rlp();
let tx_address = TransactionAddress {
block_hash: try!(d.val_at(0)),
index: try!(d.val_at(1)),
};
Ok(tx_address)
}
}
impl Encodable for TransactionAddress {
fn rlp_append(&self, s: &mut RlpStream) {
s.begin_list(2);
s.append(&self.block_hash);
s.append(&self.index);
}
}
/// Contains all block receipts.
#[derive(Clone)]
pub struct BlockReceipts {
pub receipts: Vec<Receipt>,
}
impl BlockReceipts {
pub fn new(receipts: Vec<Receipt>) -> Self {
BlockReceipts {
receipts: receipts
}
}
}
impl Decodable for BlockReceipts {
fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder {
Ok(BlockReceipts {
receipts: try!(Decodable::decode(decoder))
})
}
}
impl Encodable for BlockReceipts {
fn rlp_append(&self, s: &mut RlpStream) {
s.append(&self.receipts);
}
}
impl HeapSizeOf for BlockReceipts {
fn heap_size_of_children(&self) -> usize {
self.receipts.heap_size_of_children()
}
}

View File

@@ -26,8 +26,6 @@ pub struct ImportRoute {
pub retracted: Vec<H256>,
/// Blocks that were validated by new block.
pub enacted: Vec<H256>,
/// Blocks which are neither retracted nor enacted.
pub omitted: Vec<H256>,
}
impl ImportRoute {
@@ -35,7 +33,6 @@ impl ImportRoute {
ImportRoute {
retracted: vec![],
enacted: vec![],
omitted: vec![],
}
}
}
@@ -46,19 +43,13 @@ impl From<BlockInfo> for ImportRoute {
BlockLocation::CanonChain => ImportRoute {
retracted: vec![],
enacted: vec![info.hash],
omitted: vec![],
},
BlockLocation::Branch => ImportRoute {
retracted: vec![],
enacted: vec![],
omitted: vec![info.hash],
},
BlockLocation::BranchBecomingCanonChain(mut data) => {
data.enacted.push(info.hash);
BlockLocation::Branch => ImportRoute::none(),
BlockLocation::BranchBecomingCanonChain { mut enacted, retracted, .. } => {
enacted.push(info.hash);
ImportRoute {
retracted: data.retracted,
enacted: data.enacted,
omitted: vec![],
retracted: retracted,
enacted: enacted,
}
}
}
@@ -69,7 +60,7 @@ impl From<BlockInfo> for ImportRoute {
mod tests {
use util::hash::H256;
use util::numbers::U256;
use blockchain::block_info::{BlockInfo, BlockLocation, BranchBecomingCanonChainData};
use blockchain::block_info::{BlockInfo, BlockLocation};
use blockchain::ImportRoute;
#[test]
@@ -77,7 +68,6 @@ mod tests {
assert_eq!(ImportRoute::none(), ImportRoute {
enacted: vec![],
retracted: vec![],
omitted: vec![],
});
}
@@ -90,11 +80,7 @@ mod tests {
location: BlockLocation::Branch,
};
assert_eq!(ImportRoute::from(info), ImportRoute {
retracted: vec![],
enacted: vec![],
omitted: vec![H256::from(U256::from(1))],
});
assert_eq!(ImportRoute::from(info), ImportRoute::none());
}
#[test]
@@ -109,7 +95,6 @@ mod tests {
assert_eq!(ImportRoute::from(info), ImportRoute {
retracted: vec![],
enacted: vec![H256::from(U256::from(1))],
omitted: vec![],
});
}
@@ -119,17 +104,16 @@ mod tests {
hash: H256::from(U256::from(2)),
number: 0,
total_difficulty: U256::from(0),
location: BlockLocation::BranchBecomingCanonChain(BranchBecomingCanonChainData {
ancestor: H256::from(U256::from(0)),
location: BlockLocation::BranchBecomingCanonChain {
ancestor: H256::from(U256::from(0)),
enacted: vec![H256::from(U256::from(1))],
retracted: vec![H256::from(U256::from(3)), H256::from(U256::from(4))],
})
}
};
assert_eq!(ImportRoute::from(info), ImportRoute {
retracted: vec![H256::from(U256::from(3)), H256::from(U256::from(4))],
enacted: vec![H256::from(U256::from(1)), H256::from(U256::from(2))],
omitted: vec![],
});
}
}

View File

@@ -16,20 +16,18 @@
//! Blockchain database.
pub mod blockchain;
mod best_block;
mod block_info;
pub mod blockchain;
mod bloom_indexer;
mod cache;
mod config;
pub mod extras;
mod import_route;
mod tree_route;
mod update;
mod import_route;
#[cfg(test)]
mod generator;
pub use self::blockchain::{BlockProvider, BlockChain};
pub use self::blockchain::{BlockProvider, BlockChain, BlockChainConfig};
pub use self::cache::CacheSize;
pub use self::config::Config;
pub use types::tree_route::TreeRoute;
pub use self::tree_route::TreeRoute;
pub use self::import_route::ImportRoute;

View File

@@ -14,8 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Tree route info type definition
use util::numbers::H256;
/// Represents a tree route between `from` block and `to` block:

View File

@@ -2,8 +2,7 @@ use std::collections::HashMap;
use util::numbers::H256;
use header::BlockNumber;
use blockchain::block_info::BlockInfo;
use blooms::BloomGroup;
use super::extras::{BlockDetails, BlockReceipts, TransactionAddress, LogGroupPosition};
use extras::{BlockDetails, BlockReceipts, TransactionAddress, BlocksBlooms};
/// Block extras update info.
pub struct ExtrasUpdate {
@@ -18,5 +17,5 @@ pub struct ExtrasUpdate {
/// Modified transaction addresses.
pub transactions_addresses: HashMap<H256, TransactionAddress>,
/// Modified blocks blooms.
pub blocks_blooms: HashMap<LogGroupPosition, BloomGroup>,
pub blocks_blooms: HashMap<H256, BlocksBlooms>,
}

View File

@@ -1,62 +0,0 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use bloomchain as bc;
use util::rlp::*;
use util::HeapSizeOf;
use basic_types::LogBloom;
/// Helper structure representing bloom of the trace.
#[derive(Clone)]
pub struct Bloom(LogBloom);
impl From<LogBloom> for Bloom {
fn from(bloom: LogBloom) -> Self {
Bloom(bloom)
}
}
impl From<bc::Bloom> for Bloom {
fn from(bloom: bc::Bloom) -> Self {
let bytes: [u8; 256] = bloom.into();
Bloom(LogBloom::from(bytes))
}
}
impl Into<bc::Bloom> for Bloom {
fn into(self) -> bc::Bloom {
let log = self.0;
bc::Bloom::from(log.0)
}
}
impl Decodable for Bloom {
fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder {
Decodable::decode(decoder).map(Bloom)
}
}
impl Encodable for Bloom {
fn rlp_append(&self, s: &mut RlpStream) {
Encodable::rlp_append(&self.0, s)
}
}
impl HeapSizeOf for Bloom {
fn heap_size_of_children(&self) -> usize {
0
}
}

View File

@@ -1,74 +0,0 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use bloomchain::group as bc;
use util::rlp::*;
use util::HeapSizeOf;
use super::Bloom;
/// Represents group of X consecutive blooms.
#[derive(Clone)]
pub struct BloomGroup {
blooms: Vec<Bloom>,
}
impl From<bc::BloomGroup> for BloomGroup {
fn from(group: bc::BloomGroup) -> Self {
let blooms = group.blooms
.into_iter()
.map(From::from)
.collect();
BloomGroup {
blooms: blooms
}
}
}
impl Into<bc::BloomGroup> for BloomGroup {
fn into(self) -> bc::BloomGroup {
let blooms = self.blooms
.into_iter()
.map(Into::into)
.collect();
bc::BloomGroup {
blooms: blooms
}
}
}
impl Decodable for BloomGroup {
fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder {
let blooms = try!(Decodable::decode(decoder));
let group = BloomGroup {
blooms: blooms
};
Ok(group)
}
}
impl Encodable for BloomGroup {
fn rlp_append(&self, s: &mut RlpStream) {
Encodable::rlp_append(&self.blooms, s)
}
}
impl HeapSizeOf for BloomGroup {
fn heap_size_of_children(&self) -> usize {
self.blooms.heap_size_of_children()
}
}

View File

@@ -1,25 +0,0 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Bridge between bloomchain crate types and ethcore.
mod bloom;
mod bloom_group;
mod group_position;
pub use self::bloom::Bloom;
pub use self::bloom_group::BloomGroup;
pub use self::group_position::GroupPosition;

View File

@@ -18,7 +18,6 @@ use util::*;
use crypto::sha2::Sha256;
use crypto::ripemd160::Ripemd160;
use crypto::digest::Digest;
use ethjson;
/// Definition of a contract whose implementation is built-in.
pub struct Builtin {
@@ -47,12 +46,13 @@ impl Builtin {
}
/// Create a new object from a builtin-function name with a linear cost associated with input size.
pub fn from_named_linear(name: &str, base_cost: usize, word_cost: usize) -> Builtin {
let cost = Box::new(move|s: usize| -> U256 {
U256::from(base_cost) + U256::from(word_cost) * U256::from((s + 31) / 32)
});
Self::new(cost, new_builtin_exec(name))
pub fn from_named_linear(name: &str, base_cost: usize, word_cost: usize) -> Option<Builtin> {
new_builtin_exec(name).map(|b| {
let cost = Box::new(move|s: usize| -> U256 {
U256::from(base_cost) + U256::from(word_cost) * U256::from((s + 31) / 32)
});
Self::new(cost, b)
})
}
/// Simple forwarder for cost.
@@ -60,15 +60,24 @@ impl Builtin {
/// Simple forwarder for execute.
pub fn execute(&self, input: &[u8], output: &mut[u8]) { (*self.execute)(input, output); }
}
impl From<ethjson::spec::Builtin> for Builtin {
fn from(b: ethjson::spec::Builtin) -> Self {
match b.pricing {
ethjson::spec::Pricing::Linear(linear) => {
Self::from_named_linear(b.name.as_ref(), linear.base, linear.word)
/// Create a builtin from JSON.
///
/// JSON must be of the form `{ "name": "identity", "pricing": {"base": 10, "word": 20} }`.
pub fn from_json(json: &Json) -> Option<Builtin> {
// NICE: figure out a more convenient means of handing errors here.
if let Json::String(ref name) = json["name"] {
if let Json::Object(ref o) = json["pricing"] {
if let Json::Object(ref o) = o["linear"] {
if let Json::U64(ref word) = o["word"] {
if let Json::U64(ref base) = o["base"] {
return Self::from_named_linear(&name[..], *base as usize, *word as usize);
}
}
}
}
}
None
}
}
@@ -83,14 +92,14 @@ pub fn copy_to(src: &[u8], dest: &mut[u8]) {
/// Create a new builtin executor according to `name`.
/// TODO: turn in to a factory with dynamic registration.
pub fn new_builtin_exec(name: &str) -> Box<Fn(&[u8], &mut [u8])> {
pub fn new_builtin_exec(name: &str) -> Option<Box<Fn(&[u8], &mut [u8])>> {
match name {
"identity" => Box::new(move|input: &[u8], output: &mut[u8]| {
"identity" => Some(Box::new(move|input: &[u8], output: &mut[u8]| {
for i in 0..min(input.len(), output.len()) {
output[i] = input[i];
}
}),
"ecrecover" => Box::new(move|input: &[u8], output: &mut[u8]| {
})),
"ecrecover" => Some(Box::new(move|input: &[u8], output: &mut[u8]| {
#[repr(packed)]
#[derive(Debug)]
struct InType {
@@ -113,8 +122,8 @@ pub fn new_builtin_exec(name: &str) -> Box<Fn(&[u8], &mut [u8])> {
}
}
}
}),
"sha256" => Box::new(move|input: &[u8], output: &mut[u8]| {
})),
"sha256" => Some(Box::new(move|input: &[u8], output: &mut[u8]| {
let mut sha = Sha256::new();
sha.input(input);
if output.len() >= 32 {
@@ -124,23 +133,21 @@ pub fn new_builtin_exec(name: &str) -> Box<Fn(&[u8], &mut [u8])> {
sha.result(ret.as_slice_mut());
copy_to(&ret, output);
}
}),
"ripemd160" => Box::new(move|input: &[u8], output: &mut[u8]| {
})),
"ripemd160" => Some(Box::new(move|input: &[u8], output: &mut[u8]| {
let mut sha = Ripemd160::new();
sha.input(input);
let mut ret = H256::new();
sha.result(&mut ret.as_slice_mut()[12..32]);
copy_to(&ret, output);
}),
_ => {
panic!("invalid builtin name {}", name);
}
})),
_ => None
}
}
#[test]
fn identity() {
let f = new_builtin_exec("identity");
let f = new_builtin_exec("identity").unwrap();
let i = [0u8, 1, 2, 3];
let mut o2 = [255u8; 2];
@@ -160,7 +167,7 @@ fn identity() {
#[test]
fn sha256() {
use rustc_serialize::hex::FromHex;
let f = new_builtin_exec("sha256");
let f = new_builtin_exec("sha256").unwrap();
let i = [0u8; 0];
let mut o = [255u8; 32];
@@ -179,7 +186,7 @@ fn sha256() {
#[test]
fn ripemd160() {
use rustc_serialize::hex::FromHex;
let f = new_builtin_exec("ripemd160");
let f = new_builtin_exec("ripemd160").unwrap();
let i = [0u8; 0];
let mut o = [255u8; 32];
@@ -206,7 +213,7 @@ fn ecrecover() {
let s = k.sign(&m).unwrap();
println!("Signed: {}", s);*/
let f = new_builtin_exec("ecrecover");
let f = new_builtin_exec("ecrecover").unwrap();
let i = FromHex::from_hex("47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad000000000000000000000000000000000000000000000000000000000000001b650acf9d3f5f0a2c799776a1254355d5f4061762a237396a99a0e0e3fc2bcd6729514a0dacb2e623ac4abd157cb18163ff942280db4d5caad66ddf941ba12e03").unwrap();
let mut o = [255u8; 32];
@@ -253,15 +260,9 @@ fn ecrecover() {
assert_eq!(&o[..], &(FromHex::from_hex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap())[..]);*/
}
#[test]
#[should_panic]
fn from_unknown_linear() {
let _ = Builtin::from_named_linear("dw", 10, 20);
}
#[test]
fn from_named_linear() {
let b = Builtin::from_named_linear("identity", 10, 20);
let b = Builtin::from_named_linear("identity", 10, 20).unwrap();
assert_eq!((*b.cost)(0), U256::from(10));
assert_eq!((*b.cost)(1), U256::from(30));
assert_eq!((*b.cost)(32), U256::from(30));
@@ -275,14 +276,9 @@ fn from_named_linear() {
#[test]
fn from_json() {
let b = Builtin::from(ethjson::spec::Builtin {
name: "identity".to_owned(),
pricing: ethjson::spec::Pricing::Linear(ethjson::spec::Linear {
base: 10,
word: 20,
})
});
let text = r#"{"name": "identity", "pricing": {"linear": {"base": 10, "word": 20}}}"#;
let json = Json::from_str(text).unwrap();
let b = Builtin::from_json(&json).unwrap();
assert_eq!((*b.cost)(0), U256::from(10));
assert_eq!((*b.cost)(1), U256::from(30));
assert_eq!((*b.cost)(32), U256::from(30));

View File

@@ -14,29 +14,27 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use bloomchain::group as bc;
use util::HeapSizeOf;
//! Represents bloom index in cache
/// Represents `BloomGroup` position in database.
#[derive(PartialEq, Eq, Hash, Clone, Debug)]
pub struct GroupPosition {
/// Bloom level.
/// Represents bloom index in cache
///
/// On cache level 0, every block bloom is represented by different index.
/// On higher cache levels, multiple block blooms are represented by one
/// index. Their `BloomIndex` can be created from block number and given level.
#[derive(Eq, PartialEq, Hash, Clone, Debug)]
pub struct BloomIndex {
/// Bloom level
pub level: u8,
/// Group index.
pub index: u32,
/// Filter Index
pub index: usize,
}
impl From<bc::GroupPosition> for GroupPosition {
fn from(p: bc::GroupPosition) -> Self {
GroupPosition {
level: p.level as u8,
index: p.index as u32,
impl BloomIndex {
/// Default constructor for `BloomIndex`
pub fn new(level: u8, index: usize) -> BloomIndex {
BloomIndex {
level: level,
index: index,
}
}
}
impl HeapSizeOf for GroupPosition {
fn heap_size_of_children(&self) -> usize {
0
}
}

View File

@@ -0,0 +1,739 @@
300054 0x00000000000000000000000000000000000000000000020000001000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
300059 0x00000020000000000000000000000000000000000000000002000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000000000002000
300221 0x00000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002020000000000000000000000000000000000000000000008000000001000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
301826 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
303166 0x00000000000000000000000000000000000000001000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000808000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000020000000001000000000000000000000000000000000000000000000000000000000000000000
303345 0x00000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002020000000000000000000000000000000000000000000008000000001000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
303379 0x00000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000800000000000000001000000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000080000000006000008000000000000000000080000000000000000000000000000000000000000001000000000000000000000008000000000400000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000800000000000000000000000000000000000002004000000000000
303388 0x00000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000800000040000000001000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000080000000006001008000000000000008000080000000000000000000000000000000000000000001000000000000000000000008000000000400000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000800000000000000040000000000000000000002004000000000000
303621 0x00000000000000000000008000000000200000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000080000000000000000000000080000000001100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000
303670 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000400200000000000000
303674 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000040000000000000000000000000000000000000000000000000000000000000000000000001000000000000200000000000000
303683 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000400200000000000000
303689 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000080000000000000000000000000400000000000000000000000000000000000000000000000000000000001000000000040200000000000000
303692 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000400000000000000000000000000000000000000000000000000000000001000000000040200000000000000
303716 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000040000000000000000000000000000000000000000000000000000000000000000000000001000000000000200000000000000
303717 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000040000000000000000000000000000000000000000000000000000000000000000000000001000000000000200000000000000
303748 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000400200000000000000
303756 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000080000000000000000000000000400000000000000000000000000000000000000000000000000000000001000000000040200000000000000
303758 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000400000000000000000000000000000000000000000000000000000000001000000000040200000000000000
304090 0x00000000000000000000000000000000100000000000000000000000000000000000000000000000000200000000000000800000000000000000000000040000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000003000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000
304095 0x04000000000000000000000000000000100000000000000000000000000000000000000000000000000200000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000008000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000
304107 0x00000000000000000000000000000000100000000000000000000000000000000000000000000000000200000000000000800000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008800000000000000000400000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
304113 0x00000000000000000000000000000000100000000000000000000000000000000000000000000000000200000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000002000000000000000000000000000000000000000000000000003008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
304222 0x00000000000000000000000000000000100000000000000000000000000000000000000000000000000200000000000000800000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000800000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
304245 0x00000000000000000000000000000000100000000000000000000000000000000000000000000000000200000000000000800000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000080000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
304247 0x000000080000000000000000000000800000020000000000000000000000000000000000000000000202000000000000008000004004000000000000000000000000000000000000000000000200000000200000000080000000000000000000000004000000000000000000000000000000001040000000000000000000000000000004000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000c0002000000000000000000000000000000001000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
304312 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000020000000000002000000000000000000040000000000000200000000000000000000000000000000000000000000000000000000000000000000000000
304319 0x00000000004000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000100000000000020000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000080000000000000000000000000008000000000000000000000000000000000008000000000000000000000000000000000000020000000000002000000000000000000040000000000000200000000000000000000000000000000000000000000000000000000000000000000000000
304367 0x00000000000000000000001000000000000000000400020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000100000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
304375 0x00000000004000000000001000000000000000000400020000000800000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000020000000000000000000000000000000000000000000000000008000000000000010000000008000000000000000000000000000000000008000800000000000000000000000100000000000000000000000000000000000000000100000000000000002000000000002000000040010010000000000000000000000000000000000000000000000000000000000000000000000000000000000
304407 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000002000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000
304431 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000400000000000000000
304433 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000400000000000000000
304608 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000400000000000000000000040000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000
304609 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000400000000000000000000040000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000
304788 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000400000000000000000
304794 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000400000000000000000
304819 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000400000000000000000
304835 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000002000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000
304849 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000400000000000000000
304856 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000002000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000
304862 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000002000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000
304872 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000400000000000000000
304881 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000400000000000000000
304902 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000400000000000000000
304996 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000400000000000000000
304999 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000002000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000
305006 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000400000000000000000
305010 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000002000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000
305425 0x00000000004000000000000000000001000000000000020000000000000000000000000000000000000000000000000000000000008000000080000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010400000048000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000400000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
305445 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000080000100000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
305448 0x00000000004000000000000000000000000000000000020000000000000000000004000008000000000000000000000000000000000000000000000000000800000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000080000100000000002000000000000000000040000000000000000000000100000000000000000000000000000000000000000000000000000000000000000
305450 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000080000000000000000000000000000020000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000004000000000000000000000000000
305452 0x00000000004000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000002000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000080000000000000000000000000000020000000000000000000000000000000000000000000008002000000000000000000040000000000000000000000000400000000000000000000000000000000004000000000000000000000000000
305454 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000001000000040000000000000000000000000000000000000000000000000000000000000000000000000840000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
305457 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
305463 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000200080000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
305464 0x00000000004000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000008000000000000000000000000000000000240000000200480000000000000000000000000000000000000000000000000000002000000000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
305468 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008080000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000008800000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
305488 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000002000000000000008000000000000010000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
305492 0x00000000004000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000008000000000000000000000000000000008040000000000000000000000000000002000000000001000000000000000000000000000400000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000200000000000000000000000000000000000000000000
305501 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000008000000000000000000040000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000080000000000000
305502 0x00000000004000000000000000000000000000000000020000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000008000000000000008000000000000000000040000000001000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000080000000000000000000000000000000000010000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000080000000000000
305510 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000044000004000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
305616 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
305620 0x0000000000400000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000040000000000000080000000000000000000000000000800000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000040000000001000000000a000000000000000010000000000000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
305622 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000080000000000000000000000000200000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000080000000000000
305624 0x00000000004000000000000000000000000000000000020000000000000000000000000000000000001000000000000000080000000000000000000000000200000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000004000000000000000000000000004000000000000000000000000000000000000080000000000000
305626 0x00000000004000000000100000000000000000000000020000000000000000000000000002000000000000000000000000000000200000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000004000000000002000000000000002000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
305627 0x00000001000000000000000000000200000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000040000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
305629 0x00000001004000000000000000000200000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000040000000002000000000000000000040000000000000000001040000000000000000000000000000000000000000000000000000000000000000000
305634 0x00000000005080000000000000000000000000000000020000400000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008020000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000400000000000000000000000
305826 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000400000000000000002000000000000000000840000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
305827 0x00000000004000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000100000000000000000000000000040000000000000000000000000000000000000000000000000000000000000040000000000000000000000010000000008000000000000000000000000000000100008000000000000000000000000000000000000000000000000000000000000000000000400000000000000002004000000000000000840000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
305829 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000008000000000080000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000080000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
305834 0x00000000004002000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000041000000000000000000000000000000000000008000000000080000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000020000000000000000000000000000008000000000000000000000000000000000000000000000080000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
305839 0x00000000000000000000000000000000000010000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000080000000000000000000000000000000000000000000000000000000000000
305841 0x40000000004000000000000000000000000010000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000008000000008000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000080000000000000000000000000000000000000000000008000000000000000
306889 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
307290 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
307508 0x00000000000000000000000000000000000000000000020000000000000000000000200000000000400000000000000000000000000000000000000000000000002000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
307509 0x00000000004000000000000000000000000000000000020000000000000000000000200000000000400000000000000000000000000000000000000000000000002000000000000000008000000000000000000000000000000000040000000000040000000000000000000000000000000000000000000000000000000000000000000000000010000000008000010000004000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
307513 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000004000000000000000000000000010000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000200000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
307519 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000001000000000000002000000000000000000040000000000000000000000000000000000000000000080000000000000000000000000000000000000000000
307528 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000020000000000000000000000000000000000000000000000000000000000000000100000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
308010 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002020000000000080000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000
308115 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000040000000000000000000000000000000000000000000000000000000000000000000000001000000000000200000000000000
308124 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000400200000000000000
308127 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000040000000000000000000000000000000000000000000000000000000000000000000000001000000000000200000000000000
308157 0x00000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000440000000000000000000000000000000000000020000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000
308183 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000002020000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
308190 0x00000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000440000000000000000000000000000000000000020000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000
308216 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000002020000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000
308224 0x00000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000440000000000000000000000000000000000000020000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000
308257 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000400000000000000000
308265 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000400000000000000000
308267 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000400000000000000000
308268 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000400000000000000000
308285 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000400000000000000000
308599 0x00000000000000000000000000000000000000000000080000000000000800000000000000000010000000000000000000200002000000000000000000000000000000000000000000020000001000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004010010000002000000000000000400000000000000000000000000000000000000000000040000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
309175 0x00000000002000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
309177 0x00000000002000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
309184 0x00000000002000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
309186 0x00000000002000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
309190 0x00000000002000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
309194 0x00000000002000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
309198 0x00000000002000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
309417 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
309881 0x00400000000000000000000000000000000000000000004000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000
309883 0x00400000000000000000000000000000000000000000004000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000
309892 0x00400000000000000000000000000000000000000000004000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000
310069 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000002000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000
310114 0x00400000000000000000000000000000000000000000004000000000000000000000000000100000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
310116 0x00400000000000000000000000000000000000000000004000000000000000000000000000100000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
310177 0x00400000000000000000000000000000000000000000004000000000000000000000000000100000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
310533 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000002000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000
310589 0x00000000000008000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
310592 0x00000000000008000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
310599 0x00000000000008000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
310601 0x00000000000008000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
310604 0x00000000000008000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
311317 0x00000000002000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
311758 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
311858 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
311859 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
311865 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
311888 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
312096 0x00400000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000200000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
312124 0x00400000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000200000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
312367 0x00400000000000000000000000000000000400000000004000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
312371 0x00400000000000000000000000000000000400000000004000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
312383 0x00400000000000000000000000000000000400000000004000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
313355 0x00000000000008000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
313368 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000002000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000
313507 0x00000000000000000000000000000000000000000200000000000000000000000000800000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
313526 0x00000000000000000000000000000000000000000200000000000000000000000000800000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
313724 0x00000000000008000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
313789 0x00000000000008000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
314190 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
314375 0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000008000000000000000008000400000000000000000000000000
315698 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
315705 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
315780 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
316726 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000240000000000000000000000000000000400000000000000000000000020000000000000000000000000000000000000000000040000000000000000
316747 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
317179 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000040000000000000000000000000000000000000000000000000000000000000000000000001000000000000200000000000000
317522 0x04000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000800000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000006001008000000000000008000080000000000000000000000000000000000000000001000000000100000000000008000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000040000000000000008000002004000000000000
317526 0x00000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
317536 0x00000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000020000000000800000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000006000008000000000000000000080000000000000000000000000000000000000000001000000000000000000000008000000800400000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000002004000000000000
317567 0x00000000000000200000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000001004000000000000000004000000020000000000000000000000000000000000000000000000000000000000000000000000000000000001000040000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
317588 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
317597 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000400000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000040000000000000000
317606 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
317610 0x00000000000000200000000000000000000000000000000000020000000000000000000000000000000000400000000000000000000800000080000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000001044000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000400000000000000000000000000000000000000000000000000000000000000000000440000000000000000
317643 0x00000000000000200000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000010000000000000000000000000000004000000000020000000000000000000000000000000000000000000001004000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000040000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
317646 0x00000000000000000000000000000000000000000000000000004000000000000000000000000000000000400000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000010000000000000000000000000000004000000000020000000000000000000000000000000000000000000001000000000000000000004000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
317660 0x00000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000800000000000000001000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000080000000006000008000000000000000000080000000000000000000000000000000000000000001000000000000000000000008000000000400002000000000000000000000000000000000000000000000000000008000000000000000000000000000000000800000000000000000000000000000000000002004000000000000
317957 0x00000000000000000000000000000000000000000200000000000000000000000000800000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
318030 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
318032 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
318033 0x00000000001000000000000000000000000000000000000000000000000000000000000800000008000000000000000000000000000000000000800000000000000001000000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000004000000000000000080000000006000000000000000000000000080000000000000000000000000000000000000000005000000000000000000000000000000008400000000000000000000000000000000000000000000000000008000000000000000000000000020000000000000800000000000000000000000000000000000002004000000000000
318034 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
318036 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
318063 0x00000000001000000000000000000000000000000000000000000000000000000000000800000008000000000000000000000000000000000000800000040000000001000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000004000000000000000080000000006000000000000000000000000080000000000000000000000000000000000000000005000000000000000000000000000000008400000000000000000000000000000000000000000000000000008000000000000000000000000040000000000000800000000000000000000000000000000000002004000000000000
318074 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000100000010020000000000000000000200000000000000000080000000020000000000000000000800000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000008000000000000000000000000000000000000000000000000000008000000000000000000000000020000000000000000000000000000000000000000000000000102000000000000000
318096 0x04000000001000000000000000000000000000000000000000000000000000000000000800000008000000000000000000000000000000000000800000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000080000000006000000000000000000000000080000000000000000000000000000000000000000005000000000100000000000000000000008400000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000800000000000000000000000000000008000002004000000000000
318137 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
318528 0x00000000001000000000000000000000000000000000000000000000000000000000000800000008000000000000000000000000020000000000800000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000080000000006000000000000000000000000080000000000000000000000000000000000000000005000000000000000000000000000000808400000000000000400000000000000000000000000000000000008000000000000000000000000000000000000000800000000000000000000000000000000000002004000000000000
318627 0x00000000001000000000000000000000000000000000000000000000000000000000000800000008000000000000000000000000000000000000800000000000000001000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000004000000000000000080000000006000000000000000000000000080000000000000000000000000000000000000000005000000000000000000000000000000008400002000000000000000000000000000000000000000000000008000008000000000000000000000000000000000800000000000000000000000000000000000002004000000000000
318639 0x00000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000800000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000002000000000000000000000010000000000000004800000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000080000000000000000000000000
318650 0x00000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000800000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000010000000000000004000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000
318653 0x00000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000004000000000000000000000000080000000000000000000000000000000000000000000000000000000200000000000000000000000000800000000000000000000000000000000000000000000000000000000000010000000000000000000000000800000000000000000000000000000000000000000000000000000
318904 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
319523 0x00000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000400000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
321346 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
321884 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
321900 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000400000000000000000000000020000000000000000000000000000000000000000000040000000000000000
322038 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
322041 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
322043 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
322047 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
322048 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
322056 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
322059 0x00000000001000000000000000000000000000000000000000000000000000000000000800000008000000000000000000000000000000000000800000000000000011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000080000000006000000000000000000000001080000800000000000000000000000000000000000005000000000000000000000000000000008400000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000800000000000000000000000000000000000002004000000000000
322083 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
322090 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
322108 0x04000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000010020000000000000000000200000000000000000080000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000080000000000000000000000000000000000000000004000000000100000000000000000000008000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000800000000000000000000000000000008000100000000000000000
322121 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000010000000000100000010020000000000000000000200000000000000000080000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000001080000800000000000000000000000000000000000004000000000000000000000000000000808000000000000000400000000000000000000000000000000000008000000000000000000000000000000000000000800000000000000000000000000000000000100000000000000000
322122 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000100000010020000000000000000040200000000000000000080000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000080000000000000000000000000000000000000000004000000000000000000000000000000008000000000000000000000000000000000000000000000000000008000000000000000000000000040000000000000800000000000000000000000000000000000100000000000000000
322128 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000010020000000000000000000200000000000000000088000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000080000000000000000000000000000000000000000004000000000000000000000000000000008000002000000000000000000000000000000000000000000000008000008000000000000000000000000000000000800000000000000000000000000000000000100000000000000000
322454 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008010000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000010000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000080000000000000000000000000000000000000000000000000000000000000000000000000
322509 0x00000000004000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008010000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000080000000000000000000000000000008000000000200000000000000000010000000000000000000000000000000000000000000000000000000002000000000200000000040000000000000080000000000000000000000000000000000000000000000000000000000000000000000000
322550 0x00000000000000000000000000000000000000000200000000000000000000000000800000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
322749 0x00000000001000000000000000000000000000000000000000000000000000000000000800000008000000000000000000000000000400000000800000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000080000000006400000000000000000000000080000000000000000000000000000000000000000005000000000000000000000000000000008400000000080000000000000000000000000000000000000000008000000000000000000000000000000000000000800000000000000000000000000000000000002004000000000000
322750 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000080000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000020000000000000040000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
322752 0x00000000004000000000000000000000000000000000020000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000008000000000000000000080000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000080000020000000000000040000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000080000000000000000000000
322758 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
322760 0x00000004004000000000000000000000000000000000020000000000000000000000100000000000000000000000000000000000000000000000000000000000010000000000000000008000000000000000000000000000000000040000000000002000000000000000000000000000000000000000000004000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
322764 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000001000000000000000000000000000000000000000000000000000000000000001000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000020000000000000000000000000000000
322765 0x00000000004000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000400000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000001000000000000000000000000000000000000000000000000000000000000001000000000000000002000000000200000000040000000000000000000000000000000000000000000000000000000020000000000000000000000000000000
322767 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002080000000000000000040000000000000000000000000000000000000000000002000000000000000000000000000000000000000000
322768 0x00000000004000000000000000000000000000000000120000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000400000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002080004000000000000040000000000000000000000000000000000000000000002000000000000000000000000000000000000000000
322774 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000008000000000000000000000000000000000000000000000000000000000000000000002001000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
322776 0x00000000004000000000000000000000000000000000020000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000010000000000000000000000000040000000000000000000000000000000010000000008000000000000000000000000000000000009000000000000000008000000000000000000000000000000000000000000000000000000000000000000002001000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
322777 0x00000000004000000000008000100000000000000000020000000000000002000000000000000000000000000000000000000004000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000020000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000001000000000000000000000000000000000000000000000000
324029 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
324316 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000004000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
324318 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000
324322 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000400000000000000000000000000000000000000000000000000000008000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
325807 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
326760 0x00000000000000000000000000000000000000000000000000000040000000000000001000000000000000000000000000008000000000000000000000000000000000008000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000002000000000000008000000000000000
327103 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
327105 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
327227 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000400000000000000000000000020000000000000000000000000000000000000000000040000000000000000
327399 0x00000000000000000000000000000000000000000000000000000000001000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000080000000000000000000800008000000000000000
327544 0x00000000000000000000000000000000000000000000000000000000001000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000080000000000000000000800008000000000000000
327690 0x00000000000000000000000000000100000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
328002 0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000200000000000
328269 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
328529 0x00000000000000000000000000000000000000000000000000000000001000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000080000000000000000000800008000000000000000
328585 0x20000000000000000000100000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
328870 0x00000000000000000000000000000000000000000000000000000000001000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000080000000000000000000800008000000000000000
329480 0x00000000000000000000000000000000000000000000020000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000200000000000000000000000020000000000000000000000000000000000000000000
329484 0x00000000004000000000000008000000000000000000020000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000800000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000000000040000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000200000000000000000000000020000000000000000000000000000000000000000000
329485 0x00000000000000000000000000000000001000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
329491 0x00000000000000000000000000000000001000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
329513 0x00000000000000000000000000000000001000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
329519 0x00000000000000000000000000000000001000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
329659 0x00000000004000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000020000000000000000000000000000000000000000000000000000000000020000000010000000008000000000000000000000000000000000008000000400000000000000000000000000000000000000000000000000000000000000000000000000000002000000080000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000020000000
329667 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000100000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000002000000000000000000000000000000000000000000
329668 0x0000000000400000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000004000000000000010000000000000000000000000000000000000000000000000001000000000000000000001000000000c000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000002000000000000000000800000000000000000000000
329673 0x00000000004000001000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000004000000000000000000000000000000000000000000000000004000000000000000000010000000008000000000000000000000000000002000008000000000000000000000000000000000000000000000000000000000000000000000400400000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
329740 0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000000010000000000000
329749 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000008000000000000000000000000000000000000000002000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
329750 0x00000000004000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000008000000000000000000000000000000000040000000040000000000000000000000010000000000000000000000000000000000000000000000000000010000000008000000000000000000000080000000000008000000000000000000000000000000000000000002000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000400000000000000000000000000000000000000000000
329824 0x00000000000000000000000000000000000000000000200000000000000000000000001000000000000000000000000000008000000008000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
329964 0x00000000000000000000000000000000000000000000000000000000100000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
330023 0x00000000000000000000000000000000000000000000000000000000100000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
330207 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000004000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000200000000000000000000000008000000000000000
330473 0x00000000000400000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000001000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
330511 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000002000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000400000000000000000000000020000000000000000000000000000000000000000000040000000000000000
330579 0x00000000000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000001000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
330683 0x00000000000000000000000000000000000000000000080000000000004000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
330919 0x00020000000000000000000000000000000000000000000000000000000000000008001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
331009 0x00000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
331542 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000100000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000004000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
332007 0x00000000000000000000000000000000000000000000000000000200000080000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008200000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
333256 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000400000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000010000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
333294 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
333583 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000200000000000000000000000000000000000000000000000000010008000000000000000
333640 0x80000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000004000000008000000000000000000000000000000000000010000000000000000000000000000000000008000000000000000
334263 0x00000000000000080000000000000000000000000000000000000000000000000100001000000000000010000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
334279 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000040000020000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000
334883 0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000000000000000
334915 0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000004000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000000000000000
334919 0x00000020000000000000000000000000000000000000000000000000000000000000001000000000000020000000000000008000000000000000000000000000000000000020000000000000020000812000002000000000000000000000000001000000000000000000000000000000400000000000000000000000000000000000000000000000040000800000000010000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000008000400000000008000000000000000
335076 0x00000000000000001000000000000000000000000000000000000000000000000000001000000000000000000100000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
335348 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000080000000008000000000000000000000040000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000008000000000
335643 0x00000000000008000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
335649 0x00000000000008000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
335652 0x00000000000008000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
335684 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000002000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000004000000000000000000000000000000000000000000000000000000000000008000000000000000
336089 0x0000000000000000000000000000000000000000000000000000000000020000000000100000000000000000000000000000800000000000000000000000000000000000000000000000000000000080200000a000000000000000000000000001000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
336231 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
336234 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
336242 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
336243 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
336244 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
336245 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
336247 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
336248 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
336255 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
336260 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
336263 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
336264 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
336266 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
336334 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
336336 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
336337 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
336338 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
336439 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
336451 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
336452 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
336453 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
336461 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
336495 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
336497 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
336507 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
336508 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
336509 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
336510 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
336518 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
336520 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
336521 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
336522 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
336526 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
336527 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
336528 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
336543 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
337012 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000001000000000000000000000000400000000000000802000002000000200000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
337642 0x00000000004000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000408000000000000000000000000000000000040000080000000000000000080000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000020000000000000000002000000000000000000040000000000000001000000000000000000000000000000000000000000000000000000000000000000000000
337647 0x00000000000000000000000000000000000000000000020000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000800000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
337649 0x00000000004000000000000000000000000000000000020000000000000080000000100000000000000000000000000000000000000000000000000000000000000000000000000000008002000000000000000000000000000000040000000000000000000000000000000800000000000000000000000000000000000000000000000002000010000000008000000000000000000000000000000000008000000000000000000000000000000000200000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
337653 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000040000000000000000000040000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
337654 0x00000000004000000000008000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000002000000000000002000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000000020000040000000000000000000040000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
337655 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000040000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000400000000040000000000000000000000000000000000000000000000000000000000000000000000
337656 0x00000000004000000000000000000000000400000000020000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000008000040000000000000000000000000000040000000000000000000000000000000000000000000000000000004000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000400000000040000000000000000000000000000000000000000000000000000000000000000000000
337663 0x00000000004000000000000000000000080000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000001000000000000000000000000000050000000000000000000000000040000000000000000000000000000000000000000004000000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000080000000000000000000000000000000000000
337664 0x00000000000000000000000000000000000000000000020000000010000000000000000000000000001000000000000000000000000000000000000000000000000200000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
337669 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000020000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000008000000000
337672 0x40000000004000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000020000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000020000000000000010000000008000000000000000000000000008000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000008000008000000000
337731 0x00000000000000000000000020000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000800000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
338275 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010004000200000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
338281 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010004000200000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
338336 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
338424 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008004000000000000000000000000000000000000100000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
338435 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000008000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000004000000000000000000000000010000000000000000000000000000000000000
338439 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000010802000002000000000000000000000000001000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000040000000000000000000000000000000000000000000000008000000000000000
338661 0x00000000000000000000000000000000000000000000000000000000001000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000080000000000000000000800008000000000000000
338991 0x00000000000000000000000000200000000000000008000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000400800000000000000000000000000000010000000000000000000000000000000000000000000000000
339173 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002400000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000002000000000000000000000000000000088000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
339369 0x00000020000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000000000000000
339427 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000020000000000000000000001000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
340633 0x00000000000000000000000000000000000000000000020000000004000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000008000000000000001000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
340635 0x00000000004000000000000000000000000000000000020000000004000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000008000000000000001000000000000200000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000001000000000200000000000000000000000000000000000000000000000000000000000000000000
340653 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000001000000002000000000000000000040000000000000000000000000000000000000000000000000000000010000000000000000000000000000000
340658 0x0000000000400000000000000000000400000000000002000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000020000000000000000000001000000000800000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000100000000a000000000000000000040000000000000000000000000000000000000000000000000000000010000000000000000000000000000000
340674 0x00000000000800000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000100000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040080000000000000000000000000000000000000000000000000000000000000000000000000000000000000
340675 0x00000000004800000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000100000000000000000000000000000000000000000000000000000000000000000000000000000002000010000000000000040080000000000000000000000000000000000002000000000000000000080000000000000000000000000000
340685 0x00000000000000000000000000000000000000000000020010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000008000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
340686 0x00004000004000000000000000000000000000000000820010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000010000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000008000000000000040000000000000000000000000000000000000000000000000002000000000000000000000000000000000000
340700 0x00000000004000000000000000000000000000000000020001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000080000000000000000000000000000000000008000000000000000000000000000000000000000000002004200000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000001000
340708 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000008000000000000000000000000000040000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000080000000000000000000000000000000000000
340710 0x00000000004000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000008000000000000000000000000000040000000000000100000000000000000800000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000400000000000000000000000000000000000000000000000000002000002000000000000040000000000000000000000000000000000000000000000000080000000000000000000000000000000000000
340712 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000080040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000008000000000200000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
340713 0x00000000004000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000080840000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000028000000100000000000000000000000000008000000000200000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000001000000000000000000000
340718 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000100000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000002000000000000
340719 0x00000000004000000000000000000000000000000000020000000040000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000008000000000000080000002000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000100000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000002000000000000
340727 0x00000000004000000000040000002000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000200000000000080000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000002000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000001000000000000000000000000000000
340728 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000002000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000100000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
340835 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
340988 0x00000000000000000010000000000000000000000010000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000010000000000008000000000000000
341695 0x00000000000000000000000010000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000001000000000000000000000000000000000000000000000000000000000008000000000000000
341985 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000100000000000004000000000000001000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
341997 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000000000004000000000000001000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
342001 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000100000000000004000000000000001000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
342004 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000100000000000004000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000040000000000000000
342007 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000004000000000000001000000040000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000040000000000000000
342008 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000004000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000040000000000000000
342026 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000002000000004000000000000000000000000000000000000000000000000000000001000000000000000000004000000020000080000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000004000000000000000000000000000000000000000000000000000400000000000000000
342027 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000400000000000000000
342033 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000400000000000000000
342035 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000400000000000000000
342036 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000400000000000000000
342041 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000
342047 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000100000000000000000000000000000000002000000104000000000044100000000000001000002000000000000000000000001000000000000000000004000000000000080000000000000000000000000000000000000002000000000000000000000000020000000000000040000000000000000000000000000004000000000000000000000000000000000000000000000000000400000000000000000
342053 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000004000000000000000000000000000000000000000000000000000040000000000000000
342080 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000400000002000000000000000000000000000000000000000000040000000000000000000001040000000000000000000000000000000080000000010000000000000000000000000000000000000000000000000000000020000000000000000000000000000400000000000000004000000000000000000000000000000000000000000000000000440000000000000000
342101 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000
342107 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000004000000000000000000000000000000000000000000000000000040000000000000000
342111 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000040000000000000000000000040000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000004000000000000000000000000000000000000000000000000000040000000000000000
342115 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000
342118 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000400000002000000004000000000000000000000000000000000000000000000000000000001000000000000000000004000000000000080000000010000000000000000000000000000000000000000000000000000000020000000000000040000000000000000000000000000004000000000000000000000000000000000000000000000000000400000000000000000
342125 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000004000000000000000000000000000000000000000000000000000040000000000000000
342140 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000008000000000000000000080000000000000000800000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000
342141 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000004000000000000000000000000000000000000000000000000000040000000000000000
342145 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000400000002000000000000000000000000000000000000000000040000000000000000000001040000000000000000000000000000000080000000010000000000000000000000000000000000000000000000000000000020000000000000000000000000000400000000000000004000000000000000000000000000000000000000000000000000440000000000000000
342162 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000004000000000000000000000000000000000000000000000000000040000000000000000
342173 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000004000000000000000000000000000000000000000000000000000040000000000000000
342188 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000004000000000000000000000000000000000000000000000000000040000000000000000
342272 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000400000000000000000
342386 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000008000000000000000000000000000000000000000000000000000004000000000000000000000000000008000000000000000000000000001000000000000000000004000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000010000000004000000000000000000000000010000000000000000000400000000000000000
342399 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000
342466 0x00000000000000000000000000000000000000000000000000002000000000000000001000000000080000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
342601 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000040000000000000000000000040000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000004000000000000000000000000000000000000000000000000000040000000000000000
342616 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000008000000000000000000080000000000000000800000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000
342618 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000008000000000000000000080000000000000000800000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000
342924 0x00000000000000000000000000000000000010000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
342964 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000081000000000000000000000000000000000000000000000000000000000000000000000002000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
343006 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000080000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000
343021 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000004000000000000000000000000000000000000000000000000080000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000
343059 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000008000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
343079 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000200000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000040000000000000000
343083 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000040000000000000802000002000000000000000000000000001000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
343133 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
343162 0x00000020000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000100000000000000000000000000008000400000000000000000000000000
343185 0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000008000400000000000000000000000000
343339 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000080000000000000000802000002000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
343946 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
343966 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
343971 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
344121 0x00000000000000000000000000000000000000000000000000000040000000000000001000000000000000000000000000008000000000000000000000000000000000008000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000002000000000000008000000000000000
344164 0x00000000000000000000000000000000000000000000000000000040000000000000001000000000000000000000000000008000000000000000000000000000000000008000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000002000000000000008000000000000000
344839 0x00000000000000000000000000000000000000000000000000000000000000000200001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000008000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
345506 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
346112 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
346392 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
346395 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
346398 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
346425 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
346448 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
346451 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
346454 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
346464 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
346466 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
347014 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000400000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
347301 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000200000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000002000000000000000000000000000000000000000000000000000000000000000008000000000000000
347333 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000200000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000002000000000000000000000000000000000000000000000000000000000000000008000000000000000
347613 0x00000000000000000000000000000000000000000800000000000000000000000000000000000000000001000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010004000000002000000000000000000000000000000000000000000000000000000001000000040000000000000000000000800000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000001000000000000000000000
347700 0x00000000000000000000000000000000000000000000000000000000002000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400010000000000000
347705 0x00000000000000000000000000000000000000000000000000000000002000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400010000000000000
347711 0x00000000000000000000000000000000000000004000000000020000002000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000040010000000000000
347853 0x00000000000000000000000000000000000000000000000000000000002000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000
347953 0x00000000000000000000000000000000000000000000000000000000002000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000080000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000
347958 0x00000000000000000000000000000000000000004000000000020000002000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000040010000000000000
347960 0x00000000000000000000000000000000000000000000000000020000002000000001000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000040010000000000000
348019 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
348244 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000004000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
348443 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000400000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
348675 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000080000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000400100000000000000000000000000000000000000000000000008000000000000000
348743 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
348936 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000100000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000002000000000000000000000000000000000000000008000000000000000
350544 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
351473 0x00000000000000000000000000000000000000000000000000000000002000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000
353157 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
353181 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000004000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000400000000000000000
353196 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000000000000000000080000000000000000000000000000000000000040000000000000000
353273 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000080000000000000000800000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000
353276 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000080000000000000000000000000000000000000040000000000000000
353359 0x00000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000200000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000100000040
353360 0x00000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000040
353361 0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008002400000000000000000000000000
353367 0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000080000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000008000000000000000
353370 0x02000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000000000000000
353438 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000004000000000000000000000000000000080000000000000000000000000000000000000000000000000002000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000040
353443 0x0000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000a000400000000000000000000000000
353447 0x00000028000000000000000000000080000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000000000000000
353479 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000002000001000000000000000000000000100000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
354071 0x02000000000000000000000000000000000000000000020000000000000000000000000040000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000001000000000020000000000000000000000200000000000000020000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000
354151 0x00000000000000000000000000000000000000000000002000000000000000000000400000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004040000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000080000000400000000000000000000000000000000000000000000000000000000000000000000000000000
354162 0x00000000000000000000000000004000000000000000000000000000000000000000410000000000200000000000000002000000000002000000000040000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000
354233 0x00000000000000000000000000000000000000000000000000000000000000000000400040000004000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024040000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000400000000000000000000000040000000000000000000000000000000000100000000000000000
354585 0x00000000000000000000000000000000000000000000000000100000000000000000400000000000200000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004001000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000
354866 0x00000000000000000000000000000000000000000000000000001000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000001
356461 0x00000000000000000000000000200000000000000000000000000000010000000000000000000000000000000000000000202000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
356488 0x00000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000200000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000020000000000000080000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000
356513 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000100001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000080000000000000a00000000000000000000000
356526 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
356535 0x00000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000
356543 0x00000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000800080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000
357195 0x00000000000000000000000000000000000000000000000000000000001000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000080000000000000000000800008000000000000000
357579 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
357588 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
357590 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000200000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000040000000000000000
357592 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
357600 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
357622 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
357630 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
358290 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000400000002000000004000000000000000000000000000000000000000000000000000000001000000000000000000004000000000000080000000010000000000000000000000000000000000000000000000000000000020000000000000040000000000000000000000000000004000000000000000000000000000000000000000000000000000400000000000000000
358426 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000
358556 0x00000000000000000000000000000000000000000000000000000000001000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000080000000000000000000800008000000000000000
358811 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000400000000000000000000000000000000002000000000008000000000000000
359114 0x00000000000000000000000000000000000000000000000000000000001000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000080000000000000000000800008000000000000000
359375 0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000100000000000000000
359378 0x00000020000000000010000000000000000004000000000000000200400000000000000000000000000000000002000000000000000000020000000000000000000000000000000000000000000000010000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000040000000000040010000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000400000000000
359538 0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000008000400000000000000000000000000
361585 0x00000000000000000000000000000000000000000000000000000000001000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000080000000000000000000800008000000000000000
361588 0x00000000000000000000000000000000000000000000000000000000001000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000080000000000000000000800008000000000000000
361732 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000842000002000000000000000000000000001000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000080000000000000000000000000000000000000000000000000000008000000000000000
361757 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000040000000000000000000000040000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000040000000000000000
361775 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000008000000000000000000080000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
362002 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000010000000000000000000000000802000002000000000000000000000400001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
365791 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000040
365793 0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000010000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000400010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000000000000000
369141 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000200000000000000000000000000000000000000000000000000000000000000000008000000000010000
369239 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
369249 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
369253 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
369259 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
369261 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
369263 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
369274 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
369426 0x00000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000200000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000100000040
369428 0x20000020000000000000000000800000000004000000000000000200400000000000000040000000000000000000000000000000000000020000000000000000000000000000000000000000000000010000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000040000000000000010000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000008000400800000000000000000000000
369431 0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018000400000000000100000000000040
369538 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000040
369540 0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000008000400000000000000000000000000
370399 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000001000000000000802000002000000000000000000000000001000000100000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
370517 0x00000000000000000000000000000080200000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000080004000000000000000000000000002000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
370545 0x00000000000000000000000000000080200000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000080004000000000000000000000000002000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
371190 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
371280 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
371286 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
371288 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
371299 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
371307 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
371327 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
371329 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
371352 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
371360 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
371362 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
371369 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
371378 0x00000000000000000000000000000080200000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000080004000000000000000000000000002000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
371450 0x00000000000000000000000000000080200000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000080004000000000000000000000000002000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
371489 0x00000000000000000000000000000080000080004000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000000004000000000000000000000000002000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
371509 0x00000000000000000000000000000080000080004000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000000004000000000000000000000000002000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
371532 0x00000000000000000000000000000080000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
371658 0x00000000000000000000000000000080000080004000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000000004000000000000000000000000002000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
371660 0x00000000000000000000000000000080000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
371876 0x00000000000000000000000000000080000080004000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000000004000000000000000000000000002000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
371904 0x00000000000000000000000000000080000080004000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000000004000000000000000000000000002000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
371906 0x00000000000000000000000000000080000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
371912 0x00000000000000000000000000000080000080004000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000000004000000000000000000000000002000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
371914 0x00000000000000000000000000000080000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
371918 0x00000000000000000000000000000080000080004000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000000004000000000000000000000000002000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
371931 0x00000000000000000000000000000080000080004000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000000004000000000000000000000000002000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
371933 0x00000000000000000000000000000080000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
371938 0x00000000000000000000000000000080000080004000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000000004000000000000000000000000002000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
371940 0x00000000000000000000000000000080000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
371973 0x00000000000000000000000000000080000080004000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000000004000000000000000000000000002000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
372006 0x00000000000000000000000000000080000080004000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000000004000000000000000000000000002000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
372014 0x00000000000000000000000000000080000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
372847 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
374209 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
374225 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
374365 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000010000000000000000000000000000000000000000000000000000000020000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
374388 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020001000000000000000000000200000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
375079 0x00000000000000000000000000000080000080004000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000000004000000000000000000000000002000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
375093 0x00000000000000000000000000000080000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
375401 0x00000000000000000000000000000000000400000400000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
375440 0x00000000000000000000000000000000000400000400000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
375447 0x00000000000000000000000000000000000400000400000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
376493 0x00000000000000000000000000000080000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
376573 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
376588 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
376644 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
376650 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
376668 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
376906 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
377026 0x00000000000000000000000000000000000000000000000000000000001000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000080000000000000000000800008000000000000000
377139 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000001000000000000080000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000080000000000000000000000000000000000000040000000000000000
377506 0x00000000000000000000000000000080000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
377523 0x00000000000000000000000000000080000080004000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000000004000000000000000000000000002000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
377525 0x00000000000000000000000000000080000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
377581 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000040
377586 0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000000000000000000000000000040000000000000000000000100000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000000000000000
377608 0x00000000000000000000000000000000000000000200000000000000000000000000800000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
377627 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000000000000000000080000000000000000000000000000000000000040000000000000000
377629 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000000000000000000080000000000000000000000000000000000000040000000000000000
377703 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000001000000000000080000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000080000000000000000000000000000000000000040000000000000000
377730 0x00000000000000000000000000000000000000000000000000000000001000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000080000000000000000000800008000000000000000
377746 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000004000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000400000000000000000
377877 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000400000002000000004000000000000000000000000000000000000000000000000000000001000000000000000000004000000000000080000000010000000000000000000000000000000000000000000000000000000020000000000000040000000000000000000000000000004000000000000000000000000000000000000000000000000000400000000000000000
377894 0x00000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
377905 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000400000002000000004000000000000000000000000000000000000000000000000000000001000000000000000000004000000000000080000000010000000000000000000000000000000000000000000000000000000020000000000000040000000000000000000000000000004000000000000000000000000000000000000000000000000000400000000000000000
377917 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000004000000000000000000000000000000000000000000000000000040000000000000000
377922 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000040000000000000000000000040000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000004000000000000000000000000000000000000000000000000000040000000000000000
377925 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
378345 0x00000000000000000000000000000000000000000000000000000000001000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000080000000000000000000800008000000000000000
378347 0x00000000000000000000000000000000000000000000000000000000001000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000080000000000000000000800008000000000000000
379027 0x00000020000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000008000400000000000000000000000000
379032 0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000000000000000
379039 0x08000020000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000000000000000
379158 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000400000000000000000002000040000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
379161 0x00000400004000000000000000000000000000000000020000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000040000000000000000000000000000000000000000000010000000008000000000000000000000000000000020008000000000000000000000000000000000000000000000000000000000000000000400000000000000000002000040000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
379163 0x00000000000000000000000000000000000000000000020000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000008000010000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000080000000000000000000000000000000000000000
379164 0x00000000004000000000000000000000000000100000020000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000008000010000000000000000000000000000040000000000001000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000100000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000080000000000000000000000000000000000000000
379167 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000200000000000000000000004
379170 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
379171 0x00000000004000000000000000800000000000000000020000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000008000000000000000000000000000002000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000200000000000000000000004
379172 0x00000000000000000010000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000200000000000000000000000000000000000000000000000000000000000000000000000
379176 0x00000000004000000010000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000100000000000000000000000000000000000000000200000000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000000040000000000000000000000000000000002000000000000000000040000000000000000200000000000000000000000000000000000001000000000000000000000000000000000
379180 0x00000000000080000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000800000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
379182 0x00000000004080000000000002000000000000000800020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000800000000000000000000050000000008000000000000000000000000800000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
379210 0x00000000000000040000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000004000000000000000000000400000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
379212 0x00000000004000040000000000000000000000000000020000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000200000000000008000000000000000000000000000000000000000004000000000000000000000400000000000000000000002000000000000000000040002000000000000000000000000000000000000000000000000000000000000000000000000000000000000
379214 0x00000001000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000080000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
379216 0x00000001004000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000008000000000000008000000000000000000000000000000000040000000000000000000000000000000000020000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000000000080000000000000000000000000000000000000000020002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
379217 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000800000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000020000000000000000000000000000000000000000000000000000000000000000
379219 0x00000000004000000000000000000000000000000000020000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000008000000000000000000000000010000000000000000010000000008800000000000000000000000000000000008000020000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000020000000000000000000000000000000000000000000000000000000000000000
379220 0x00000000000000000000000000200000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000100000000000100002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
379224 0x00000000004000000000000000200000000000000000020000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000008000000000000000040000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000100000000000100002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000400000000000000
379235 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000080000000000000000000000000000000000000000800000000000000000000000000000
379237 0x00000000004000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000100000000008000000000000000000000000000000000000010000000008008000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000080000000000000040000000000000000080000000000000000000000000000000000000000800000000000000000000000000000
381271 0x00000000000000000000000000000080000080004000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000000004000000000000000000000000002000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
381276 0x00000000000000000000000000000080000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
381689 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
382200 0x00000020000000000000000008000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000000000000000
382217 0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000400000010000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000000000000000
382644 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000200000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000002000000000000000000000000000000000000000000000000000000000000000008000000000000000
383284 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
383337 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
383354 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
383361 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
383427 0x00000000000000000000000000000000000004000800000000000000000000000000000000000000000001000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000800000001000000000008000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000040000000000000000000
383466 0x00000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
383469 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000001000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000400000000000000000
383515 0x00000000000000000000000000000000000004000800000000000000000000000000000000000000000001000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000800000001000000000008000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000040000000000000000000
383519 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000010000000800000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000002000000000000000000000000000
383630 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000400000000000000000
383760 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000010000000000000000000000000000000000000000000000000000000020000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
383802 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000080000000000400000000000000000
383815 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000400000000000000004000000000000000000000000000000000000000000000000000000001000000000000000000004000000000000000000000010000000000000000000000040000000000000000000000000000000020000000100000040000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
383844 0x00000000000000000000000000000000100000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
383852 0x00000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000002000000000000000000000000000400000000000000004000000000000000080000000000000000000000000000000000000001000000000000000000004000000000000000000000010000000000000000000000000000000000000000000000000000000020000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
383859 0x00000000000000000000000000000000000000804000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000002000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000040000000000000000
383864 0x00000000000000000000000000000000000000800000000000020000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000080000000000000000040000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000040000000000000000
383968 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000001000000000000080000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000080000000000000000000000000000000000000040000000000000000
383973 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000
384127 0x00000000000000000000000000000000000004000800000000000000000000000000000000000000000001000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000800000001000000000008000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000040000000000000000000
384138 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
384149 0x00000000000000000000000000000000100000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
384173 0x00000000000000000000000000000000100000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000400000000000000000000080000000000000000000000000000000000008000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000001000000000000000000005000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000800000000000000000000000000000400000000000000000
384301 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000040000000000000000000000000000000000000000400000000000000000
384422 0x00000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000400000000000000000
384506 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000400000000000000000
384511 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000400000000000000000
384546 0x00000000000000000000000000000000000004000800000000000000000000000000000000000000000001000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000800000001000000000008000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000040000000000000000000
384771 0x00001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000800000
384825 0x00001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000
384861 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000100000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
384917 0x00000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000400000000000000000
384923 0x00002000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000001000000
384965 0x00000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
385067 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000008000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000400000000000000000
385073 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000008000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000400000000000000000
385356 0x00002000000000000000000000000000000000010000000000000000000000000000000400000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000004000000000000000000000000000000004000000000000000000000000000000000000000000000000000000001000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000001000000
386571 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
386620 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000
386736 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000040000000000000000000000000000010000000020000000000000000000000000000000000000000000000000000000000000000010
386786 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000280000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000040000000000000000000000000000010000000040000000000000000000000000000000000000000000000000000000000000000010
386795 0x04000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000040000000000000000000000000000000000040000000000000000000000000000010000000000000000000000000000000000000000000000000000008000000000000000000010
386804 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000040000000000400000000000000000000000040000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000010
386812 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000042000000000000000000000000000000000040000000000000000008000000000010000000000000000000000000000000000000000000000000000000000000000000000000010
386818 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000280000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000800000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000040000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000010
386899 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000080000000000000000000000000000040000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000010
386939 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000002000000000000000000000000000000000000000200000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000010000000020000000000000000000000000000000000000000000000000000000000000000000
386945 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000020000000000000000000800000000000000000000000000000000000000000200000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000
386975 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000100000000000000000020000000000000000000000000000000000000000000000000000000000000000000
387011 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000010000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000
387014 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000001000000000000000000000040000000000000000000000000000000000000000000000040000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000
387016 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000400000000800000000
387032 0x04000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000
387044 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000020000000000000000000000000000000000000000000080000000000000000000000
387045 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000400000000800000000
387206 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
387225 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
387241 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
387276 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000008000000000000000004000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000021000000000000000000004000000000000000000000400000000000000000000000000000000080000000000000000000000000000000000000040000000000001000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
387284 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000040000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
387365 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000440000000000000000
387615 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000800008000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
387627 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000800000000000000000400000000000000000
387641 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800008000000000000000000000001000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
387648 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000800008000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
387654 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000800008000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000040000000000000000
387658 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000800008000000000000000000000001000000000000000000000000000000000000000000000000040000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000040000000000000000
387683 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000800008000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
387688 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000800008000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000040000000000000000
387690 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000800008000000000000000000000001000000000000000000000000000000000000000000000000040000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000040000000000000000
387761 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000
388108 0x00000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
388111 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000800000000
388150 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000800000000
388246 0x00000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000001000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000
388285 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
388296 0x00000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000001000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000
388516 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
388860 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000020000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000
388893 0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000008000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000020000000000000000000010000000000001000000000000000000000000000000000000000000000000000000000000000400000000000000000
388894 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000020000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000
388907 0x00000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000104000000000004000000000000001000000000000000000000000000001000000000000000000004080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000004000000000000000400000000000000000
388909 0x00000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000400000000000000000
388912 0x00000000000000000000000000000000000000004000000000020000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000000000000000000000000000000000000000004000000000000000040000000000000000
388918 0x00000000000000000000000000000000000000000000000000020000002000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000040000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000004000000000000000040000000000000000
388923 0x00000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000008000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000001000000000000000000000080000000000000000000000000000000000000000000000000000000000008000000000000000020000000000000000000000000000000001000000000000000000000000000000000000000000000004000000000000000400000000000000000
388940 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000020000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000
388971 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000004000000000000000000000000000000000000000800000000000000000000000000000000000
388990 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000
389012 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000
389158 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000
389206 0x00000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000400000000000000000
389238 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000
389277 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000100000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000400000000000000000
389292 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000800000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
389301 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000020000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000040000000000000000
389309 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000020000000000000000000000000000000000000000000000000000000008000000000000000000080000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
389324 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000008000000000000000000000000004000000000000000000000000004000000000000000000000000000000000000000000000000000000001000000000000800000024000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000440000000000000000
389328 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000
389343 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000020000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000040000000000000000
390001 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000001000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
390004 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000200000000000000000000000000000000000000020000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
390024 0x00000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
390042 0x00000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
390236 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
390306 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000001000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
390867 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
391685 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000010000000800000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000002000000000000000000000000000
391690 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000010000000800000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000002000000000000000000000000000
391691 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000010000000800000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000002000000000000000000000000000
391697 0x00000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000040000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000
391713 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000
391849 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000100000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000400000000000000000
392002 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000
392097 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000020000000000000000000000000000000000000000000000000000000008000000000000000000080000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
392104 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000010000000000000000000000000000000000000000000000000000000020000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
392110 0x00000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000
392294 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000004000000000000000000000000000000000000000000000000000000000
392697 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000010000000000000000000000000000400000000000000000
392960 0x00000000000000200000400000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000002000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
392970 0x00000000000000200000400000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000002000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
392990 0x00000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000002000000000000000000000000000000100000000000000000100000000000000000000000000000000000000000000000000000000000002000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
393302 0x00000010000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000400000000000000000
393370 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
393752 0x00000000000000000000000000000000001000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
394354 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000800000024000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
394389 0x00000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000002000000000000000000000000000000100000000000000000100000000000000000000000000000000000000000000000000000000000002000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
394390 0x00000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000002000000000000000000000000000000100000000000000000100000000000000000000000000000000000000000000000000000000000002000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
394391 0x00000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000002000000000000000000000000000000100000000000000000100000000000000000000000000000000000000000000000000000000000002000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
394393 0x00000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000002000000000000000000000000000000100000000000000000100000000000000000000000000000000000000000000000000000000000002000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
394394 0x00000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000002000000000000000000000000000000100000000000000000100000000000000000000000000000000000000000000000000000000000002000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
394395 0x00000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000002000000000000000000000000000000100000000000000000100000000000000000000000000000000000000000000000000000000000002000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
394426 0x00000000000000200000400000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000200000000000000000000000000000000000000000000000000000000000000000000000008000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
394800 0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000100000010000000000000000000000000000000000000000000000000000000000020000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000000000000000
395595 0x00000000000000000000000000000000000000000000000000000000000100000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000800000000000000000000000000000000000000000000000000000000000000000008000000000000000
395969 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
396348 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000010000000000000000000000000000400000000000000000
397108 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000004000000004000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000
397588 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000004000000004000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000
397591 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000004000000004000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000
398412 0x00000000000000000000000000000000000000000000000000000000001000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000080000000000000000000800008000000000000000
398456 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
398477 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
398679 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
398968 0x00000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020200000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000
398972 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000400000000000000000
399058 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000200000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
399804 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000010000000000000000000000000000400000000000000000
399849 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000004000000004000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000

View File

@@ -0,0 +1,197 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Multilevel blockchain bloom filter.
//!
//! ```not_run
//! extern crate ethcore_util as util;
//! extern crate ethcore;
//! use std::str::FromStr;
//! use util::sha3::*;
//! use util::hash::*;
//! use ethcore::chainfilter::*;
//!
//! fn main() {
//! let (index_size, bloom_levels) = (16, 3);
//! let mut cache = MemoryCache::new();
//!
//! let address = Address::from_str("ef2d6d194084c2de36e0dabfce45d046b37d1106").unwrap();
//!
//! // borrow cache for reading inside the scope
//! let modified_blooms = {
//! let filter = ChainFilter::new(&cache, index_size, bloom_levels);
//! let block_number = 39;
//! let mut bloom = H2048::new();
//! bloom.shift_bloomed(&address.sha3());
//! filter.add_bloom(&bloom, block_number)
//! };
//!
//! // number of updated blooms is equal number of levels
//! assert_eq!(modified_blooms.len(), bloom_levels as usize);
//!
//! // lets inserts modified blooms into the cache
//! cache.insert_blooms(modified_blooms);
//!
//! // borrow cache for another reading operations
//! {
//! let filter = ChainFilter::new(&cache, index_size, bloom_levels);
//! let blocks = filter.blocks_with_address(&address, 10, 40);
//! assert_eq!(blocks.len(), 1);
//! assert_eq!(blocks[0], 39);
//! }
//! }
//! ```
//!
use std::collections::{HashMap};
use util::hash::*;
use chainfilter::{BloomIndex, FilterDataSource};
use chainfilter::indexer::Indexer;
/// Should be used for search operations on blockchain.
pub struct ChainFilter<'a, D>
where D: FilterDataSource + 'a
{
data_source: &'a D,
indexer: Indexer,
}
impl<'a, D> ChainFilter<'a, D> where D: FilterDataSource
{
/// Creates new filter instance.
///
/// Borrows `FilterDataSource` for reading.
pub fn new(data_source: &'a D, index_size: usize, levels: u8) -> Self {
ChainFilter {
data_source: data_source,
indexer: Indexer::new(index_size, levels)
}
}
/// internal function which does bloom search recursively
fn blocks(&self, bloom: &H2048, from_block: usize, to_block: usize, level: u8, offset: usize) -> Option<Vec<usize>> {
let index = self.indexer.bloom_index(offset, level);
match self.data_source.bloom_at_index(&index) {
None => return None,
Some(level_bloom) => match level {
// if we are on the lowest level
0 => return match offset <= to_block {
// take the value if its smaller than to_block
true if level_bloom.contains(bloom) => Some(vec![offset]),
// return None if it is is equal to to_block
_ => None
},
// return None if current level doesnt contain given bloom
_ if !level_bloom.contains(bloom) => return None,
// continue processing && go down
_ => ()
}
};
let level_size = self.indexer.level_size(level - 1);
let from_index = self.indexer.bloom_index(from_block, level - 1);
let to_index = self.indexer.bloom_index(to_block, level - 1);
let res: Vec<usize> = self.indexer.lower_level_bloom_indexes(&index).into_iter()
// chose only blooms in range
.filter(|li| li.index >= from_index.index && li.index <= to_index.index)
// map them to offsets
.map(|li| li.index * level_size)
// get all blocks that may contain our bloom
// filter existing ones
.filter_map(|off| self.blocks(bloom, from_block, to_block, level - 1, off))
// flatten nested structures
.flat_map(|v| v)
.collect();
Some(res)
}
/// Adds new bloom to all filter levels
pub fn add_bloom(&self, bloom: &H2048, block_number: usize) -> HashMap<BloomIndex, H2048> {
let mut result: HashMap<BloomIndex, H2048> = HashMap::new();
for level in 0..self.indexer.levels() {
let bloom_index = self.indexer.bloom_index(block_number, level);
let new_bloom = match self.data_source.bloom_at_index(&bloom_index) {
Some(old_bloom) => old_bloom | bloom.clone(),
None => bloom.clone(),
};
result.insert(bloom_index, new_bloom);
}
result
}
/// Resets blooms at level 0 and forces rebuild on higher levels.
pub fn reset_chain_head(&self, blooms: &[H2048], block_number: usize, old_highest_block: usize) -> HashMap<BloomIndex, H2048> {
let mut result: HashMap<BloomIndex, H2048> = HashMap::new();
// insert all new blooms at level 0
for (i, bloom) in blooms.iter().enumerate() {
result.insert(self.indexer.bloom_index(block_number + i, 0), bloom.clone());
}
// reset the rest of blooms
for reset_number in block_number + blooms.len()..(old_highest_block + 1) {
result.insert(self.indexer.bloom_index(reset_number, 0), H2048::new());
}
for level in 1..self.indexer.levels() {
for i in 0..blooms.len() {
let index = self.indexer.bloom_index(block_number + i, level);
let new_bloom = {
// use new blooms before db blooms where necessary
let bloom_at = | index | { result.get(&index).cloned().or_else(|| self.data_source.bloom_at_index(&index)) };
self.indexer.lower_level_bloom_indexes(&index)
.into_iter()
// get blooms
// filter existing ones
.filter_map(bloom_at)
// BitOr all of them
.fold(H2048::new(), |acc, bloom| acc | bloom)
};
result.insert(index, new_bloom);
}
}
result
}
/// Returns numbers of blocks that may log bloom.
pub fn blocks_with_bloom(&self, bloom: &H2048, from_block: usize, to_block: usize) -> Vec<usize> {
let mut result = vec![];
// lets start from highest level
let max_level = self.indexer.max_level();
let level_size = self.indexer.level_size(max_level);
let from_index = self.indexer.bloom_index(from_block, max_level);
let to_index = self.indexer.bloom_index(to_block, max_level);
for index in from_index.index..to_index.index + 1 {
// offset will be used to calculate where we are right now
let offset = level_size * index;
// go doooown!
if let Some(blocks) = self.blocks(bloom, from_block, to_block, max_level, offset) {
result.extend(blocks);
}
}
result
}
}

View File

@@ -0,0 +1,154 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Simplifies working with bloom indexes.
use chainfilter::BloomIndex;
/// Simplifies working with bloom indexes.
pub struct Indexer {
index_size: usize,
level_sizes: Vec<usize>,
}
impl Indexer {
/// Creates new indexer.
pub fn new(index_size: usize, levels: u8) -> Self {
if levels == 0 {
panic!("Indexer requires at least 1 level.");
}
let mut level_sizes = vec![1];
level_sizes.extend_from_slice(&(1..).into_iter()
.scan(1, |acc, _| {
*acc = *acc * index_size;
Some(*acc)
})
.take(levels as usize - 1)
.collect::<Vec<usize>>());
Indexer {
index_size: index_size,
level_sizes: level_sizes,
}
}
/// unsafely get level size.
pub fn level_size(&self, level: u8) -> usize {
self.level_sizes[level as usize]
}
/// Converts block number and level to `BloomIndex`.
pub fn bloom_index(&self, block_number: usize, level: u8) -> BloomIndex {
BloomIndex {
level: level,
index: block_number / self.level_size(level),
}
}
/// Return bloom which are dependencies for given index.
///
/// Bloom indexes are ordered from lowest to highest.
pub fn lower_level_bloom_indexes(&self, index: &BloomIndex) -> Vec<BloomIndex> {
// this is the lowest level
if index.level == 0 {
return vec![];
}
let new_level = index.level - 1;
let offset = self.index_size * index.index;
(0..self.index_size).map(|i| BloomIndex::new(new_level, offset + i)).collect()
}
/// Return number of levels.
pub fn levels(&self) -> u8 {
self.level_sizes.len() as u8
}
/// Returns max indexer level.
pub fn max_level(&self) -> u8 {
self.level_sizes.len() as u8 - 1
}
}
#[cfg(test)]
mod tests {
use chainfilter::BloomIndex;
use chainfilter::indexer::Indexer;
#[test]
fn test_level_size() {
let indexer = Indexer::new(16, 3);
assert_eq!(indexer.level_size(0), 1);
assert_eq!(indexer.level_size(1), 16);
assert_eq!(indexer.level_size(2), 256);
}
#[test]
fn test_bloom_index() {
let indexer = Indexer::new(16, 3);
let bi0 = indexer.bloom_index(0, 0);
assert_eq!(bi0.level, 0);
assert_eq!(bi0.index, 0);
let bi1 = indexer.bloom_index(1, 0);
assert_eq!(bi1.level, 0);
assert_eq!(bi1.index, 1);
let bi2 = indexer.bloom_index(2, 0);
assert_eq!(bi2.level, 0);
assert_eq!(bi2.index, 2);
let bi3 = indexer.bloom_index(3, 1);
assert_eq!(bi3.level, 1);
assert_eq!(bi3.index, 0);
let bi4 = indexer.bloom_index(15, 1);
assert_eq!(bi4.level, 1);
assert_eq!(bi4.index, 0);
let bi5 = indexer.bloom_index(16, 1);
assert_eq!(bi5.level, 1);
assert_eq!(bi5.index, 1);
let bi6 = indexer.bloom_index(255, 2);
assert_eq!(bi6.level, 2);
assert_eq!(bi6.index, 0);
let bi7 = indexer.bloom_index(256, 2);
assert_eq!(bi7.level, 2);
assert_eq!(bi7.index, 1);
}
#[test]
fn test_lower_level_bloom_indexes() {
let indexer = Indexer::new(16, 3);
let bi = indexer.bloom_index(256, 2);
assert_eq!(bi.level, 2);
assert_eq!(bi.index, 1);
let mut ebis = vec![];
for i in 16..32 {
ebis.push(BloomIndex::new(1, i));
}
let bis = indexer.lower_level_bloom_indexes(&bi);
assert_eq!(ebis, bis);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -14,24 +14,22 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use ethkey::Address;
use {SafeAccount, Error};
//! Multilevel blockchain bloom filter.
mod disk;
mod geth;
mod parity;
mod bloomindex;
mod chainfilter;
mod indexer;
pub enum DirectoryType {
Testnet,
Main,
#[cfg(test)]
mod tests;
pub use self::bloomindex::BloomIndex;
pub use self::chainfilter::ChainFilter;
use util::hash::H2048;
/// Types implementing this trait provide read access for bloom filters database.
pub trait FilterDataSource {
/// returns reference to log at given position if it exists
fn bloom_at_index(&self, index: &BloomIndex) -> Option<H2048>;
}
pub trait KeyDirectory: Send + Sync {
fn load(&self) -> Result<Vec<SafeAccount>, Error>;
fn insert(&self, account: SafeAccount) -> Result<(), Error>;
fn remove(&self, address: &Address) -> Result<(), Error>;
}
pub use self::disk::DiskDirectory;
pub use self::geth::GethDirectory;
pub use self::parity::ParityDirectory;

View File

@@ -0,0 +1,283 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::collections::HashMap;
use std::io::{BufRead, BufReader, Read};
use std::str::FromStr;
use util::hash::*;
use util::sha3::*;
use chainfilter::{BloomIndex, FilterDataSource, ChainFilter};
/// In memory cache for blooms.
///
/// Stores all blooms in HashMap, which indexes them by `BloomIndex`.
pub struct MemoryCache {
blooms: HashMap<BloomIndex, H2048>,
}
impl Default for MemoryCache {
fn default() -> Self {
MemoryCache::new()
}
}
impl MemoryCache {
/// Default constructor for MemoryCache
pub fn new() -> Self {
MemoryCache { blooms: HashMap::new() }
}
/// inserts all blooms into cache
///
/// if bloom at given index already exists, overwrites it
pub fn insert_blooms(&mut self, blooms: HashMap<BloomIndex, H2048>) {
self.blooms.extend(blooms);
}
}
impl FilterDataSource for MemoryCache {
fn bloom_at_index(&self, index: &BloomIndex) -> Option<H2048> {
self.blooms.get(index).cloned()
}
}
fn to_bloom<T>(hashable: &T) -> H2048 where T: Hashable {
let mut bloom = H2048::new();
bloom.shift_bloomed(&hashable.sha3());
bloom
}
#[test]
fn test_topic_basic_search() {
let index_size = 16;
let bloom_levels = 3;
let mut cache = MemoryCache::new();
let topic = H256::from_str("8d936b1bd3fc635710969ccfba471fb17d598d9d1971b538dd712e1e4b4f4dba").unwrap();
let modified_blooms = {
let filter = ChainFilter::new(&cache, index_size, bloom_levels);
let block_number = 23;
filter.add_bloom(&to_bloom(&topic), block_number)
};
// number of modified blooms should always be equal number of levels
assert_eq!(modified_blooms.len(), bloom_levels as usize);
cache.insert_blooms(modified_blooms);
{
let filter = ChainFilter::new(&cache, index_size, bloom_levels);
let blocks = filter.blocks_with_bloom(&to_bloom(&topic), 0, 100);
assert_eq!(blocks.len(), 1);
assert_eq!(blocks[0], 23);
}
{
let filter = ChainFilter::new(&cache, index_size, bloom_levels);
let blocks = filter.blocks_with_bloom(&to_bloom(&topic), 0, 22);
assert_eq!(blocks.len(), 0);
}
{
let filter = ChainFilter::new(&cache, index_size, bloom_levels);
let blocks = filter.blocks_with_bloom(&to_bloom(&topic), 23, 23);
assert_eq!(blocks.len(), 1);
assert_eq!(blocks[0], 23);
}
{
let filter = ChainFilter::new(&cache, index_size, bloom_levels);
let blocks = filter.blocks_with_bloom(&to_bloom(&topic), 24, 100);
assert_eq!(blocks.len(), 0);
}
}
#[test]
fn test_reset_chain_head_simple() {
let index_size = 16;
let bloom_levels = 3;
let mut cache = MemoryCache::new();
let topic_0 = H256::from_str("8d936b1bd3fc635710969ccfba471fb17d598d9d1971b538dd712e1e4b4f4dba").unwrap();
let topic_1 = H256::from_str("8d936b1bd3fc635710969ccfba471fb17d598d9d1971b538dd712e1e4b4f4dbb").unwrap();
let topic_2 = H256::from_str("8d936b1bd3fc635710969ccfba471fb17d598d9d1971b538dd712e1e4b4f4dbc").unwrap();
let topic_3 = H256::from_str("8d936b1bd3fc635710969ccfba471fb17d598d9d1971b538dd712e1e4b4f4dbd").unwrap();
let topic_4 = H256::from_str("8d936b1bd3fc635710969ccfba471fb17d598d9d1971b538dd712e1e4b4f4dbe").unwrap();
let topic_5 = H256::from_str("8d936b1bd3fc635710969ccfba471fb17d598d9d1971b538dd712e1e4b4f4dbf").unwrap();
let modified_blooms_0 = {
let filter = ChainFilter::new(&cache, index_size, bloom_levels);
let block_number = 14;
filter.add_bloom(&to_bloom(&topic_0), block_number)
};
cache.insert_blooms(modified_blooms_0);
let modified_blooms_1 = {
let filter = ChainFilter::new(&cache, index_size, bloom_levels);
let block_number = 15;
filter.add_bloom(&to_bloom(&topic_1), block_number)
};
cache.insert_blooms(modified_blooms_1);
let modified_blooms_2 = {
let filter = ChainFilter::new(&cache, index_size, bloom_levels);
let block_number = 16;
filter.add_bloom(&to_bloom(&topic_2), block_number)
};
cache.insert_blooms(modified_blooms_2);
let modified_blooms_3 = {
let filter = ChainFilter::new(&cache, index_size, bloom_levels);
let block_number = 17;
filter.add_bloom(&to_bloom(&topic_3), block_number)
};
cache.insert_blooms(modified_blooms_3);
let reset_modified_blooms = {
let filter = ChainFilter::new(&cache, index_size, bloom_levels);
filter.reset_chain_head(&[to_bloom(&topic_4), to_bloom(&topic_5)], 15, 17)
};
cache.insert_blooms(reset_modified_blooms);
let filter = ChainFilter::new(&cache, index_size, bloom_levels);
assert_eq!(filter.blocks_with_bloom(&to_bloom(&topic_0), 0, 100), vec![14]);
assert_eq!(filter.blocks_with_bloom(&to_bloom(&topic_1), 0, 100), vec![]);
assert_eq!(filter.blocks_with_bloom(&to_bloom(&topic_2), 0, 100), vec![]);
assert_eq!(filter.blocks_with_bloom(&to_bloom(&topic_3), 0, 100), vec![]);
assert_eq!(filter.blocks_with_bloom(&to_bloom(&topic_4), 0, 100), vec![15]);
assert_eq!(filter.blocks_with_bloom(&to_bloom(&topic_5), 0, 100), vec![16]);
}
fn for_each_bloom<F>(bytes: &[u8], mut f: F) where F: FnMut(usize, &H2048) {
let mut reader = BufReader::new(bytes);
let mut line = String::new();
while reader.read_line(&mut line).unwrap() > 0 {
{
let mut number_bytes = vec![];
let mut bloom_bytes = [0; 512];
let mut line_reader = BufReader::new(line.as_ref() as &[u8]);
line_reader.read_until(b' ', &mut number_bytes).unwrap();
line_reader.consume(2);
line_reader.read_exact(&mut bloom_bytes).unwrap();
let number = String::from_utf8(number_bytes).map(|s| s[..s.len() -1].to_owned()).unwrap().parse::<usize>().unwrap();
let bloom = H2048::from_str(&String::from_utf8(bloom_bytes.to_vec()).unwrap()).unwrap();
f(number, &bloom);
}
line.clear();
}
}
fn for_each_log<F>(bytes: &[u8], mut f: F) where F: FnMut(usize, &Address, &[H256]) {
let mut reader = BufReader::new(bytes);
let mut line = String::new();
while reader.read_line(&mut line).unwrap() > 0 {
{
let mut number_bytes = vec![];
let mut address_bytes = [0;42];
let mut topic = [0;66];
let mut topics_bytes = vec![];
let mut line_reader = BufReader::new(line.as_ref() as &[u8]);
line_reader.read_until(b' ', &mut number_bytes).unwrap();
line_reader.read_exact(&mut address_bytes).unwrap();
line_reader.consume(1);
while let Ok(_) = line_reader.read_exact(&mut topic) {
line_reader.consume(1);
topics_bytes.push(topic.to_vec());
}
let number = String::from_utf8(number_bytes).map(|s| s[..s.len() -1].to_owned()).unwrap().parse::<usize>().unwrap();
let address = Address::from_str(&String::from_utf8(address_bytes.to_vec()).map(|a| a[2..].to_owned()).unwrap()).unwrap();
let topics: Vec<H256> = topics_bytes
.into_iter()
.map(|t| H256::from_str(&String::from_utf8(t).map(|t| t[2..].to_owned()).unwrap()).unwrap())
.collect();
f(number, &address, &topics);
}
line.clear();
}
}
// tests chain filter on real data between blocks 300_000 and 400_000
#[test]
fn test_chainfilter_real_data_short_searches() {
let index_size = 16;
let bloom_levels = 3;
let mut cache = MemoryCache::new();
for_each_bloom(include_bytes!("blooms.txt"), | block_number, bloom | {
let modified_blooms = {
let filter = ChainFilter::new(&cache, index_size, bloom_levels);
filter.add_bloom(bloom, block_number)
};
// number of modified blooms should always be equal number of levels
assert_eq!(modified_blooms.len(), bloom_levels as usize);
cache.insert_blooms(modified_blooms);
});
for_each_log(include_bytes!("logs.txt"), | block_number, address, topics | {
println!("block_number: {:?}", block_number);
let filter = ChainFilter::new(&cache, index_size, bloom_levels);
let blocks = filter.blocks_with_bloom(&to_bloom(address), block_number, block_number);
assert_eq!(blocks.len(), 1);
for (i, topic) in topics.iter().enumerate() {
println!("topic: {:?}", i);
let blocks = filter.blocks_with_bloom(&to_bloom(topic), block_number, block_number);
assert_eq!(blocks.len(), 1);
}
});
}
// tests chain filter on real data between blocks 300_000 and 400_000
#[test]
fn test_chainfilter_real_data_single_search() {
let index_size = 16;
let bloom_levels = 3;
let mut cache = MemoryCache::new();
for_each_bloom(include_bytes!("blooms.txt"), | block_number, bloom | {
let modified_blooms = {
let filter = ChainFilter::new(&cache, index_size, bloom_levels);
filter.add_bloom(bloom, block_number)
};
// number of modified blooms should always be equal number of levels
assert_eq!(modified_blooms.len(), bloom_levels as usize);
cache.insert_blooms(modified_blooms);
});
let address = Address::from_str("c4395759e26469baa0e6421bdc1d0232c6f4b6c3").unwrap();
let filter = ChainFilter::new(&cache, index_size, bloom_levels);
let blocks = filter.blocks_with_bloom(&to_bloom(&address), 300_000, 400_000);
// bloom may return more blocks, but our log density is low, so it should be fine
assert_eq!(blocks.len(), 3);
assert_eq!(blocks[0], 392697);
assert_eq!(blocks[1], 396348);
assert_eq!(blocks[2], 399804);
}

View File

@@ -17,12 +17,10 @@
//! Blockchain database client.
use std::marker::PhantomData;
use std::path::PathBuf;
use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering};
use util::*;
use util::panics::*;
use views::BlockView;
use error::{Error, ImportError, ExecutionError, BlockError, ImportResult};
use error::*;
use header::{BlockNumber, Header};
use state::State;
use spec::Spec;
@@ -33,25 +31,44 @@ use env_info::LastHashes;
use verification::*;
use block::*;
use transaction::{LocalizedTransaction, SignedTransaction, Action};
use blockchain::extras::TransactionAddress;
use extras::TransactionAddress;
use filter::Filter;
use log_entry::LocalizedLogEntry;
use block_queue::{BlockQueue, BlockQueueInfo};
use blockchain::{BlockChain, BlockProvider, TreeRoute, ImportRoute};
use client::{BlockID, TransactionID, UncleID, TraceId, ClientConfig, BlockChainClient, MiningBlockChainClient, TraceFilter, CallAnalytics};
use client::Error as ClientError;
use client::{BlockId, TransactionId, UncleId, ClientConfig, BlockChainClient};
use env_info::EnvInfo;
use executive::{Executive, Executed, TransactOptions, contract_address};
use receipt::LocalizedReceipt;
pub use blockchain::CacheSize as BlockChainCacheSize;
use trace::{TraceDB, ImportRequest as TraceImportRequest, LocalizedTrace, Database as TraceDatabase};
use trace;
pub use types::blockchain_info::BlockChainInfo;
pub use types::block_status::BlockStatus;
use evm::Factory as EvmFactory;
use miner::{Miner, MinerService, TransactionImportResult, AccountDetails};
const MAX_TX_QUEUE_SIZE: usize = 4096;
/// General block status
#[derive(Debug, Eq, PartialEq)]
pub enum BlockStatus {
/// Part of the blockchain.
InChain,
/// Queued for import.
Queued,
/// Known as bad.
Bad,
/// Unknown.
Unknown,
}
/// Information about the blockchain gathered together.
#[derive(Debug)]
pub struct BlockChainInfo {
/// Blockchain difficulty.
pub total_difficulty: U256,
/// Block queue difficulty.
pub pending_total_difficulty: U256,
/// Genesis block hash.
pub genesis_hash: H256,
/// Best blockchain block hash.
pub best_block_hash: H256,
/// Best blockchain block number.
pub best_block_number: BlockNumber
}
impl fmt::Display for BlockChainInfo {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -85,7 +102,6 @@ impl ClientReport {
/// Call `import_block()` to import a block asynchronously; `flush_queue()` flushes the queue.
pub struct Client<V = CanonVerifier> where V: Verifier {
chain: Arc<BlockChain>,
tracedb: Arc<TraceDB<BlockChain>>,
engine: Arc<Box<Engine>>,
state_db: Mutex<Box<JournalDB>>,
block_queue: BlockQueue,
@@ -93,10 +109,6 @@ pub struct Client<V = CanonVerifier> where V: Verifier {
import_lock: Mutex<()>,
panic_handler: Arc<PanicHandler>,
verifier: PhantomData<V>,
vm_factory: Arc<EvmFactory>,
miner: Arc<Miner>,
io_channel: IoChannel<NetSyncMessage>,
queue_transactions: AtomicUsize,
}
const HISTORY: u64 = 1200;
@@ -109,61 +121,39 @@ const CLIENT_DB_VER_STR: &'static str = "5.3";
impl Client<CanonVerifier> {
/// Create a new client with given spec and DB path.
pub fn new(config: ClientConfig, spec: Spec, path: &Path, miner: Arc<Miner>, message_channel: IoChannel<NetSyncMessage> ) -> Result<Arc<Client>, ClientError> {
Client::<CanonVerifier>::new_with_verifier(config, spec, path, miner, message_channel)
pub fn new(config: ClientConfig, spec: Spec, path: &Path, message_channel: IoChannel<NetSyncMessage> ) -> Result<Arc<Client>, Error> {
Client::<CanonVerifier>::new_with_verifier(config, spec, path, message_channel)
}
}
/// Get the path for the databases given the root path and information on the databases.
pub fn get_db_path(path: &Path, pruning: journaldb::Algorithm, genesis_hash: H256) -> PathBuf {
let mut dir = path.to_path_buf();
dir.push(H64::from(genesis_hash).hex());
//TODO: sec/fat: pruned/full versioning
// version here is a bit useless now, since it's controlled only be the pruning algo.
dir.push(format!("v{}-sec-{}", CLIENT_DB_VER_STR, pruning));
dir
}
/// Append a path element to the given path and return the string.
pub fn append_path(path: &Path, item: &str) -> String {
let mut p = path.to_path_buf();
p.push(item);
p.to_str().unwrap().to_owned()
}
impl<V> Client<V> where V: Verifier {
/// Create a new client with given spec and DB path and custom verifier.
pub fn new_with_verifier(
config: ClientConfig,
spec: Spec,
path: &Path,
miner: Arc<Miner>,
message_channel: IoChannel<NetSyncMessage>)
-> Result<Arc<Client<V>>, ClientError>
{
let path = get_db_path(path, config.pruning, spec.genesis_header().hash());
pub fn new_with_verifier(config: ClientConfig, spec: Spec, path: &Path, message_channel: IoChannel<NetSyncMessage> ) -> Result<Arc<Client<V>>, Error> {
let mut dir = path.to_path_buf();
dir.push(H64::from(spec.genesis_header().hash()).hex());
//TODO: sec/fat: pruned/full versioning
// version here is a bit useless now, since it's controlled only be the pruning algo.
dir.push(format!("v{}-sec-{}", CLIENT_DB_VER_STR, config.pruning));
let path = dir.as_path();
let gb = spec.genesis_block();
let chain = Arc::new(BlockChain::new(config.blockchain, &gb, &path));
let tracedb = Arc::new(try!(TraceDB::new(config.tracing, &path, chain.clone())));
let chain = Arc::new(BlockChain::new(config.blockchain, &gb, path));
let mut state_path = path.to_path_buf();
state_path.push("state");
let mut state_db = journaldb::new(
&append_path(&path, "state"),
config.pruning,
config.db_cache_size);
let engine = Arc::new(try!(spec.to_engine()));
let state_path_str = state_path.to_str().unwrap();
let mut state_db = journaldb::new(state_path_str, config.pruning);
if state_db.is_empty() && spec.ensure_db_good(state_db.as_hashdb_mut()) {
state_db.commit(0, &spec.genesis_header().hash(), None).expect("Error commiting genesis state to state DB");
if state_db.is_empty() && engine.spec().ensure_db_good(state_db.as_hashdb_mut()) {
state_db.commit(0, &engine.spec().genesis_header().hash(), None).expect("Error commiting genesis state to state DB");
}
let engine = Arc::new(spec.engine);
let block_queue = BlockQueue::new(config.queue, engine.clone(), message_channel.clone());
let block_queue = BlockQueue::new(config.queue, engine.clone(), message_channel);
let panic_handler = PanicHandler::new_in_arc();
panic_handler.forward_from(&block_queue);
let client = Client {
Ok(Arc::new(Client {
chain: chain,
tracedb: tracedb,
engine: engine,
state_db: Mutex::new(state_db),
block_queue: block_queue,
@@ -171,13 +161,7 @@ impl<V> Client<V> where V: Verifier {
import_lock: Mutex::new(()),
panic_handler: panic_handler,
verifier: PhantomData,
vm_factory: Arc::new(EvmFactory::new(config.vm_type)),
miner: miner,
io_channel: message_channel,
queue_transactions: AtomicUsize::new(0),
};
Ok(Arc::new(client))
}))
}
/// Flush the block import queue.
@@ -200,7 +184,7 @@ impl<V> Client<V> where V: Verifier {
last_hashes
}
fn check_and_close_block(&self, block: &PreverifiedBlock) -> Result<LockedBlock, ()> {
fn check_and_close_block(&self, block: &PreverifiedBlock) -> Result<ClosedBlock, ()> {
let engine = self.engine.deref().deref();
let header = &block.header;
@@ -228,22 +212,23 @@ impl<V> Client<V> where V: Verifier {
// Enact Verified Block
let parent = chain_has_parent.unwrap();
let last_hashes = self.build_last_hashes(header.parent_hash.clone());
let db = self.state_db.lock().unwrap().boxed_clone();
let db = self.state_db.lock().unwrap().spawn();
let enact_result = enact_verified(&block, engine, self.tracedb.tracing_enabled(), db, &parent, last_hashes, self.dao_rescue_block_gas_limit(header.parent_hash.clone()), &self.vm_factory);
let enact_result = enact_verified(&block, engine, db, &parent, last_hashes);
if let Err(e) = enact_result {
warn!(target: "client", "Block import failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e);
return Err(());
};
// Final Verification
let locked_block = enact_result.unwrap();
if let Err(e) = V::verify_block_final(&header, locked_block.block().header()) {
let closed_block = enact_result.unwrap();
if let Err(e) = V::verify_block_final(&header, closed_block.block().header()) {
warn!(target: "client", "Stage 4 block verification failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e);
return Err(());
}
Ok(locked_block)
Ok(closed_block)
}
fn calculate_enacted_retracted(&self, import_results: Vec<ImportRoute>) -> (Vec<H256>, Vec<H256>) {
@@ -274,14 +259,13 @@ impl<V> Client<V> where V: Verifier {
/// This is triggered by a message coming from a block queue when the block is ready for insertion
pub fn import_verified_blocks(&self, io: &IoChannel<NetSyncMessage>) -> usize {
let max_blocks_to_import = 64;
let max_blocks_to_import = 128;
let mut imported_blocks = Vec::with_capacity(max_blocks_to_import);
let mut invalid_blocks = HashSet::new();
let mut import_results = Vec::with_capacity(max_blocks_to_import);
let _import_lock = self.import_lock.lock();
let _timer = PerfTimer::new("import_verified_blocks");
let blocks = self.block_queue.drain(max_blocks_to_import);
let original_best = self.chain_info().best_block_hash;
@@ -311,8 +295,6 @@ impl<V> Client<V> where V: Verifier {
// Commit results
let closed_block = closed_block.unwrap();
let receipts = closed_block.block().receipts().clone();
let traces = From::from(closed_block.block().traces().clone().unwrap_or_else(Vec::new));
closed_block.drain()
.commit(header.number(), &header.hash(), ancient)
.expect("State DB commit failed.");
@@ -320,14 +302,6 @@ impl<V> Client<V> where V: Verifier {
// And update the chain after commit to prevent race conditions
// (when something is in chain but you are not able to fetch details)
let route = self.chain.insert_block(&block.bytes, receipts);
self.tracedb.import(TraceImportRequest {
traces: traces,
block_hash: header.hash(),
block_number: header.number(),
enacted: route.enacted.clone(),
retracted: route.retracted.len()
});
import_results.push(route);
self.report.write().unwrap().accrue_block(&block);
@@ -349,11 +323,6 @@ impl<V> Client<V> where V: Verifier {
{
if !imported_blocks.is_empty() && self.block_queue.queue_info().is_empty() {
let (enacted, retracted) = self.calculate_enacted_retracted(import_results);
if self.queue_info().is_empty() {
self.miner.chain_new_blocks(self, &imported_blocks, &invalid_blocks, &enacted, &retracted);
}
io.send(NetworkIoMessage::User(SyncMessage::NewChainBlocks {
imported: imported_blocks,
invalid: invalid_blocks,
@@ -365,59 +334,16 @@ impl<V> Client<V> where V: Verifier {
{
if self.chain_info().best_block_hash != original_best {
self.miner.update_sealing(self);
io.send(NetworkIoMessage::User(SyncMessage::NewChainHead)).unwrap();
}
}
imported
}
/// Import transactions from the IO queue
pub fn import_queued_transactions(&self, transactions: &[Bytes]) -> usize {
let _timer = PerfTimer::new("import_queued_transactions");
self.queue_transactions.fetch_sub(transactions.len(), AtomicOrdering::SeqCst);
let fetch_account = |a: &Address| AccountDetails {
nonce: self.latest_nonce(a),
balance: self.latest_balance(a),
};
let tx = transactions.iter().filter_map(|bytes| UntrustedRlp::new(&bytes).as_val().ok()).collect();
let results = self.miner.import_transactions(self, tx, fetch_account);
results.len()
}
/// Attempt to get a copy of a specific block's state.
///
/// This will not fail if given BlockID::Latest.
/// Otherwise, this can fail (but may not) if the DB prunes state.
pub fn state_at(&self, id: BlockID) -> Option<State> {
// fast path for latest state.
if let BlockID::Latest = id.clone() {
return Some(self.state())
}
let block_number = match self.block_number(id.clone()) {
Some(num) => num,
None => return None,
};
self.block_header(id).and_then(|header| {
let db = self.state_db.lock().unwrap().boxed_clone();
// early exit for pruned blocks
if db.is_pruned() && self.chain.best_block_number() >= block_number + HISTORY {
return None;
}
let root = HeaderView::new(&header).state_root();
State::from_existing(db, root, self.engine.account_start_nonce()).ok()
})
}
/// Get a copy of the best block's state.
pub fn state(&self) -> State {
State::from_existing(self.state_db.lock().unwrap().boxed_clone(), HeaderView::new(&self.best_block_header()).state_root(), self.engine.account_start_nonce())
.expect("State root of best block header always valid.")
State::from_existing(self.state_db.lock().unwrap().spawn(), HeaderView::new(&self.best_block_header()).state_root(), self.engine.account_start_nonce())
}
/// Get info on the cache.
@@ -443,39 +369,38 @@ impl<V> Client<V> where V: Verifier {
self.chain.configure_cache(pref_cache_size, max_cache_size);
}
/// Look up the block number for the given block ID.
pub fn block_number(&self, id: BlockID) -> Option<BlockNumber> {
fn block_hash(chain: &BlockChain, id: BlockId) -> Option<H256> {
match id {
BlockID::Number(number) => Some(number),
BlockID::Hash(ref hash) => self.chain.block_number(hash),
BlockID::Earliest => Some(0),
BlockID::Latest => Some(self.chain.best_block_number())
BlockId::Hash(hash) => Some(hash),
BlockId::Number(number) => chain.block_hash(number),
BlockId::Earliest => chain.block_hash(0),
BlockId::Latest => Some(chain.best_block_hash())
}
}
fn block_hash(chain: &BlockChain, id: BlockID) -> Option<H256> {
fn block_number(&self, id: BlockId) -> Option<BlockNumber> {
match id {
BlockID::Hash(hash) => Some(hash),
BlockID::Number(number) => chain.block_hash(number),
BlockID::Earliest => chain.block_hash(0),
BlockID::Latest => Some(chain.best_block_hash())
BlockId::Number(number) => Some(number),
BlockId::Hash(ref hash) => self.chain.block_number(hash),
BlockId::Earliest => Some(0),
BlockId::Latest => Some(self.chain.best_block_number())
}
}
fn transaction_address(&self, id: TransactionID) -> Option<TransactionAddress> {
fn transaction_address(&self, id: TransactionId) -> Option<TransactionAddress> {
match id {
TransactionID::Hash(ref hash) => self.chain.transaction_address(hash),
TransactionID::Location(id, index) => Self::block_hash(&self.chain, id).map(|hash| TransactionAddress {
TransactionId::Hash(ref hash) => self.chain.transaction_address(hash),
TransactionId::Location(id, index) => Self::block_hash(&self.chain, id).map(|hash| TransactionAddress {
block_hash: hash,
index: index,
index: index
})
}
}
}
impl<V> BlockChainClient for Client<V> where V: Verifier {
fn call(&self, t: &SignedTransaction, analytics: CallAnalytics) -> Result<Executed, ExecutionError> {
let header = self.block_header(BlockID::Latest).unwrap();
fn call(&self, t: &SignedTransaction) -> Result<Executed, Error> {
let header = self.block_header(BlockId::Latest).unwrap();
let view = HeaderView::new(&header);
let last_hashes = self.build_last_hashes(view.hash());
let env_info = EnvInfo {
@@ -486,41 +411,92 @@ impl<V> BlockChainClient for Client<V> where V: Verifier {
last_hashes: last_hashes,
gas_used: U256::zero(),
gas_limit: U256::max_value(),
dao_rescue_block_gas_limit: self.dao_rescue_block_gas_limit(view.parent_hash()),
};
// that's just a copy of the state.
let mut state = self.state();
let sender = try!(t.sender().map_err(|e| {
let message = format!("Transaction malformed: {:?}", e);
ExecutionError::TransactionMalformed(message)
}));
let sender = try!(t.sender());
let balance = state.balance(&sender);
let needed_balance = t.value + t.gas * t.gas_price;
if balance < needed_balance {
// give the sender a sufficient balance
state.add_balance(&sender, &(needed_balance - balance));
}
let options = TransactOptions { tracing: analytics.transaction_tracing, vm_tracing: analytics.vm_tracing, check_nonce: false };
let mut ret = Executive::new(&mut state, &env_info, self.engine.deref().deref(), &self.vm_factory).transact(t, options);
// give the sender max balance
state.sub_balance(&sender, &balance);
state.add_balance(&sender, &U256::max_value());
let options = TransactOptions { tracing: false, check_nonce: false };
Executive::new(&mut state, &env_info, self.engine.deref().deref()).transact(t, options)
}
// TODO gav move this into Executive.
if analytics.state_diffing {
if let Ok(ref mut x) = ret {
x.state_diff = Some(state.diff_from(self.state()));
// TODO [todr] Should be moved to miner crate eventually.
fn try_seal(&self, block: ClosedBlock, seal: Vec<Bytes>) -> Result<SealedBlock, ClosedBlock> {
block.try_seal(self.engine.deref().deref(), seal)
}
// TODO [todr] Should be moved to miner crate eventually.
fn prepare_sealing(&self, author: Address, gas_floor_target: U256, extra_data: Bytes, transactions: Vec<SignedTransaction>)
-> Option<(ClosedBlock, HashSet<H256>)> {
let engine = self.engine.deref().deref();
let h = self.chain.best_block_hash();
let mut b = OpenBlock::new(
engine,
self.state_db.lock().unwrap().spawn(),
match self.chain.block_header(&h) { Some(ref x) => x, None => {return None} },
self.build_last_hashes(h.clone()),
author,
gas_floor_target,
extra_data,
);
// Add uncles
self.chain
.find_uncle_headers(&h, engine.maximum_uncle_age())
.unwrap()
.into_iter()
.take(engine.maximum_uncle_count())
.foreach(|h| {
b.push_uncle(h).unwrap();
});
// Add transactions
let block_number = b.block().header().number();
let min_tx_gas = U256::from(self.engine.schedule(&b.env_info()).tx_gas);
let mut invalid_transactions = HashSet::new();
for tx in transactions {
// Push transaction to block
let hash = tx.hash();
let import = b.push_transaction(tx, None);
match import {
Err(Error::Execution(ExecutionError::BlockGasLimitReached { gas_limit, gas_used, .. })) => {
trace!(target: "miner", "Skipping adding transaction to block because of gas limit: {:?}", hash);
// Exit early if gas left is smaller then min_tx_gas
if gas_limit - gas_used < min_tx_gas {
break;
}
},
Err(e) => {
invalid_transactions.insert(hash);
trace!(target: "miner",
"Error adding transaction to block: number={}. transaction_hash={:?}, Error: {:?}",
block_number, hash, e);
},
_ => {}
}
}
ret
// And close
let b = b.close();
trace!(target: "miner", "Sealing: number={}, hash={}, diff={}",
b.block().header().number(),
b.hash(),
b.block().header().difficulty()
);
Some((b, invalid_transactions))
}
fn vm_factory(&self) -> &EvmFactory {
&self.vm_factory
}
fn block_header(&self, id: BlockID) -> Option<Bytes> {
fn block_header(&self, id: BlockId) -> Option<Bytes> {
Self::block_hash(&self.chain, id).and_then(|hash| self.chain.block(&hash).map(|bytes| BlockView::new(&bytes).rlp().at(0).as_raw().to_vec()))
}
fn block_body(&self, id: BlockID) -> Option<Bytes> {
fn block_body(&self, id: BlockId) -> Option<Bytes> {
Self::block_hash(&self.chain, id).and_then(|hash| {
self.chain.block(&hash).map(|bytes| {
let rlp = Rlp::new(&bytes);
@@ -532,13 +508,13 @@ impl<V> BlockChainClient for Client<V> where V: Verifier {
})
}
fn block(&self, id: BlockID) -> Option<Bytes> {
fn block(&self, id: BlockId) -> Option<Bytes> {
Self::block_hash(&self.chain, id).and_then(|hash| {
self.chain.block(&hash)
})
}
fn block_status(&self, id: BlockID) -> BlockStatus {
fn block_status(&self, id: BlockId) -> BlockStatus {
match Self::block_hash(&self.chain, id) {
Some(ref hash) if self.chain.is_known(hash) => BlockStatus::InChain,
Some(hash) => self.block_queue.block_status(&hash),
@@ -546,15 +522,15 @@ impl<V> BlockChainClient for Client<V> where V: Verifier {
}
}
fn block_total_difficulty(&self, id: BlockID) -> Option<U256> {
fn block_total_difficulty(&self, id: BlockId) -> Option<U256> {
Self::block_hash(&self.chain, id).and_then(|hash| self.chain.block_details(&hash)).map(|d| d.total_difficulty)
}
fn nonce(&self, address: &Address, id: BlockID) -> Option<U256> {
self.state_at(id).map(|s| s.nonce(address))
fn nonce(&self, address: &Address) -> U256 {
self.state().nonce(address)
}
fn block_hash(&self, id: BlockID) -> Option<H256> {
fn block_hash(&self, id: BlockId) -> Option<H256> {
Self::block_hash(&self.chain, id)
}
@@ -562,24 +538,24 @@ impl<V> BlockChainClient for Client<V> where V: Verifier {
self.state().code(address)
}
fn balance(&self, address: &Address, id: BlockID) -> Option<U256> {
self.state_at(id).map(|s| s.balance(address))
fn balance(&self, address: &Address) -> U256 {
self.state().balance(address)
}
fn storage_at(&self, address: &Address, position: &H256, id: BlockID) -> Option<H256> {
self.state_at(id).map(|s| s.storage_at(address, position))
fn storage_at(&self, address: &Address, position: &H256) -> H256 {
self.state().storage_at(address, position)
}
fn transaction(&self, id: TransactionID) -> Option<LocalizedTransaction> {
fn transaction(&self, id: TransactionId) -> Option<LocalizedTransaction> {
self.transaction_address(id).and_then(|address| self.chain.transaction(&address))
}
fn uncle(&self, id: UncleID) -> Option<Header> {
fn uncle(&self, id: UncleId) -> Option<Header> {
let index = id.1;
self.block(id.0).and_then(|block| BlockView::new(&block).uncle_at(index))
}
fn transaction_receipt(&self, id: TransactionID) -> Option<LocalizedReceipt> {
fn transaction_receipt(&self, id: TransactionId) -> Option<LocalizedReceipt> {
self.transaction_address(id).and_then(|address| {
let t = self.chain.block(&address.block_hash)
.and_then(|block| BlockView::new(&block).localized_transaction_at(address.index));
@@ -590,21 +566,14 @@ impl<V> BlockChainClient for Client<V> where V: Verifier {
let block_number = tx.block_number.clone();
let transaction_hash = tx.hash();
let transaction_index = tx.transaction_index;
let prior_gas_used = match tx.transaction_index {
0 => U256::zero(),
i => {
let prior_address = TransactionAddress { block_hash: address.block_hash, index: i - 1 };
let prior_receipt = self.chain.transaction_receipt(&prior_address).expect("Transaction receipt at `address` exists; `prior_address` has lower index in same block; qed");
prior_receipt.gas_used
}
};
Some(LocalizedReceipt {
transaction_hash: tx.hash(),
transaction_index: tx.transaction_index,
block_hash: tx.block_hash,
block_number: tx.block_number,
// TODO: to fix this, query all previous transaction receipts and retrieve their gas usage
cumulative_gas_used: receipt.gas_used,
gas_used: receipt.gas_used - prior_gas_used,
gas_used: receipt.gas_used,
contract_address: match tx.action {
Action::Call(_) => None,
Action::Create => Some(contract_address(&tx.sender().unwrap(), &tx.nonce))
@@ -631,10 +600,6 @@ impl<V> BlockChainClient for Client<V> where V: Verifier {
}
}
fn find_uncles(&self, hash: &H256) -> Option<Vec<H256>> {
self.chain.find_uncle_hashes(hash, self.engine.maximum_uncle_age())
}
fn state_data(&self, hash: &H256) -> Option<Bytes> {
self.state_db.lock().unwrap().state(hash)
}
@@ -647,10 +612,10 @@ impl<V> BlockChainClient for Client<V> where V: Verifier {
{
let header = BlockView::new(&bytes).header_view();
if self.chain.is_known(&header.sha3()) {
return Err(ImportError::AlreadyInChain.into());
return Err(x!(ImportError::AlreadyInChain));
}
if self.block_status(BlockID::Hash(header.parent_hash())) == BlockStatus::Unknown {
return Err(BlockError::UnknownParent(header.parent_hash()).into());
if self.block_status(BlockId::Hash(header.parent_hash())) == BlockStatus::Unknown {
return Err(x!(BlockError::UnknownParent(header.parent_hash())));
}
}
self.block_queue.import_block(bytes)
@@ -674,7 +639,7 @@ impl<V> BlockChainClient for Client<V> where V: Verifier {
}
}
fn blocks_with_bloom(&self, bloom: &H2048, from_block: BlockID, to_block: BlockID) -> Option<Vec<BlockNumber>> {
fn blocks_with_bloom(&self, bloom: &H2048, from_block: BlockId, to_block: BlockId) -> Option<Vec<BlockNumber>> {
match (self.block_number(from_block), self.block_number(to_block)) {
(Some(from), Some(to)) => Some(self.chain.blocks_with_bloom(bloom, from, to)),
_ => None
@@ -722,110 +687,6 @@ impl<V> BlockChainClient for Client<V> where V: Verifier {
})
.collect()
}
fn filter_traces(&self, filter: TraceFilter) -> Option<Vec<LocalizedTrace>> {
let start = self.block_number(filter.range.start);
let end = self.block_number(filter.range.end);
if start.is_some() && end.is_some() {
let filter = trace::Filter {
range: start.unwrap() as usize..end.unwrap() as usize,
from_address: From::from(filter.from_address),
to_address: From::from(filter.to_address),
};
let traces = self.tracedb.filter(&filter);
Some(traces)
} else {
None
}
}
fn trace(&self, trace: TraceId) -> Option<LocalizedTrace> {
let trace_address = trace.address;
self.transaction_address(trace.transaction)
.and_then(|tx_address| {
self.block_number(BlockID::Hash(tx_address.block_hash))
.and_then(|number| self.tracedb.trace(number, tx_address.index, trace_address))
})
}
fn transaction_traces(&self, transaction: TransactionID) -> Option<Vec<LocalizedTrace>> {
self.transaction_address(transaction)
.and_then(|tx_address| {
self.block_number(BlockID::Hash(tx_address.block_hash))
.and_then(|number| self.tracedb.transaction_traces(number, tx_address.index))
})
}
fn block_traces(&self, block: BlockID) -> Option<Vec<LocalizedTrace>> {
self.block_number(block)
.and_then(|number| self.tracedb.block_traces(number))
}
fn last_hashes(&self) -> LastHashes {
self.build_last_hashes(self.chain.best_block_hash())
}
fn import_transactions(&self, transactions: Vec<SignedTransaction>) -> Vec<Result<TransactionImportResult, Error>> {
let fetch_account = |a: &Address| AccountDetails {
nonce: self.latest_nonce(a),
balance: self.latest_balance(a),
};
self.miner.import_transactions(self, transactions, fetch_account)
}
fn queue_transactions(&self, transactions: Vec<Bytes>) {
if self.queue_transactions.load(AtomicOrdering::Relaxed) > MAX_TX_QUEUE_SIZE {
debug!("Ignoring {} transactions: queue is full", transactions.len());
} else {
let len = transactions.len();
match self.io_channel.send(NetworkIoMessage::User(SyncMessage::NewTransactions(transactions))) {
Ok(_) => {
self.queue_transactions.fetch_add(len, AtomicOrdering::SeqCst);
}
Err(e) => {
debug!("Ignoring {} transactions: error queueing: {}", len, e);
}
}
}
}
fn all_transactions(&self) -> Vec<SignedTransaction> {
self.miner.all_transactions()
}
}
impl<V> MiningBlockChainClient for Client<V> where V: Verifier {
fn prepare_open_block(&self, author: Address, gas_floor_target: U256, extra_data: Bytes) -> OpenBlock {
let engine = self.engine.deref().deref();
let h = self.chain.best_block_hash();
let mut open_block = OpenBlock::new(
engine,
&self.vm_factory,
false, // TODO: this will need to be parameterised once we want to do immediate mining insertion.
self.state_db.lock().unwrap().boxed_clone(),
&self.chain.block_header(&h).expect("h is best block hash: so it's header must exist: qed"),
self.build_last_hashes(h.clone()),
self.dao_rescue_block_gas_limit(h.clone()),
author,
gas_floor_target,
extra_data,
).expect("OpenBlock::new only fails if parent state root invalid; state root of best block's header is never invalid; qed");
// Add uncles
self.chain
.find_uncle_headers(&h, engine.maximum_uncle_age())
.unwrap()
.into_iter()
.take(engine.maximum_uncle_count())
.foreach(|h| {
open_block.push_uncle(h).unwrap();
});
open_block
}
}
impl MayPanic for Client {

View File

@@ -15,9 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
pub use block_queue::BlockQueueConfig;
pub use blockchain::Config as BlockChainConfig;
pub use trace::{Config as TraceConfig, Switch};
pub use evm::VMType;
pub use blockchain::BlockChainConfig;
use util::journaldb;
/// Client configuration. Includes configs for all sub-systems.
@@ -27,14 +25,8 @@ pub struct ClientConfig {
pub queue: BlockQueueConfig,
/// Blockchain configuration.
pub blockchain: BlockChainConfig,
/// Trace configuration.
pub tracing: TraceConfig,
/// VM type.
pub vm_type: VMType,
/// The JournalDB ("pruning") algorithm to use.
pub pruning: journaldb::Algorithm,
/// The name of the client instance.
pub name: String,
/// State db cache-size if not default
pub db_cache_size: Option<usize>,
}

View File

@@ -1,23 +0,0 @@
use trace::Error as TraceError;
use std::fmt::{Display, Formatter, Error as FmtError};
/// Client configuration errors.
#[derive(Debug)]
pub enum Error {
/// TraceDB configuration error.
Trace(TraceError),
}
impl From<TraceError> for Error {
fn from(err: TraceError) -> Self {
Error::Trace(err)
}
}
impl Display for Error {
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
match *self {
Error::Trace(ref err) => write!(f, "{}", err)
}
}
}

View File

@@ -18,13 +18,10 @@
use util::hash::H256;
use header::BlockNumber;
use ipc::binary::BinaryConvertError;
use std::mem;
use std::collections::VecDeque;
/// Uniquely identifies block.
#[derive(Debug, PartialEq, Clone, Hash, Eq, Binary)]
pub enum BlockID {
#[derive(Debug, PartialEq, Clone, Hash, Eq)]
pub enum BlockId {
/// Block's sha3.
/// Querying by hash is always faster.
Hash(H256),
@@ -37,28 +34,19 @@ pub enum BlockID {
}
/// Uniquely identifies transaction.
#[derive(Debug, PartialEq, Clone, Hash, Eq, Binary)]
pub enum TransactionID {
#[derive(Debug, PartialEq, Clone, Hash, Eq)]
pub enum TransactionId {
/// Transaction's sha3.
Hash(H256),
/// Block id and transaction index within this block.
/// Querying by block position is always faster.
Location(BlockID, usize)
}
/// Uniquely identifies Trace.
pub struct TraceId {
/// Transaction
pub transaction: TransactionID,
/// Trace address within transaction.
pub address: Vec<usize>,
Location(BlockId, usize)
}
/// Uniquely identifies Uncle.
#[derive(Debug)]
pub struct UncleID (
pub struct UncleId (
/// Block id.
pub BlockID,
pub BlockId,
/// Position in block.
pub usize
);

View File

@@ -18,126 +18,75 @@
mod client;
mod config;
mod error;
mod ids;
mod test_client;
mod trace;
pub use self::client::*;
pub use self::config::{ClientConfig, BlockQueueConfig, BlockChainConfig, Switch, VMType};
pub use self::error::Error;
pub use types::ids::*;
pub use self::config::{ClientConfig, BlockQueueConfig, BlockChainConfig};
pub use self::ids::{BlockId, TransactionId, UncleId};
pub use self::test_client::{TestBlockChainClient, EachBlockWith};
pub use self::trace::Filter as TraceFilter;
pub use executive::{Executed, Executive, TransactOptions};
pub use env_info::{LastHashes, EnvInfo};
pub use executive::Executed;
use std::collections::HashSet;
use util::bytes::Bytes;
use util::hash::{Address, H256, H2048};
use util::numbers::U256;
use util::Itertools;
use blockchain::TreeRoute;
use block_queue::BlockQueueInfo;
use block::OpenBlock;
use block::{ClosedBlock, SealedBlock};
use header::{BlockNumber, Header};
use transaction::{LocalizedTransaction, SignedTransaction};
use log_entry::LocalizedLogEntry;
use filter::Filter;
use views::{HeaderView, BlockView};
use error::{ImportResult, ExecutionError};
use error::{ImportResult, Error};
use receipt::LocalizedReceipt;
use trace::LocalizedTrace;
use evm::Factory as EvmFactory;
use miner::{TransactionImportResult};
use error::Error as EthError;
/// Options concerning what analytics we run on the call.
#[derive(Eq, PartialEq, Default, Clone, Copy, Debug)]
pub struct CallAnalytics {
/// Make a transaction trace.
pub transaction_tracing: bool,
/// Make a VM trace.
pub vm_tracing: bool,
/// Make a diff.
pub state_diffing: bool,
}
/// Blockchain database client. Owns and manages a blockchain and a block queue.
pub trait BlockChainClient : Sync + Send {
/// Get raw block header data by block id.
fn block_header(&self, id: BlockID) -> Option<Bytes>;
fn block_header(&self, id: BlockId) -> Option<Bytes>;
/// Get raw block body data by block id.
/// Block body is an RLP list of two items: uncles and transactions.
fn block_body(&self, id: BlockID) -> Option<Bytes>;
fn block_body(&self, id: BlockId) -> Option<Bytes>;
/// Get raw block data by block header hash.
fn block(&self, id: BlockID) -> Option<Bytes>;
fn block(&self, id: BlockId) -> Option<Bytes>;
/// Get block status by block header hash.
fn block_status(&self, id: BlockID) -> BlockStatus;
fn block_status(&self, id: BlockId) -> BlockStatus;
/// Get block total difficulty.
fn block_total_difficulty(&self, id: BlockID) -> Option<U256>;
fn block_total_difficulty(&self, id: BlockId) -> Option<U256>;
/// Attempt to get address nonce at given block.
/// May not fail on BlockID::Latest.
fn nonce(&self, address: &Address, id: BlockID) -> Option<U256>;
/// Get address nonce at the latest block's state.
fn latest_nonce(&self, address: &Address) -> U256 {
self.nonce(address, BlockID::Latest)
.expect("nonce will return Some when given BlockID::Latest. nonce was given BlockID::Latest. \
Therefore nonce has returned Some; qed")
}
/// Get address nonce.
fn nonce(&self, address: &Address) -> U256;
/// Get block hash.
fn block_hash(&self, id: BlockID) -> Option<H256>;
fn block_hash(&self, id: BlockId) -> Option<H256>;
/// Get address code.
fn code(&self, address: &Address) -> Option<Bytes>;
/// Get address balance at the given block's state.
///
/// May not return None if given BlockID::Latest.
/// Returns None if and only if the block's root hash has been pruned from the DB.
fn balance(&self, address: &Address, id: BlockID) -> Option<U256>;
/// Get address balance.
fn balance(&self, address: &Address) -> U256;
/// Get address balance at the latest block's state.
fn latest_balance(&self, address: &Address) -> U256 {
self.balance(address, BlockID::Latest)
.expect("balance will return Some if given BlockID::Latest. balance was given BlockID::Latest \
Therefore balance has returned Some; qed")
}
/// Get value of the storage at given position at the given block's state.
///
/// May not return None if given BlockID::Latest.
/// Returns None if and only if the block's root hash has been pruned from the DB.
fn storage_at(&self, address: &Address, position: &H256, id: BlockID) -> Option<H256>;
/// Get value of the storage at given position at the latest block's state.
fn latest_storage_at(&self, address: &Address, position: &H256) -> H256 {
self.storage_at(address, position, BlockID::Latest)
.expect("storage_at will return Some if given BlockID::Latest. storage_at was given BlockID::Latest. \
Therefore storage_at has returned Some; qed")
}
/// Get value of the storage at given position.
fn storage_at(&self, address: &Address, position: &H256) -> H256;
/// Get transaction with given hash.
fn transaction(&self, id: TransactionID) -> Option<LocalizedTransaction>;
fn transaction(&self, id: TransactionId) -> Option<LocalizedTransaction>;
/// Get uncle with given id.
fn uncle(&self, id: UncleID) -> Option<Header>;
fn uncle(&self, id: UncleId) -> Option<Header>;
/// Get transaction receipt with given hash.
fn transaction_receipt(&self, id: TransactionID) -> Option<LocalizedReceipt>;
fn transaction_receipt(&self, id: TransactionId) -> Option<LocalizedReceipt>;
/// Get a tree route between `from` and `to`.
/// See `BlockChain::tree_route`.
fn tree_route(&self, from: &H256, to: &H256) -> Option<TreeRoute>;
/// Get all possible uncle hashes for a block.
fn find_uncles(&self, hash: &H256) -> Option<Vec<H256>>;
/// Get latest state node
fn state_data(&self, hash: &H256) -> Option<Bytes>;
@@ -159,98 +108,25 @@ pub trait BlockChainClient : Sync + Send {
/// Get the best block header.
fn best_block_header(&self) -> Bytes {
// TODO: lock blockchain only once
self.block_header(BlockID::Hash(self.chain_info().best_block_hash)).unwrap()
self.block_header(BlockId::Hash(self.chain_info().best_block_hash)).unwrap()
}
/// Returns numbers of blocks containing given bloom.
fn blocks_with_bloom(&self, bloom: &H2048, from_block: BlockID, to_block: BlockID) -> Option<Vec<BlockNumber>>;
fn blocks_with_bloom(&self, bloom: &H2048, from_block: BlockId, to_block: BlockId) -> Option<Vec<BlockNumber>>;
/// Returns logs matching given filter.
fn logs(&self, filter: Filter) -> Vec<LocalizedLogEntry>;
// TODO [todr] Should be moved to miner crate eventually.
/// Returns ClosedBlock prepared for sealing.
fn prepare_sealing(&self, author: Address, gas_floor_target: U256, extra_data: Bytes, transactions: Vec<SignedTransaction>)
-> Option<(ClosedBlock, HashSet<H256>)>;
// TODO [todr] Should be moved to miner crate eventually.
/// Attempts to seal given block. Returns `SealedBlock` on success and the same block in case of error.
fn try_seal(&self, block: ClosedBlock, seal: Vec<Bytes>) -> Result<SealedBlock, ClosedBlock>;
/// Makes a non-persistent transaction call.
// TODO: should be able to accept blockchain location for call.
fn call(&self, t: &SignedTransaction, analytics: CallAnalytics) -> Result<Executed, ExecutionError>;
/// Returns EvmFactory.
fn vm_factory(&self) -> &EvmFactory;
/// Returns traces matching given filter.
fn filter_traces(&self, filter: TraceFilter) -> Option<Vec<LocalizedTrace>>;
/// Returns trace with given id.
fn trace(&self, trace: TraceId) -> Option<LocalizedTrace>;
/// Returns traces created by transaction.
fn transaction_traces(&self, trace: TransactionID) -> Option<Vec<LocalizedTrace>>;
/// Returns traces created by transaction from block.
fn block_traces(&self, trace: BlockID) -> Option<Vec<LocalizedTrace>>;
/// Get last hashes starting from best block.
fn last_hashes(&self) -> LastHashes;
/// import transactions from network/other 3rd party
fn import_transactions(&self, transactions: Vec<SignedTransaction>) -> Vec<Result<TransactionImportResult, EthError>>;
/// Queue transactions for importing.
fn queue_transactions(&self, transactions: Vec<Bytes>);
/// list all transactions
fn all_transactions(&self) -> Vec<SignedTransaction>;
/// Get the gas price distribution.
fn gas_price_statistics(&self, sample_size: usize, distribution_size: usize) -> Result<Vec<U256>, ()> {
let mut h = self.chain_info().best_block_hash;
let mut corpus = Vec::new();
for _ in 0..sample_size {
let block_bytes = self.block(BlockID::Hash(h)).expect("h is either the best_block_hash or an ancestor; qed");
let block = BlockView::new(&block_bytes);
let header = block.header_view();
if header.number() == 0 {
break;
}
block.transaction_views().iter().foreach(|t| corpus.push(t.gas_price()));
h = header.parent_hash().clone();
}
corpus.sort();
let n = corpus.len();
if n > 0 {
Ok((0..(distribution_size + 1))
.map(|i| corpus[i * (n - 1) / distribution_size])
.collect::<Vec<_>>()
)
} else {
Err(())
}
}
/// Get `Some` gas limit of SOFT_FORK_BLOCK, or `None` if chain is not yet that long.
fn dao_rescue_block_gas_limit(&self, chain_hash: H256) -> Option<U256> {
const SOFT_FORK_BLOCK: u64 = 1775000;
// shortcut if the canon chain is already known.
if self.chain_info().best_block_number > SOFT_FORK_BLOCK + 1000 {
return self.block_header(BlockID::Number(SOFT_FORK_BLOCK)).map(|header| HeaderView::new(&header).gas_limit());
}
// otherwise check according to `chain_hash`.
if let Some(mut header) = self.block_header(BlockID::Hash(chain_hash)) {
if HeaderView::new(&header).number() < SOFT_FORK_BLOCK {
None
} else {
while HeaderView::new(&header).number() != SOFT_FORK_BLOCK {
header = self.block_header(BlockID::Hash(HeaderView::new(&header).parent_hash())).expect("chain is complete; parent of chain entry must be in chain; qed");
}
Some(HeaderView::new(&header).gas_limit())
}
} else {
None
}
}
fn call(&self, t: &SignedTransaction) -> Result<Executed, Error>;
}
/// Extended client interface used for mining
pub trait MiningBlockChainClient : BlockChainClient {
/// Returns OpenBlock prepared for closing.
fn prepare_open_block(&self, author: Address, gas_floor_target: U256, extra_data: Bytes)
-> OpenBlock;
}

View File

@@ -20,24 +20,18 @@ use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrder};
use util::*;
use transaction::{Transaction, LocalizedTransaction, SignedTransaction, Action};
use blockchain::TreeRoute;
use client::{BlockChainClient, MiningBlockChainClient, BlockChainInfo, BlockStatus, BlockID, TransactionID, UncleID, TraceId, TraceFilter, LastHashes, CallAnalytics};
use client::{BlockChainClient, BlockChainInfo, BlockStatus, BlockId, TransactionId, UncleId};
use header::{Header as BlockHeader, BlockNumber};
use filter::Filter;
use log_entry::LocalizedLogEntry;
use receipt::{Receipt, LocalizedReceipt};
use blockchain::extras::BlockReceipts;
use extras::BlockReceipts;
use error::{ImportResult};
use evm::Factory as EvmFactory;
use miner::{Miner, MinerService};
use block_queue::BlockQueueInfo;
use block::OpenBlock;
use block::{SealedBlock, ClosedBlock};
use executive::Executed;
use error::{ExecutionError};
use trace::LocalizedTrace;
use miner::{TransactionImportResult, AccountDetails};
use error::Error as EthError;
use error::Error;
/// Test client.
pub struct TestBlockChainClient {
@@ -53,8 +47,6 @@ pub struct TestBlockChainClient {
pub difficulty: RwLock<U256>,
/// Balances.
pub balances: RwLock<HashMap<Address, U256>>,
/// Nonces.
pub nonces: RwLock<HashMap<Address, U256>>,
/// Storage.
pub storage: RwLock<HashMap<(Address, H256), H256>>,
/// Code.
@@ -62,11 +54,9 @@ pub struct TestBlockChainClient {
/// Execution result.
pub execution_result: RwLock<Option<Executed>>,
/// Transaction receipts.
pub receipts: RwLock<HashMap<TransactionID, LocalizedReceipt>>,
pub receipts: RwLock<HashMap<TransactionId, LocalizedReceipt>>,
/// Block queue size.
pub queue_size: AtomicUsize,
/// Miner
pub miner: Arc<Miner>,
}
#[derive(Clone)]
@@ -99,13 +89,11 @@ impl TestBlockChainClient {
last_hash: RwLock::new(H256::new()),
difficulty: RwLock::new(From::from(0)),
balances: RwLock::new(HashMap::new()),
nonces: RwLock::new(HashMap::new()),
storage: RwLock::new(HashMap::new()),
code: RwLock::new(HashMap::new()),
execution_result: RwLock::new(None),
receipts: RwLock::new(HashMap::new()),
queue_size: AtomicUsize::new(0),
miner: Arc::new(Miner::default()),
};
client.add_blocks(1, EachBlockWith::Nothing); // add genesis block
client.genesis_hash = client.last_hash.read().unwrap().clone();
@@ -113,7 +101,7 @@ impl TestBlockChainClient {
}
/// Set the transaction receipt result
pub fn set_transaction_receipt(&self, id: TransactionID, receipt: LocalizedReceipt) {
pub fn set_transaction_receipt(&self, id: TransactionId, receipt: LocalizedReceipt) {
self.receipts.write().unwrap().insert(id, receipt);
}
@@ -127,11 +115,6 @@ impl TestBlockChainClient {
self.balances.write().unwrap().insert(address, balance);
}
/// Set nonce of account `address` to `nonce`.
pub fn set_nonce(&self, address: Address, nonce: U256) {
self.nonces.write().unwrap().insert(address, nonce);
}
/// Set `code` at `address`.
pub fn set_code(&self, address: Address, code: Bytes) {
self.code.write().unwrap().insert(address, code);
@@ -173,8 +156,6 @@ impl TestBlockChainClient {
EachBlockWith::Transaction | EachBlockWith::UncleAndTransaction => {
let mut txs = RlpStream::new_list(1);
let keypair = KeyPair::create().unwrap();
// Update nonces value
self.nonces.write().unwrap().insert(keypair.address(), U256::one());
let tx = Transaction {
action: Action::Create,
value: U256::from(100),
@@ -187,7 +168,7 @@ impl TestBlockChainClient {
txs.append(&signed_tx);
txs.out()
},
_ => rlp::EMPTY_LIST_RLP.to_vec()
_ => rlp::NULL_RLP.to_vec()
};
let mut rlp = RlpStream::new_list(3);
@@ -198,23 +179,11 @@ impl TestBlockChainClient {
}
}
/// Make a bad block by setting invalid extra data.
/// TODO:
pub fn corrupt_block(&mut self, n: BlockNumber) {
let hash = self.block_hash(BlockID::Number(n)).unwrap();
let mut header: BlockHeader = decode(&self.block_header(BlockID::Number(n)).unwrap());
header.extra_data = b"This extra data is way too long to be considered valid".to_vec();
let mut rlp = RlpStream::new_list(3);
rlp.append(&header);
rlp.append_raw(&rlp::NULL_RLP, 1);
rlp.append_raw(&rlp::NULL_RLP, 1);
self.blocks.write().unwrap().insert(hash, rlp.out());
}
/// Make a bad block by setting invalid parent hash.
pub fn corrupt_block_parent(&mut self, n: BlockNumber) {
let hash = self.block_hash(BlockID::Number(n)).unwrap();
let mut header: BlockHeader = decode(&self.block_header(BlockID::Number(n)).unwrap());
header.parent_hash = H256::from(42);
let hash = self.block_hash(BlockId::Number(n)).unwrap();
let mut header: BlockHeader = decode(&self.block_header(BlockId::Number(n)).unwrap());
header.parent_hash = H256::new();
let mut rlp = RlpStream::new_list(3);
rlp.append(&header);
rlp.append_raw(&rlp::NULL_RLP, 1);
@@ -229,75 +198,58 @@ impl TestBlockChainClient {
blocks_read[&index].clone()
}
fn block_hash(&self, id: BlockID) -> Option<H256> {
fn block_hash(&self, id: BlockId) -> Option<H256> {
match id {
BlockID::Hash(hash) => Some(hash),
BlockID::Number(n) => self.numbers.read().unwrap().get(&(n as usize)).cloned(),
BlockID::Earliest => self.numbers.read().unwrap().get(&0).cloned(),
BlockID::Latest => self.numbers.read().unwrap().get(&(self.numbers.read().unwrap().len() - 1)).cloned()
BlockId::Hash(hash) => Some(hash),
BlockId::Number(n) => self.numbers.read().unwrap().get(&(n as usize)).cloned(),
BlockId::Earliest => self.numbers.read().unwrap().get(&0).cloned(),
BlockId::Latest => self.numbers.read().unwrap().get(&(self.numbers.read().unwrap().len() - 1)).cloned()
}
}
}
impl MiningBlockChainClient for TestBlockChainClient {
fn prepare_open_block(&self, _author: Address, _gas_floor_target: U256, _extra_data: Bytes) -> OpenBlock {
unimplemented!();
}
}
impl BlockChainClient for TestBlockChainClient {
fn call(&self, _t: &SignedTransaction, _analytics: CallAnalytics) -> Result<Executed, ExecutionError> {
fn call(&self, _t: &SignedTransaction) -> Result<Executed, Error> {
Ok(self.execution_result.read().unwrap().clone().unwrap())
}
fn block_total_difficulty(&self, _id: BlockID) -> Option<U256> {
fn block_total_difficulty(&self, _id: BlockId) -> Option<U256> {
Some(U256::zero())
}
fn block_hash(&self, id: BlockID) -> Option<H256> {
Self::block_hash(self, id)
fn block_hash(&self, _id: BlockId) -> Option<H256> {
unimplemented!();
}
fn nonce(&self, address: &Address, id: BlockID) -> Option<U256> {
match id {
BlockID::Latest => Some(self.nonces.read().unwrap().get(address).cloned().unwrap_or_else(U256::zero)),
_ => None,
}
fn nonce(&self, _address: &Address) -> U256 {
U256::zero()
}
fn code(&self, address: &Address) -> Option<Bytes> {
self.code.read().unwrap().get(address).cloned()
}
fn balance(&self, address: &Address, id: BlockID) -> Option<U256> {
if let BlockID::Latest = id {
Some(self.balances.read().unwrap().get(address).cloned().unwrap_or_else(U256::zero))
} else {
None
}
fn balance(&self, address: &Address) -> U256 {
self.balances.read().unwrap().get(address).cloned().unwrap_or_else(U256::zero)
}
fn storage_at(&self, address: &Address, position: &H256, id: BlockID) -> Option<H256> {
if let BlockID::Latest = id {
Some(self.storage.read().unwrap().get(&(address.clone(), position.clone())).cloned().unwrap_or_else(H256::new))
} else {
None
}
fn storage_at(&self, address: &Address, position: &H256) -> H256 {
self.storage.read().unwrap().get(&(address.clone(), position.clone())).cloned().unwrap_or_else(H256::new)
}
fn transaction(&self, _id: TransactionID) -> Option<LocalizedTransaction> {
fn transaction(&self, _id: TransactionId) -> Option<LocalizedTransaction> {
unimplemented!();
}
fn uncle(&self, _id: UncleID) -> Option<BlockHeader> {
fn uncle(&self, _id: UncleId) -> Option<BlockHeader> {
unimplemented!();
}
fn transaction_receipt(&self, id: TransactionID) -> Option<LocalizedReceipt> {
fn transaction_receipt(&self, id: TransactionId) -> Option<LocalizedReceipt> {
self.receipts.read().unwrap().get(&id).cloned()
}
fn blocks_with_bloom(&self, _bloom: &H2048, _from_block: BlockID, _to_block: BlockID) -> Option<Vec<BlockNumber>> {
fn blocks_with_bloom(&self, _bloom: &H2048, _from_block: BlockId, _to_block: BlockId) -> Option<Vec<BlockNumber>> {
unimplemented!();
}
@@ -305,15 +257,19 @@ impl BlockChainClient for TestBlockChainClient {
unimplemented!();
}
fn last_hashes(&self) -> LastHashes {
unimplemented!();
fn prepare_sealing(&self, _author: Address, _gas_floor_target: U256, _extra_data: Bytes, _transactions: Vec<SignedTransaction>) -> Option<(ClosedBlock, HashSet<H256>)> {
None
}
fn block_header(&self, id: BlockID) -> Option<Bytes> {
fn try_seal(&self, block: ClosedBlock, _seal: Vec<Bytes>) -> Result<SealedBlock, ClosedBlock> {
Err(block)
}
fn block_header(&self, id: BlockId) -> Option<Bytes> {
self.block_hash(id).and_then(|hash| self.blocks.read().unwrap().get(&hash).map(|r| Rlp::new(r).at(0).as_raw().to_vec()))
}
fn block_body(&self, id: BlockID) -> Option<Bytes> {
fn block_body(&self, id: BlockId) -> Option<Bytes> {
self.block_hash(id).and_then(|hash| self.blocks.read().unwrap().get(&hash).map(|r| {
let mut stream = RlpStream::new_list(2);
stream.append_raw(Rlp::new(&r).at(1).as_raw(), 1);
@@ -322,14 +278,14 @@ impl BlockChainClient for TestBlockChainClient {
}))
}
fn block(&self, id: BlockID) -> Option<Bytes> {
fn block(&self, id: BlockId) -> Option<Bytes> {
self.block_hash(id).and_then(|hash| self.blocks.read().unwrap().get(&hash).cloned())
}
fn block_status(&self, id: BlockID) -> BlockStatus {
fn block_status(&self, id: BlockId) -> BlockStatus {
match id {
BlockID::Number(number) if (number as usize) < self.blocks.read().unwrap().len() => BlockStatus::InChain,
BlockID::Hash(ref hash) if self.blocks.read().unwrap().get(hash).is_some() => BlockStatus::InChain,
BlockId::Number(number) if (number as usize) < self.blocks.read().unwrap().len() => BlockStatus::InChain,
BlockId::Hash(ref hash) if self.blocks.read().unwrap().get(hash).is_some() => BlockStatus::InChain,
_ => BlockStatus::Unknown
}
}
@@ -364,10 +320,6 @@ impl BlockChainClient for TestBlockChainClient {
})
}
fn find_uncles(&self, _hash: &H256) -> Option<Vec<H256>> {
None
}
// TODO: returns just hashes instead of node state rlp(?)
fn state_data(&self, hash: &H256) -> Option<Bytes> {
// starts with 'f' ?
@@ -461,45 +413,4 @@ impl BlockChainClient for TestBlockChainClient {
best_block_number: self.blocks.read().unwrap().len() as BlockNumber - 1,
}
}
fn vm_factory(&self) -> &EvmFactory {
unimplemented!();
}
fn filter_traces(&self, _filter: TraceFilter) -> Option<Vec<LocalizedTrace>> {
unimplemented!();
}
fn trace(&self, _trace: TraceId) -> Option<LocalizedTrace> {
unimplemented!();
}
fn transaction_traces(&self, _trace: TransactionID) -> Option<Vec<LocalizedTrace>> {
unimplemented!();
}
fn block_traces(&self, _trace: BlockID) -> Option<Vec<LocalizedTrace>> {
unimplemented!();
}
fn import_transactions(&self, transactions: Vec<SignedTransaction>) -> Vec<Result<TransactionImportResult, EthError>> {
let nonces = self.nonces.read().unwrap();
let balances = self.balances.read().unwrap();
let fetch_account = |a: &Address| AccountDetails {
nonce: nonces[a],
balance: balances[a],
};
self.miner.import_transactions(self, transactions, &fetch_account)
}
fn queue_transactions(&self, transactions: Vec<Bytes>) {
// import right here
let tx = transactions.into_iter().filter_map(|bytes| UntrustedRlp::new(&bytes).as_val().ok()).collect();
self.import_transactions(tx);
}
fn all_transactions(&self) -> Vec<SignedTransaction> {
self.miner.all_transactions()
}
}

View File

@@ -1,38 +0,0 @@
//! Bridge between Tracedb and Blockchain.
use std::ops::Range;
use util::{Address, H256};
use header::BlockNumber;
use trace::DatabaseExtras as TraceDatabaseExtras;
use blockchain::{BlockChain, BlockProvider};
use blockchain::extras::TransactionAddress;
use super::BlockID;
impl TraceDatabaseExtras for BlockChain {
fn block_hash(&self, block_number: BlockNumber) -> Option<H256> {
(self as &BlockProvider).block_hash(block_number)
}
fn transaction_hash(&self, block_number: BlockNumber, tx_position: usize) -> Option<H256> {
(self as &BlockProvider).block_hash(block_number)
.and_then(|block_hash| {
let tx_address = TransactionAddress {
block_hash: block_hash,
index: tx_position
};
self.transaction(&tx_address)
})
.map(|tx| tx.hash())
}
}
/// Easy to use trace filter.
pub struct Filter {
/// Range of filtering.
pub range: Range<BlockID>,
/// From address.
pub from_address: Vec<Address>,
/// To address.
pub to_address: Vec<Address>,
}

View File

@@ -25,4 +25,4 @@ pub use account::*;
pub use transaction::*;
pub use log_entry::*;
pub use receipt::*;
pub use action_params::*;
pub use action_params::*;

View File

@@ -1,181 +0,0 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Extras db utils.
use std::ops::Deref;
use std::hash::Hash;
use std::sync::RwLock;
use std::collections::HashMap;
use util::{DBTransaction, Database};
use util::rlp::{encode, Encodable, decode, Decodable};
#[derive(Clone, Copy)]
pub enum CacheUpdatePolicy {
Overwrite,
Remove,
}
pub trait Cache<K, V> {
fn insert(&mut self, k: K, v: V) -> Option<V>;
fn remove(&mut self, k: &K) -> Option<V>;
fn get(&self, k: &K) -> Option<&V>;
}
impl<K, V> Cache<K, V> for HashMap<K, V> where K: Hash + Eq {
fn insert(&mut self, k: K, v: V) -> Option<V> {
HashMap::insert(self, k, v)
}
fn remove(&mut self, k: &K) -> Option<V> {
HashMap::remove(self, k)
}
fn get(&self, k: &K) -> Option<&V> {
HashMap::get(self, k)
}
}
/// Should be used to get database key associated with given value.
pub trait Key<T> {
type Target: Deref<Target = [u8]>;
/// Returns db key.
fn key(&self) -> Self::Target;
}
/// Should be used to write value into database.
pub trait Writable {
/// Writes the value into the database.
fn write<T, R>(&self, key: &Key<T, Target = R>, value: &T) where T: Encodable, R: Deref<Target = [u8]>;
/// Writes the value into the database and updates the cache.
fn write_with_cache<K, T, R>(&self, cache: &mut Cache<K, T>, key: K, value: T, policy: CacheUpdatePolicy) where
K: Key<T, Target = R> + Hash + Eq,
T: Encodable,
R: Deref<Target = [u8]> {
self.write(&key, &value);
match policy {
CacheUpdatePolicy::Overwrite => {
cache.insert(key, value);
},
CacheUpdatePolicy::Remove => {
cache.remove(&key);
}
}
}
/// Writes the values into the database and updates the cache.
fn extend_with_cache<K, T, R>(&self, cache: &mut Cache<K, T>, values: HashMap<K, T>, policy: CacheUpdatePolicy) where
K: Key<T, Target = R> + Hash + Eq,
T: Encodable,
R: Deref<Target = [u8]> {
match policy {
CacheUpdatePolicy::Overwrite => {
for (key, value) in values.into_iter() {
self.write(&key, &value);
cache.insert(key, value);
}
},
CacheUpdatePolicy::Remove => {
for (key, value) in &values {
self.write(key, value);
cache.remove(key);
}
},
}
}
}
/// Should be used to read values from database.
pub trait Readable {
/// Returns value for given key.
fn read<T, R>(&self, key: &Key<T, Target = R>) -> Option<T> where
T: Decodable,
R: Deref<Target = [u8]>;
/// Returns value for given key either in cache or in database.
fn read_with_cache<K, T, C>(&self, cache: &RwLock<C>, key: &K) -> Option<T> where
K: Key<T> + Eq + Hash + Clone,
T: Clone + Decodable,
C: Cache<K, T> {
{
let read = cache.read().unwrap();
if let Some(v) = read.get(key) {
return Some(v.clone());
}
}
self.read(key).map(|value: T|{
let mut write = cache.write().unwrap();
write.insert(key.clone(), value.clone());
value
})
}
/// Returns true if given value exists.
fn exists<T, R>(&self, key: &Key<T, Target = R>) -> bool where R: Deref<Target= [u8]>;
/// Returns true if given value exists either in cache or in database.
fn exists_with_cache<K, T, R, C>(&self, cache: &RwLock<C>, key: &K) -> bool where
K: Eq + Hash + Key<T, Target = R>,
R: Deref<Target = [u8]>,
C: Cache<K, T> {
{
let read = cache.read().unwrap();
if read.get(key).is_some() {
return true;
}
}
self.exists::<T, R>(key)
}
}
impl Writable for DBTransaction {
fn write<T, R>(&self, key: &Key<T, Target = R>, value: &T) where T: Encodable, R: Deref<Target = [u8]> {
let result = self.put(&key.key(), &encode(value));
if let Err(err) = result {
panic!("db put failed, key: {:?}, err: {:?}", &key.key() as &[u8], err);
}
}
}
impl Readable for Database {
fn read<T, R>(&self, key: &Key<T, Target = R>) -> Option<T> where T: Decodable, R: Deref<Target = [u8]> {
let result = self.get(&key.key());
match result {
Ok(option) => option.map(|v| decode(&v)),
Err(err) => {
panic!("db get failed, key: {:?}, err: {:?}", &key.key() as &[u8], err);
}
}
}
fn exists<T, R>(&self, key: &Key<T, Target = R>) -> bool where R: Deref<Target = [u8]> {
let result = self.get(&key.key());
match result {
Ok(v) => v.is_some(),
Err(err) => {
panic!("db get failed, key: {:?}, err: {:?}", &key.key() as &[u8], err);
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More