Compare commits
1658 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a9a41a03c5 | ||
|
|
73376f0c3a | ||
|
|
e4f6871646 | ||
|
|
282e7d10d0 | ||
|
|
bdd04d10af | ||
|
|
8b658b257f | ||
|
|
03fad0869e | ||
|
|
8017daf47c | ||
|
|
429c83f92f | ||
|
|
a453bab9e8 | ||
|
|
2cf4549d01 | ||
|
|
68dfae8f06 | ||
|
|
b7caa24c2e | ||
|
|
ed5d797662 | ||
|
|
69847e3b8b | ||
|
|
ef124fa3ef | ||
|
|
aece120e77 | ||
|
|
cc127eed15 | ||
|
|
acfabe5431 | ||
|
|
a600b1ac80 | ||
|
|
1ce3fc24cf | ||
|
|
7ae0eb8137 | ||
|
|
df04c95f9a | ||
|
|
6e7b003e78 | ||
|
|
1d780f456a | ||
|
|
0de297adf7 | ||
|
|
29b6ba4a87 | ||
|
|
5a7fd628db | ||
|
|
cf7830fa8f | ||
|
|
1dc56fc3e1 | ||
|
|
91efef8497 | ||
|
|
6962e1d211 | ||
|
|
dd62e2d43b | ||
|
|
038ef2b3c3 | ||
|
|
c8c7fbbf27 | ||
|
|
6bbd237711 | ||
|
|
6bdbc2cb93 | ||
|
|
f370e17a54 | ||
|
|
30f2e8f60c | ||
|
|
4a60407c2a | ||
|
|
5dd3c6196c | ||
|
|
a681566967 | ||
|
|
ff0d8ea868 | ||
|
|
489ddd1d6f | ||
|
|
90a4475f52 | ||
|
|
bee2102424 | ||
|
|
bb70cd889e | ||
|
|
8134a89b87 | ||
|
|
d3cb79833b | ||
|
|
673c5afd4d | ||
|
|
3921e10af0 | ||
|
|
4ba8b3c1e0 | ||
|
|
6616b5e17d | ||
|
|
a7c332ecea | ||
|
|
070c1b170f | ||
|
|
c38d15ad4d | ||
|
|
24e73f3aec | ||
|
|
6ae467252c | ||
|
|
9c58ebf2d2 | ||
|
|
ff29c82c9e | ||
|
|
dff7d9603c | ||
|
|
9c07e5c355 | ||
|
|
5665083e20 | ||
|
|
30fad64621 | ||
|
|
51c6b85f80 | ||
|
|
af65945b58 | ||
|
|
5a794b21cf | ||
|
|
6ca2e6b29b | ||
|
|
93a89049ed | ||
|
|
92edf7f511 | ||
|
|
4a6206c514 | ||
|
|
60270083e5 | ||
|
|
34155730ff | ||
|
|
946c1fd76a | ||
|
|
2df737bebf | ||
|
|
9885bdcf0a | ||
|
|
86ba6f1912 | ||
|
|
ee01ad1324 | ||
|
|
f24ba94fbd | ||
|
|
dc24448900 | ||
|
|
b3f37f3cb4 | ||
|
|
e24f9c9936 | ||
|
|
19d83a9074 | ||
|
|
5958c87e56 | ||
|
|
83c967c082 | ||
|
|
aec4130dca | ||
|
|
98ae9cad6f | ||
|
|
5d1ff3d7ba | ||
|
|
580913fa7d | ||
|
|
05927eba1f | ||
|
|
7c27f9dfed | ||
|
|
c096c087df | ||
|
|
78ebc8b975 | ||
|
|
e3214c63c6 | ||
|
|
2138a53067 | ||
|
|
72771bd833 | ||
|
|
91aee536ca | ||
|
|
09e1970bbf | ||
|
|
ebcbb19aef | ||
|
|
e3ca87c4d1 | ||
|
|
1fcf5c7cc2 | ||
|
|
dd0e681847 | ||
|
|
c006f446a4 | ||
|
|
9a16e593e2 | ||
|
|
5ef767f7f2 | ||
|
|
071da2eec5 | ||
|
|
a3f165cf48 | ||
|
|
93facbf854 | ||
|
|
42f5d7f897 | ||
|
|
97e553f1bf | ||
|
|
8caa859111 | ||
|
|
a3758161ac | ||
|
|
38870fb3e4 | ||
|
|
3ae8ccf8c6 | ||
|
|
477fdefb55 | ||
|
|
8dbf182618 | ||
|
|
2462193df8 | ||
|
|
0b86723e68 | ||
|
|
af891f65a7 | ||
|
|
39307b2bea | ||
|
|
4ecf23df9a | ||
|
|
4f56f8b27c | ||
|
|
6895a56099 | ||
|
|
599a6104b7 | ||
|
|
31de739122 | ||
|
|
af935df553 | ||
|
|
d0cec2434e | ||
|
|
c221f69ccd | ||
|
|
a3a68a20f4 | ||
|
|
993f707fbe | ||
|
|
ff788e4199 | ||
|
|
5919c660e5 | ||
|
|
495e56034f | ||
|
|
ed153995f9 | ||
|
|
150d7c1c78 | ||
|
|
5d67a32cef | ||
|
|
10aa32b0f5 | ||
|
|
a83def78b3 | ||
|
|
60b70dada1 | ||
|
|
dc79e63db7 | ||
|
|
7b5eeb1dd7 | ||
|
|
a102015ecf | ||
|
|
2a51a30d41 | ||
|
|
9f4bfd9e7a | ||
|
|
1667808ecb | ||
|
|
ac9e6f2649 | ||
|
|
33dfb819f0 | ||
|
|
6c1802e412 | ||
|
|
2e99bfafc8 | ||
|
|
a2c4d550d0 | ||
|
|
bc8ba10184 | ||
|
|
222404f801 | ||
|
|
044bf5511a | ||
|
|
1fdbfa14ad | ||
|
|
6859152c21 | ||
|
|
f9f25fd147 | ||
|
|
2e5d5f12dd | ||
|
|
627b67db0a | ||
|
|
07098fd16f | ||
|
|
e4763e90bc | ||
|
|
6b51dffca0 | ||
|
|
c21550a663 | ||
|
|
4f1f33d1b8 | ||
|
|
b3398cec33 | ||
|
|
593d947fcd | ||
|
|
2bd0c5ebcb | ||
|
|
6bbaced3cd | ||
|
|
cdc34957db | ||
|
|
8a644e7185 | ||
|
|
516b015325 | ||
|
|
2ef929dcbd | ||
|
|
2400001675 | ||
|
|
2574d000a3 | ||
|
|
a72d8ee0e7 | ||
|
|
482d910b15 | ||
|
|
b02d7a4311 | ||
|
|
ab0d280232 | ||
|
|
4fd0a95112 | ||
|
|
59d1a82814 | ||
|
|
83af81f443 | ||
|
|
6c40cdf5c6 | ||
|
|
a109a4a72b | ||
|
|
102626f2c2 | ||
|
|
8cc349bcb0 | ||
|
|
3c63244c00 | ||
|
|
a9b757a75c | ||
|
|
92bc21ba9c | ||
|
|
879bee994d | ||
|
|
a6f7957042 | ||
|
|
2785d61e75 | ||
|
|
8b49b315d9 | ||
|
|
313d9048bf | ||
|
|
29e2ba91a7 | ||
|
|
bf11fb6633 | ||
|
|
3e7edb2665 | ||
|
|
60d259c9d5 | ||
|
|
568dc90769 | ||
|
|
b9649c0e78 | ||
|
|
4e0d6f735a | ||
|
|
44d6e1f443 | ||
|
|
031a91ebc6 | ||
|
|
4ece68349c | ||
|
|
653a368783 | ||
|
|
566bb030ec | ||
|
|
23732fa516 | ||
|
|
84ce5af2b0 | ||
|
|
e3e10335f9 | ||
|
|
54fc5a533b | ||
|
|
dc7c53d59a | ||
|
|
34c89e5841 | ||
|
|
84ded6f43c | ||
|
|
e77cce66a1 | ||
|
|
6edb981bfa | ||
|
|
416781a8d4 | ||
|
|
27b18df3dd | ||
|
|
1d31cee524 | ||
|
|
19585947a5 | ||
|
|
bca9e1f31a | ||
|
|
41e0769e63 | ||
|
|
8fcec20398 | ||
|
|
082294fe81 | ||
|
|
f3486c48ea | ||
|
|
fb7ca8539e | ||
|
|
5bf906625b | ||
|
|
129ce97ad5 | ||
|
|
4f39fb2551 | ||
|
|
be8f922b3f | ||
|
|
a76e3a134f | ||
|
|
9ac30ad409 | ||
|
|
8a867262ad | ||
|
|
fc9ceb9131 | ||
|
|
1602906b56 | ||
|
|
230c6c889a | ||
|
|
9a1e1b7c89 | ||
|
|
e346cbc7f9 | ||
|
|
cb9b1e2ad5 | ||
|
|
d53306382d | ||
|
|
cc7038383a | ||
|
|
5302a7dd58 | ||
|
|
9547324b46 | ||
|
|
927ffa7e9c | ||
|
|
eafc1b153d | ||
|
|
f947a9cb71 | ||
|
|
78cc5a6ed1 | ||
|
|
bc1f603e0c | ||
|
|
353b9e91e6 | ||
|
|
53b0862096 | ||
|
|
11314a660d | ||
|
|
e2de1987c7 | ||
|
|
e7d96484a1 | ||
|
|
7c94b1495e | ||
|
|
0e9ffff8ea | ||
|
|
1646a82ecc | ||
|
|
b82b44bc1a | ||
|
|
0ba9782bb2 | ||
|
|
bbe5cd001a | ||
|
|
6e4ddde005 | ||
|
|
613d4c95f6 | ||
|
|
fe09d8d291 | ||
|
|
de079ebe31 | ||
|
|
9132895d0e | ||
|
|
b2891fcdda | ||
|
|
bca4e23df6 | ||
|
|
3aaf938add | ||
|
|
94a0193047 | ||
|
|
a8bc86151e | ||
|
|
7136cd7057 | ||
|
|
be03a6acbd | ||
|
|
7cfb9a2b0b | ||
|
|
57e9ed3f08 | ||
|
|
840f961dc2 | ||
|
|
c5f6250668 | ||
|
|
951512f9c9 | ||
|
|
878298f061 | ||
|
|
e0b4eab819 | ||
|
|
a8a731ba11 | ||
|
|
70db48961a | ||
|
|
c2ffa90478 | ||
|
|
3de482a431 | ||
|
|
06ba7e258e | ||
|
|
d2057a3f72 | ||
|
|
b667378820 | ||
|
|
d42f8eac1e | ||
|
|
c912bb8c17 | ||
|
|
f58e211b11 | ||
|
|
7e424d2713 | ||
|
|
7aa73f300a | ||
|
|
1f599ac6f9 | ||
|
|
f4f842f48e | ||
|
|
d874555310 | ||
|
|
05583c2cd7 | ||
|
|
855ae91c4c | ||
|
|
5705ecf95f | ||
|
|
beedbd5126 | ||
|
|
72debeebcf | ||
|
|
69c29fce84 | ||
|
|
71bfda3534 | ||
|
|
09b8116cde | ||
|
|
8fa9a240cc | ||
|
|
0716eaa036 | ||
|
|
38b9264de6 | ||
|
|
5f7bdc028d | ||
|
|
8b845e56da | ||
|
|
1ffe0c185c | ||
|
|
7b9db37d84 | ||
|
|
75a38500f1 | ||
|
|
e9900be6ea | ||
|
|
da7b30628b | ||
|
|
71c49eaaa2 | ||
|
|
7a6fa97d98 | ||
|
|
b05c218338 | ||
|
|
3d3041d418 | ||
|
|
f5682737d3 | ||
|
|
a6713467a7 | ||
|
|
09253ef19c | ||
|
|
c6616431b0 | ||
|
|
deb20c6249 | ||
|
|
e97f62e33c | ||
|
|
a4b35180d1 | ||
|
|
8d61c0298c | ||
|
|
7e452ab2e0 | ||
|
|
06a3557e3e | ||
|
|
c348508b40 | ||
|
|
1bad0783fe | ||
|
|
edd43cd5c3 | ||
|
|
18c35a031b | ||
|
|
5e9c8db4c9 | ||
|
|
7393de94f7 | ||
|
|
1dd87a39f5 | ||
|
|
d0b2df07db | ||
|
|
3bf67486ae | ||
|
|
a2f24a0083 | ||
|
|
91acb22bd4 | ||
|
|
ca35f116a6 | ||
|
|
03cd1c0494 | ||
|
|
074311d95b | ||
|
|
6d435d038f | ||
|
|
4b3f23f0ac | ||
|
|
bf6308312e | ||
|
|
3ee3171b8c | ||
|
|
6b074e8fb2 | ||
|
|
ab4561b5bc | ||
|
|
2ea45134ab | ||
|
|
d8fca91a2f | ||
|
|
a4dacca262 | ||
|
|
08522eec37 | ||
|
|
5ceb1b084c | ||
|
|
2245baaaab | ||
|
|
8fad728e9b | ||
|
|
7430cf72e2 | ||
|
|
46d588dcae | ||
|
|
026bfd6741 | ||
|
|
bff1c5bdcb | ||
|
|
d915eae7f7 | ||
|
|
2582253f95 | ||
|
|
3617923d3c | ||
|
|
2b65011706 | ||
|
|
47cd9ff34c | ||
|
|
7208f9f95c | ||
|
|
81df97a737 | ||
|
|
c1c64bedc2 | ||
|
|
ec654feaf8 | ||
|
|
d416e5d9bc | ||
|
|
22e390f922 | ||
|
|
c9f8eff92d | ||
|
|
5e1e3ce857 | ||
|
|
91dc31fd70 | ||
|
|
e957565144 | ||
|
|
75a7cf2860 | ||
|
|
591fa9625d | ||
|
|
42478add64 | ||
|
|
76b413b5f7 | ||
|
|
b4aae6bd9c | ||
|
|
1baa150086 | ||
|
|
defe688797 | ||
|
|
2c9a5fc0a9 | ||
|
|
335bce85e8 | ||
|
|
6026dd3657 | ||
|
|
d6701065ea | ||
|
|
da058d0e86 | ||
|
|
232274546b | ||
|
|
55fec2dcc3 | ||
|
|
29e286572c | ||
|
|
3f77f7ce1f | ||
|
|
16412eb0c9 | ||
|
|
fc60ed92e6 | ||
|
|
c340d8a34f | ||
|
|
67ffac1df9 | ||
|
|
b38488dd07 | ||
|
|
2a101baf1d | ||
|
|
07641b8f0a | ||
|
|
10bbe8c8a2 | ||
|
|
88b03580ff | ||
|
|
1e9da1e0fa | ||
|
|
5a0d367e0b | ||
|
|
80e56cb8d7 | ||
|
|
9603597da7 | ||
|
|
77c3e10b6a | ||
|
|
7649037e51 | ||
|
|
87e9ca7517 | ||
|
|
5538527016 | ||
|
|
7284df9bf5 | ||
|
|
6803375301 | ||
|
|
dcd64f73d4 | ||
|
|
549647b6f2 | ||
|
|
6b852a0635 | ||
|
|
2527130831 | ||
|
|
3d86d099bb | ||
|
|
0f1e2f5d2f | ||
|
|
818b87e311 | ||
|
|
79bd168267 | ||
|
|
be6c572449 | ||
|
|
44ed899fb3 | ||
|
|
dac387fac1 | ||
|
|
71131c41e5 | ||
|
|
b562480173 | ||
|
|
b89888eda1 | ||
|
|
efa8f661e5 | ||
|
|
f7536876d5 | ||
|
|
aeae4670f1 | ||
|
|
58948c53ff | ||
|
|
f5cc3db4da | ||
|
|
7b89d6a263 | ||
|
|
a26a4edc85 | ||
|
|
91bb6c5d43 | ||
|
|
37260d7cf5 | ||
|
|
8ced25b36c | ||
|
|
39e2f6c891 | ||
|
|
5920a7068f | ||
|
|
7610d308e8 | ||
|
|
a03da30510 | ||
|
|
65d42d6a5a | ||
|
|
b3caeee758 | ||
|
|
9940432051 | ||
|
|
dbddb6a566 | ||
|
|
9ed2122ae2 | ||
|
|
5c019b74e4 | ||
|
|
0b8710a2a1 | ||
|
|
ca33f7c18d | ||
|
|
1dac2e3b23 | ||
|
|
8c7bcdafdb | ||
|
|
925869d462 | ||
|
|
bee3669e9b | ||
|
|
4c812169d1 | ||
|
|
f5efd444f5 | ||
|
|
6b12334136 | ||
|
|
4ef4819bf9 | ||
|
|
a8831fe896 | ||
|
|
12a76597d4 | ||
|
|
b33482ce74 | ||
|
|
b1849bd1ad | ||
|
|
7064624b6f | ||
|
|
7f9e8d0b48 | ||
|
|
070aae6562 | ||
|
|
fca22e92ce | ||
|
|
9260d44362 | ||
|
|
c2b226ec57 | ||
|
|
833dc16040 | ||
|
|
6d9baef12c | ||
|
|
89a77149bf | ||
|
|
e5e238746b | ||
|
|
036b324804 | ||
|
|
3e7d8bf1a8 | ||
|
|
e633cd2f75 | ||
|
|
383b7a3cab | ||
|
|
2a92e10fcd | ||
|
|
d54d3a2c60 | ||
|
|
6e7828fa71 | ||
|
|
2e52c99042 | ||
|
|
c6369a4ae7 | ||
|
|
2e56fbad2c | ||
|
|
293d9f15d5 | ||
|
|
a72ee5c16a | ||
|
|
cfaa0389e1 | ||
|
|
becf1d7b28 | ||
|
|
b4b883b341 | ||
|
|
be435cde99 | ||
|
|
c5d8f5e136 | ||
|
|
446c9096f4 | ||
|
|
5397da0c93 | ||
|
|
13968aaa38 | ||
|
|
2abe8cc5dd | ||
|
|
fdc22db3f4 | ||
|
|
bf9173e673 | ||
|
|
f61ee1a5f1 | ||
|
|
e6d141e14f | ||
|
|
5168a1c851 | ||
|
|
db869fcdd1 | ||
|
|
e46c9f67ab | ||
|
|
482fe3b211 | ||
|
|
9ae93d6962 | ||
|
|
ef39eed12f | ||
|
|
62e37aef8f | ||
|
|
3db2328f52 | ||
|
|
4efd658577 | ||
|
|
0cb1affd48 | ||
|
|
e408b7ac99 | ||
|
|
b4899f4d47 | ||
|
|
79919bdc3c | ||
|
|
18ffd94674 | ||
|
|
1dae61f22f | ||
|
|
302126ebcf | ||
|
|
98d9752097 | ||
|
|
b93c83b8a0 | ||
|
|
54c20f6f9c | ||
|
|
a460813788 | ||
|
|
ba8c7bc959 | ||
|
|
a7de430193 | ||
|
|
67b9e08ff0 | ||
|
|
a063a63ac7 | ||
|
|
9572f6e5fc | ||
|
|
1fa8f108d9 | ||
|
|
64b74eae43 | ||
|
|
3dff5a9f3f | ||
|
|
e6921144dc | ||
|
|
f775606c37 | ||
|
|
bbd024d646 | ||
|
|
4675b7408f | ||
|
|
c8c47ebe32 | ||
|
|
ec61c7534c | ||
|
|
d39b9506d2 | ||
|
|
4153052148 | ||
|
|
d5048967e2 | ||
|
|
aa465fa2cd | ||
|
|
6f850ebdac | ||
|
|
4dc9aedfb5 | ||
|
|
bb1b8cc08a | ||
|
|
3905717d5d | ||
|
|
ae2deaaf72 | ||
|
|
1e10445f82 | ||
|
|
6c6229c963 | ||
|
|
d7b79c1274 | ||
|
|
3ba15f6c64 | ||
|
|
8752a60018 | ||
|
|
3e2479cf40 | ||
|
|
81d8dafd9e | ||
|
|
0318bb9fe9 | ||
|
|
18dac64abb | ||
|
|
f357274ced | ||
|
|
7dc05f1bcc | ||
|
|
35753f22f7 | ||
|
|
c3404c9b59 | ||
|
|
a132fefcc7 | ||
|
|
cce18cb4c5 | ||
|
|
79a60e157b | ||
|
|
ee3f608204 | ||
|
|
c202abe09d | ||
|
|
d40504caa5 | ||
|
|
77942c0b48 | ||
|
|
4c44994807 | ||
|
|
9a626c84bc | ||
|
|
29e18cfc4d | ||
|
|
401bdca153 | ||
|
|
b17581d7de | ||
|
|
b9ec87548d | ||
|
|
bc5c3da2af | ||
|
|
716c9bb43c | ||
|
|
e9bcce05a1 | ||
|
|
7ad9c73c75 | ||
|
|
8596a347ea | ||
|
|
d40a038f37 | ||
|
|
26da38a439 | ||
|
|
e170916563 | ||
|
|
5f68b81f68 | ||
|
|
89deaef809 | ||
|
|
626acda6a3 | ||
|
|
b7ada4dee0 | ||
|
|
5c63311268 | ||
|
|
555555e6f7 | ||
|
|
c370bcaded | ||
|
|
6676c6cf7e | ||
|
|
99e26b8480 | ||
|
|
a7a2b55362 | ||
|
|
d601e11d59 | ||
|
|
4742860b2e | ||
|
|
1fd9110829 | ||
|
|
b9b0ce8d65 | ||
|
|
1ef4db82e8 | ||
|
|
ae572cb8f5 | ||
|
|
ee77fc3bc3 | ||
|
|
985d412c48 | ||
|
|
c00b84e10b | ||
|
|
0c782bf34b | ||
|
|
f41466c8b5 | ||
|
|
db749dc564 | ||
|
|
e743972102 | ||
|
|
cee31f9e8d | ||
|
|
d45a676dc0 | ||
|
|
67421fc69e | ||
|
|
ae1bcd6a5b | ||
|
|
5fd4b9d7bd | ||
|
|
dad61bb7cf | ||
|
|
9957328607 | ||
|
|
c33b1caf21 | ||
|
|
bbb858b386 | ||
|
|
77cef76518 | ||
|
|
4146e1f02b | ||
|
|
2a08fb8fe3 | ||
|
|
495e7feb62 | ||
|
|
34edecd59d | ||
|
|
ec7af964ab | ||
|
|
10d914d6c6 | ||
|
|
f5ed31792f | ||
|
|
a845e08bc6 | ||
|
|
ed0d60bc16 | ||
|
|
4d29508b4c | ||
|
|
8e252d5f1b | ||
|
|
c81e4e24b3 | ||
|
|
4ccaabde40 | ||
|
|
4f732972bc | ||
|
|
da9d6bf8d5 | ||
|
|
c62bfcddef | ||
|
|
3abaeadcf3 | ||
|
|
3dd642abe9 | ||
|
|
ff7c755930 | ||
|
|
0cd8644292 | ||
|
|
3788b3a149 | ||
|
|
b729a381f8 | ||
|
|
5cb58c4269 | ||
|
|
266b4eedaa | ||
|
|
1465b0d34c | ||
|
|
a944638b5e | ||
|
|
1d5f407a29 | ||
|
|
134f48cdfb | ||
|
|
d0b32f8d42 | ||
|
|
2d604324b9 | ||
|
|
f9a0cc47a0 | ||
|
|
12547ecd37 | ||
|
|
1fdb1de218 | ||
|
|
649767b911 | ||
|
|
5766354c19 | ||
|
|
d49152c8b0 | ||
|
|
b036f1de98 | ||
|
|
6d25e7f8b4 | ||
|
|
8082fdb3ff | ||
|
|
70cecb49b0 | ||
|
|
fb5efa2ffc | ||
|
|
43348c1629 | ||
|
|
baa2f7c5bb | ||
|
|
b4bc395c6e | ||
|
|
84882922b4 | ||
|
|
ba296408d5 | ||
|
|
13e5c19be7 | ||
|
|
68e62030d5 | ||
|
|
79503e4f14 | ||
|
|
e037f32408 | ||
|
|
76bb0729ba | ||
|
|
16432129b5 | ||
|
|
ea26deaab1 | ||
|
|
11f4e8cb73 | ||
|
|
bbe6a287f8 | ||
|
|
89659606dd | ||
|
|
be1ec93271 | ||
|
|
7cea3eb5ed | ||
|
|
191bae5cd4 | ||
|
|
fb2ea765d5 | ||
|
|
af05939d74 | ||
|
|
1176f6acec | ||
|
|
7dfd7e883f | ||
|
|
a8cf0ddf50 | ||
|
|
22c4298bee | ||
|
|
c20eaf98ec | ||
|
|
a5808833b1 | ||
|
|
cd16828fef | ||
|
|
b9f7ed9185 | ||
|
|
7f3ba85a3f | ||
|
|
86fdcabd0e | ||
|
|
ea08dd76a5 | ||
|
|
1ba39538a7 | ||
|
|
f339b6a491 | ||
|
|
d74fc2c285 | ||
|
|
87d0f09a44 | ||
|
|
d4e66ba52f | ||
|
|
1607478405 | ||
|
|
50e5c88b7b | ||
|
|
30362bfebe | ||
|
|
a7dfa83da1 | ||
|
|
99f9747a3f | ||
|
|
d4a06b27ed | ||
|
|
8c3b56511a | ||
|
|
1e8bf8c89d | ||
|
|
0e905a06d9 | ||
|
|
d1fc5a5611 | ||
|
|
f85e409ff7 | ||
|
|
6d5ba59515 | ||
|
|
c1ed520de0 | ||
|
|
f794018e95 | ||
|
|
ffa113511b | ||
|
|
07399d377f | ||
|
|
42e4c2d51c | ||
|
|
129ad0bbcb | ||
|
|
468d761e5c | ||
|
|
098f9b6ebb | ||
|
|
5197ca87ee | ||
|
|
20846c11c9 | ||
|
|
f60097ddb6 | ||
|
|
6f93ecf1d2 | ||
|
|
325a257f7d | ||
|
|
c021ecd13b | ||
|
|
9d4cd7b73e | ||
|
|
e7791c220a | ||
|
|
7ee23240f0 | ||
|
|
4c55e4968e | ||
|
|
1de7ea090c | ||
|
|
f67486e31f | ||
|
|
688790f13f | ||
|
|
cf18c4bb0a | ||
|
|
d370a86b43 | ||
|
|
152bb6f21b | ||
|
|
56b020987e | ||
|
|
58039fb420 | ||
|
|
c4e2f65051 | ||
|
|
b28a8411a4 | ||
|
|
ba600ac06a | ||
|
|
194ca19720 | ||
|
|
c9efb56e19 | ||
|
|
db2efe8485 | ||
|
|
72031d6f95 | ||
|
|
a272f8570c | ||
|
|
3f89362630 | ||
|
|
30eee76767 | ||
|
|
c2a4ed6fc4 | ||
|
|
a3b1cdb175 | ||
|
|
5afa4621f9 | ||
|
|
3c7e4b8c6c | ||
|
|
86eab79d9d | ||
|
|
3405f3eab1 | ||
|
|
2b7fae8fa6 | ||
|
|
cf19e38663 | ||
|
|
d0ae713b29 | ||
|
|
e2db4972be | ||
|
|
b77fdcdd68 | ||
|
|
945ebcbf9b | ||
|
|
aa9e4af783 | ||
|
|
ca008fb541 | ||
|
|
637f4eeb12 | ||
|
|
8872558e0d | ||
|
|
1a1467169d | ||
|
|
e0e722784c | ||
|
|
946ee8f8c4 | ||
|
|
a7bf13f23f | ||
|
|
977ad428ae | ||
|
|
a61bf90c17 | ||
|
|
7370776af1 | ||
|
|
cc1a334ba7 | ||
|
|
33f187eeee | ||
|
|
28391d2f52 | ||
|
|
09d9697985 | ||
|
|
28545d706f | ||
|
|
3a5e7fc2ed | ||
|
|
94ec245187 | ||
|
|
6fd9780e60 | ||
|
|
049537e470 | ||
|
|
5b0c936fee | ||
|
|
f811fdc2cd | ||
|
|
32298cad6b | ||
|
|
e24ab5a4f1 | ||
|
|
fa6b35ec8d | ||
|
|
75d0606bc0 | ||
|
|
a0bc1f9dae | ||
|
|
1741597a20 | ||
|
|
ebd0cdbc7a | ||
|
|
fba5082b00 | ||
|
|
27380cdadb | ||
|
|
2969d015ed | ||
|
|
bf46531372 | ||
|
|
90a272c519 | ||
|
|
f484beb7e1 | ||
|
|
78d3dfbfa6 | ||
|
|
503a5aea19 | ||
|
|
31b6b59f20 | ||
|
|
1def165c0b | ||
|
|
11f1aeb36e | ||
|
|
6c64aec137 | ||
|
|
b1cfbc460e | ||
|
|
fb0be9e730 | ||
|
|
256557d3cc | ||
|
|
5579582a52 | ||
|
|
564a996620 | ||
|
|
49899d0dee | ||
|
|
6fb54f4c9d | ||
|
|
1251315b28 | ||
|
|
5d997ef099 | ||
|
|
f738f5e032 | ||
|
|
0c4cd00c1f | ||
|
|
c8d2237f0a | ||
|
|
b53d0050dd | ||
|
|
9f84326ca7 | ||
|
|
9706f78a09 | ||
|
|
e952d62950 | ||
|
|
33e7f5e390 | ||
|
|
f8553ef90a | ||
|
|
828bf7cb9e | ||
|
|
399dfc4c2e | ||
|
|
3cba91bdd5 | ||
|
|
a7d7cb9ecb | ||
|
|
b0452cf309 | ||
|
|
5e1229366d | ||
|
|
cf9b6e9e07 | ||
|
|
852155959d | ||
|
|
f383af093c | ||
|
|
ca6c91f591 | ||
|
|
5ec096d57e | ||
|
|
dfac17538f | ||
|
|
95365670e4 | ||
|
|
1946346711 | ||
|
|
f084399d4b | ||
|
|
bfdbff5ac7 | ||
|
|
506ca15a15 | ||
|
|
634679966e | ||
|
|
306315e3e5 | ||
|
|
0ac41975a4 | ||
|
|
7d873b2c81 | ||
|
|
bb56c5827b | ||
|
|
6c6bbe9c57 | ||
|
|
7f0d1173ba | ||
|
|
55ebab2392 | ||
|
|
6cff58055d | ||
|
|
46f3b5f913 | ||
|
|
8f6febae18 | ||
|
|
407f046b9c | ||
|
|
01db310cea | ||
|
|
ef38d9c769 | ||
|
|
44c29ece17 | ||
|
|
b9febdda34 | ||
|
|
57b0be2a0b | ||
|
|
14b6b389f2 | ||
|
|
361d36f7d6 | ||
|
|
53308b4deb | ||
|
|
dcc695dda5 | ||
|
|
f9604892ce | ||
|
|
28fc0aacc0 | ||
|
|
fa7944ce3d | ||
|
|
a950b81ee8 | ||
|
|
f7929ffdd4 | ||
|
|
9b9ea93ff7 | ||
|
|
00ae3cf218 | ||
|
|
d249918fe7 | ||
|
|
d424194bbf | ||
|
|
2ef6f756d0 | ||
|
|
6363b0f69f | ||
|
|
9d2823da89 | ||
|
|
f3f45a1dd9 | ||
|
|
caec38d533 | ||
|
|
8cc321fe24 | ||
|
|
7c28b1cef9 | ||
|
|
4e41cbca81 | ||
|
|
994d056922 | ||
|
|
71278def5e | ||
|
|
9301963d98 | ||
|
|
ab06c9209b | ||
|
|
b5e10a53af | ||
|
|
56c705968b | ||
|
|
2d18bc936f | ||
|
|
237bd37030 | ||
|
|
d94030294a | ||
|
|
f4d5c7b48e | ||
|
|
96e92f1c38 | ||
|
|
d67d1eb355 | ||
|
|
9e7968c92e | ||
|
|
326e1b3a42 | ||
|
|
483687b6bf | ||
|
|
2d992d0c29 | ||
|
|
52e22b8a51 | ||
|
|
05f00a946d | ||
|
|
3ea26fcb0a | ||
|
|
93aa6c613a | ||
|
|
33248528b9 | ||
|
|
354ac7d6e5 | ||
|
|
2b78e511c9 | ||
|
|
9b91444638 | ||
|
|
72b1b41748 | ||
|
|
96496d6349 | ||
|
|
7c19930efa | ||
|
|
9150538ac4 | ||
|
|
d5d5b0918c | ||
|
|
0a85df10e8 | ||
|
|
effa2cf96d | ||
|
|
4a8fe6c99d | ||
|
|
3fc7faf24c | ||
|
|
f62d058186 | ||
|
|
06aefb54bc | ||
|
|
a22f0a0d03 | ||
|
|
889642c3d4 | ||
|
|
89b1b25fde | ||
|
|
6c74bfb153 | ||
|
|
9836c79962 | ||
|
|
ab288268bc | ||
|
|
80e48f3672 | ||
|
|
16395a820f | ||
|
|
6d8749fbdd | ||
|
|
152afbcbf7 | ||
|
|
7f26b5cbba | ||
|
|
2a19f91e99 | ||
|
|
49cc40708d | ||
|
|
a4dcbceb10 | ||
|
|
c75348392c | ||
|
|
04f7322f06 | ||
|
|
f5e44e373e | ||
|
|
da6a8b98e2 | ||
|
|
5bf047825f | ||
|
|
2e76def295 | ||
|
|
79d6c84a43 | ||
|
|
e7c4e5273a | ||
|
|
f9c08df235 | ||
|
|
c622fc62d5 | ||
|
|
29531ae72f | ||
|
|
96a4eb5b9e | ||
|
|
8721f868a6 | ||
|
|
0d642f3109 | ||
|
|
d9acbbb027 | ||
|
|
c16a46dca7 | ||
|
|
2cb085db91 | ||
|
|
aa6db4e69d | ||
|
|
00ce4aaa26 | ||
|
|
14bcca54d2 | ||
|
|
e95f610195 | ||
|
|
25c88b7529 | ||
|
|
2a721b4eda | ||
|
|
a8affa6dee | ||
|
|
beb33672bd | ||
|
|
b6d1801e12 | ||
|
|
7e9779e334 | ||
|
|
271d3f3e57 | ||
|
|
7d27aceee4 | ||
|
|
23f1a8fd48 | ||
|
|
e74c333819 | ||
|
|
a51bc6cd36 | ||
|
|
75981ec0ab | ||
|
|
0bb5167fda | ||
|
|
b99825bcac | ||
|
|
0d507922ce | ||
|
|
5a1564a63b | ||
|
|
4dd63c81a6 | ||
|
|
ad00bd7bc8 | ||
|
|
0b1442faa2 | ||
|
|
4480cf512a | ||
|
|
b32e2f9549 | ||
|
|
c449bf5663 | ||
|
|
15a8860e8a | ||
|
|
0a49efd018 | ||
|
|
c3f33aefdd | ||
|
|
58fd0175bf | ||
|
|
ac73b2628a | ||
|
|
1583f7d434 | ||
|
|
8f56b21ca9 | ||
|
|
59ed67a3f7 | ||
|
|
b49e652ae7 | ||
|
|
9b13dd7216 | ||
|
|
1e117d1ee5 | ||
|
|
0595caf50c | ||
|
|
2ac438a82d | ||
|
|
008d009e3e | ||
|
|
c34e3535e0 | ||
|
|
e2465b1eab | ||
|
|
7c2adc4137 | ||
|
|
e22e4b9b8b | ||
|
|
fdd030d101 | ||
|
|
66477a9476 | ||
|
|
e942f86bd7 | ||
|
|
4fe99b7dea | ||
|
|
0ab9775561 | ||
|
|
f83a8f3ba1 | ||
|
|
8f7624f5cb | ||
|
|
ea669ac6b6 | ||
|
|
d238b5e578 | ||
|
|
a86c39f7fa | ||
|
|
0260e9322a | ||
|
|
5ef2605cbc | ||
|
|
d1f123967c | ||
|
|
6cd4724901 | ||
|
|
aed9c79237 | ||
|
|
6a544b7d8e | ||
|
|
7068901649 | ||
|
|
ea4346e945 | ||
|
|
c2787d80c8 | ||
|
|
bf62357731 | ||
|
|
b16fa5cc34 | ||
|
|
3865e4cdba | ||
|
|
45b908f6ba | ||
|
|
2f52699c9b | ||
|
|
940dda885b | ||
|
|
9ecbc160dc | ||
|
|
b9d956c69b | ||
|
|
36104edc63 | ||
|
|
5aaa8e439f | ||
|
|
922400f191 | ||
|
|
d4a0ad0a60 | ||
|
|
fe14f6f160 | ||
|
|
1e9b64a786 | ||
|
|
9a3e6a6135 | ||
|
|
7cacdba191 | ||
|
|
020b490a72 | ||
|
|
2d6f9af612 | ||
|
|
22e6e3f995 | ||
|
|
a73323e64c | ||
|
|
242b986196 | ||
|
|
0810de4415 | ||
|
|
80a28b9b72 | ||
|
|
b4fc75828e | ||
|
|
2947a91c3e | ||
|
|
0f4fbadd36 | ||
|
|
d5555de1b9 | ||
|
|
3417b27832 | ||
|
|
0b78a1ead9 | ||
|
|
4670fd43ed | ||
|
|
5d06b04e41 | ||
|
|
4709edefff | ||
|
|
53281a9454 | ||
|
|
fb82d185c7 | ||
|
|
8956d7e02b | ||
|
|
dcb7546d6d | ||
|
|
3c6669bd98 | ||
|
|
6b1db6a656 | ||
|
|
4c5425dbde | ||
|
|
c97cb5d665 | ||
|
|
8b84b4f128 | ||
|
|
11b0daf6cb | ||
|
|
04e704603f | ||
|
|
729f9c803d | ||
|
|
bb6d47d0cd | ||
|
|
08a0d42ed3 | ||
|
|
5fc944ae1d | ||
|
|
bacac7d0af | ||
|
|
0458a3378c | ||
|
|
5ccf653841 | ||
|
|
ef9b49f0b2 | ||
|
|
ffc5d726bd | ||
|
|
f5c2bea134 | ||
|
|
8381e79da6 | ||
|
|
3e280a3386 | ||
|
|
f5fcada5ba | ||
|
|
ee474b425b | ||
|
|
c47d08e308 | ||
|
|
69af2de3ba | ||
|
|
bad735a8e6 | ||
|
|
3e4adcb3b6 | ||
|
|
09b2d7b3a6 | ||
|
|
3c665f7640 | ||
|
|
f2a5630fdf | ||
|
|
26ed38ecc2 | ||
|
|
ffc10fec8b | ||
|
|
a61ab6d40f | ||
|
|
e3c20e1c64 | ||
|
|
8b1197b335 | ||
|
|
3908ddf609 | ||
|
|
59e18ad659 | ||
|
|
e0ae0724e2 | ||
|
|
e149402d81 | ||
|
|
e47af7f745 | ||
|
|
273e4d6f32 | ||
|
|
bffa1e1ec9 | ||
|
|
9ce9fd390d | ||
|
|
4b82fc1d1f | ||
|
|
c56a67a55a | ||
|
|
f2a08d57e4 | ||
|
|
225a5ee825 | ||
|
|
407ab30503 | ||
|
|
a21f2a0998 | ||
|
|
2f174a6441 | ||
|
|
314ced57c8 | ||
|
|
46c8324c52 | ||
|
|
b8eb3d07ba | ||
|
|
3c67ac636b | ||
|
|
10e2659600 | ||
|
|
98b3962412 | ||
|
|
5df817c8e0 | ||
|
|
cd044ec096 | ||
|
|
caf4d179a2 | ||
|
|
58c47069d8 | ||
|
|
60157e6f6c | ||
|
|
62455a4094 | ||
|
|
41153dd37c | ||
|
|
55051951f8 | ||
|
|
524a495ffd | ||
|
|
2812f8cae6 | ||
|
|
881678b613 | ||
|
|
5aa54e0c1a | ||
|
|
5b8ca74d65 | ||
|
|
d093c5755e | ||
|
|
3c1c3ac156 | ||
|
|
8389f771e9 | ||
|
|
3c88e70270 | ||
|
|
5086880093 | ||
|
|
bde0a5b811 | ||
|
|
3138584320 | ||
|
|
17f26ad588 | ||
|
|
bd2149406d | ||
|
|
5547b44e5a | ||
|
|
6826712861 | ||
|
|
0ffc222fba | ||
|
|
ef34b3d9aa | ||
|
|
3e2875f3d5 | ||
|
|
060e4bcd32 | ||
|
|
2812dee8d4 | ||
|
|
799f1b7b08 | ||
|
|
763d78af87 | ||
|
|
119ae94816 | ||
|
|
7516b737ee | ||
|
|
5c4086bf8e | ||
|
|
295efdba55 | ||
|
|
ca4ddfb963 | ||
|
|
13c25c5d49 | ||
|
|
29b0bb1184 | ||
|
|
59f98a2a20 | ||
|
|
38fa25edbe | ||
|
|
099e57c4e3 | ||
|
|
d5b6f42965 | ||
|
|
058ef59b13 | ||
|
|
d84f382ab8 | ||
|
|
e7d8cfb8e0 | ||
|
|
b441750cc9 | ||
|
|
00372cf747 | ||
|
|
0b589915b9 | ||
|
|
16ad086e7f | ||
|
|
264c9bfd3c | ||
|
|
77a535865b | ||
|
|
99b8e28051 | ||
|
|
c4c17aa1da | ||
|
|
222a1bd29b | ||
|
|
b7798d3869 | ||
|
|
9b2f545391 | ||
|
|
b7ab2c4da8 | ||
|
|
1708a0e3b4 | ||
|
|
d909bc05c4 | ||
|
|
dc7e105ef8 | ||
|
|
edb8f1fd7e | ||
|
|
6f4a98333e | ||
|
|
f81914351d | ||
|
|
7ac985dded | ||
|
|
1b2ef60bbe | ||
|
|
313e77fc3b | ||
|
|
4d527e152c | ||
|
|
4931a300f2 | ||
|
|
5b2d726a02 | ||
|
|
01e7d2d872 | ||
|
|
f5985bbffc | ||
|
|
32ca8066e9 | ||
|
|
405e3e2e7d | ||
|
|
30dc58ce49 | ||
|
|
cb4288b861 | ||
|
|
08874e8483 | ||
|
|
987b84c530 | ||
|
|
1e1e567435 | ||
|
|
f5f79ee0a9 | ||
|
|
293722a179 | ||
|
|
fd2d55934b | ||
|
|
158f75b65d | ||
|
|
3f5382d52c | ||
|
|
dca67a3c85 | ||
|
|
a9cceefaa4 | ||
|
|
3ce2374aeb | ||
|
|
fbc28ce493 | ||
|
|
f88498dad0 | ||
|
|
4b9aa76f1a | ||
|
|
9892e43c4e | ||
|
|
f858a38d3b | ||
|
|
a19629e2d2 | ||
|
|
6149423e47 | ||
|
|
3ce71171b6 | ||
|
|
fc4dbe8713 | ||
|
|
87c2d27a5a | ||
|
|
b191d3517d | ||
|
|
c7d6444ae0 | ||
|
|
bdb35cfaed | ||
|
|
5a5f13205e | ||
|
|
f1f81777cc | ||
|
|
dab16af018 | ||
|
|
7fbe3f4721 | ||
|
|
6b03a3218c | ||
|
|
99c7e1efed | ||
|
|
8af86aae84 | ||
|
|
b1330b9375 | ||
|
|
806f5b9064 | ||
|
|
cb1096d1e1 | ||
|
|
9a82607385 | ||
|
|
40e0d370c2 | ||
|
|
5609b555d2 | ||
|
|
0c42126b8f | ||
|
|
fa47f1c28b | ||
|
|
9adb79ed0e | ||
|
|
a6d140616b | ||
|
|
c5dc281934 | ||
|
|
f836e07fd3 | ||
|
|
c351bcd5a2 | ||
|
|
41f15929b9 | ||
|
|
14241c8d14 | ||
|
|
283ce13454 | ||
|
|
6af8e5f7e7 | ||
|
|
ef3e9489a8 | ||
|
|
a232aabda3 | ||
|
|
36515570b4 | ||
|
|
9b329296e4 | ||
|
|
593ccd2510 | ||
|
|
54300b136c | ||
|
|
98ab30d102 | ||
|
|
c0e7b859d7 | ||
|
|
93822bd2a2 | ||
|
|
60ea89ca1c | ||
|
|
a8bd7d07df | ||
|
|
edba351335 | ||
|
|
be7eb63d1c | ||
|
|
8ecbb53e99 | ||
|
|
fa95419c27 | ||
|
|
6e97496b27 | ||
|
|
3fe21f5931 | ||
|
|
c48374dbc6 | ||
|
|
1d09844950 | ||
|
|
edf4735542 | ||
|
|
2d9db0cf67 | ||
|
|
dfa8196543 | ||
|
|
2004f1b5e5 | ||
|
|
dc6ade4ae3 | ||
|
|
4bfbb56701 | ||
|
|
610251fdf7 | ||
|
|
66e63ee081 | ||
|
|
587862a370 | ||
|
|
6c35c5e604 | ||
|
|
fed853593b | ||
|
|
8340f135fc | ||
|
|
26e23da4c0 | ||
|
|
d3411a50a4 | ||
|
|
69add61174 | ||
|
|
032d29ec86 | ||
|
|
5f7cc437dd | ||
|
|
219e88a023 | ||
|
|
6ebd5009fc | ||
|
|
373284ca0a | ||
|
|
d823fd7685 | ||
|
|
a63be702e1 | ||
|
|
04d5b5cbe6 | ||
|
|
e839404bd2 | ||
|
|
1d5b29fb48 | ||
|
|
60875905ac | ||
|
|
0ef6de930f | ||
|
|
215973c7ab | ||
|
|
dab54cf2a7 | ||
|
|
8f16515d82 | ||
|
|
80d04ead33 | ||
|
|
fcf7f392f0 | ||
|
|
508daad011 | ||
|
|
f9f11b6f74 | ||
|
|
f129126a82 | ||
|
|
64294853cc | ||
|
|
c4727ac021 | ||
|
|
2560640b29 | ||
|
|
72acd67644 | ||
|
|
6395095659 | ||
|
|
1852f1b462 | ||
|
|
9bd41761fc | ||
|
|
b7c790d741 | ||
|
|
bf4ab6daa8 | ||
|
|
4569c25127 | ||
|
|
46a25b31ab | ||
|
|
08980dabd6 | ||
|
|
ed633bd0b7 | ||
|
|
8074fee28c | ||
|
|
8e64379ed4 | ||
|
|
6279237c86 | ||
|
|
db2354a252 | ||
|
|
2adeb9fe88 | ||
|
|
d1e3c633e5 | ||
|
|
123a0f0b40 | ||
|
|
1e0a787012 | ||
|
|
ccd417f713 | ||
|
|
91f1f4c174 | ||
|
|
1e9e0c32fa | ||
|
|
da05aa51fe | ||
|
|
ad37b7fd2a | ||
|
|
5d6ca1498e | ||
|
|
e3ce5d94e1 | ||
|
|
12d1dcddeb | ||
|
|
0668f91b0c | ||
|
|
d1d3d847ab | ||
|
|
730d60e5e4 | ||
|
|
f27d88f6ab | ||
|
|
d4f0902968 | ||
|
|
3438cda432 | ||
|
|
09beeaba8e | ||
|
|
fd03f58eae | ||
|
|
a52043d5b3 | ||
|
|
1f9eb97d0a | ||
|
|
dc91e57c2f | ||
|
|
5685fde606 | ||
|
|
a8eb34ddb8 | ||
|
|
b671cbd71f | ||
|
|
460d5bffd7 | ||
|
|
ca17644289 | ||
|
|
e6be5016f9 | ||
|
|
9b7c48110a | ||
|
|
8b3e84f7fe | ||
|
|
d14d590c2b | ||
|
|
d5f9cccf5e | ||
|
|
405a6bfc04 | ||
|
|
1105b74174 | ||
|
|
85da55a537 | ||
|
|
e8fa429438 | ||
|
|
aea185471a | ||
|
|
47cfab2bbf | ||
|
|
6d425bb5bb | ||
|
|
201d47a483 | ||
|
|
0d7e52ac6f | ||
|
|
4cde01d81a | ||
|
|
d01a79f58f | ||
|
|
963b82afe9 | ||
|
|
9d8feff28d | ||
|
|
952a834e43 | ||
|
|
d8179ceeb2 | ||
|
|
919c185021 | ||
|
|
18503eaa53 | ||
|
|
2a185963a9 | ||
|
|
072a8e0105 | ||
|
|
167f61bef0 | ||
|
|
35465debd6 | ||
|
|
fa63d9e34a | ||
|
|
675af841e8 | ||
|
|
1395d58d39 | ||
|
|
99d127bb34 | ||
|
|
5cd6a04082 | ||
|
|
326855dc3a | ||
|
|
b04d8196c7 | ||
|
|
ebd9eb1715 | ||
|
|
2f02b43352 | ||
|
|
0a60da622f | ||
|
|
8c447dcce2 | ||
|
|
2fd23dc18f | ||
|
|
da315845ff | ||
|
|
f29c59404f | ||
|
|
54d594c486 | ||
|
|
67d04c5952 | ||
|
|
4854f6923b | ||
|
|
a8772ed5c1 | ||
|
|
3468b9a8c0 | ||
|
|
123287d977 | ||
|
|
0f7e3cdfe2 | ||
|
|
12f4b5ea8a | ||
|
|
f23f35aa13 | ||
|
|
71dd9fb2df | ||
|
|
7f1a1b7b96 | ||
|
|
0681346201 | ||
|
|
239e2c82e6 | ||
|
|
d681b96a7b | ||
|
|
97fbc11a8f | ||
|
|
92feabf3e7 | ||
|
|
3bbfcefb0b | ||
|
|
ba30234397 | ||
|
|
054fa71b52 | ||
|
|
0291b9a1c3 | ||
|
|
71de6b8849 | ||
|
|
40d3301c68 | ||
|
|
3e09f99845 | ||
|
|
7097451323 | ||
|
|
be40553674 | ||
|
|
198613a854 | ||
|
|
fc3d424315 | ||
|
|
579d2b1f02 | ||
|
|
34f6c1f2f1 | ||
|
|
bd377e1f28 | ||
|
|
bf5023f4d4 | ||
|
|
94ec102d67 | ||
|
|
3d578bec76 | ||
|
|
3a2f5954d7 | ||
|
|
3de46a31d9 | ||
|
|
44ea98801b | ||
|
|
15ecbaf59c | ||
|
|
02b336ee29 | ||
|
|
40b97045f0 | ||
|
|
6399c0a2c7 | ||
|
|
5d626c7dd3 | ||
|
|
9592ccc0df | ||
|
|
b1cf44a88c | ||
|
|
6da9e19f73 | ||
|
|
cd6a09c0df | ||
|
|
6a7c25e2be | ||
|
|
c20ca0fa4e | ||
|
|
3ebfd0183a | ||
|
|
63a9fa172c | ||
|
|
d7c377dea6 | ||
|
|
75b23aac02 | ||
|
|
ad86feb667 | ||
|
|
2178f09eec | ||
|
|
b606fb68cf | ||
|
|
d150529730 | ||
|
|
9655ce8dbf | ||
|
|
7c5b171e3f | ||
|
|
6b8e7bdfb3 | ||
|
|
a8c725a891 | ||
|
|
6cac296366 | ||
|
|
8bb49f05d0 | ||
|
|
8b7e0a0dbe | ||
|
|
254ac6f253 | ||
|
|
43e1d89067 | ||
|
|
0d453e52ad | ||
|
|
f608db3a68 | ||
|
|
6db02134e9 | ||
|
|
bdd6674958 | ||
|
|
156a2336de | ||
|
|
cbe1e4599d | ||
|
|
32fd35843f | ||
|
|
a37647b3d1 | ||
|
|
edc527b3ab | ||
|
|
8805d04183 | ||
|
|
53c4ed09a3 | ||
|
|
fc211f0934 | ||
|
|
7d7b315511 | ||
|
|
c8ac1a2351 | ||
|
|
ff0e6eb0d5 | ||
|
|
993e16afbd | ||
|
|
785e9d1be6 | ||
|
|
f9c0e0c152 | ||
|
|
579d41b174 | ||
|
|
c2ffb6c255 | ||
|
|
64819981f2 | ||
|
|
00685f357f | ||
|
|
845fa97da1 | ||
|
|
aaf04e793d | ||
|
|
b34ff82987 | ||
|
|
af14c68acc | ||
|
|
2aa3183c16 | ||
|
|
8ea53b69eb | ||
|
|
44d9ccf2c5 | ||
|
|
c981d6431d | ||
|
|
52726088f3 | ||
|
|
079a39a5f1 | ||
|
|
dc4654fa4c | ||
|
|
3d94670f1f | ||
|
|
b30fc3a715 | ||
|
|
51d182eb5a | ||
|
|
3f04f4e5c6 | ||
|
|
f231440480 | ||
|
|
b45ed30936 | ||
|
|
8184e27cb8 | ||
|
|
c014d5d12e | ||
|
|
22d9edb138 | ||
|
|
cdcbc56255 | ||
|
|
100e6fa88f | ||
|
|
e1b841b526 | ||
|
|
2c2e8ef154 | ||
|
|
c99a486826 | ||
|
|
d50c9f9fac | ||
|
|
830ef7ddfc | ||
|
|
cb2e1e1572 | ||
|
|
1864c243fa | ||
|
|
19e05595c8 | ||
|
|
17a9bb81e8 | ||
|
|
28122a1e89 | ||
|
|
ee337471c2 | ||
|
|
aa7ecdbd65 | ||
|
|
01a39e4f4e | ||
|
|
b2665d0c5e | ||
|
|
3be2763929 | ||
|
|
416040f313 | ||
|
|
8dbd6f36b5 | ||
|
|
a7ce6fca9e | ||
|
|
ae5eece76f | ||
|
|
6c18a1f285 | ||
|
|
cbba403992 | ||
|
|
e6136eb075 | ||
|
|
e214489106 | ||
|
|
0ab57c48c3 | ||
|
|
bc03040b0f | ||
|
|
1700b6a087 | ||
|
|
1aa34e9dd4 | ||
|
|
3352b0e916 | ||
|
|
9a867ad277 | ||
|
|
4e013ba2fc | ||
|
|
a0db1d5416 | ||
|
|
97449afbb9 | ||
|
|
038b67cbd4 | ||
|
|
c2d2e41624 | ||
|
|
ebd7273071 | ||
|
|
0e026ed11f | ||
|
|
7624bcf49e | ||
|
|
d7fb464fa9 | ||
|
|
a0cbe7cd7e | ||
|
|
0cdac6de3c | ||
|
|
a134f939e9 | ||
|
|
0c8afa932a | ||
|
|
f2a0e24491 | ||
|
|
2ab9d02158 | ||
|
|
0e5395013a | ||
|
|
8906b78b07 | ||
|
|
205f062433 | ||
|
|
8ed8652296 | ||
|
|
068c0f3782 | ||
|
|
c4d45e0cf0 | ||
|
|
6701aff2a2 | ||
|
|
677193ca52 | ||
|
|
7051529880 | ||
|
|
74f7f3f016 | ||
|
|
72b604b8e8 | ||
|
|
52e9801721 | ||
|
|
8a5aa354f2 | ||
|
|
c2933e005a | ||
|
|
2a3e695f8a | ||
|
|
b4c2505eab | ||
|
|
dcb23de65c | ||
|
|
6ac350a996 | ||
|
|
6e9ea76aab | ||
|
|
f1f421af76 | ||
|
|
fbb166f3ce | ||
|
|
ef10c6f637 | ||
|
|
f4df3860b0 | ||
|
|
40fc3dc060 | ||
|
|
2ec40604d9 | ||
|
|
5afd32dd84 | ||
|
|
d2d5806e9b | ||
|
|
aa47d944e1 | ||
|
|
f75fb6a59f | ||
|
|
d15ce15751 | ||
|
|
d536d20643 | ||
|
|
05a9c16329 | ||
|
|
83d08ba399 | ||
|
|
7c6f0e472d | ||
|
|
6feb503c67 | ||
|
|
004cd00f13 | ||
|
|
865847f71d | ||
|
|
c611566a3e | ||
|
|
4396eaeebb | ||
|
|
fef8237701 | ||
|
|
46bfed6750 | ||
|
|
9fb19e6dd0 | ||
|
|
0cef2cfc46 | ||
|
|
c729f9d9ca | ||
|
|
387d0743e6 | ||
|
|
83b132ace2 | ||
|
|
b9623e6c5b | ||
|
|
2cb1937e1e | ||
|
|
cabccf9ef5 | ||
|
|
7bba745f8b | ||
|
|
bc6a892f2b | ||
|
|
9a227dce46 | ||
|
|
521f2a1433 | ||
|
|
718feeccbc | ||
|
|
a2fc006ee5 | ||
|
|
da027e93cf | ||
|
|
2d55e08b41 | ||
|
|
ab9b8c7bf3 | ||
|
|
40f20de7aa | ||
|
|
24cb15ef2e | ||
|
|
7d93fa2533 | ||
|
|
2face3f938 | ||
|
|
bd7cd68c32 | ||
|
|
bc5df9c908 | ||
|
|
c837c3164a | ||
|
|
152f132b7b | ||
|
|
66837452c2 | ||
|
|
203438fb42 | ||
|
|
693a3b0739 | ||
|
|
1bfcbca8af | ||
|
|
e5c6579a8c | ||
|
|
52dbcd8152 | ||
|
|
906e9b395e | ||
|
|
48d8d1c628 | ||
|
|
1d822132f0 | ||
|
|
d6f94c4ad7 | ||
|
|
a76aad2e12 | ||
|
|
d16558eb83 | ||
|
|
bd338a5741 | ||
|
|
ef297dbec7 | ||
|
|
79aa8570d0 | ||
|
|
48be70e4a8 | ||
|
|
e4ec80941c | ||
|
|
f8dd1a6354 | ||
|
|
839cecd2da | ||
|
|
62c32eb288 | ||
|
|
1c9cc6167d | ||
|
|
3b8c6a1ab2 | ||
|
|
79b8dd829d | ||
|
|
ae3e6d7fe8 | ||
|
|
757f0c9bc4 | ||
|
|
2309e19fd9 | ||
|
|
a1fb0619bb | ||
|
|
7d77324765 | ||
|
|
0dc1ddef9a | ||
|
|
58bb5e967a | ||
|
|
4e97a0b868 | ||
|
|
7fb365634a | ||
|
|
942d38fb13 | ||
|
|
e58ec31e20 | ||
|
|
338e5fadb9 | ||
|
|
cee45e1a8e | ||
|
|
a6bd15d333 | ||
|
|
48c72a168c | ||
|
|
3e6d0602ea | ||
|
|
0d77937caf | ||
|
|
4da8ede826 | ||
|
|
a61d1d8d51 | ||
|
|
b1793fcb16 | ||
|
|
2dc314f993 | ||
|
|
7ae60056b2 | ||
|
|
a3f6d36018 | ||
|
|
c695b83e52 | ||
|
|
3fb180973b | ||
|
|
fece330ca4 | ||
|
|
309af743e0 | ||
|
|
1f03ae54d6 | ||
|
|
85b08e6e7b | ||
|
|
7929af67c8 | ||
|
|
0f96ce9bd2 | ||
|
|
c4021a77ca | ||
|
|
0b35a36cb0 | ||
|
|
a285fbab6d | ||
|
|
0f889d4222 | ||
|
|
dec69651fd | ||
|
|
0621da8535 | ||
|
|
833c5fdd31 | ||
|
|
a76eb022d0 | ||
|
|
c88601a376 | ||
|
|
caedb64ade | ||
|
|
83f5cc6aa6 | ||
|
|
e1c3ab1846 | ||
|
|
b684bc9ba0 | ||
|
|
cd26ccba6b | ||
|
|
c382fa7eab | ||
|
|
5c4edbdd6b | ||
|
|
de484b2495 | ||
|
|
7247f9e27f | ||
|
|
03ca9d2c06 | ||
|
|
f92a0c8df2 | ||
|
|
bc04e0c713 | ||
|
|
b1557b547b | ||
|
|
0e7778a7b7 | ||
|
|
4050462ad4 | ||
|
|
22bc9f6458 | ||
|
|
884f2dd873 | ||
|
|
5e44769f82 | ||
|
|
95dda4aa68 | ||
|
|
81c36499ea | ||
|
|
10c309fccb | ||
|
|
c0da47db9c | ||
|
|
5cd3eaa111 | ||
|
|
ecfcc4f3b6 | ||
|
|
b9584b7ec9 | ||
|
|
0925968840 | ||
|
|
8741a85443 | ||
|
|
d54c95da9d | ||
|
|
fdba8de600 | ||
|
|
bd892026f6 | ||
|
|
be32e79a7a | ||
|
|
8427e99c73 | ||
|
|
974222aabd | ||
|
|
188e325b20 | ||
|
|
5a96f99a8c | ||
|
|
196c6e8ecc | ||
|
|
b4849d1c58 | ||
|
|
d96858d38c | ||
|
|
99bae23996 | ||
|
|
ab4bfbac0d | ||
|
|
d57b0177a7 | ||
|
|
74245be4f5 | ||
|
|
c970d7f80e | ||
|
|
7045e9f2f7 | ||
|
|
2cecb1eada | ||
|
|
26dd67ebeb | ||
|
|
22e2458ce5 | ||
|
|
771bcb5bda | ||
|
|
f0ef6ed016 |
86
.travis.yml
86
.travis.yml
@@ -8,20 +8,44 @@ branches:
|
||||
- /^stable-.*$/
|
||||
- /^beta$/
|
||||
- /^stable$/
|
||||
git:
|
||||
depth: 3
|
||||
matrix:
|
||||
fast_finish: false
|
||||
fast_finish: true
|
||||
allow_failures:
|
||||
- rust: nightly
|
||||
include:
|
||||
- rust: stable
|
||||
env: FEATURES="--features travis-beta" KCOV_FEATURES="" TARGETS="-p ethash -p ethcore-util -p ethcore -p ethsync -p ethcore-rpc -p parity -p ethminer" ARCHIVE_SUFFIX="-${TRAVIS_OS_NAME}-${TRAVIS_TAG}"
|
||||
env: FEATURES="--features travis-beta" RUN_TESTS="true"
|
||||
# - rust: beta
|
||||
# env: FEATURES="--features travis-beta" RUN_TESTS="true"
|
||||
- rust: stable
|
||||
env: FEATURES="--features travis-beta" RUN_BUILD="true"
|
||||
- rust: beta
|
||||
env: FEATURES="--features travis-beta" RUN_BUILD="true"
|
||||
- rust: stable
|
||||
env: FEATURES="--features travis-beta" RUN_COVERAGE="true"
|
||||
# - rust: nightly
|
||||
# env: FEATURES="--features travis-nightly" RUN_BENCHES="true"
|
||||
- rust: nightly
|
||||
env: FEATURES="--features travis-nightly" RUN_TESTS="true"
|
||||
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"
|
||||
- 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"
|
||||
- RUN_TESTS="false"
|
||||
- RUN_COVERAGE="false"
|
||||
- RUN_BUILD="false"
|
||||
- RUN_BENCHES="false"
|
||||
- RUST_BACKTRACE="1"
|
||||
cache:
|
||||
apt: true
|
||||
directories:
|
||||
- target/debug/deps
|
||||
- target/debug/build
|
||||
- target/release/deps
|
||||
- target/release/build
|
||||
- $TRAVIS_BUILD_DIR/target
|
||||
- $HOME/.cargo
|
||||
addons:
|
||||
apt:
|
||||
@@ -29,22 +53,29 @@ addons:
|
||||
- libcurl4-openssl-dev
|
||||
- libelf-dev
|
||||
- libdw-dev
|
||||
|
||||
script:
|
||||
- cargo build --release --verbose ${FEATURES}
|
||||
- cargo test --release --verbose ${FEATURES} ${TARGETS}
|
||||
#- cargo bench --no-run ${FEATURES} ${TARGETS}
|
||||
- tar cvzf parity${ARCHIVE_SUFFIX}.tar.gz -C target/release parity
|
||||
- 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
|
||||
- if [ "$RUN_BUILD" = "true" ]; then tar cvzf parity${ARCHIVE_SUFFIX}.tar.gz -C target/release parity; fi
|
||||
|
||||
after_success: |
|
||||
[ "$RUN_COVERAGE" = "true" ] &&
|
||||
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-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 target/debug/deps/ethcore_util-* &&
|
||||
./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 target/debug/deps/ethash-* &&
|
||||
./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 target/debug/deps/ethcore-* &&
|
||||
./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 target/debug/deps/ethsync-* &&
|
||||
./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 target/debug/deps/ethcore_rpc-* &&
|
||||
./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 target/debug/deps/ethminer-* &&
|
||||
./kcov-master/tmp/usr/local/bin/kcov --coveralls-id=${TRAVIS_JOB_ID} --exclude-pattern /usr/,/.cargo,/root/.multirust target/kcov target/debug/parity-* &&
|
||||
$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/parity-* &&
|
||||
[ $TRAVIS_BRANCH = master ] &&
|
||||
[ $TRAVIS_PULL_REQUEST = false ] &&
|
||||
[ $TRAVIS_RUST_VERSION = stable ] &&
|
||||
@@ -53,10 +84,6 @@ after_success: |
|
||||
pip install --user ghp-import &&
|
||||
/home/travis/.local/bin/ghp-import -n target/doc &&
|
||||
git push -fq https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages
|
||||
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=
|
||||
|
||||
deploy:
|
||||
provider: releases
|
||||
@@ -68,9 +95,14 @@ deploy:
|
||||
tags: true
|
||||
|
||||
notifications:
|
||||
webhooks:
|
||||
urls:
|
||||
- https://hooks.slack.com/services/${SLACK_WEBHOOK}
|
||||
on_success: always
|
||||
on_failure: always
|
||||
on_start: never
|
||||
webhooks:
|
||||
urls:
|
||||
- https://hooks.slack.com/services/${SLACK_WEBHOOK}
|
||||
on_success: always
|
||||
on_failure: always
|
||||
on_start: never
|
||||
|
||||
notifications:
|
||||
slack:
|
||||
rooms:
|
||||
- ethcore:4EGxt9WP6AS7uX4JKXSfR9vi#chatops
|
||||
|
||||
1040
Cargo.lock
generated
1040
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
40
Cargo.toml
40
Cargo.toml
@@ -1,13 +1,15 @@
|
||||
[package]
|
||||
description = "Ethcore client."
|
||||
name = "parity"
|
||||
version = "1.1.0"
|
||||
version = "1.2.3"
|
||||
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"
|
||||
@@ -15,23 +17,43 @@ env_logger = "0.3"
|
||||
rustc-serialize = "0.3"
|
||||
docopt = "0.6"
|
||||
time = "0.1"
|
||||
ctrlc = { git = "https://github.com/tomusdrw/rust-ctrlc.git" }
|
||||
ctrlc = { git = "https://github.com/ethcore/rust-ctrlc.git" }
|
||||
fdlimit = { path = "util/fdlimit" }
|
||||
daemonize = "0.2"
|
||||
num_cpus = "0.2"
|
||||
number_prefix = "0.2"
|
||||
rpassword = "0.1"
|
||||
clippy = { version = "0.0.50", optional = true }
|
||||
rpassword = "0.2.1"
|
||||
clippy = { version = "0.0.77", 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"]
|
||||
default = ["rpc", "ethcore-signer", "ui", "use-precompiled-js"]
|
||||
ui = ["dapps", "ethcore-signer/ui"]
|
||||
use-precompiled-js = ["ethcore-dapps/use-precompiled-js", "ethcore-signer/use-precompiled-js"]
|
||||
dapps = ["ethcore-dapps"]
|
||||
rpc = ["ethcore-rpc"]
|
||||
dev = ["clippy", "ethcore/dev", "ethcore-util/dev", "ethsync/dev", "ethcore-rpc/dev", "ethminer/dev"]
|
||||
dev = ["clippy", "ethcore/dev", "ethcore-util/dev", "ethsync/dev", "ethcore-rpc/dev",
|
||||
"ethcore-dapps/dev", "ethcore-signer/dev"]
|
||||
travis-beta = ["ethcore/json-tests"]
|
||||
travis-nightly = ["ethcore/json-tests", "dev"]
|
||||
|
||||
@@ -40,5 +62,5 @@ path = "parity/main.rs"
|
||||
name = "parity"
|
||||
|
||||
[profile.release]
|
||||
debug = false
|
||||
debug = true
|
||||
lto = false
|
||||
|
||||
77
README.md
77
README.md
@@ -1,4 +1,5 @@
|
||||
# ethcore
|
||||
# [Parity](https://ethcore.io/parity.html)
|
||||
### Fast, light, and robust Ethereum implementation
|
||||
|
||||
[![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]
|
||||
|
||||
@@ -11,29 +12,77 @@
|
||||
[license-image]: https://img.shields.io/badge/license-GPL%20v3-green.svg
|
||||
[license-url]: http://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
[Documentation](http://ethcore.github.io/parity/ethcore/index.html)
|
||||
[Internal Documentation](http://ethcore.github.io/parity/ethcore/index.html)
|
||||
|
||||
### Building from source
|
||||
----
|
||||
|
||||
First (if you don't already have it) get multirust:
|
||||
## 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.2. 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
|
||||
|
||||
- Linux:
|
||||
```bash
|
||||
curl -sf https://raw.githubusercontent.com/brson/multirust/master/quick-install.sh | sudo sh -s -- --yes
|
||||
cargo install --git https://github.com/ethcore/parity.git parity
|
||||
```
|
||||
|
||||
- OSX with Homebrew:
|
||||
```bash
|
||||
brew update && brew install multirust
|
||||
```
|
||||
----
|
||||
|
||||
Then, download and build Parity:
|
||||
## Build from source
|
||||
|
||||
```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.
|
||||
|
||||
50
appveyor.yml
Normal file
50
appveyor.yml
Normal file
@@ -0,0 +1,50 @@
|
||||
environment:
|
||||
matrix:
|
||||
- TARGET: x86_64-pc-windows-msvc
|
||||
cert:
|
||||
secure: ESPpYVVAMG1fbJx6kq4ct/g9SQTXac4Hs6xXr6Oh4Zrk2dwYglNjxmzErdPnvu7gs/gekzrJ6KEQHYRc+5+4dKg6rRADQ681NLVx9vOggBs=
|
||||
certpass:
|
||||
secure: 0BgXJqxq9Ei34/hZ7121FQ==
|
||||
keyfile: C:\users\appveyor\Certificates.p12
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- /^beta-.*$/
|
||||
- /^stable-.*$/
|
||||
- /^beta$/
|
||||
- /^stable$/
|
||||
|
||||
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;C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Bin
|
||||
- rustc -V
|
||||
- cargo -V
|
||||
|
||||
build: off
|
||||
|
||||
test_script:
|
||||
- cargo test --verbose --release
|
||||
|
||||
after_test:
|
||||
- cargo build --verbose --release
|
||||
- ps: if($env:cert) { Start-FileDownload $env:cert -FileName $env:keyfile }
|
||||
- ps: if($env:cert) { signtool sign /f $env:keyfile /p $env:certpass target\release\parity.exe }
|
||||
- makensis.exe nsis\installer.nsi
|
||||
- ps: if($env:cert) { signtool sign /f $env:keyfile /p $env:certpass nsis\installer.exe }
|
||||
|
||||
artifacts:
|
||||
- path: nsis\installer.exe
|
||||
name: Windows Installer (x86_64)
|
||||
- path: target\release\parity.exe
|
||||
name: Windows Executable (x86_64)
|
||||
- path: target\release\parity.pdb
|
||||
name: Windows Executable Debug Symbols (x86_64)
|
||||
|
||||
cache:
|
||||
- target
|
||||
- C:\users\appveyor\.cargo -> appveyor.yml
|
||||
24
build.rs
24
build.rs
@@ -15,11 +15,35 @@
|
||||
// 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
12
cov.sh
@@ -16,22 +16,28 @@ 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 ethminer \
|
||||
-p ethcore-signer \
|
||||
-p ethcore-dapps \
|
||||
--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"
|
||||
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-*
|
||||
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/ethminer-*
|
||||
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-*
|
||||
xdg-open target/coverage/index.html
|
||||
|
||||
45
dapps/Cargo.toml
Normal file
45
dapps/Cargo.toml
Normal file
@@ -0,0 +1,45 @@
|
||||
[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-ui.git", version = "0.6" }
|
||||
# List of apps
|
||||
parity-dapps-status = { git = "https://github.com/ethcore/parity-ui.git", version = "0.6" }
|
||||
parity-dapps-home = { git = "https://github.com/ethcore/parity-ui.git", version = "0.6" }
|
||||
parity-dapps-wallet = { git = "https://github.com/ethcore/parity-ui.git", version = "0.6", 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"]
|
||||
|
||||
use-precompiled-js = [
|
||||
"parity-dapps-status/use-precompiled-js",
|
||||
"parity-dapps-home/use-precompiled-js",
|
||||
"parity-dapps-wallet/use-precompiled-js"
|
||||
]
|
||||
45
dapps/build.rs
Normal file
45
dapps/build.rs
Normal file
@@ -0,0 +1,45 @@
|
||||
// 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();
|
||||
}
|
||||
69
dapps/src/api/api.rs
Normal file
69
dapps/src/api/api.rs
Normal file
@@ -0,0 +1,69 @@
|
||||
// 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())
|
||||
}
|
||||
}
|
||||
|
||||
28
dapps/src/api/mod.rs
Normal file
28
dapps/src/api/mod.rs
Normal file
@@ -0,0 +1,28 @@
|
||||
// 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"));
|
||||
|
||||
21
dapps/src/api/mod.rs.in
Normal file
21
dapps/src/api/mod.rs.in
Normal file
@@ -0,0 +1,21 @@
|
||||
// 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;
|
||||
23
dapps/src/api/response.rs
Normal file
23
dapps/src/api/response.rs
Normal file
@@ -0,0 +1,23 @@
|
||||
// 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()))
|
||||
}
|
||||
116
dapps/src/apps/fs.rs
Normal file
116
dapps/src/apps/fs.rs
Normal file
@@ -0,0 +1,116 @@
|
||||
// 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
|
||||
}
|
||||
69
dapps/src/apps/mod.rs
Normal file
69
dapps/src/apps/mod.rs
Normal file
@@ -0,0 +1,69 @@
|
||||
// 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_home;
|
||||
|
||||
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_home::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_home::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);
|
||||
|
||||
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) {}
|
||||
|
||||
fn insert<T : WebApp + Default + 'static>(pages: &mut Endpoints, id: &str) {
|
||||
pages.insert(id.to_owned(), Box::new(PageEndpoint::new(T::default())));
|
||||
}
|
||||
99
dapps/src/endpoint.rs
Normal file
99
dapps/src/endpoint.rs
Normal file
@@ -0,0 +1,99 @@
|
||||
// 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> + Send>;
|
||||
}
|
||||
|
||||
pub type Endpoints = BTreeMap<String, Box<Endpoint>>;
|
||||
pub type Handler = server::Handler<HttpStream> + Send;
|
||||
|
||||
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<HttpStream>) -> 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()
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
177
dapps/src/lib.rs
Normal file
177
dapps/src/lib.rs
Normal file
@@ -0,0 +1,177 @@
|
||||
// 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, srv)| {
|
||||
|
||||
::std::thread::spawn(move || {
|
||||
srv.run();
|
||||
});
|
||||
|
||||
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),
|
||||
}
|
||||
}
|
||||
}
|
||||
154
dapps/src/page/builtin.rs
Normal file
154
dapps/src/page/builtin.rs
Normal 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/>.
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
207
dapps/src/page/handler.rs
Normal file
207
dapps/src/page/handler.rs
Normal file
@@ -0,0 +1,207 @@
|
||||
// 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<HttpStream>) -> 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");
|
||||
}
|
||||
118
dapps/src/page/local.rs
Normal file
118
dapps/src/page/local.rs
Normal file
@@ -0,0 +1,118 @@
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
24
dapps/src/page/mod.rs
Normal file
24
dapps/src/page/mod.rs
Normal file
@@ -0,0 +1,24 @@
|
||||
// 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;
|
||||
|
||||
48
dapps/src/proxypac.rs
Normal file
48
dapps/src/proxypac.rs
Normal file
@@ -0,0 +1,48 @@
|
||||
// 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()))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
161
dapps/src/router/auth.rs
Normal file
161
dapps/src/router/auth.rs
Normal file
@@ -0,0 +1,161 @@
|
||||
// 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> + Send>),
|
||||
}
|
||||
|
||||
/// Authorization interface
|
||||
pub trait Authorization : Send + Sync {
|
||||
/// Checks if authorization is valid.
|
||||
fn is_authorized(&self, req: &server::Request<HttpStream>)-> 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<HttpStream>)-> Authorized {
|
||||
Authorized::Yes
|
||||
}
|
||||
}
|
||||
|
||||
impl Authorization for HttpBasicAuth {
|
||||
fn is_authorized(&self, req: &server::Request<HttpStream>) -> 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<HttpStream>) -> 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<HttpStream>) -> 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<HttpStream>) -> 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()
|
||||
}
|
||||
}
|
||||
255
dapps/src/router/mod.rs
Normal file
255
dapps/src/router/mod.rs
Normal file
@@ -0,0 +1,255 @@
|
||||
// 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> + Send>,
|
||||
}
|
||||
|
||||
impl<A: Authorization + 'static> server::Handler<HttpStream> for Router<A> {
|
||||
|
||||
fn on_request(&mut self, req: server::Request<HttpStream>) -> 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<HttpStream>) -> 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)
|
||||
);
|
||||
}
|
||||
55
dapps/src/router/redirect.rs
Normal file
55
dapps/src/router/redirect.rs
Normal file
@@ -0,0 +1,55 @@
|
||||
// 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<HttpStream>) -> 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()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
145
dapps/src/router/url.rs
Normal file
145
dapps/src/router/url.rs
Normal file
@@ -0,0 +1,145 @@
|
||||
// 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");
|
||||
}
|
||||
}
|
||||
41
dapps/src/rpc.rs
Normal file
41
dapps/src/rpc.rs
Normal file
@@ -0,0 +1,41 @@
|
||||
// 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))
|
||||
}
|
||||
}
|
||||
26
db/Cargo.toml
Normal file
26
db/Cargo.toml
Normal file
@@ -0,0 +1,26 @@
|
||||
[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"]
|
||||
43
db/build.rs
Normal file
43
db/build.rs
Normal file
@@ -0,0 +1,43 @@
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
573
db/src/database.rs
Normal file
573
db/src/database.rs
Normal file
@@ -0,0 +1,573 @@
|
||||
// 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());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
20
db/src/lib.rs
Normal file
20
db/src/lib.rs
Normal file
@@ -0,0 +1,20 @@
|
||||
// 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"));
|
||||
89
db/src/lib.rs.in
Normal file
89
db/src/lib.rs.in
Normal file
@@ -0,0 +1,89 @@
|
||||
// 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();
|
||||
}
|
||||
});
|
||||
}
|
||||
132
db/src/traits.rs
Normal file
132
db/src/traits.rs
Normal file
@@ -0,0 +1,132 @@
|
||||
// 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());
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ description = "Ethcore development/test/build tools"
|
||||
homepage = "http://ethcore.io"
|
||||
license = "GPL-3.0"
|
||||
name = "ethcore-devtools"
|
||||
version = "1.1.0"
|
||||
version = "1.2.0"
|
||||
authors = ["Ethcore <admin@ethcore.io>"]
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
# ethcore dev tools
|
||||
@@ -20,5 +20,9 @@
|
||||
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::*;
|
||||
|
||||
@@ -26,7 +26,11 @@ pub struct RandomTempPath {
|
||||
}
|
||||
|
||||
pub fn random_filename() -> String {
|
||||
(0..8).map(|_| ((random::<f32>() * 26.0) as u8 + 97) as char).collect()
|
||||
random_str(8)
|
||||
}
|
||||
|
||||
pub fn random_str(len: usize) -> String {
|
||||
(0..len).map(|_| ((random::<f32>() * 26.0) as u8 + 97) as char).collect()
|
||||
}
|
||||
|
||||
impl RandomTempPath {
|
||||
@@ -54,12 +58,18 @@ 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, probably something failed to destroyed ({})", e);
|
||||
panic!("Failed to remove temp directory. Here's what prevented this from happening: ({})", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
45
devtools/src/stop_guard.rs
Normal file
45
devtools/src/stop_guard.rs
Normal file
@@ -0,0 +1,45 @@
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
94
devtools/src/test_socket.rs
Normal file
94
devtools/src/test_socket.rs
Normal file
@@ -0,0 +1,94 @@
|
||||
// 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
5
doc.sh
@@ -2,10 +2,13 @@
|
||||
# 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
|
||||
|
||||
29
docker/centos/Dockerfile
Normal file
29
docker/centos/Dockerfile
Normal file
@@ -0,0 +1,29 @@
|
||||
FROM centos:latest
|
||||
WORKDIR /build
|
||||
# install tools and dependencies
|
||||
RUN yum -y update&& \
|
||||
yum install -y git make gcc-c++ gcc file binutils
|
||||
# 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
|
||||
# set compiler
|
||||
ENV CXX g++
|
||||
ENV CC gcc
|
||||
# show tools
|
||||
RUN rustc -vV && \
|
||||
cargo -V && \
|
||||
gcc -v &&\
|
||||
g++ -v
|
||||
# build parity
|
||||
RUN git clone https://github.com/ethcore/parity && \
|
||||
cd parity&&\
|
||||
git checkout beta && \
|
||||
git pull && \
|
||||
ls -a&&\
|
||||
cargo build --release --verbose && \
|
||||
ls /build/parity/target/release/parity && \
|
||||
strip /build/parity/target/release/parity
|
||||
RUN file /build/parity/target/release/parity
|
||||
49
docker/ubuntu-aarch64/Dockerfile
Normal file
49
docker/ubuntu-aarch64/Dockerfile
Normal file
@@ -0,0 +1,49 @@
|
||||
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-aarch64-linux-gnu g++-aarch64-linux-gnu \
|
||||
libc6-arm64-cross libc6-dev-arm64-cross wget file ca-certificates \
|
||||
binutils-aarch64-linux-gnu \
|
||||
&& \
|
||||
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="aarch64-unknown-linux-gnu"
|
||||
|
||||
# multirust add arm--linux-gnuabhf toolchain
|
||||
RUN rustup target add aarch64-unknown-linux-gnu
|
||||
|
||||
# show backtraces
|
||||
ENV RUST_BACKTRACE 1
|
||||
|
||||
# set compilers
|
||||
ENV CXX aarch64-linux-gnu-g++
|
||||
ENV CC aarch64-linux-gnu-gcc
|
||||
|
||||
# show tools
|
||||
RUN rustc -vV && \
|
||||
cargo -V && \
|
||||
gcc -v &&\
|
||||
g++ -v
|
||||
|
||||
# build parity
|
||||
RUN git clone https://github.com/ethcore/parity && \
|
||||
cd parity && \
|
||||
git checkout beta && \
|
||||
git pull && \
|
||||
mkdir -p .cargo && \
|
||||
echo '[target.aarch64-unknown-linux-gnu]\n\
|
||||
linker = "aarch64-linux-gnu-gcc"\n'\
|
||||
>>.cargo/config && \
|
||||
cat .cargo/config && \
|
||||
cargo build --target aarch64-unknown-linux-gnu --release --verbose && \
|
||||
ls /build/parity/target/aarch64-unknown-linux-gnu/release/parity && \
|
||||
/usr/bin/aarch64-linux-gnu-strip /build/parity/target/aarch64-unknown-linux-gnu/release/parity
|
||||
RUN file /build/parity/target/aarch64-unknown-linux-gnu/release/parity
|
||||
49
docker/ubuntu-arm/Dockerfile
Normal file
49
docker/ubuntu-arm/Dockerfile
Normal file
@@ -0,0 +1,49 @@
|
||||
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 armv7-unknown-linux-gnueabihf
|
||||
|
||||
# show backtraces
|
||||
ENV RUST_BACKTRACE 1
|
||||
|
||||
# set compilers
|
||||
ENV CXX arm-linux-gnueabihf-g++
|
||||
ENV CC arm-linux-gnueabihf-gcc
|
||||
|
||||
# show tools
|
||||
RUN rustc -vV && \
|
||||
cargo -V && \
|
||||
gcc -v &&\
|
||||
g++ -v
|
||||
|
||||
# build parity
|
||||
RUN git clone https://github.com/ethcore/parity && \
|
||||
cd parity && \
|
||||
git checkout beta && \
|
||||
git pull && \
|
||||
mkdir -p .cargo && \
|
||||
echo '[target.armv7-unknown-linux-gnueabihf]\n\
|
||||
linker = "arm-linux-gnueabihf-gcc"\n'\
|
||||
>>.cargo/config && \
|
||||
cat .cargo/config && \
|
||||
cargo build --target armv7-unknown-linux-gnueabihf --release --verbose && \
|
||||
ls /build/parity/target/armv7-unknown-linux-gnueabihf/release/parity && \
|
||||
/usr/bin/arm-linux-gnueabihf-strip /build/parity/target/armv7-unknown-linux-gnueabihf/release/parity
|
||||
RUN file /build/parity/target/armv7-unknown-linux-gnueabihf/release/parity
|
||||
@@ -27,11 +27,11 @@ RUN git clone https://github.com/debris/evmjit && \
|
||||
mkdir build && cd build && \
|
||||
cmake .. && make && make install && cd
|
||||
|
||||
# install multirust
|
||||
RUN curl -sf https://raw.githubusercontent.com/brson/multirust/master/blastoff.sh | sh -s -- --yes
|
||||
# install rustup
|
||||
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y
|
||||
|
||||
# export rust LIBRARY_PATH
|
||||
ENV LIBRARY_PATH /usr/local/lib
|
||||
# rustup directory
|
||||
ENV PATH /root/.cargo/bin:$PATH
|
||||
|
||||
# show backtraces
|
||||
ENV RUST_BACKTRACE 1
|
||||
|
||||
@@ -1,42 +1,55 @@
|
||||
FROM ubuntu:14.04
|
||||
|
||||
WORKDIR /build
|
||||
# install tools and dependencies
|
||||
RUN apt-get update && \
|
||||
apt-get install -y \
|
||||
# make
|
||||
build-essential \
|
||||
# add-apt-repository
|
||||
software-properties-common \
|
||||
curl \
|
||||
wget \
|
||||
git \
|
||||
g++ \
|
||||
# evmjit dependencies
|
||||
zlib1g-dev \
|
||||
libedit-dev
|
||||
apt-get install -y \
|
||||
# make
|
||||
build-essential \
|
||||
# add-apt-repository
|
||||
software-properties-common \
|
||||
curl \
|
||||
wget \
|
||||
git \
|
||||
g++ \
|
||||
binutils \
|
||||
file \
|
||||
# evmjit dependencies
|
||||
zlib1g-dev \
|
||||
libedit-dev
|
||||
|
||||
# cmake, llvm and rocksdb ppas. then update ppas
|
||||
# cmake and llvm ppas. then update ppas
|
||||
RUN add-apt-repository -y "ppa:george-edison55/cmake-3.x" && \
|
||||
add-apt-repository "deb http://llvm.org/apt/trusty/ llvm-toolchain-trusty-3.7 main" && \
|
||||
apt-get update && \
|
||||
apt-get install -y --force-yes cmake llvm-3.7-dev
|
||||
add-apt-repository "deb http://llvm.org/apt/trusty/ llvm-toolchain-trusty-3.7 main" && \
|
||||
apt-get update && \
|
||||
apt-get install -y --force-yes cmake llvm-3.7-dev
|
||||
|
||||
# install evmjit
|
||||
RUN git clone https://github.com/debris/evmjit && \
|
||||
cd evmjit && \
|
||||
mkdir build && cd build && \
|
||||
cmake .. && make && make install && cd
|
||||
cd evmjit && \
|
||||
mkdir build && cd build && \
|
||||
cmake .. && make && make install && cd
|
||||
|
||||
# install multirust
|
||||
RUN curl -sf https://raw.githubusercontent.com/brson/multirust/master/blastoff.sh | sh -s -- --yes
|
||||
# install rustup
|
||||
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y
|
||||
|
||||
# export rust LIBRARY_PATH
|
||||
ENV LIBRARY_PATH /usr/local/lib
|
||||
# rustup directory
|
||||
ENV PATH /root/.cargo/bin:$PATH
|
||||
|
||||
# show backtraces
|
||||
ENV RUST_BACKTRACE 1
|
||||
|
||||
# show tools
|
||||
RUN rustc -vV && \
|
||||
cargo -V && \
|
||||
gcc -v &&\
|
||||
g++ -v
|
||||
|
||||
# build parity
|
||||
RUN git clone https://github.com/ethcore/parity && \
|
||||
cd parity && \
|
||||
cargo build --release --features ethcore/jit
|
||||
cd parity && \
|
||||
git checkout beta && \
|
||||
git pull && \
|
||||
cargo build --release --features ethcore/jit --verbose && \
|
||||
ls /build/parity/target/release/parity && \
|
||||
strip /build/parity/target/release/parity
|
||||
RUN file /build/parity/target/release/parity
|
||||
|
||||
@@ -1,23 +1,35 @@
|
||||
FROM ubuntu:14.04
|
||||
|
||||
WORKDIR /build
|
||||
# install tools and dependencies
|
||||
RUN apt-get update && \
|
||||
apt-get install -y \
|
||||
g++ \
|
||||
curl \
|
||||
git \
|
||||
make
|
||||
apt-get install -y \
|
||||
g++ \
|
||||
curl \
|
||||
git \
|
||||
file \
|
||||
binutils
|
||||
|
||||
# install multirust
|
||||
RUN curl -sf https://raw.githubusercontent.com/brson/multirust/master/blastoff.sh | sh -s -- --yes
|
||||
# install rustup
|
||||
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y
|
||||
|
||||
# export rust LIBRARY_PATH
|
||||
ENV LIBRARY_PATH /usr/local/lib
|
||||
# rustup directory
|
||||
ENV PATH /root/.cargo/bin:$PATH
|
||||
|
||||
# show backtraces
|
||||
ENV RUST_BACKTRACE 1
|
||||
|
||||
# show tools
|
||||
RUN rustc -vV && \
|
||||
cargo -V && \
|
||||
gcc -v &&\
|
||||
g++ -v
|
||||
|
||||
# build parity
|
||||
RUN git clone https://github.com/ethcore/parity && \
|
||||
cd parity && \
|
||||
cargo build --release
|
||||
cd parity && \
|
||||
git checkout beta && \
|
||||
git pull && \
|
||||
cargo build --release --verbose && \
|
||||
ls /build/parity/target/release/parity && \
|
||||
strip /build/parity/target/release/parity
|
||||
RUN file /build/parity/target/release/parity
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ethash"
|
||||
version = "1.1.0"
|
||||
version = "1.2.0"
|
||||
authors = ["arkpar <arkadiy@ethcore.io"]
|
||||
|
||||
[lib]
|
||||
|
||||
@@ -20,12 +20,14 @@
|
||||
// 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::{Read, Write, self};
|
||||
use std::io::{self, Read, Write};
|
||||
use std::fs::{self, File};
|
||||
|
||||
pub const ETHASH_EPOCH_LENGTH: u64 = 30000;
|
||||
@@ -42,14 +44,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 {
|
||||
@@ -85,6 +87,7 @@ pub type H256 = [u8; 32];
|
||||
pub struct Light {
|
||||
block_number: u64,
|
||||
cache: Vec<Node>,
|
||||
seed_compute: Mutex<SeedHashCompute>,
|
||||
}
|
||||
|
||||
/// Light cache structur
|
||||
@@ -101,17 +104,17 @@ impl Light {
|
||||
light_compute(self, header_hash, nonce)
|
||||
}
|
||||
|
||||
pub fn file_path(block_number: u64) -> PathBuf {
|
||||
pub fn file_path(seed_hash: H256) -> 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 path = Light::file_path(block_number);
|
||||
let seed_compute = SeedHashCompute::new();
|
||||
let path = Light::file_path(seed_compute.get_seedhash(block_number));
|
||||
let mut file = try!(File::open(path));
|
||||
|
||||
let cache_size = get_cache_size(block_number);
|
||||
@@ -126,11 +129,13 @@ impl Light {
|
||||
Ok(Light {
|
||||
cache: nodes,
|
||||
block_number: block_number,
|
||||
seed_compute: Mutex::new(seed_compute),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn to_file(&self) -> io::Result<()> {
|
||||
let path = Light::file_path(self.block_number);
|
||||
let seed_compute = self.seed_compute.lock().unwrap();
|
||||
let path = Light::file_path(seed_compute.get_seedhash(self.block_number));
|
||||
try!(fs::create_dir_all(path.parent().unwrap()));
|
||||
let mut file = try!(File::create(path));
|
||||
|
||||
@@ -141,6 +146,51 @@ 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;
|
||||
@@ -153,34 +203,24 @@ 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
|
||||
///
|
||||
@@ -211,12 +251,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) };
|
||||
|
||||
@@ -257,7 +297,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,
|
||||
@@ -287,7 +327,9 @@ fn calculate_dag_item(node_index: u32, light: &Light) -> Node {
|
||||
}
|
||||
|
||||
fn light_new(block_number: u64) -> Light {
|
||||
let seedhash = get_seedhash(block_number);
|
||||
|
||||
let seed_compute = SeedHashCompute::new();
|
||||
let seedhash = seed_compute.get_seedhash(block_number);
|
||||
let cache_size = get_cache_size(block_number);
|
||||
|
||||
if cache_size % NODE_BYTES != 0 {
|
||||
@@ -308,7 +350,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);
|
||||
}
|
||||
@@ -318,10 +360,11 @@ 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() {
|
||||
@@ -329,9 +372,7 @@ 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]
|
||||
@@ -361,8 +402,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[..]);
|
||||
@@ -372,8 +413,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;
|
||||
@@ -382,3 +423,34 @@ 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);
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ mod compute;
|
||||
|
||||
use std::mem;
|
||||
use compute::Light;
|
||||
pub use compute::{get_seedhash, quick_get_difficulty, H256, ProofOfWork, ETHASH_EPOCH_LENGTH};
|
||||
pub use compute::{ETHASH_EPOCH_LENGTH, H256, ProofOfWork, SeedHashCompute, quick_get_difficulty};
|
||||
|
||||
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)
|
||||
|
||||
@@ -3,8 +3,13 @@ description = "Ethcore library"
|
||||
homepage = "http://ethcore.io"
|
||||
license = "GPL-3.0"
|
||||
name = "ethcore"
|
||||
version = "1.1.0"
|
||||
version = "1.2.0"
|
||||
authors = ["Ethcore <admin@ethcore.io>"]
|
||||
build = "build.rs"
|
||||
|
||||
[build-dependencies]
|
||||
syntex = "*"
|
||||
"ethcore-ipc-codegen" = { path = "../ipc/codegen" }
|
||||
|
||||
[dependencies]
|
||||
log = "0.3"
|
||||
@@ -17,10 +22,19 @@ ethcore-util = { path = "../util" }
|
||||
evmjit = { path = "../evmjit", optional = true }
|
||||
ethash = { path = "../ethash" }
|
||||
num_cpus = "0.2"
|
||||
clippy = { version = "0.0.50", optional = true }
|
||||
crossbeam = "0.1.5"
|
||||
lazy_static = "0.1"
|
||||
clippy = { version = "0.0.77", optional = true}
|
||||
crossbeam = "0.2.9"
|
||||
lazy_static = "0.2"
|
||||
ethcore-devtools = { path = "../devtools" }
|
||||
ethjson = { path = "../json" }
|
||||
bloomchain = "0.1"
|
||||
"ethcore-ipc" = { path = "../ipc/rpc" }
|
||||
rayon = "0.3.1"
|
||||
ethstore = { path = "../ethstore" }
|
||||
|
||||
[dependencies.hyper]
|
||||
git = "https://github.com/ethcore/hyper"
|
||||
default-features = false
|
||||
|
||||
[features]
|
||||
jit = ["evmjit"]
|
||||
|
||||
33
ethcore/build.rs
Normal file
33
ethcore/build.rs
Normal file
@@ -0,0 +1,33 @@
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
162
ethcore/res/ethereum/daohardfork_test.json
Normal file
162
ethcore/res/ethereum/daohardfork_test.json
Normal file
@@ -0,0 +1,162 @@
|
||||
{
|
||||
"name": "DAO hard-fork consensus test",
|
||||
"engine": {
|
||||
"Ethash": {
|
||||
"params": {
|
||||
"gasLimitBoundDivisor": "0x0400",
|
||||
"minimumDifficulty": "0x020000",
|
||||
"difficultyBoundDivisor": "0x0800",
|
||||
"durationLimit": "0x0d",
|
||||
"blockReward": "0x4563918244F40000",
|
||||
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
||||
"frontierCompatibilityModeLimit": "0x5",
|
||||
"daoHardforkTransition": "0x8",
|
||||
"daoHardforkBeneficiary": "0xbf4ed7b27f1d666546e30d74d50d173d20bca754",
|
||||
"daoHardforkAccounts": [
|
||||
"0xd4fe7bc31cedb7bfb8a345f31e668033056b2728",
|
||||
"0xb3fb0e5aba0e20e5c49d252dfd30e102b171a425",
|
||||
"0x2c19c7f9ae8b751e37aeb2d93a699722395ae18f",
|
||||
"0xecd135fa4f61a655311e86238c92adcd779555d2",
|
||||
"0x1975bd06d486162d5dc297798dfc41edd5d160a7",
|
||||
"0xa3acf3a1e16b1d7c315e23510fdd7847b48234f6",
|
||||
"0x319f70bab6845585f412ec7724b744fec6095c85",
|
||||
"0x06706dd3f2c9abf0a21ddcc6941d9b86f0596936",
|
||||
"0x5c8536898fbb74fc7445814902fd08422eac56d0",
|
||||
"0x6966ab0d485353095148a2155858910e0965b6f9",
|
||||
"0x779543a0491a837ca36ce8c635d6154e3c4911a6",
|
||||
"0x2a5ed960395e2a49b1c758cef4aa15213cfd874c",
|
||||
"0x5c6e67ccd5849c0d29219c4f95f1a7a93b3f5dc5",
|
||||
"0x9c50426be05db97f5d64fc54bf89eff947f0a321",
|
||||
"0x200450f06520bdd6c527622a273333384d870efb",
|
||||
"0xbe8539bfe837b67d1282b2b1d61c3f723966f049",
|
||||
"0x6b0c4d41ba9ab8d8cfb5d379c69a612f2ced8ecb",
|
||||
"0xf1385fb24aad0cd7432824085e42aff90886fef5",
|
||||
"0xd1ac8b1ef1b69ff51d1d401a476e7e612414f091",
|
||||
"0x8163e7fb499e90f8544ea62bbf80d21cd26d9efd",
|
||||
"0x51e0ddd9998364a2eb38588679f0d2c42653e4a6",
|
||||
"0x627a0a960c079c21c34f7612d5d230e01b4ad4c7",
|
||||
"0xf0b1aa0eb660754448a7937c022e30aa692fe0c5",
|
||||
"0x24c4d950dfd4dd1902bbed3508144a54542bba94",
|
||||
"0x9f27daea7aca0aa0446220b98d028715e3bc803d",
|
||||
"0xa5dc5acd6a7968a4554d89d65e59b7fd3bff0f90",
|
||||
"0xd9aef3a1e38a39c16b31d1ace71bca8ef58d315b",
|
||||
"0x63ed5a272de2f6d968408b4acb9024f4cc208ebf",
|
||||
"0x6f6704e5a10332af6672e50b3d9754dc460dfa4d",
|
||||
"0x77ca7b50b6cd7e2f3fa008e24ab793fd56cb15f6",
|
||||
"0x492ea3bb0f3315521c31f273e565b868fc090f17",
|
||||
"0x0ff30d6de14a8224aa97b78aea5388d1c51c1f00",
|
||||
"0x9ea779f907f0b315b364b0cfc39a0fde5b02a416",
|
||||
"0xceaeb481747ca6c540a000c1f3641f8cef161fa7",
|
||||
"0xcc34673c6c40e791051898567a1222daf90be287",
|
||||
"0x579a80d909f346fbfb1189493f521d7f48d52238",
|
||||
"0xe308bd1ac5fda103967359b2712dd89deffb7973",
|
||||
"0x4cb31628079fb14e4bc3cd5e30c2f7489b00960c",
|
||||
"0xac1ecab32727358dba8962a0f3b261731aad9723",
|
||||
"0x4fd6ace747f06ece9c49699c7cabc62d02211f75",
|
||||
"0x440c59b325d2997a134c2c7c60a8c61611212bad",
|
||||
"0x4486a3d68fac6967006d7a517b889fd3f98c102b",
|
||||
"0x9c15b54878ba618f494b38f0ae7443db6af648ba",
|
||||
"0x27b137a85656544b1ccb5a0f2e561a5703c6a68f",
|
||||
"0x21c7fdb9ed8d291d79ffd82eb2c4356ec0d81241",
|
||||
"0x23b75c2f6791eef49c69684db4c6c1f93bf49a50",
|
||||
"0x1ca6abd14d30affe533b24d7a21bff4c2d5e1f3b",
|
||||
"0xb9637156d330c0d605a791f1c31ba5890582fe1c",
|
||||
"0x6131c42fa982e56929107413a9d526fd99405560",
|
||||
"0x1591fc0f688c81fbeb17f5426a162a7024d430c2",
|
||||
"0x542a9515200d14b68e934e9830d91645a980dd7a",
|
||||
"0xc4bbd073882dd2add2424cf47d35213405b01324",
|
||||
"0x782495b7b3355efb2833d56ecb34dc22ad7dfcc4",
|
||||
"0x58b95c9a9d5d26825e70a82b6adb139d3fd829eb",
|
||||
"0x3ba4d81db016dc2890c81f3acec2454bff5aada5",
|
||||
"0xb52042c8ca3f8aa246fa79c3feaa3d959347c0ab",
|
||||
"0xe4ae1efdfc53b73893af49113d8694a057b9c0d1",
|
||||
"0x3c02a7bc0391e86d91b7d144e61c2c01a25a79c5",
|
||||
"0x0737a6b837f97f46ebade41b9bc3e1c509c85c53",
|
||||
"0x97f43a37f595ab5dd318fb46e7a155eae057317a",
|
||||
"0x52c5317c848ba20c7504cb2c8052abd1fde29d03",
|
||||
"0x4863226780fe7c0356454236d3b1c8792785748d",
|
||||
"0x5d2b2e6fcbe3b11d26b525e085ff818dae332479",
|
||||
"0x5f9f3392e9f62f63b8eac0beb55541fc8627f42c",
|
||||
"0x057b56736d32b86616a10f619859c6cd6f59092a",
|
||||
"0x9aa008f65de0b923a2a4f02012ad034a5e2e2192",
|
||||
"0x304a554a310c7e546dfe434669c62820b7d83490",
|
||||
"0x914d1b8b43e92723e64fd0a06f5bdb8dd9b10c79",
|
||||
"0x4deb0033bb26bc534b197e61d19e0733e5679784",
|
||||
"0x07f5c1e1bc2c93e0402f23341973a0e043f7bf8a",
|
||||
"0x35a051a0010aba705c9008d7a7eff6fb88f6ea7b",
|
||||
"0x4fa802324e929786dbda3b8820dc7834e9134a2a",
|
||||
"0x9da397b9e80755301a3b32173283a91c0ef6c87e",
|
||||
"0x8d9edb3054ce5c5774a420ac37ebae0ac02343c6",
|
||||
"0x0101f3be8ebb4bbd39a2e3b9a3639d4259832fd9",
|
||||
"0x5dc28b15dffed94048d73806ce4b7a4612a1d48f",
|
||||
"0xbcf899e6c7d9d5a215ab1e3444c86806fa854c76",
|
||||
"0x12e626b0eebfe86a56d633b9864e389b45dcb260",
|
||||
"0xa2f1ccba9395d7fcb155bba8bc92db9bafaeade7",
|
||||
"0xec8e57756626fdc07c63ad2eafbd28d08e7b0ca5",
|
||||
"0xd164b088bd9108b60d0ca3751da4bceb207b0782",
|
||||
"0x6231b6d0d5e77fe001c2a460bd9584fee60d409b",
|
||||
"0x1cba23d343a983e9b5cfd19496b9a9701ada385f",
|
||||
"0xa82f360a8d3455c5c41366975bde739c37bfeb8a",
|
||||
"0x9fcd2deaff372a39cc679d5c5e4de7bafb0b1339",
|
||||
"0x005f5cee7a43331d5a3d3eec71305925a62f34b6",
|
||||
"0x0e0da70933f4c7849fc0d203f5d1d43b9ae4532d",
|
||||
"0xd131637d5275fd1a68a3200f4ad25c71a2a9522e",
|
||||
"0xbc07118b9ac290e4622f5e77a0853539789effbe",
|
||||
"0x47e7aa56d6bdf3f36be34619660de61275420af8",
|
||||
"0xacd87e28b0c9d1254e868b81cba4cc20d9a32225",
|
||||
"0xadf80daec7ba8dcf15392f1ac611fff65d94f880",
|
||||
"0x5524c55fb03cf21f549444ccbecb664d0acad706",
|
||||
"0x40b803a9abce16f50f36a77ba41180eb90023925",
|
||||
"0xfe24cdd8648121a43a7c86d289be4dd2951ed49f",
|
||||
"0x17802f43a0137c506ba92291391a8a8f207f487d",
|
||||
"0x253488078a4edf4d6f42f113d1e62836a942cf1a",
|
||||
"0x86af3e9626fce1957c82e88cbf04ddf3a2ed7915",
|
||||
"0xb136707642a4ea12fb4bae820f03d2562ebff487",
|
||||
"0xdbe9b615a3ae8709af8b93336ce9b477e4ac0940",
|
||||
"0xf14c14075d6c4ed84b86798af0956deef67365b5",
|
||||
"0xca544e5c4687d109611d0f8f928b53a25af72448",
|
||||
"0xaeeb8ff27288bdabc0fa5ebb731b6f409507516c",
|
||||
"0xcbb9d3703e651b0d496cdefb8b92c25aeb2171f7",
|
||||
"0x6d87578288b6cb5549d5076a207456a1f6a63dc0",
|
||||
"0xb2c6f0dfbb716ac562e2d85d6cb2f8d5ee87603e",
|
||||
"0xaccc230e8a6e5be9160b8cdf2864dd2a001c28b6",
|
||||
"0x2b3455ec7fedf16e646268bf88846bd7a2319bb2",
|
||||
"0x4613f3bca5c44ea06337a9e439fbc6d42e501d0a",
|
||||
"0xd343b217de44030afaa275f54d31a9317c7f441e",
|
||||
"0x84ef4b2357079cd7a7c69fd7a37cd0609a679106",
|
||||
"0xda2fef9e4a3230988ff17df2165440f37e8b1708",
|
||||
"0xf4c64518ea10f995918a454158c6b61407ea345c",
|
||||
"0x7602b46df5390e432ef1c307d4f2c9ff6d65cc97",
|
||||
"0xbb9bc244d798123fde783fcc1c72d3bb8c189413",
|
||||
"0x807640a13483f8ac783c557fcdf27be11ea4ac7a"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"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 } } } }
|
||||
}
|
||||
}
|
||||
26730
ethcore/res/ethereum/frontier-dogmatic.json
Normal file
26730
ethcore/res/ethereum/frontier-dogmatic.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,24 +1,154 @@
|
||||
{
|
||||
"name": "Frontier/Homestead",
|
||||
"engineName": "Ethash",
|
||||
"engine": {
|
||||
"Ethash": {
|
||||
"params": {
|
||||
"gasLimitBoundDivisor": "0x0400",
|
||||
"minimumDifficulty": "0x020000",
|
||||
"difficultyBoundDivisor": "0x0800",
|
||||
"durationLimit": "0x0d",
|
||||
"blockReward": "0x4563918244F40000",
|
||||
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
||||
"frontierCompatibilityModeLimit": "0x118c30",
|
||||
"daoHardforkTransition": "0x1d4c00",
|
||||
"daoHardforkBeneficiary": "0xbf4ed7b27f1d666546e30d74d50d173d20bca754",
|
||||
"daoHardforkAccounts": [
|
||||
"0xd4fe7bc31cedb7bfb8a345f31e668033056b2728",
|
||||
"0xb3fb0e5aba0e20e5c49d252dfd30e102b171a425",
|
||||
"0x2c19c7f9ae8b751e37aeb2d93a699722395ae18f",
|
||||
"0xecd135fa4f61a655311e86238c92adcd779555d2",
|
||||
"0x1975bd06d486162d5dc297798dfc41edd5d160a7",
|
||||
"0xa3acf3a1e16b1d7c315e23510fdd7847b48234f6",
|
||||
"0x319f70bab6845585f412ec7724b744fec6095c85",
|
||||
"0x06706dd3f2c9abf0a21ddcc6941d9b86f0596936",
|
||||
"0x5c8536898fbb74fc7445814902fd08422eac56d0",
|
||||
"0x6966ab0d485353095148a2155858910e0965b6f9",
|
||||
"0x779543a0491a837ca36ce8c635d6154e3c4911a6",
|
||||
"0x2a5ed960395e2a49b1c758cef4aa15213cfd874c",
|
||||
"0x5c6e67ccd5849c0d29219c4f95f1a7a93b3f5dc5",
|
||||
"0x9c50426be05db97f5d64fc54bf89eff947f0a321",
|
||||
"0x200450f06520bdd6c527622a273333384d870efb",
|
||||
"0xbe8539bfe837b67d1282b2b1d61c3f723966f049",
|
||||
"0x6b0c4d41ba9ab8d8cfb5d379c69a612f2ced8ecb",
|
||||
"0xf1385fb24aad0cd7432824085e42aff90886fef5",
|
||||
"0xd1ac8b1ef1b69ff51d1d401a476e7e612414f091",
|
||||
"0x8163e7fb499e90f8544ea62bbf80d21cd26d9efd",
|
||||
"0x51e0ddd9998364a2eb38588679f0d2c42653e4a6",
|
||||
"0x627a0a960c079c21c34f7612d5d230e01b4ad4c7",
|
||||
"0xf0b1aa0eb660754448a7937c022e30aa692fe0c5",
|
||||
"0x24c4d950dfd4dd1902bbed3508144a54542bba94",
|
||||
"0x9f27daea7aca0aa0446220b98d028715e3bc803d",
|
||||
"0xa5dc5acd6a7968a4554d89d65e59b7fd3bff0f90",
|
||||
"0xd9aef3a1e38a39c16b31d1ace71bca8ef58d315b",
|
||||
"0x63ed5a272de2f6d968408b4acb9024f4cc208ebf",
|
||||
"0x6f6704e5a10332af6672e50b3d9754dc460dfa4d",
|
||||
"0x77ca7b50b6cd7e2f3fa008e24ab793fd56cb15f6",
|
||||
"0x492ea3bb0f3315521c31f273e565b868fc090f17",
|
||||
"0x0ff30d6de14a8224aa97b78aea5388d1c51c1f00",
|
||||
"0x9ea779f907f0b315b364b0cfc39a0fde5b02a416",
|
||||
"0xceaeb481747ca6c540a000c1f3641f8cef161fa7",
|
||||
"0xcc34673c6c40e791051898567a1222daf90be287",
|
||||
"0x579a80d909f346fbfb1189493f521d7f48d52238",
|
||||
"0xe308bd1ac5fda103967359b2712dd89deffb7973",
|
||||
"0x4cb31628079fb14e4bc3cd5e30c2f7489b00960c",
|
||||
"0xac1ecab32727358dba8962a0f3b261731aad9723",
|
||||
"0x4fd6ace747f06ece9c49699c7cabc62d02211f75",
|
||||
"0x440c59b325d2997a134c2c7c60a8c61611212bad",
|
||||
"0x4486a3d68fac6967006d7a517b889fd3f98c102b",
|
||||
"0x9c15b54878ba618f494b38f0ae7443db6af648ba",
|
||||
"0x27b137a85656544b1ccb5a0f2e561a5703c6a68f",
|
||||
"0x21c7fdb9ed8d291d79ffd82eb2c4356ec0d81241",
|
||||
"0x23b75c2f6791eef49c69684db4c6c1f93bf49a50",
|
||||
"0x1ca6abd14d30affe533b24d7a21bff4c2d5e1f3b",
|
||||
"0xb9637156d330c0d605a791f1c31ba5890582fe1c",
|
||||
"0x6131c42fa982e56929107413a9d526fd99405560",
|
||||
"0x1591fc0f688c81fbeb17f5426a162a7024d430c2",
|
||||
"0x542a9515200d14b68e934e9830d91645a980dd7a",
|
||||
"0xc4bbd073882dd2add2424cf47d35213405b01324",
|
||||
"0x782495b7b3355efb2833d56ecb34dc22ad7dfcc4",
|
||||
"0x58b95c9a9d5d26825e70a82b6adb139d3fd829eb",
|
||||
"0x3ba4d81db016dc2890c81f3acec2454bff5aada5",
|
||||
"0xb52042c8ca3f8aa246fa79c3feaa3d959347c0ab",
|
||||
"0xe4ae1efdfc53b73893af49113d8694a057b9c0d1",
|
||||
"0x3c02a7bc0391e86d91b7d144e61c2c01a25a79c5",
|
||||
"0x0737a6b837f97f46ebade41b9bc3e1c509c85c53",
|
||||
"0x97f43a37f595ab5dd318fb46e7a155eae057317a",
|
||||
"0x52c5317c848ba20c7504cb2c8052abd1fde29d03",
|
||||
"0x4863226780fe7c0356454236d3b1c8792785748d",
|
||||
"0x5d2b2e6fcbe3b11d26b525e085ff818dae332479",
|
||||
"0x5f9f3392e9f62f63b8eac0beb55541fc8627f42c",
|
||||
"0x057b56736d32b86616a10f619859c6cd6f59092a",
|
||||
"0x9aa008f65de0b923a2a4f02012ad034a5e2e2192",
|
||||
"0x304a554a310c7e546dfe434669c62820b7d83490",
|
||||
"0x914d1b8b43e92723e64fd0a06f5bdb8dd9b10c79",
|
||||
"0x4deb0033bb26bc534b197e61d19e0733e5679784",
|
||||
"0x07f5c1e1bc2c93e0402f23341973a0e043f7bf8a",
|
||||
"0x35a051a0010aba705c9008d7a7eff6fb88f6ea7b",
|
||||
"0x4fa802324e929786dbda3b8820dc7834e9134a2a",
|
||||
"0x9da397b9e80755301a3b32173283a91c0ef6c87e",
|
||||
"0x8d9edb3054ce5c5774a420ac37ebae0ac02343c6",
|
||||
"0x0101f3be8ebb4bbd39a2e3b9a3639d4259832fd9",
|
||||
"0x5dc28b15dffed94048d73806ce4b7a4612a1d48f",
|
||||
"0xbcf899e6c7d9d5a215ab1e3444c86806fa854c76",
|
||||
"0x12e626b0eebfe86a56d633b9864e389b45dcb260",
|
||||
"0xa2f1ccba9395d7fcb155bba8bc92db9bafaeade7",
|
||||
"0xec8e57756626fdc07c63ad2eafbd28d08e7b0ca5",
|
||||
"0xd164b088bd9108b60d0ca3751da4bceb207b0782",
|
||||
"0x6231b6d0d5e77fe001c2a460bd9584fee60d409b",
|
||||
"0x1cba23d343a983e9b5cfd19496b9a9701ada385f",
|
||||
"0xa82f360a8d3455c5c41366975bde739c37bfeb8a",
|
||||
"0x9fcd2deaff372a39cc679d5c5e4de7bafb0b1339",
|
||||
"0x005f5cee7a43331d5a3d3eec71305925a62f34b6",
|
||||
"0x0e0da70933f4c7849fc0d203f5d1d43b9ae4532d",
|
||||
"0xd131637d5275fd1a68a3200f4ad25c71a2a9522e",
|
||||
"0xbc07118b9ac290e4622f5e77a0853539789effbe",
|
||||
"0x47e7aa56d6bdf3f36be34619660de61275420af8",
|
||||
"0xacd87e28b0c9d1254e868b81cba4cc20d9a32225",
|
||||
"0xadf80daec7ba8dcf15392f1ac611fff65d94f880",
|
||||
"0x5524c55fb03cf21f549444ccbecb664d0acad706",
|
||||
"0x40b803a9abce16f50f36a77ba41180eb90023925",
|
||||
"0xfe24cdd8648121a43a7c86d289be4dd2951ed49f",
|
||||
"0x17802f43a0137c506ba92291391a8a8f207f487d",
|
||||
"0x253488078a4edf4d6f42f113d1e62836a942cf1a",
|
||||
"0x86af3e9626fce1957c82e88cbf04ddf3a2ed7915",
|
||||
"0xb136707642a4ea12fb4bae820f03d2562ebff487",
|
||||
"0xdbe9b615a3ae8709af8b93336ce9b477e4ac0940",
|
||||
"0xf14c14075d6c4ed84b86798af0956deef67365b5",
|
||||
"0xca544e5c4687d109611d0f8f928b53a25af72448",
|
||||
"0xaeeb8ff27288bdabc0fa5ebb731b6f409507516c",
|
||||
"0xcbb9d3703e651b0d496cdefb8b92c25aeb2171f7",
|
||||
"0x6d87578288b6cb5549d5076a207456a1f6a63dc0",
|
||||
"0xb2c6f0dfbb716ac562e2d85d6cb2f8d5ee87603e",
|
||||
"0xaccc230e8a6e5be9160b8cdf2864dd2a001c28b6",
|
||||
"0x2b3455ec7fedf16e646268bf88846bd7a2319bb2",
|
||||
"0x4613f3bca5c44ea06337a9e439fbc6d42e501d0a",
|
||||
"0xd343b217de44030afaa275f54d31a9317c7f441e",
|
||||
"0x84ef4b2357079cd7a7c69fd7a37cd0609a679106",
|
||||
"0xda2fef9e4a3230988ff17df2165440f37e8b1708",
|
||||
"0xf4c64518ea10f995918a454158c6b61407ea345c",
|
||||
"0x7602b46df5390e432ef1c307d4f2c9ff6d65cc97",
|
||||
"0xbb9bc244d798123fde783fcc1c72d3bb8c189413",
|
||||
"0x807640a13483f8ac783c557fcdf27be11ea4ac7a"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"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"
|
||||
"networkID" : "0x1",
|
||||
"forkBlock": "0x1d4c00",
|
||||
"forkCanonHash": "0x4985f5ca3d2afbec36529aa96f74de3cc10a2a4a6c44f2157a57d2c6059a11bb"
|
||||
},
|
||||
"genesis": {
|
||||
"nonce": "0x0000000000000042",
|
||||
"seal": {
|
||||
"ethereum": {
|
||||
"nonce": "0x0000000000000042",
|
||||
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||
}
|
||||
},
|
||||
"difficulty": "0x400000000",
|
||||
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"author": "0x0000000000000000000000000000000000000000",
|
||||
"timestamp": "0x00",
|
||||
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
@@ -30,13 +160,13 @@
|
||||
"enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@52.16.188.185:30303",
|
||||
"enode://de471bccee3d042261d52e9bff31458daecc406142b401d4cd848f677479f73104b9fdeb090af9583d3391b7f10cb2ba9e26865dd5fca4fcdc0fb1e3b723c786@54.94.239.50:30303",
|
||||
"enode://1118980bf48b0a3640bdba04e0fe78b1add18e1cd99bf22d53daac1fd9972ad650df52176e7c7d89d1114cfef2bc23a2959aa54998a46afcf7d91809f0855082@52.74.57.123:30303",
|
||||
"enode://248f12bc8b18d5289358085520ac78cd8076485211e6d96ab0bc93d6cd25442db0ce3a937dc404f64f207b0b9aed50e25e98ce32af5ac7cb321ff285b97de485@parity-node-zero.ethcore.io:30303"
|
||||
"enode://248f12bc8b18d5289358085520ac78cd8076485211e6d96ab0bc93d6cd25442db0ce3a937dc404f64f207b0b9aed50e25e98ce32af5ac7cb321ff285b97de485@zero.parity.io:30303"
|
||||
],
|
||||
"accounts": {
|
||||
"0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } },
|
||||
"0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "linear": { "base": 60, "word": 12 } } },
|
||||
"0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } },
|
||||
"0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "linear": { "base": 15, "word": 3 } } },
|
||||
"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 } } } },
|
||||
"3282791d6fd713f1e94f4bfd565eaa78b3a0599d": {
|
||||
"balance": "1337000000000000000000"
|
||||
},
|
||||
|
||||
@@ -1,24 +1,152 @@
|
||||
{
|
||||
"engineName": "Frontier (Test)",
|
||||
"engineName": "Ethash",
|
||||
"name": "Frontier (Test)",
|
||||
"engine": {
|
||||
"Ethash": {
|
||||
"params": {
|
||||
"gasLimitBoundDivisor": "0x0400",
|
||||
"minimumDifficulty": "0x020000",
|
||||
"difficultyBoundDivisor": "0x0800",
|
||||
"durationLimit": "0x0d",
|
||||
"blockReward": "0x4563918244F40000",
|
||||
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
||||
"frontierCompatibilityModeLimit": "0x118c30",
|
||||
"daoHardforkTransition": "0x1d4c00",
|
||||
"daoHardforkBeneficiary": "0xbf4ed7b27f1d666546e30d74d50d173d20bca754",
|
||||
"daoHardforkAccounts": [
|
||||
"0xd4fe7bc31cedb7bfb8a345f31e668033056b2728",
|
||||
"0xb3fb0e5aba0e20e5c49d252dfd30e102b171a425",
|
||||
"0x2c19c7f9ae8b751e37aeb2d93a699722395ae18f",
|
||||
"0xecd135fa4f61a655311e86238c92adcd779555d2",
|
||||
"0x1975bd06d486162d5dc297798dfc41edd5d160a7",
|
||||
"0xa3acf3a1e16b1d7c315e23510fdd7847b48234f6",
|
||||
"0x319f70bab6845585f412ec7724b744fec6095c85",
|
||||
"0x06706dd3f2c9abf0a21ddcc6941d9b86f0596936",
|
||||
"0x5c8536898fbb74fc7445814902fd08422eac56d0",
|
||||
"0x6966ab0d485353095148a2155858910e0965b6f9",
|
||||
"0x779543a0491a837ca36ce8c635d6154e3c4911a6",
|
||||
"0x2a5ed960395e2a49b1c758cef4aa15213cfd874c",
|
||||
"0x5c6e67ccd5849c0d29219c4f95f1a7a93b3f5dc5",
|
||||
"0x9c50426be05db97f5d64fc54bf89eff947f0a321",
|
||||
"0x200450f06520bdd6c527622a273333384d870efb",
|
||||
"0xbe8539bfe837b67d1282b2b1d61c3f723966f049",
|
||||
"0x6b0c4d41ba9ab8d8cfb5d379c69a612f2ced8ecb",
|
||||
"0xf1385fb24aad0cd7432824085e42aff90886fef5",
|
||||
"0xd1ac8b1ef1b69ff51d1d401a476e7e612414f091",
|
||||
"0x8163e7fb499e90f8544ea62bbf80d21cd26d9efd",
|
||||
"0x51e0ddd9998364a2eb38588679f0d2c42653e4a6",
|
||||
"0x627a0a960c079c21c34f7612d5d230e01b4ad4c7",
|
||||
"0xf0b1aa0eb660754448a7937c022e30aa692fe0c5",
|
||||
"0x24c4d950dfd4dd1902bbed3508144a54542bba94",
|
||||
"0x9f27daea7aca0aa0446220b98d028715e3bc803d",
|
||||
"0xa5dc5acd6a7968a4554d89d65e59b7fd3bff0f90",
|
||||
"0xd9aef3a1e38a39c16b31d1ace71bca8ef58d315b",
|
||||
"0x63ed5a272de2f6d968408b4acb9024f4cc208ebf",
|
||||
"0x6f6704e5a10332af6672e50b3d9754dc460dfa4d",
|
||||
"0x77ca7b50b6cd7e2f3fa008e24ab793fd56cb15f6",
|
||||
"0x492ea3bb0f3315521c31f273e565b868fc090f17",
|
||||
"0x0ff30d6de14a8224aa97b78aea5388d1c51c1f00",
|
||||
"0x9ea779f907f0b315b364b0cfc39a0fde5b02a416",
|
||||
"0xceaeb481747ca6c540a000c1f3641f8cef161fa7",
|
||||
"0xcc34673c6c40e791051898567a1222daf90be287",
|
||||
"0x579a80d909f346fbfb1189493f521d7f48d52238",
|
||||
"0xe308bd1ac5fda103967359b2712dd89deffb7973",
|
||||
"0x4cb31628079fb14e4bc3cd5e30c2f7489b00960c",
|
||||
"0xac1ecab32727358dba8962a0f3b261731aad9723",
|
||||
"0x4fd6ace747f06ece9c49699c7cabc62d02211f75",
|
||||
"0x440c59b325d2997a134c2c7c60a8c61611212bad",
|
||||
"0x4486a3d68fac6967006d7a517b889fd3f98c102b",
|
||||
"0x9c15b54878ba618f494b38f0ae7443db6af648ba",
|
||||
"0x27b137a85656544b1ccb5a0f2e561a5703c6a68f",
|
||||
"0x21c7fdb9ed8d291d79ffd82eb2c4356ec0d81241",
|
||||
"0x23b75c2f6791eef49c69684db4c6c1f93bf49a50",
|
||||
"0x1ca6abd14d30affe533b24d7a21bff4c2d5e1f3b",
|
||||
"0xb9637156d330c0d605a791f1c31ba5890582fe1c",
|
||||
"0x6131c42fa982e56929107413a9d526fd99405560",
|
||||
"0x1591fc0f688c81fbeb17f5426a162a7024d430c2",
|
||||
"0x542a9515200d14b68e934e9830d91645a980dd7a",
|
||||
"0xc4bbd073882dd2add2424cf47d35213405b01324",
|
||||
"0x782495b7b3355efb2833d56ecb34dc22ad7dfcc4",
|
||||
"0x58b95c9a9d5d26825e70a82b6adb139d3fd829eb",
|
||||
"0x3ba4d81db016dc2890c81f3acec2454bff5aada5",
|
||||
"0xb52042c8ca3f8aa246fa79c3feaa3d959347c0ab",
|
||||
"0xe4ae1efdfc53b73893af49113d8694a057b9c0d1",
|
||||
"0x3c02a7bc0391e86d91b7d144e61c2c01a25a79c5",
|
||||
"0x0737a6b837f97f46ebade41b9bc3e1c509c85c53",
|
||||
"0x97f43a37f595ab5dd318fb46e7a155eae057317a",
|
||||
"0x52c5317c848ba20c7504cb2c8052abd1fde29d03",
|
||||
"0x4863226780fe7c0356454236d3b1c8792785748d",
|
||||
"0x5d2b2e6fcbe3b11d26b525e085ff818dae332479",
|
||||
"0x5f9f3392e9f62f63b8eac0beb55541fc8627f42c",
|
||||
"0x057b56736d32b86616a10f619859c6cd6f59092a",
|
||||
"0x9aa008f65de0b923a2a4f02012ad034a5e2e2192",
|
||||
"0x304a554a310c7e546dfe434669c62820b7d83490",
|
||||
"0x914d1b8b43e92723e64fd0a06f5bdb8dd9b10c79",
|
||||
"0x4deb0033bb26bc534b197e61d19e0733e5679784",
|
||||
"0x07f5c1e1bc2c93e0402f23341973a0e043f7bf8a",
|
||||
"0x35a051a0010aba705c9008d7a7eff6fb88f6ea7b",
|
||||
"0x4fa802324e929786dbda3b8820dc7834e9134a2a",
|
||||
"0x9da397b9e80755301a3b32173283a91c0ef6c87e",
|
||||
"0x8d9edb3054ce5c5774a420ac37ebae0ac02343c6",
|
||||
"0x0101f3be8ebb4bbd39a2e3b9a3639d4259832fd9",
|
||||
"0x5dc28b15dffed94048d73806ce4b7a4612a1d48f",
|
||||
"0xbcf899e6c7d9d5a215ab1e3444c86806fa854c76",
|
||||
"0x12e626b0eebfe86a56d633b9864e389b45dcb260",
|
||||
"0xa2f1ccba9395d7fcb155bba8bc92db9bafaeade7",
|
||||
"0xec8e57756626fdc07c63ad2eafbd28d08e7b0ca5",
|
||||
"0xd164b088bd9108b60d0ca3751da4bceb207b0782",
|
||||
"0x6231b6d0d5e77fe001c2a460bd9584fee60d409b",
|
||||
"0x1cba23d343a983e9b5cfd19496b9a9701ada385f",
|
||||
"0xa82f360a8d3455c5c41366975bde739c37bfeb8a",
|
||||
"0x9fcd2deaff372a39cc679d5c5e4de7bafb0b1339",
|
||||
"0x005f5cee7a43331d5a3d3eec71305925a62f34b6",
|
||||
"0x0e0da70933f4c7849fc0d203f5d1d43b9ae4532d",
|
||||
"0xd131637d5275fd1a68a3200f4ad25c71a2a9522e",
|
||||
"0xbc07118b9ac290e4622f5e77a0853539789effbe",
|
||||
"0x47e7aa56d6bdf3f36be34619660de61275420af8",
|
||||
"0xacd87e28b0c9d1254e868b81cba4cc20d9a32225",
|
||||
"0xadf80daec7ba8dcf15392f1ac611fff65d94f880",
|
||||
"0x5524c55fb03cf21f549444ccbecb664d0acad706",
|
||||
"0x40b803a9abce16f50f36a77ba41180eb90023925",
|
||||
"0xfe24cdd8648121a43a7c86d289be4dd2951ed49f",
|
||||
"0x17802f43a0137c506ba92291391a8a8f207f487d",
|
||||
"0x253488078a4edf4d6f42f113d1e62836a942cf1a",
|
||||
"0x86af3e9626fce1957c82e88cbf04ddf3a2ed7915",
|
||||
"0xb136707642a4ea12fb4bae820f03d2562ebff487",
|
||||
"0xdbe9b615a3ae8709af8b93336ce9b477e4ac0940",
|
||||
"0xf14c14075d6c4ed84b86798af0956deef67365b5",
|
||||
"0xca544e5c4687d109611d0f8f928b53a25af72448",
|
||||
"0xaeeb8ff27288bdabc0fa5ebb731b6f409507516c",
|
||||
"0xcbb9d3703e651b0d496cdefb8b92c25aeb2171f7",
|
||||
"0x6d87578288b6cb5549d5076a207456a1f6a63dc0",
|
||||
"0xb2c6f0dfbb716ac562e2d85d6cb2f8d5ee87603e",
|
||||
"0xaccc230e8a6e5be9160b8cdf2864dd2a001c28b6",
|
||||
"0x2b3455ec7fedf16e646268bf88846bd7a2319bb2",
|
||||
"0x4613f3bca5c44ea06337a9e439fbc6d42e501d0a",
|
||||
"0xd343b217de44030afaa275f54d31a9317c7f441e",
|
||||
"0x84ef4b2357079cd7a7c69fd7a37cd0609a679106",
|
||||
"0xda2fef9e4a3230988ff17df2165440f37e8b1708",
|
||||
"0xf4c64518ea10f995918a454158c6b61407ea345c",
|
||||
"0x7602b46df5390e432ef1c307d4f2c9ff6d65cc97",
|
||||
"0xbb9bc244d798123fde783fcc1c72d3bb8c189413",
|
||||
"0x807640a13483f8ac783c557fcdf27be11ea4ac7a"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"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": {
|
||||
"nonce": "0x0000000000000042",
|
||||
"seal": {
|
||||
"ethereum": {
|
||||
"nonce": "0x0000000000000042",
|
||||
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||
}
|
||||
},
|
||||
"difficulty": "0x400000000",
|
||||
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"author": "0x0000000000000000000000000000000000000000",
|
||||
"timestamp": "0x00",
|
||||
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
@@ -26,9 +154,9 @@
|
||||
"gasLimit": "0x1388"
|
||||
},
|
||||
"accounts": {
|
||||
"0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } },
|
||||
"0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "linear": { "base": 60, "word": 12 } } },
|
||||
"0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } },
|
||||
"0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "linear": { "base": 15, "word": 3 } } }
|
||||
"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 } } } }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +1,32 @@
|
||||
{
|
||||
"engineName": "Frontier (Test)",
|
||||
"engineName": "Ethash",
|
||||
"name": "Frontier (Test)",
|
||||
"engine": {
|
||||
"Ethash": {
|
||||
"params": {
|
||||
"gasLimitBoundDivisor": "0x0400",
|
||||
"minimumDifficulty": "0x020000",
|
||||
"difficultyBoundDivisor": "0x0800",
|
||||
"durationLimit": "0x0d",
|
||||
"blockReward": "0x4563918244F40000",
|
||||
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
||||
"frontierCompatibilityModeLimit": "0xffffffffffffffff"
|
||||
}
|
||||
}
|
||||
},
|
||||
"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": {
|
||||
"nonce": "0x0000000000000042",
|
||||
"seal": {
|
||||
"ethereum": {
|
||||
"nonce": "0x0000000000000042",
|
||||
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||
}
|
||||
},
|
||||
"difficulty": "0x400000000",
|
||||
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"author": "0x0000000000000000000000000000000000000000",
|
||||
"timestamp": "0x00",
|
||||
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
@@ -26,9 +34,9 @@
|
||||
"gasLimit": "0x1388"
|
||||
},
|
||||
"accounts": {
|
||||
"0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } },
|
||||
"0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "linear": { "base": 60, "word": 12 } } },
|
||||
"0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } },
|
||||
"0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "linear": { "base": 15, "word": 3 } } }
|
||||
"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 } } } }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +1,32 @@
|
||||
{
|
||||
"name": "Homestead (Test)",
|
||||
"engineName": "Ethash",
|
||||
"engine": {
|
||||
"Ethash": {
|
||||
"params": {
|
||||
"gasLimitBoundDivisor": "0x0400",
|
||||
"minimumDifficulty": "0x020000",
|
||||
"difficultyBoundDivisor": "0x0800",
|
||||
"durationLimit": "0x0d",
|
||||
"blockReward": "0x4563918244F40000",
|
||||
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
||||
"frontierCompatibilityModeLimit": "0x0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"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": {
|
||||
"nonce": "0x0000000000000042",
|
||||
"seal": {
|
||||
"ethereum": {
|
||||
"nonce": "0x0000000000000042",
|
||||
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||
}
|
||||
},
|
||||
"difficulty": "0x400000000",
|
||||
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"author": "0x0000000000000000000000000000000000000000",
|
||||
"timestamp": "0x00",
|
||||
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
@@ -26,9 +34,9 @@
|
||||
"gasLimit": "0x1388"
|
||||
},
|
||||
"accounts": {
|
||||
"0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } },
|
||||
"0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "linear": { "base": 60, "word": 12 } } },
|
||||
"0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } },
|
||||
"0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "linear": { "base": 15, "word": 3 } } }
|
||||
"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 } } } }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +1,32 @@
|
||||
{
|
||||
"name": "Morden",
|
||||
"engineName": "Ethash",
|
||||
"engine": {
|
||||
"Ethash": {
|
||||
"params": {
|
||||
"gasLimitBoundDivisor": "0x0400",
|
||||
"minimumDifficulty": "0x020000",
|
||||
"difficultyBoundDivisor": "0x0800",
|
||||
"durationLimit": "0x0d",
|
||||
"blockReward": "0x4563918244F40000",
|
||||
"registrar": "",
|
||||
"frontierCompatibilityModeLimit": "0x789b0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"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": {
|
||||
"nonce": "0x00006d6f7264656e",
|
||||
"seal": {
|
||||
"ethereum": {
|
||||
"nonce": "0x00006d6f7264656e",
|
||||
"mixHash": "0x00000000000000000000000000000000000000647572616c65787365646c6578"
|
||||
}
|
||||
},
|
||||
"difficulty": "0x20000",
|
||||
"mixHash": "0x00000000000000000000000000000000000000647572616c65787365646c6578",
|
||||
"author": "0x0000000000000000000000000000000000000000",
|
||||
"timestamp": "0x00",
|
||||
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
@@ -26,13 +34,14 @@
|
||||
"gasLimit": "0x2fefd8"
|
||||
},
|
||||
"nodes": [
|
||||
"enode://b1217cbaa440e35ed471157123fe468e19e8b5ad5bedb4b1fdbcbdab6fb2f5ed3e95dd9c24a22a79fdb2352204cea207df27d92bfd21bfd41545e8b16f637499@104.44.138.37:30303"
|
||||
"enode://e731347db0521f3476e6bbbb83375dcd7133a1601425ebd15fd10f3835fd4c304fba6282087ca5a0deeafadf0aa0d4fd56c3323331901c1f38bd181c283e3e35@128.199.55.137:30303",
|
||||
"enode://ceb5c0f85eb994dbe9693bf46d99b03f6b838d17cc74e68d5eb003171ff39e5f120b17f965b267c319303f94d80b9d994b77062fb1486d76ce95d9f3d8fe1cb4@46.101.122.141:30303"
|
||||
],
|
||||
"accounts": {
|
||||
"0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } },
|
||||
"0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "linear": { "base": 60, "word": 12 } } },
|
||||
"0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } },
|
||||
"0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "linear": { "base": 15, "word": 3 } } },
|
||||
"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 } } } },
|
||||
"102e61f5d8f9bc71d0ad4a084df4e65e05ce0e1c": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +1,31 @@
|
||||
{
|
||||
"name": "Olympic",
|
||||
"engineName": "Ethash",
|
||||
"engine": {
|
||||
"Ethash": {
|
||||
"params": {
|
||||
"gasLimitBoundDivisor": "0x0400",
|
||||
"minimumDifficulty": "0x020000",
|
||||
"difficultyBoundDivisor": "0x0800",
|
||||
"durationLimit": "0x08",
|
||||
"blockReward": "0x14D1120D7B160000",
|
||||
"registrar": "5e70c0bbcd5636e0f9f9316e9f8633feb64d4050"
|
||||
}
|
||||
}
|
||||
},
|
||||
"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": {
|
||||
"nonce": "0x000000000000002a",
|
||||
"seal": {
|
||||
"ethereum": {
|
||||
"nonce": "0x000000000000002a",
|
||||
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||
}
|
||||
},
|
||||
"difficulty": "0x20000",
|
||||
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"author": "0x0000000000000000000000000000000000000000",
|
||||
"timestamp": "0x00",
|
||||
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
@@ -26,10 +33,10 @@
|
||||
"gasLimit": "0x2fefd8"
|
||||
},
|
||||
"accounts": {
|
||||
"0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } },
|
||||
"0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "linear": { "base": 60, "word": 12 } } },
|
||||
"0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } },
|
||||
"0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "linear": { "base": 15, "word": 3 } } },
|
||||
"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 } } } },
|
||||
"dbdbdb2cbd23b783741e8d7fcf51e459b497e4a6": { "balance": "1606938044258990275541962092341162602522202993782792835301376" },
|
||||
"e6716f9544a56c530d868e4bfbacb172315bdead": { "balance": "1606938044258990275541962092341162602522202993782792835301376" },
|
||||
"b9c015918bdaba24b4ff057a92a3873d6eb201be": { "balance": "1606938044258990275541962092341162602522202993782792835301376" },
|
||||
|
||||
Submodule ethcore/res/ethereum/tests updated: 99afe8f5aa...ac5475d676
33
ethcore/res/null.json
Normal file
33
ethcore/res/null.json
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"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" }
|
||||
}
|
||||
}
|
||||
@@ -1,24 +1,22 @@
|
||||
{
|
||||
"name": "Morden",
|
||||
"engineName": "NullEngine",
|
||||
"engine": {
|
||||
"Null": null
|
||||
},
|
||||
"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": {
|
||||
"nonce": "0x00006d6f7264656e",
|
||||
"seal": {
|
||||
"ethereum": {
|
||||
"nonce": "0x00006d6f7264656e",
|
||||
"mixHash": "0x00000000000000000000000000000000000000647572616c65787365646c6578"
|
||||
}
|
||||
},
|
||||
"difficulty": "0x20000",
|
||||
"mixHash": "0x00000000000000000000000000000000000000647572616c65787365646c6578",
|
||||
"author": "0x0000000000000000000000000000000000000000",
|
||||
"timestamp": "0x00",
|
||||
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
@@ -26,10 +24,10 @@
|
||||
"gasLimit": "0x2fefd8"
|
||||
},
|
||||
"accounts": {
|
||||
"0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } },
|
||||
"0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "linear": { "base": 60, "word": 12 } } },
|
||||
"0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } },
|
||||
"0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "linear": { "base": 15, "word": 3 } } },
|
||||
"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 } } } },
|
||||
"102e61f5d8f9bc71d0ad4a084df4e65e05ce0e1c": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" }
|
||||
}
|
||||
}
|
||||
|
||||
39
ethcore/res/test_authority.json
Normal file
39
ethcore/res/test_authority.json
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"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" }
|
||||
}
|
||||
}
|
||||
@@ -51,8 +51,6 @@ impl Account {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[cfg(feature = "json-tests")]
|
||||
/// General constructor.
|
||||
pub fn from_pod(pod: PodAccount) -> Account {
|
||||
Account {
|
||||
@@ -60,8 +58,8 @@ impl Account {
|
||||
nonce: pod.nonce,
|
||||
storage_root: SHA3_NULL_RLP,
|
||||
storage_overlay: RefCell::new(pod.storage.into_iter().map(|(k, v)| (k, (Filth::Dirty, v))).collect()),
|
||||
code_hash: Some(pod.code.sha3()),
|
||||
code_cache: pod.code
|
||||
code_hash: pod.code.as_ref().map(|c| c.sha3()),
|
||||
code_cache: pod.code.as_ref().map_or_else(|| { warn!("POD account with unknown code is being created! Assuming no code."); vec![] }, |c| c.clone()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,6 +108,12 @@ impl Account {
|
||||
self.code_cache = code;
|
||||
}
|
||||
|
||||
/// Reset this account's code to the given code.
|
||||
pub fn reset_code(&mut self, code: Bytes) {
|
||||
self.code_hash = None;
|
||||
self.init_code(code);
|
||||
}
|
||||
|
||||
/// Set (and cache) the contents of the trie's storage at `key` to `value`.
|
||||
pub fn set_storage(&mut self, key: H256, value: H256) {
|
||||
self.storage_overlay.borrow_mut().insert(key, (Filth::Dirty, value));
|
||||
@@ -118,7 +122,12 @@ 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(||{
|
||||
(Filth::Clean, H256::from(SecTrieDB::new(db, &self.storage_root).get(key.bytes()).map_or(U256::zero(), |v| -> U256 {decode(v)})))
|
||||
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)})))
|
||||
}).1.clone()
|
||||
}
|
||||
|
||||
@@ -138,7 +147,7 @@ impl Account {
|
||||
/// get someone who knows to call `note_code`.
|
||||
pub fn code(&self) -> Option<&[u8]> {
|
||||
match self.code_hash {
|
||||
Some(SHA3_EMPTY) | None if 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,
|
||||
@@ -163,16 +172,16 @@ impl Account {
|
||||
!self.code_cache.is_empty() || (self.code_cache.is_empty() && self.code_hash == Some(SHA3_EMPTY))
|
||||
}
|
||||
|
||||
/// Provide a database to lookup `code_hash`. Should not be called if it is a contract without code.
|
||||
/// Provide a database to get `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.lookup(h) {
|
||||
Some(ref h) => match db.get(h) {
|
||||
Some(x) => { self.code_cache = x.to_vec(); true },
|
||||
_ => {
|
||||
warn!("Failed reverse lookup of {}", h);
|
||||
warn!("Failed reverse get of {}", h);
|
||||
false
|
||||
},
|
||||
},
|
||||
@@ -206,7 +215,10 @@ 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);
|
||||
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.");
|
||||
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,
|
||||
@@ -261,7 +273,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(x!(69), x!(0));
|
||||
let mut a = Account::new_contract(69.into(), 0.into());
|
||||
a.set_storage(H256::from(&U256::from(0x00u64)), H256::from(&U256::from(0x1234u64)));
|
||||
a.commit_storage(&mut db);
|
||||
a.init_code(vec![]);
|
||||
@@ -281,7 +293,7 @@ mod tests {
|
||||
let mut db = AccountDBMut::new(&mut db, &Address::new());
|
||||
|
||||
let rlp = {
|
||||
let mut a = Account::new_contract(x!(69), x!(0));
|
||||
let mut a = Account::new_contract(69.into(), 0.into());
|
||||
a.init_code(vec![0x55, 0x44, 0xffu8]);
|
||||
a.commit_code(&mut db);
|
||||
a.rlp()
|
||||
@@ -296,10 +308,10 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn commit_storage() {
|
||||
let mut a = Account::new_contract(x!(69), x!(0));
|
||||
let mut a = Account::new_contract(69.into(), 0.into());
|
||||
let mut db = MemoryDB::new();
|
||||
let mut db = AccountDBMut::new(&mut db, &Address::new());
|
||||
a.set_storage(x!(0), x!(0x1234));
|
||||
a.set_storage(0.into(), 0x1234.into());
|
||||
assert_eq!(a.storage_root(), None);
|
||||
a.commit_storage(&mut db);
|
||||
assert_eq!(a.storage_root().unwrap().hex(), "c57e1afb758b07f8d2c8f13a3b6e44fa5ff94ab266facc5a4fd3f062426e50b2");
|
||||
@@ -307,21 +319,21 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn commit_remove_commit_storage() {
|
||||
let mut a = Account::new_contract(x!(69), x!(0));
|
||||
let mut a = Account::new_contract(69.into(), 0.into());
|
||||
let mut db = MemoryDB::new();
|
||||
let mut db = AccountDBMut::new(&mut db, &Address::new());
|
||||
a.set_storage(x!(0), x!(0x1234));
|
||||
a.set_storage(0.into(), 0x1234.into());
|
||||
a.commit_storage(&mut db);
|
||||
a.set_storage(x!(1), x!(0x1234));
|
||||
a.set_storage(1.into(), 0x1234.into());
|
||||
a.commit_storage(&mut db);
|
||||
a.set_storage(x!(1), x!(0));
|
||||
a.set_storage(1.into(), 0.into());
|
||||
a.commit_storage(&mut db);
|
||||
assert_eq!(a.storage_root().unwrap().hex(), "c57e1afb758b07f8d2c8f13a3b6e44fa5ff94ab266facc5a4fd3f062426e50b2");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn commit_code() {
|
||||
let mut a = Account::new_contract(x!(69), x!(0));
|
||||
let mut a = Account::new_contract(69.into(), 0.into());
|
||||
let mut db = MemoryDB::new();
|
||||
let mut db = AccountDBMut::new(&mut db, &Address::new());
|
||||
a.init_code(vec![0x55, 0x44, 0xffu8]);
|
||||
@@ -330,6 +342,21 @@ mod tests {
|
||||
assert_eq!(a.code_hash().hex(), "af231e631776a517ca23125370d542873eca1fb4d613ed9b5d5335a46ae5b7eb");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reset_code() {
|
||||
let mut a = Account::new_contract(69.into(), 0.into());
|
||||
let mut db = MemoryDB::new();
|
||||
let mut db = AccountDBMut::new(&mut db, &Address::new());
|
||||
a.init_code(vec![0x55, 0x44, 0xffu8]);
|
||||
assert_eq!(a.code_hash(), SHA3_EMPTY);
|
||||
a.commit_code(&mut db);
|
||||
assert_eq!(a.code_hash().hex(), "af231e631776a517ca23125370d542873eca1fb4d613ed9b5d5335a46ae5b7eb");
|
||||
a.reset_code(vec![0x55]);
|
||||
assert_eq!(a.code_hash(), SHA3_EMPTY);
|
||||
a.commit_code(&mut db);
|
||||
assert_eq!(a.code_hash().hex(), "37bf2238b11b68cdc8382cece82651b59d3c3988873b6e0f33d79694aa45f1be");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rlpio() {
|
||||
let a = Account::new(U256::from(69u8), U256::from(0u8), HashMap::new(), Bytes::new());
|
||||
@@ -342,8 +369,6 @@ 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");
|
||||
assert_eq!(a.balance(), &U256::from(69u8));
|
||||
@@ -354,8 +379,6 @@ 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");
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ impl<'db> AccountDB<'db> {
|
||||
pub fn new(db: &'db HashDB, address: &Address) -> AccountDB<'db> {
|
||||
AccountDB {
|
||||
db: db,
|
||||
address: x!(address),
|
||||
address: address.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,18 +30,18 @@ impl<'db> HashDB for AccountDB<'db>{
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn lookup(&self, key: &H256) -> Option<&[u8]> {
|
||||
fn get(&self, key: &H256) -> Option<&[u8]> {
|
||||
if key == &SHA3_NULL_RLP {
|
||||
return Some(&NULL_RLP_STATIC);
|
||||
}
|
||||
self.db.lookup(&combine_key(&self.address, key))
|
||||
self.db.get(&combine_key(&self.address, key))
|
||||
}
|
||||
|
||||
fn exists(&self, key: &H256) -> bool {
|
||||
fn contains(&self, key: &H256) -> bool {
|
||||
if key == &SHA3_NULL_RLP {
|
||||
return true;
|
||||
}
|
||||
self.db.exists(&combine_key(&self.address, key))
|
||||
self.db.contains(&combine_key(&self.address, key))
|
||||
}
|
||||
|
||||
fn insert(&mut self, _value: &[u8]) -> H256 {
|
||||
@@ -52,7 +52,7 @@ impl<'db> HashDB for AccountDB<'db>{
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn kill(&mut self, _key: &H256) {
|
||||
fn remove(&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: x!(address),
|
||||
address: address.into(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,18 +82,18 @@ impl<'db> HashDB for AccountDBMut<'db>{
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn lookup(&self, key: &H256) -> Option<&[u8]> {
|
||||
fn get(&self, key: &H256) -> Option<&[u8]> {
|
||||
if key == &SHA3_NULL_RLP {
|
||||
return Some(&NULL_RLP_STATIC);
|
||||
}
|
||||
self.db.lookup(&combine_key(&self.address, key))
|
||||
self.db.get(&combine_key(&self.address, key))
|
||||
}
|
||||
|
||||
fn exists(&self, key: &H256) -> bool {
|
||||
fn contains(&self, key: &H256) -> bool {
|
||||
if key == &SHA3_NULL_RLP {
|
||||
return true;
|
||||
}
|
||||
self.db.exists(&combine_key(&self.address, key))
|
||||
self.db.contains(&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 kill(&mut self, key: &H256) {
|
||||
fn remove(&mut self, key: &H256) {
|
||||
if key == &SHA3_NULL_RLP {
|
||||
return;
|
||||
}
|
||||
let key = combine_key(&self.address, key);
|
||||
self.db.kill(&key)
|
||||
self.db.remove(&key)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
272
ethcore/src/account_provider.rs
Normal file
272
ethcore/src/account_provider.rs
Normal file
@@ -0,0 +1,272 @@
|
||||
// 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());
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
//! Evm input params.
|
||||
use common::*;
|
||||
use ethjson;
|
||||
use types::executed::CallType;
|
||||
|
||||
/// Transaction value
|
||||
#[derive(Clone, Debug)]
|
||||
@@ -26,6 +28,15 @@ 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)]
|
||||
@@ -48,7 +59,10 @@ pub struct ActionParams {
|
||||
/// Code being executed.
|
||||
pub code: Option<Bytes>,
|
||||
/// Input data.
|
||||
pub data: Option<Bytes>
|
||||
pub data: Option<Bytes>,
|
||||
/// Type of call
|
||||
pub call_type: CallType,
|
||||
|
||||
}
|
||||
|
||||
impl Default for ActionParams {
|
||||
@@ -63,7 +77,26 @@ impl Default for ActionParams {
|
||||
gas_price: U256::zero(),
|
||||
value: ActionValue::Transfer(U256::zero()),
|
||||
code: None,
|
||||
data: None
|
||||
data: None,
|
||||
call_type: CallType::None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ethjson::vm::Transaction> for ActionParams {
|
||||
fn from(t: ethjson::vm::Transaction) -> Self {
|
||||
let address: Address = t.address.into();
|
||||
ActionParams {
|
||||
code_address: Address::new(),
|
||||
address: address,
|
||||
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()),
|
||||
call_type: match address.is_zero() { true => CallType::None, false => CallType::Call }, // TODO @debris is this correct?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
261
ethcore/src/basic_authority.rs
Normal file
261
ethcore/src/basic_authority.rs
Normal file
@@ -0,0 +1,261 @@
|
||||
// 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, _gas_ceil_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![],
|
||||
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, addr, (3141562.into(), 31415620.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());
|
||||
}
|
||||
}
|
||||
@@ -22,9 +22,10 @@ use common::*;
|
||||
use engine::*;
|
||||
use state::*;
|
||||
use verification::PreverifiedBlock;
|
||||
use trace::FlatTrace;
|
||||
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.
|
||||
@@ -37,27 +38,21 @@ 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()
|
||||
}
|
||||
|
||||
/// Get the RLP-encoding of the block without the seal.
|
||||
pub fn rlp_bytes(&self, seal: Seal) -> Bytes {
|
||||
let mut block_rlp = RlpStream::new_list(3);
|
||||
self.header.stream_rlp(&mut block_rlp, seal);
|
||||
block_rlp.append(&self.transactions);
|
||||
block_rlp.append(&self.uncles);
|
||||
block_rlp.out()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl Decodable for Block {
|
||||
fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder {
|
||||
if decoder.as_raw().len() != try!(decoder.as_rlp().payload_info()).total() {
|
||||
@@ -76,19 +71,34 @@ impl Decodable for Block {
|
||||
}
|
||||
|
||||
/// Internal type for a block's common elements.
|
||||
// TODO: rename to ExecutedBlock
|
||||
// TODO: use BareBlock
|
||||
#[derive(Debug)]
|
||||
#[derive(Clone)]
|
||||
pub struct ExecutedBlock {
|
||||
base: Block,
|
||||
|
||||
receipts: Vec<Receipt>,
|
||||
transactions_set: HashSet<H256>,
|
||||
state: State,
|
||||
traces: Option<Vec<Vec<FlatTrace>>>,
|
||||
}
|
||||
|
||||
/// 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<Vec<FlatTrace>>>,
|
||||
}
|
||||
|
||||
/// 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,30 +108,56 @@ pub struct BlockRefMut<'a> {
|
||||
/// Transaction receipts.
|
||||
pub receipts: &'a Vec<Receipt>,
|
||||
/// State.
|
||||
pub state: &'a mut State,
|
||||
pub state: &'a State,
|
||||
/// Traces.
|
||||
pub traces: &'a Option<Vec<Vec<FlatTrace>>>,
|
||||
}
|
||||
|
||||
impl ExecutedBlock {
|
||||
/// Create a new block from the given `state`.
|
||||
fn new(state: State) -> ExecutedBlock { ExecutedBlock { base: Default::default(), receipts: Default::default(), transactions_set: Default::default(), state: 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},
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a structure containing individual references to all public fields.
|
||||
pub fn fields(&mut self) -> BlockRefMut {
|
||||
pub fn fields_mut(&mut self) -> BlockRefMut {
|
||||
BlockRefMut {
|
||||
header: &self.base.header,
|
||||
header: &mut 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.
|
||||
/// Get the `ExecutedBlock` associated with this object.
|
||||
fn block(&self) -> &ExecutedBlock;
|
||||
|
||||
/// Get the base `Block` object associated with this.
|
||||
fn base(&self) -> &Block { &self.block().base }
|
||||
|
||||
/// Get the header associated with this object's block.
|
||||
fn header(&self) -> &Header { &self.block().base.header }
|
||||
|
||||
@@ -134,10 +170,19 @@ 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<Vec<FlatTrace>>> { &self.block().traces }
|
||||
|
||||
/// Get all uncles in this block.
|
||||
fn uncles(&self) -> &Vec<Header> { &self.block().base.uncles }
|
||||
}
|
||||
|
||||
/// Trait for a object that has a state database.
|
||||
pub trait Drain {
|
||||
/// Drop this object and return the underlieing database.
|
||||
fn drain(self) -> Box<JournalDB>;
|
||||
}
|
||||
|
||||
impl IsBlock for ExecutedBlock {
|
||||
fn block(&self) -> &ExecutedBlock { self }
|
||||
}
|
||||
@@ -149,32 +194,58 @@ impl IsBlock for ExecutedBlock {
|
||||
pub struct OpenBlock<'x> {
|
||||
block: ExecutedBlock,
|
||||
engine: &'x Engine,
|
||||
vm_factory: &'x EvmFactory,
|
||||
last_hashes: LastHashes,
|
||||
}
|
||||
|
||||
/// 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,
|
||||
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> {
|
||||
/// 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 {
|
||||
#[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,
|
||||
author: Address,
|
||||
gas_range_target: (U256, U256),
|
||||
extra_data: Bytes,
|
||||
) -> Result<Self, Error> {
|
||||
let state = try!(State::from_existing(db, parent.state_root().clone(), engine.account_start_nonce()));
|
||||
let mut r = OpenBlock {
|
||||
block: ExecutedBlock::new(State::from_existing(db, parent.state_root().clone(), engine.account_start_nonce())),
|
||||
block: ExecutedBlock::new(state, tracing),
|
||||
engine: engine,
|
||||
vm_factory: vm_factory,
|
||||
last_hashes: last_hashes,
|
||||
};
|
||||
|
||||
@@ -185,9 +256,9 @@ impl<'x> OpenBlock<'x> {
|
||||
r.block.base.header.extra_data = extra_data;
|
||||
r.block.base.header.note_dirty();
|
||||
|
||||
engine.populate_from_parent(&mut r.block.base.header, parent, gas_floor_target);
|
||||
engine.populate_from_parent(&mut r.block.base.header, parent, gas_range_target.0, gas_range_target.1);
|
||||
engine.on_new_block(&mut r.block);
|
||||
r
|
||||
Ok(r)
|
||||
}
|
||||
|
||||
/// Alter the author for the block.
|
||||
@@ -247,22 +318,31 @@ 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, &t) {
|
||||
Ok(receipt) => {
|
||||
match self.block.state.apply(&env_info, self.engine, self.vm_factory, &t, self.block.traces.is_some()) {
|
||||
Ok(outcome) => {
|
||||
self.block.transactions_set.insert(h.unwrap_or_else(||t.hash()));
|
||||
self.block.base.transactions.push(t);
|
||||
self.block.receipts.push(receipt);
|
||||
let t = outcome.trace;
|
||||
self.block.traces.as_mut().map(|traces| traces.push(t));
|
||||
self.block.receipts.push(outcome.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();
|
||||
@@ -276,6 +356,28 @@ impl<'x> OpenBlock<'x> {
|
||||
ClosedBlock {
|
||||
block: s.block,
|
||||
uncle_bytes: uncle_bytes,
|
||||
last_hashes: s.last_hashes,
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -288,10 +390,40 @@ 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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
@@ -307,7 +439,7 @@ impl ClosedBlock {
|
||||
/// 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, ClosedBlock> {
|
||||
pub fn try_seal(self, engine: &Engine, seal: Vec<Bytes>) -> Result<SealedBlock, LockedBlock> {
|
||||
let mut s = self;
|
||||
s.block.base.header.set_seal(seal);
|
||||
match engine.verify_block_seal(&s.block.base.header) {
|
||||
@@ -315,9 +447,11 @@ impl ClosedBlock {
|
||||
_ => Ok(SealedBlock { block: s.block, uncle_bytes: s.uncle_bytes }),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drain for LockedBlock {
|
||||
/// Drop this object and return the underlieing database.
|
||||
pub fn drain(self) -> Box<JournalDB> { self.block.state.drop().1 }
|
||||
fn drain(self) -> Box<JournalDB> { self.block.state.drop().1 }
|
||||
}
|
||||
|
||||
impl SealedBlock {
|
||||
@@ -329,9 +463,11 @@ impl SealedBlock {
|
||||
block_rlp.append_raw(&self.uncle_bytes, 1);
|
||||
block_rlp.out()
|
||||
}
|
||||
}
|
||||
|
||||
impl Drain for SealedBlock {
|
||||
/// Drop this object and return the underlieing database.
|
||||
pub fn drain(self) -> Box<JournalDB> { self.block.state.drop().1 }
|
||||
fn drain(self) -> Box<JournalDB> { self.block.state.drop().1 }
|
||||
}
|
||||
|
||||
impl IsBlock for SealedBlock {
|
||||
@@ -339,40 +475,80 @@ impl IsBlock for SealedBlock {
|
||||
}
|
||||
|
||||
/// Enact the block given by block header, transactions and uncles
|
||||
pub fn enact(header: &Header, transactions: &[SignedTransaction], uncles: &[Header], engine: &Engine, db: Box<JournalDB>, parent: &Header, last_hashes: LastHashes) -> Result<ClosedBlock, Error> {
|
||||
#[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,
|
||||
vm_factory: &EvmFactory
|
||||
) -> Result<LockedBlock, Error> {
|
||||
{
|
||||
if ::log::max_log_level() >= ::log::LogLevel::Trace {
|
||||
let s = State::from_existing(db.spawn(), parent.state_root().clone(), engine.account_start_nonce());
|
||||
let s = try!(State::from_existing(db.boxed_clone(), 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 = OpenBlock::new(engine, db, parent, last_hashes, header.author().clone(), x!(3141562), header.extra_data().clone());
|
||||
let mut b = try!(OpenBlock::new(engine, vm_factory, tracing, db, parent, last_hashes, Address::new(), (3141562.into(), 31415620.into()), vec![]));
|
||||
b.set_difficulty(*header.difficulty());
|
||||
b.set_gas_limit(*header.gas_limit());
|
||||
b.set_timestamp(header.timestamp());
|
||||
b.set_author(header.author().clone());
|
||||
b.set_extra_data(header.extra_data().clone()).unwrap_or_else(|e| warn!("Couldn't set extradata: {}. Ignoring.", e));
|
||||
for t in transactions { try!(b.push_transaction(t.clone(), None)); }
|
||||
for u in uncles { try!(b.push_uncle(u.clone())); }
|
||||
Ok(b.close())
|
||||
Ok(b.close_and_lock())
|
||||
}
|
||||
|
||||
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header
|
||||
pub fn enact_bytes(block_bytes: &[u8], engine: &Engine, db: Box<JournalDB>, parent: &Header, last_hashes: LastHashes) -> Result<ClosedBlock, Error> {
|
||||
#[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,
|
||||
vm_factory: &EvmFactory
|
||||
) -> Result<LockedBlock, Error> {
|
||||
let block = BlockView::new(block_bytes);
|
||||
let header = block.header();
|
||||
enact(&header, &block.transactions(), &block.uncles(), engine, db, parent, last_hashes)
|
||||
enact(&header, &block.transactions(), &block.uncles(), engine, tracing, db, parent, last_hashes, vm_factory)
|
||||
}
|
||||
|
||||
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header
|
||||
pub fn enact_verified(block: &PreverifiedBlock, engine: &Engine, db: Box<JournalDB>, parent: &Header, last_hashes: LastHashes) -> Result<ClosedBlock, Error> {
|
||||
#[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,
|
||||
vm_factory: &EvmFactory
|
||||
) -> Result<LockedBlock, Error> {
|
||||
let view = BlockView::new(&block.bytes);
|
||||
enact(&block.header, &block.transactions, &view.uncles(), engine, db, parent, last_hashes)
|
||||
enact(&block.header, &block.transactions, &view.uncles(), engine, tracing, db, parent, last_hashes, vm_factory)
|
||||
}
|
||||
|
||||
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header. Seal the block aferwards
|
||||
pub fn enact_and_seal(block_bytes: &[u8], engine: &Engine, db: Box<JournalDB>, parent: &Header, last_hashes: LastHashes) -> Result<SealedBlock, Error> {
|
||||
#[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,
|
||||
vm_factory: &EvmFactory
|
||||
) -> Result<SealedBlock, Error> {
|
||||
let header = BlockView::new(block_bytes).header_view();
|
||||
Ok(try!(try!(enact_bytes(block_bytes, engine, db, parent, last_hashes)).seal(engine, header.seal())))
|
||||
Ok(try!(try!(enact_bytes(block_bytes, engine, tracing, db, parent, last_hashes, vm_factory)).seal(engine, header.seal())))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -380,39 +556,43 @@ mod tests {
|
||||
use tests::helpers::*;
|
||||
use super::*;
|
||||
use common::*;
|
||||
use engine::*;
|
||||
|
||||
#[test]
|
||||
fn open_block() {
|
||||
use spec::*;
|
||||
let engine = Spec::new_test().to_engine().unwrap();
|
||||
let genesis_header = engine.spec().genesis_header();
|
||||
let spec = Spec::new_test();
|
||||
let engine = &spec.engine;
|
||||
let genesis_header = spec.genesis_header();
|
||||
let mut db_result = get_temp_journal_db();
|
||||
let mut db = db_result.take();
|
||||
engine.spec().ensure_db_good(db.as_hashdb_mut());
|
||||
spec.ensure_db_good(db.as_hashdb_mut());
|
||||
let last_hashes = vec![genesis_header.hash()];
|
||||
let b = OpenBlock::new(engine.deref(), db, &genesis_header, last_hashes, Address::zero(), x!(3141562), vec![]);
|
||||
let b = b.close();
|
||||
let vm_factory = Default::default();
|
||||
let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
|
||||
let b = b.close_and_lock();
|
||||
let _ = b.seal(engine.deref(), vec![]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn enact_block() {
|
||||
use spec::*;
|
||||
let engine = Spec::new_test().to_engine().unwrap();
|
||||
let genesis_header = engine.spec().genesis_header();
|
||||
let spec = Spec::new_test();
|
||||
let engine = &spec.engine;
|
||||
let genesis_header = spec.genesis_header();
|
||||
|
||||
let mut db_result = get_temp_journal_db();
|
||||
let mut db = db_result.take();
|
||||
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();
|
||||
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()], Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap()
|
||||
.close_and_lock().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();
|
||||
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();
|
||||
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()], &Default::default()).unwrap();
|
||||
|
||||
assert_eq!(e.rlp_bytes(), orig_bytes);
|
||||
|
||||
@@ -424,28 +604,30 @@ mod tests {
|
||||
#[test]
|
||||
fn enact_block_with_uncle() {
|
||||
use spec::*;
|
||||
let engine = Spec::new_test().to_engine().unwrap();
|
||||
let genesis_header = engine.spec().genesis_header();
|
||||
let spec = Spec::new_test();
|
||||
let engine = &spec.engine;
|
||||
let genesis_header = spec.genesis_header();
|
||||
|
||||
let mut db_result = get_temp_journal_db();
|
||||
let mut db = db_result.take();
|
||||
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![]);
|
||||
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()], Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
|
||||
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().seal(engine.deref(), vec![]).unwrap();
|
||||
|
||||
let b = open_block.close_and_lock().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();
|
||||
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();
|
||||
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()], &Default::default()).unwrap();
|
||||
|
||||
let bytes = e.rlp_bytes();
|
||||
assert_eq!(bytes, orig_bytes);
|
||||
|
||||
@@ -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>,
|
||||
@@ -116,6 +116,7 @@ struct VerifyingBlock {
|
||||
}
|
||||
|
||||
struct QueueSignal {
|
||||
deleting: Arc<AtomicBool>,
|
||||
signalled: AtomicBool,
|
||||
message_channel: IoChannel<NetSyncMessage>,
|
||||
}
|
||||
@@ -123,10 +124,18 @@ struct QueueSignal {
|
||||
impl QueueSignal {
|
||||
#[cfg_attr(feature="dev", allow(bool_comparison))]
|
||||
fn set(&self) {
|
||||
// Do not signal when we are about to close
|
||||
if self.deleting.load(AtomicOrdering::Relaxed) {
|
||||
return;
|
||||
}
|
||||
|
||||
if self.signalled.compare_and_swap(false, true, AtomicOrdering::Relaxed) == false {
|
||||
self.message_channel.send(UserMessage(SyncMessage::BlockVerified)).expect("Error sending BlockVerified message");
|
||||
if let Err(e) = self.message_channel.send(UserMessage(SyncMessage::BlockVerified)) {
|
||||
debug!("Error sending BlockVerified message: {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn reset(&self) {
|
||||
self.signalled.store(false, AtomicOrdering::Relaxed);
|
||||
}
|
||||
@@ -150,8 +159,12 @@ impl BlockQueue {
|
||||
bad: Mutex::new(HashSet::new()),
|
||||
});
|
||||
let more_to_verify = Arc::new(Condvar::new());
|
||||
let ready_signal = Arc::new(QueueSignal { signalled: AtomicBool::new(false), message_channel: message_channel });
|
||||
let deleting = Arc::new(AtomicBool::new(false));
|
||||
let ready_signal = Arc::new(QueueSignal {
|
||||
deleting: deleting.clone(),
|
||||
signalled: AtomicBool::new(false),
|
||||
message_channel: message_channel
|
||||
});
|
||||
let empty = Arc::new(Condvar::new());
|
||||
let panic_handler = PanicHandler::new_in_arc();
|
||||
|
||||
@@ -300,17 +313,17 @@ impl BlockQueue {
|
||||
let h = header.hash();
|
||||
{
|
||||
if self.processing.read().unwrap().contains(&h) {
|
||||
return Err(x!(ImportError::AlreadyQueued));
|
||||
return Err(ImportError::AlreadyQueued.into());
|
||||
}
|
||||
|
||||
let mut bad = self.verification.bad.lock().unwrap();
|
||||
if bad.contains(&h) {
|
||||
return Err(x!(ImportError::KnownBad));
|
||||
return Err(ImportError::KnownBad.into());
|
||||
}
|
||||
|
||||
if bad.contains(&header.parent_hash) {
|
||||
bad.insert(h.clone());
|
||||
return Err(x!(ImportError::KnownBad));
|
||||
return Err(ImportError::KnownBad.into());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -431,12 +444,14 @@ impl MayPanic for BlockQueue {
|
||||
|
||||
impl Drop for BlockQueue {
|
||||
fn drop(&mut self) {
|
||||
trace!(target: "shutdown", "[BlockQueue] Closing...");
|
||||
self.clear();
|
||||
self.deleting.store(true, AtomicOrdering::Release);
|
||||
self.more_to_verify.notify_all();
|
||||
for t in self.verifiers.drain(..) {
|
||||
t.join().unwrap();
|
||||
}
|
||||
trace!(target: "shutdown", "[BlockQueue] Closed.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -451,7 +466,7 @@ mod tests {
|
||||
|
||||
fn get_test_queue() -> BlockQueue {
|
||||
let spec = get_test_spec();
|
||||
let engine = spec.to_engine().unwrap();
|
||||
let engine = spec.engine;
|
||||
BlockQueue::new(BlockQueueConfig::default(), Arc::new(engine), IoChannel::disconnected())
|
||||
}
|
||||
|
||||
@@ -459,7 +474,7 @@ mod tests {
|
||||
fn can_be_created() {
|
||||
// TODO better test
|
||||
let spec = Spec::new_test();
|
||||
let engine = spec.to_engine().unwrap();
|
||||
let engine = spec.engine;
|
||||
let _ = BlockQueue::new(BlockQueueConfig::default(), Arc::new(engine), IoChannel::disconnected());
|
||||
}
|
||||
|
||||
@@ -520,7 +535,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_mem_limit() {
|
||||
let spec = get_test_spec();
|
||||
let engine = spec.to_engine().unwrap();
|
||||
let engine = spec.engine;
|
||||
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());
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
use util::numbers::{U256,H256};
|
||||
use header::BlockNumber;
|
||||
|
||||
use util::bytes::{FromRawBytesVariable, FromBytesError, ToBytesWithMap};
|
||||
|
||||
/// Brief info about inserted block.
|
||||
#[derive(Clone)]
|
||||
pub struct BlockInfo {
|
||||
@@ -40,12 +42,55 @@ 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 {
|
||||
/// 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>,
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,40 +17,23 @@
|
||||
//! Blockchain database.
|
||||
|
||||
use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrder};
|
||||
use bloomchain as bc;
|
||||
use util::*;
|
||||
use header::*;
|
||||
use extras::*;
|
||||
use super::extras::*;
|
||||
use transaction::*;
|
||||
use views::*;
|
||||
use receipt::Receipt;
|
||||
use chainfilter::{ChainFilter, BloomIndex, FilterDataSource};
|
||||
use blockchain::block_info::{BlockInfo, BlockLocation};
|
||||
use blooms::{Bloom, BloomGroup};
|
||||
use blockchain::block_info::{BlockInfo, BlockLocation, BranchBecomingCanonChainData};
|
||||
use blockchain::best_block::BestBlock;
|
||||
use blockchain::bloom_indexer::BloomIndexer;
|
||||
use blockchain::tree_route::TreeRoute;
|
||||
use types::tree_route::TreeRoute;
|
||||
use blockchain::update::ExtrasUpdate;
|
||||
use blockchain::{CacheSize, ImportRoute};
|
||||
use blockchain::{CacheSize, ImportRoute, Config};
|
||||
use db::{Writable, Readable, CacheUpdatePolicy, Key};
|
||||
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
const LOG_BLOOMS_LEVELS: usize = 3;
|
||||
const LOG_BLOOMS_ELEMENTS_PER_INDEX: usize = 16;
|
||||
|
||||
/// Interface for querying blocks by hash and by number.
|
||||
pub trait BlockProvider {
|
||||
@@ -100,6 +83,11 @@ pub trait BlockProvider {
|
||||
self.block(&address.block_hash).and_then(|bytes| BlockView::new(&bytes).localized_transaction_at(address.index))
|
||||
}
|
||||
|
||||
/// Get transaction receipt.
|
||||
fn transaction_receipt(&self, address: &TransactionAddress) -> Option<Receipt> {
|
||||
self.block_receipts(&address.block_hash).and_then(|br| br.receipts.into_iter().nth(address.index))
|
||||
}
|
||||
|
||||
/// Get a list of transactions for a given block.
|
||||
/// Returns None if block does not exist.
|
||||
fn transactions(&self, hash: &H256) -> Option<Vec<LocalizedTransaction>> {
|
||||
@@ -123,7 +111,11 @@ pub trait BlockProvider {
|
||||
#[derive(Debug, Hash, Eq, PartialEq, Clone)]
|
||||
enum CacheID {
|
||||
Block(H256),
|
||||
Extras(ExtrasIndex, H256),
|
||||
BlockDetails(H256),
|
||||
BlockHashes(BlockNumber),
|
||||
TransactionAddresses(H256),
|
||||
BlocksBlooms(LogGroupPosition),
|
||||
BlockReceipts(H256),
|
||||
}
|
||||
|
||||
struct CacheManager {
|
||||
@@ -131,6 +123,14 @@ 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,6 +138,7 @@ 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>,
|
||||
|
||||
@@ -148,8 +149,7 @@ pub struct BlockChain {
|
||||
block_details: RwLock<HashMap<H256, BlockDetails>>,
|
||||
block_hashes: RwLock<HashMap<BlockNumber, H256>>,
|
||||
transaction_addresses: RwLock<HashMap<H256, TransactionAddress>>,
|
||||
block_logs: RwLock<HashMap<H256, BlockLogBlooms>>,
|
||||
blocks_blooms: RwLock<HashMap<H256, BlocksBlooms>>,
|
||||
blocks_blooms: RwLock<HashMap<LogGroupPosition, BloomGroup>>,
|
||||
block_receipts: RwLock<HashMap<H256, BlockReceipts>>,
|
||||
|
||||
extras_db: Database,
|
||||
@@ -157,24 +157,14 @@ 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.query_extras_exist(hash, &self.block_details)
|
||||
self.extras_db.exists_with_cache(&self.block_details, hash)
|
||||
}
|
||||
|
||||
/// Get raw block data
|
||||
@@ -204,28 +194,36 @@ impl BlockProvider for BlockChain {
|
||||
|
||||
/// Get the familial details concerning a block.
|
||||
fn block_details(&self, hash: &H256) -> Option<BlockDetails> {
|
||||
self.query_extras(hash, &self.block_details)
|
||||
self.note_used(CacheID::BlockDetails(hash.clone()));
|
||||
self.extras_db.read_with_cache(&self.block_details, hash)
|
||||
}
|
||||
|
||||
/// Get the hash of given block's number.
|
||||
fn block_hash(&self, index: BlockNumber) -> Option<H256> {
|
||||
self.query_extras(&index, &self.block_hashes)
|
||||
self.note_used(CacheID::BlockHashes(index));
|
||||
self.extras_db.read_with_cache(&self.block_hashes, &index)
|
||||
}
|
||||
|
||||
/// Get the address of transaction with given hash.
|
||||
fn transaction_address(&self, hash: &H256) -> Option<TransactionAddress> {
|
||||
self.query_extras(hash, &self.transaction_addresses)
|
||||
self.note_used(CacheID::TransactionAddresses(hash.clone()));
|
||||
self.extras_db.read_with_cache(&self.transaction_addresses, hash)
|
||||
}
|
||||
|
||||
/// Get receipts of block with given hash.
|
||||
fn block_receipts(&self, hash: &H256) -> Option<BlockReceipts> {
|
||||
self.query_extras(hash, &self.block_receipts)
|
||||
self.note_used(CacheID::BlockReceipts(hash.clone()));
|
||||
self.extras_db.read_with_cache(&self.block_receipts, hash)
|
||||
}
|
||||
|
||||
/// Returns numbers of blocks containing given bloom.
|
||||
fn blocks_with_bloom(&self, bloom: &H2048, from_block: BlockNumber, to_block: BlockNumber) -> Vec<BlockNumber> {
|
||||
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()
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,16 +249,26 @@ impl<'a> Iterator for AncestryIter<'a> {
|
||||
|
||||
impl BlockChain {
|
||||
/// Create new instance of blockchain from given Genesis
|
||||
pub fn new(config: BlockChainConfig, genesis: &[u8], path: &Path) -> BlockChain {
|
||||
pub fn new(config: Config, genesis: &[u8], path: &Path) -> BlockChain {
|
||||
// open extras db
|
||||
let mut extras_path = path.to_path_buf();
|
||||
extras_path.push("extras");
|
||||
let extras_db = Database::open_default(extras_path.to_str().unwrap()).unwrap();
|
||||
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(),
|
||||
};
|
||||
|
||||
// open blocks db
|
||||
let mut blocks_path = path.to_path_buf();
|
||||
blocks_path.push("blocks");
|
||||
let blocks_db = Database::open_default(blocks_path.to_str().unwrap()).unwrap();
|
||||
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 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()));
|
||||
@@ -268,24 +276,53 @@ 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(()),
|
||||
};
|
||||
|
||||
// load best block
|
||||
let best_block_hash = match bc.extras_db.get(b"best").unwrap() {
|
||||
Some(best) => H256::from_slice(&best),
|
||||
Some(best) => {
|
||||
let best = H256::from_slice(&best);
|
||||
let mut b = best.clone();
|
||||
let mut removed = 0;
|
||||
let mut best_num = 0;
|
||||
while !bc.blocks_db.get(&b).unwrap().is_some() {
|
||||
// track back to the best block we have in the blocks database
|
||||
let extras: BlockDetails = bc.extras_db.read(&b).unwrap();
|
||||
type DetailsKey = Key<BlockDetails, Target=H264>;
|
||||
bc.extras_db.delete(&(DetailsKey::key(&b))).unwrap();
|
||||
b = extras.parent;
|
||||
best_num = extras.number;
|
||||
removed += 1;
|
||||
}
|
||||
if b != best {
|
||||
let batch = DBTransaction::new();
|
||||
let range = (best_num + 1) as bc::Number .. (best_num + removed) as bc::Number;
|
||||
let chain = bc::group::BloomGroupChain::new(bc.blooms_config, &bc);
|
||||
let changes = chain.replace(&range, vec![]);
|
||||
for (k, v) in changes.into_iter() {
|
||||
batch.write(&LogGroupPosition::from(k), &BloomGroup::from(v));
|
||||
}
|
||||
batch.put(b"best", &b).unwrap();
|
||||
bc.extras_db.write(batch).unwrap();
|
||||
info!("Restored mismatched best block. Was: {}, new: {}", best.hex(), b.hex());
|
||||
}
|
||||
b
|
||||
}
|
||||
None => {
|
||||
// best block does not exist
|
||||
// we need to insert genesis into the cache
|
||||
@@ -303,8 +340,8 @@ impl BlockChain {
|
||||
bc.blocks_db.put(&hash, genesis).unwrap();
|
||||
|
||||
let batch = DBTransaction::new();
|
||||
batch.put_extras(&hash, &details);
|
||||
batch.put_extras(&header.number(), &hash);
|
||||
batch.write(&hash, &details);
|
||||
batch.write(&header.number(), &hash);
|
||||
batch.put(b"best", &hash).unwrap();
|
||||
bc.extras_db.write(batch).unwrap();
|
||||
|
||||
@@ -416,6 +453,7 @@ 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.
|
||||
@@ -450,43 +488,34 @@ impl BlockChain {
|
||||
/// Applies extras update.
|
||||
fn apply_update(&self, update: ExtrasUpdate) {
|
||||
let batch = DBTransaction::new();
|
||||
batch.put(b"best", &update.info.hash).unwrap();
|
||||
|
||||
{
|
||||
let mut write_details = self.block_details.write().unwrap();
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
{
|
||||
let mut write_receipts = self.block_receipts.write().unwrap();
|
||||
for (hash, receipt) in &update.block_receipts {
|
||||
batch.put_extras(hash, receipt);
|
||||
write_receipts.remove(hash);
|
||||
}
|
||||
batch.extend_with_cache(write_receipts.deref_mut(), update.block_receipts, CacheUpdatePolicy::Remove);
|
||||
}
|
||||
|
||||
{
|
||||
let mut write_blocks_blooms = self.blocks_blooms.write().unwrap();
|
||||
for (bloom_hash, blocks_bloom) in &update.blocks_blooms {
|
||||
batch.put_extras(bloom_hash, blocks_bloom);
|
||||
write_blocks_blooms.remove(bloom_hash);
|
||||
}
|
||||
batch.extend_with_cache(write_blocks_blooms.deref_mut(), update.blocks_blooms, CacheUpdatePolicy::Remove);
|
||||
}
|
||||
|
||||
// These cached values must be updated last and togeterh
|
||||
{
|
||||
let mut best_block = self.best_block.write().unwrap();
|
||||
let mut write_hashes = self.block_hashes.write().unwrap();
|
||||
let mut write_txs = self.transaction_addresses.write().unwrap();
|
||||
|
||||
// update best block
|
||||
match update.info.location {
|
||||
BlockLocation::Branch => (),
|
||||
_ => {
|
||||
batch.put(b"best", &update.info.hash).unwrap();
|
||||
let mut best_block = self.best_block.write().unwrap();
|
||||
*best_block = BestBlock {
|
||||
hash: update.info.hash,
|
||||
number: update.info.number,
|
||||
@@ -495,15 +524,11 @@ impl BlockChain {
|
||||
}
|
||||
}
|
||||
|
||||
for (number, hash) in &update.block_hashes {
|
||||
batch.put_extras(number, hash);
|
||||
write_hashes.remove(number);
|
||||
}
|
||||
let mut write_hashes = self.block_hashes.write().unwrap();
|
||||
let mut write_txs = self.transaction_addresses.write().unwrap();
|
||||
|
||||
for (hash, tx_address) in &update.transactions_addresses {
|
||||
batch.put_extras(hash, tx_address);
|
||||
write_txs.remove(hash);
|
||||
}
|
||||
batch.extend_with_cache(&mut *write_hashes, update.block_hashes, CacheUpdatePolicy::Remove);
|
||||
batch.extend_with_cache(&mut *write_txs, update.transactions_addresses, CacheUpdatePolicy::Remove);
|
||||
|
||||
// update extras database
|
||||
self.extras_db.write(batch).unwrap();
|
||||
@@ -524,6 +549,11 @@ 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();
|
||||
@@ -535,13 +565,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_map(|h| if excluded.contains(h) { None } else { self.block_header(h) })
|
||||
.filter(|h| !excluded.contains(h))
|
||||
);
|
||||
}
|
||||
Some(ret)
|
||||
}
|
||||
|
||||
/// Get inserted block info which is critical to preapre extras updates.
|
||||
/// Get inserted block info which is critical to prepare extras updates.
|
||||
fn block_info(&self, block_bytes: &[u8]) -> BlockInfo {
|
||||
let block = BlockView::new(block_bytes);
|
||||
let header = block.header_view();
|
||||
@@ -570,11 +600,11 @@ impl BlockChain {
|
||||
_ => {
|
||||
let retracted = route.blocks.iter().take(route.index).cloned().collect::<Vec<H256>>();
|
||||
|
||||
BlockLocation::BranchBecomingCanonChain {
|
||||
BlockLocation::BranchBecomingCanonChain(BranchBecomingCanonChainData {
|
||||
ancestor: route.ancestor,
|
||||
enacted: route.blocks.into_iter().skip(route.index).collect(),
|
||||
retracted: retracted.into_iter().rev().collect(),
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -595,11 +625,11 @@ impl BlockChain {
|
||||
BlockLocation::CanonChain => {
|
||||
block_hashes.insert(number, info.hash.clone());
|
||||
},
|
||||
BlockLocation::BranchBecomingCanonChain { ref ancestor, ref enacted, .. } => {
|
||||
let ancestor_number = self.block_number(ancestor).unwrap();
|
||||
BlockLocation::BranchBecomingCanonChain(ref data) => {
|
||||
let ancestor_number = self.block_number(&data.ancestor).unwrap();
|
||||
let start_number = ancestor_number + 1;
|
||||
|
||||
for (index, hash) in enacted.iter().cloned().enumerate() {
|
||||
for (index, hash) in data.enacted.iter().cloned().enumerate() {
|
||||
block_hashes.insert(start_number + index as BlockNumber, hash);
|
||||
}
|
||||
|
||||
@@ -674,44 +704,38 @@ 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<H256, BlocksBlooms> {
|
||||
fn prepare_block_blooms_update(&self, block_bytes: &[u8], info: &BlockInfo) -> HashMap<LogGroupPosition, BloomGroup> {
|
||||
let block = BlockView::new(block_bytes);
|
||||
let header = block.header_view();
|
||||
|
||||
let modified_blooms = match info.location {
|
||||
let log_blooms = match info.location {
|
||||
BlockLocation::Branch => HashMap::new(),
|
||||
BlockLocation::CanonChain => {
|
||||
ChainFilter::new(self, self.bloom_indexer.index_size(), self.bloom_indexer.levels())
|
||||
.add_bloom(&header.log_bloom(), header.number() as usize)
|
||||
let chain = bc::group::BloomGroupChain::new(self.blooms_config, self);
|
||||
chain.insert(info.number as bc::Number, Bloom::from(header.log_bloom()).into())
|
||||
},
|
||||
BlockLocation::BranchBecomingCanonChain { ref ancestor, ref enacted, .. } => {
|
||||
let ancestor_number = self.block_number(ancestor).unwrap();
|
||||
BlockLocation::BranchBecomingCanonChain(ref data) => {
|
||||
let ancestor_number = self.block_number(&data.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<H2048> = enacted.iter()
|
||||
let mut blooms: Vec<bc::Bloom> = data.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(header.log_bloom());
|
||||
blooms.push(Bloom::from(header.log_bloom()).into());
|
||||
|
||||
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)
|
||||
let chain = bc::group::BloomGroupChain::new(self.blooms_config, self);
|
||||
chain.replace(&range, blooms)
|
||||
}
|
||||
};
|
||||
|
||||
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
|
||||
})
|
||||
log_blooms.into_iter()
|
||||
.map(|p| (From::from(p.0), From::from(p.1)))
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Get best block hash.
|
||||
@@ -729,54 +753,14 @@ 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(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -805,7 +789,6 @@ 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();
|
||||
@@ -814,12 +797,11 @@ impl BlockChain {
|
||||
cache_man.in_use.remove(&id);
|
||||
match id {
|
||||
CacheID::Block(h) => { blocks.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!(),
|
||||
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); }
|
||||
}
|
||||
}
|
||||
cache_man.cache_usage.push_front(HashSet::new());
|
||||
@@ -831,7 +813,6 @@ 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();
|
||||
}
|
||||
@@ -844,11 +825,12 @@ 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, BlockChainConfig, ImportRoute};
|
||||
use blockchain::{BlockProvider, BlockChain, Config, ImportRoute};
|
||||
use tests::helpers::*;
|
||||
use devtools::*;
|
||||
use blockchain::generator::{ChainGenerator, ChainIterator, BlockFinalizer};
|
||||
@@ -864,7 +846,7 @@ mod tests {
|
||||
let first_hash = BlockView::new(&first).header_view().sha3();
|
||||
|
||||
let temp = RandomTempPath::new();
|
||||
let bc = BlockChain::new(BlockChainConfig::default(), &genesis, temp.as_path());
|
||||
let bc = BlockChain::new(Config::default(), &genesis, temp.as_path());
|
||||
|
||||
assert_eq!(bc.genesis_hash(), genesis_hash.clone());
|
||||
assert_eq!(bc.best_block_number(), 0);
|
||||
@@ -892,7 +874,7 @@ mod tests {
|
||||
let genesis_hash = BlockView::new(&genesis).header_view().sha3();
|
||||
|
||||
let temp = RandomTempPath::new();
|
||||
let bc = BlockChain::new(BlockChainConfig::default(), &genesis, temp.as_path());
|
||||
let bc = BlockChain::new(Config::default(), &genesis, temp.as_path());
|
||||
|
||||
let mut block_hashes = vec![genesis_hash.clone()];
|
||||
for _ in 0..10 {
|
||||
@@ -924,7 +906,7 @@ mod tests {
|
||||
let b5a = canon_chain.generate(&mut finalizer).unwrap();
|
||||
|
||||
let temp = RandomTempPath::new();
|
||||
let bc = BlockChain::new(BlockChainConfig::default(), &genesis, temp.as_path());
|
||||
let bc = BlockChain::new(Config::default(), &genesis, temp.as_path());
|
||||
bc.insert_block(&b1a, vec![]);
|
||||
bc.insert_block(&b1b, vec![]);
|
||||
bc.insert_block(&b2a, vec![]);
|
||||
@@ -965,7 +947,7 @@ mod tests {
|
||||
let best_block_hash = b3a_hash.clone();
|
||||
|
||||
let temp = RandomTempPath::new();
|
||||
let bc = BlockChain::new(BlockChainConfig::default(), &genesis, temp.as_path());
|
||||
let bc = BlockChain::new(Config::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![]);
|
||||
@@ -974,21 +956,25 @@ 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);
|
||||
@@ -1066,14 +1052,14 @@ mod tests {
|
||||
|
||||
let temp = RandomTempPath::new();
|
||||
{
|
||||
let bc = BlockChain::new(BlockChainConfig::default(), &genesis, temp.as_path());
|
||||
let bc = BlockChain::new(Config::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(BlockChainConfig::default(), &genesis, temp.as_path());
|
||||
let bc = BlockChain::new(Config::default(), &genesis, temp.as_path());
|
||||
assert_eq!(bc.best_block_hash(), first_hash);
|
||||
}
|
||||
}
|
||||
@@ -1126,7 +1112,7 @@ mod tests {
|
||||
let b1_hash = H256::from_str("f53f268d23a71e85c7d6d83a9504298712b84c1a2ba220441c86eeda0bf0b6e3").unwrap();
|
||||
|
||||
let temp = RandomTempPath::new();
|
||||
let bc = BlockChain::new(BlockChainConfig::default(), &genesis, temp.as_path());
|
||||
let bc = BlockChain::new(Config::default(), &genesis, temp.as_path());
|
||||
bc.insert_block(&b1, vec![]);
|
||||
|
||||
let transactions = bc.transactions(&b1_hash).unwrap();
|
||||
@@ -1157,7 +1143,7 @@ mod tests {
|
||||
let b2a = canon_chain.with_bloom(bloom_ba.clone()).generate(&mut finalizer).unwrap();
|
||||
|
||||
let temp = RandomTempPath::new();
|
||||
let bc = BlockChain::new(BlockChainConfig::default(), &genesis, temp.as_path());
|
||||
let bc = BlockChain::new(Config::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);
|
||||
@@ -1203,4 +1189,31 @@ mod tests {
|
||||
assert_eq!(blocks_b2, vec![2]);
|
||||
assert_eq!(blocks_ba, vec![3]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_best_block_update() {
|
||||
let mut canon_chain = ChainGenerator::default();
|
||||
let mut finalizer = BlockFinalizer::default();
|
||||
let genesis = canon_chain.generate(&mut finalizer).unwrap();
|
||||
|
||||
let temp = RandomTempPath::new();
|
||||
|
||||
{
|
||||
let bc = BlockChain::new(Config::default(), &genesis, temp.as_path());
|
||||
let uncle = canon_chain.fork(1).generate(&mut finalizer.fork()).unwrap();
|
||||
|
||||
// create a longer fork
|
||||
for _ in 0..5 {
|
||||
let canon_block = canon_chain.generate(&mut finalizer).unwrap();
|
||||
bc.insert_block(&canon_block, vec![]);
|
||||
}
|
||||
|
||||
assert_eq!(bc.best_block_number(), 5);
|
||||
bc.insert_block(&uncle, vec![]);
|
||||
}
|
||||
|
||||
// re-loading the blockchain should load the correct best block.
|
||||
let bc = BlockChain::new(Config::default(), &genesis, temp.as_path());
|
||||
assert_eq!(bc.best_block_number(), 5);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,102 +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 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
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -23,8 +23,6 @@ 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.
|
||||
@@ -33,5 +31,7 @@ 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.block_logs + self.blocks_blooms }
|
||||
pub fn total(&self) -> usize {
|
||||
self.blocks + self.block_details + self.transaction_addresses + self.blocks_blooms + self.block_receipts
|
||||
}
|
||||
}
|
||||
|
||||
39
ethcore/src/blockchain/config.rs
Normal file
39
ethcore/src/blockchain/config.rs
Normal file
@@ -0,0 +1,39 @@
|
||||
// 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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
243
ethcore/src/blockchain/extras.rs
Normal file
243
ethcore/src/blockchain/extras.rs
Normal file
@@ -0,0 +1,243 @@
|
||||
// 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()
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,8 @@ 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 {
|
||||
@@ -33,6 +35,7 @@ impl ImportRoute {
|
||||
ImportRoute {
|
||||
retracted: vec![],
|
||||
enacted: vec![],
|
||||
omitted: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -43,13 +46,19 @@ impl From<BlockInfo> for ImportRoute {
|
||||
BlockLocation::CanonChain => ImportRoute {
|
||||
retracted: vec![],
|
||||
enacted: vec![info.hash],
|
||||
omitted: vec![],
|
||||
},
|
||||
BlockLocation::Branch => ImportRoute::none(),
|
||||
BlockLocation::BranchBecomingCanonChain { mut enacted, retracted, .. } => {
|
||||
enacted.push(info.hash);
|
||||
BlockLocation::Branch => ImportRoute {
|
||||
retracted: vec![],
|
||||
enacted: vec![],
|
||||
omitted: vec![info.hash],
|
||||
},
|
||||
BlockLocation::BranchBecomingCanonChain(mut data) => {
|
||||
data.enacted.push(info.hash);
|
||||
ImportRoute {
|
||||
retracted: retracted,
|
||||
enacted: enacted,
|
||||
retracted: data.retracted,
|
||||
enacted: data.enacted,
|
||||
omitted: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -60,7 +69,7 @@ impl From<BlockInfo> for ImportRoute {
|
||||
mod tests {
|
||||
use util::hash::H256;
|
||||
use util::numbers::U256;
|
||||
use blockchain::block_info::{BlockInfo, BlockLocation};
|
||||
use blockchain::block_info::{BlockInfo, BlockLocation, BranchBecomingCanonChainData};
|
||||
use blockchain::ImportRoute;
|
||||
|
||||
#[test]
|
||||
@@ -68,6 +77,7 @@ mod tests {
|
||||
assert_eq!(ImportRoute::none(), ImportRoute {
|
||||
enacted: vec![],
|
||||
retracted: vec![],
|
||||
omitted: vec![],
|
||||
});
|
||||
}
|
||||
|
||||
@@ -80,7 +90,11 @@ mod tests {
|
||||
location: BlockLocation::Branch,
|
||||
};
|
||||
|
||||
assert_eq!(ImportRoute::from(info), ImportRoute::none());
|
||||
assert_eq!(ImportRoute::from(info), ImportRoute {
|
||||
retracted: vec![],
|
||||
enacted: vec![],
|
||||
omitted: vec![H256::from(U256::from(1))],
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -95,6 +109,7 @@ mod tests {
|
||||
assert_eq!(ImportRoute::from(info), ImportRoute {
|
||||
retracted: vec![],
|
||||
enacted: vec![H256::from(U256::from(1))],
|
||||
omitted: vec![],
|
||||
});
|
||||
}
|
||||
|
||||
@@ -104,16 +119,17 @@ mod tests {
|
||||
hash: H256::from(U256::from(2)),
|
||||
number: 0,
|
||||
total_difficulty: U256::from(0),
|
||||
location: BlockLocation::BranchBecomingCanonChain {
|
||||
ancestor: H256::from(U256::from(0)),
|
||||
location: BlockLocation::BranchBecomingCanonChain(BranchBecomingCanonChainData {
|
||||
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![],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,18 +16,20 @@
|
||||
|
||||
//! Blockchain database.
|
||||
|
||||
pub mod blockchain;
|
||||
mod best_block;
|
||||
mod block_info;
|
||||
mod bloom_indexer;
|
||||
pub mod blockchain;
|
||||
mod cache;
|
||||
mod tree_route;
|
||||
mod update;
|
||||
mod config;
|
||||
pub mod extras;
|
||||
mod import_route;
|
||||
mod update;
|
||||
|
||||
#[cfg(test)]
|
||||
mod generator;
|
||||
|
||||
pub use self::blockchain::{BlockProvider, BlockChain, BlockChainConfig};
|
||||
pub use self::blockchain::{BlockProvider, BlockChain};
|
||||
pub use self::cache::CacheSize;
|
||||
pub use self::tree_route::TreeRoute;
|
||||
pub use self::config::Config;
|
||||
pub use types::tree_route::TreeRoute;
|
||||
pub use self::import_route::ImportRoute;
|
||||
|
||||
@@ -2,7 +2,8 @@ use std::collections::HashMap;
|
||||
use util::numbers::H256;
|
||||
use header::BlockNumber;
|
||||
use blockchain::block_info::BlockInfo;
|
||||
use extras::{BlockDetails, BlockReceipts, TransactionAddress, BlocksBlooms};
|
||||
use blooms::BloomGroup;
|
||||
use super::extras::{BlockDetails, BlockReceipts, TransactionAddress, LogGroupPosition};
|
||||
|
||||
/// Block extras update info.
|
||||
pub struct ExtrasUpdate {
|
||||
@@ -17,5 +18,5 @@ pub struct ExtrasUpdate {
|
||||
/// Modified transaction addresses.
|
||||
pub transactions_addresses: HashMap<H256, TransactionAddress>,
|
||||
/// Modified blocks blooms.
|
||||
pub blocks_blooms: HashMap<H256, BlocksBlooms>,
|
||||
pub blocks_blooms: HashMap<LogGroupPosition, BloomGroup>,
|
||||
}
|
||||
|
||||
62
ethcore/src/blooms/bloom.rs
Normal file
62
ethcore/src/blooms/bloom.rs
Normal file
@@ -0,0 +1,62 @@
|
||||
// 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(Debug, 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
|
||||
}
|
||||
}
|
||||
74
ethcore/src/blooms/bloom_group.rs
Normal file
74
ethcore/src/blooms/bloom_group.rs
Normal file
@@ -0,0 +1,74 @@
|
||||
// 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(Debug, 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()
|
||||
}
|
||||
}
|
||||
@@ -14,27 +14,29 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Represents bloom index in cache
|
||||
use bloomchain::group as bc;
|
||||
use util::HeapSizeOf;
|
||||
|
||||
/// 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
|
||||
/// Represents `BloomGroup` position in database.
|
||||
#[derive(PartialEq, Eq, Hash, Clone, Debug)]
|
||||
pub struct GroupPosition {
|
||||
/// Bloom level.
|
||||
pub level: u8,
|
||||
/// Filter Index
|
||||
pub index: usize,
|
||||
/// Group index.
|
||||
pub index: u32,
|
||||
}
|
||||
|
||||
impl BloomIndex {
|
||||
/// Default constructor for `BloomIndex`
|
||||
pub fn new(level: u8, index: usize) -> BloomIndex {
|
||||
BloomIndex {
|
||||
level: level,
|
||||
index: index,
|
||||
impl From<bc::GroupPosition> for GroupPosition {
|
||||
fn from(p: bc::GroupPosition) -> Self {
|
||||
GroupPosition {
|
||||
level: p.level as u8,
|
||||
index: p.index as u32,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl HeapSizeOf for GroupPosition {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
0
|
||||
}
|
||||
}
|
||||
25
ethcore/src/blooms/mod.rs
Normal file
25
ethcore/src/blooms/mod.rs
Normal file
@@ -0,0 +1,25 @@
|
||||
// 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;
|
||||
@@ -18,8 +18,9 @@ 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.
|
||||
/// Definition of a contract whose implementation is built-in.
|
||||
pub struct Builtin {
|
||||
/// The gas cost of running this built-in for the given size of input data.
|
||||
pub cost: Box<Fn(usize) -> U256>, // TODO: U256 should be bignum.
|
||||
@@ -46,13 +47,12 @@ 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) -> 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)
|
||||
})
|
||||
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))
|
||||
}
|
||||
|
||||
/// Simple forwarder for cost.
|
||||
@@ -60,22 +60,15 @@ impl Builtin {
|
||||
|
||||
/// Simple forwarder for execute.
|
||||
pub fn execute(&self, input: &[u8], output: &mut[u8]) { (*self.execute)(input, output); }
|
||||
}
|
||||
|
||||
/// Create a builtin from JSON.
|
||||
///
|
||||
/// JSON must be of the form `{ "name": "identity", "linear": {"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["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);
|
||||
}
|
||||
}
|
||||
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)
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,14 +83,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) -> Option<Box<Fn(&[u8], &mut [u8])>> {
|
||||
pub fn new_builtin_exec(name: &str) -> Box<Fn(&[u8], &mut [u8])> {
|
||||
match name {
|
||||
"identity" => Some(Box::new(move|input: &[u8], output: &mut[u8]| {
|
||||
"identity" => Box::new(move|input: &[u8], output: &mut[u8]| {
|
||||
for i in 0..min(input.len(), output.len()) {
|
||||
output[i] = input[i];
|
||||
}
|
||||
})),
|
||||
"ecrecover" => Some(Box::new(move|input: &[u8], output: &mut[u8]| {
|
||||
}),
|
||||
"ecrecover" => Box::new(move|input: &[u8], output: &mut[u8]| {
|
||||
#[repr(packed)]
|
||||
#[derive(Debug)]
|
||||
struct InType {
|
||||
@@ -120,8 +113,8 @@ pub fn new_builtin_exec(name: &str) -> Option<Box<Fn(&[u8], &mut [u8])>> {
|
||||
}
|
||||
}
|
||||
}
|
||||
})),
|
||||
"sha256" => Some(Box::new(move|input: &[u8], output: &mut[u8]| {
|
||||
}),
|
||||
"sha256" => Box::new(move|input: &[u8], output: &mut[u8]| {
|
||||
let mut sha = Sha256::new();
|
||||
sha.input(input);
|
||||
if output.len() >= 32 {
|
||||
@@ -131,21 +124,23 @@ pub fn new_builtin_exec(name: &str) -> Option<Box<Fn(&[u8], &mut [u8])>> {
|
||||
sha.result(ret.as_slice_mut());
|
||||
copy_to(&ret, output);
|
||||
}
|
||||
})),
|
||||
"ripemd160" => Some(Box::new(move|input: &[u8], output: &mut[u8]| {
|
||||
}),
|
||||
"ripemd160" => 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);
|
||||
})),
|
||||
_ => None
|
||||
}),
|
||||
_ => {
|
||||
panic!("invalid builtin name {}", name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn identity() {
|
||||
let f = new_builtin_exec("identity").unwrap();
|
||||
let f = new_builtin_exec("identity");
|
||||
let i = [0u8, 1, 2, 3];
|
||||
|
||||
let mut o2 = [255u8; 2];
|
||||
@@ -165,7 +160,7 @@ fn identity() {
|
||||
#[test]
|
||||
fn sha256() {
|
||||
use rustc_serialize::hex::FromHex;
|
||||
let f = new_builtin_exec("sha256").unwrap();
|
||||
let f = new_builtin_exec("sha256");
|
||||
let i = [0u8; 0];
|
||||
|
||||
let mut o = [255u8; 32];
|
||||
@@ -184,7 +179,7 @@ fn sha256() {
|
||||
#[test]
|
||||
fn ripemd160() {
|
||||
use rustc_serialize::hex::FromHex;
|
||||
let f = new_builtin_exec("ripemd160").unwrap();
|
||||
let f = new_builtin_exec("ripemd160");
|
||||
let i = [0u8; 0];
|
||||
|
||||
let mut o = [255u8; 32];
|
||||
@@ -211,7 +206,7 @@ fn ecrecover() {
|
||||
let s = k.sign(&m).unwrap();
|
||||
println!("Signed: {}", s);*/
|
||||
|
||||
let f = new_builtin_exec("ecrecover").unwrap();
|
||||
let f = new_builtin_exec("ecrecover");
|
||||
let i = FromHex::from_hex("47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad000000000000000000000000000000000000000000000000000000000000001b650acf9d3f5f0a2c799776a1254355d5f4061762a237396a99a0e0e3fc2bcd6729514a0dacb2e623ac4abd157cb18163ff942280db4d5caad66ddf941ba12e03").unwrap();
|
||||
|
||||
let mut o = [255u8; 32];
|
||||
@@ -258,9 +253,15 @@ 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).unwrap();
|
||||
let b = Builtin::from_named_linear("identity", 10, 20);
|
||||
assert_eq!((*b.cost)(0), U256::from(10));
|
||||
assert_eq!((*b.cost)(1), U256::from(30));
|
||||
assert_eq!((*b.cost)(32), U256::from(30));
|
||||
@@ -274,9 +275,14 @@ fn from_named_linear() {
|
||||
|
||||
#[test]
|
||||
fn from_json() {
|
||||
let text = "{ \"name\": \"identity\", \"linear\": {\"base\": 10, \"word\": 20} }";
|
||||
let json = Json::from_str(text).unwrap();
|
||||
let b = Builtin::from_json(&json).unwrap();
|
||||
let b = Builtin::from(ethjson::spec::Builtin {
|
||||
name: "identity".to_owned(),
|
||||
pricing: ethjson::spec::Pricing::Linear(ethjson::spec::Linear {
|
||||
base: 10,
|
||||
word: 20,
|
||||
})
|
||||
});
|
||||
|
||||
assert_eq!((*b.cost)(0), U256::from(10));
|
||||
assert_eq!((*b.cost)(1), U256::from(30));
|
||||
assert_eq!((*b.cost)(32), U256::from(30));
|
||||
|
||||
@@ -1,739 +0,0 @@
|
||||
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
|
||||
@@ -1,197 +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/>.
|
||||
|
||||
//! 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
|
||||
}
|
||||
}
|
||||
@@ -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/>.
|
||||
|
||||
//! 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
@@ -1,283 +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::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);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,56 +16,47 @@
|
||||
|
||||
//! 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::*;
|
||||
use header::{BlockNumber};
|
||||
use error::{ImportError, ExecutionError, BlockError, ImportResult};
|
||||
use header::{BlockNumber, Header};
|
||||
use state::State;
|
||||
use spec::Spec;
|
||||
use basic_types::Seal;
|
||||
use engine::Engine;
|
||||
use views::HeaderView;
|
||||
use service::{NetSyncMessage, SyncMessage};
|
||||
use env_info::LastHashes;
|
||||
use verification::*;
|
||||
use verification;
|
||||
use verification::{PreverifiedBlock, Verifier};
|
||||
use block::*;
|
||||
use transaction::{LocalizedTransaction, SignedTransaction};
|
||||
use extras::TransactionAddress;
|
||||
use transaction::{LocalizedTransaction, SignedTransaction, Action};
|
||||
use blockchain::extras::TransactionAddress;
|
||||
use filter::Filter;
|
||||
use log_entry::LocalizedLogEntry;
|
||||
use block_queue::{BlockQueue, BlockQueueInfo};
|
||||
use blockchain::{BlockChain, BlockProvider, TreeRoute, ImportRoute};
|
||||
use client::{BlockId, TransactionId, ClientConfig, BlockChainClient};
|
||||
use client::{BlockID, TransactionID, UncleID, TraceId, ClientConfig, DatabaseCompactionProfile,
|
||||
BlockChainClient, MiningBlockChainClient, TraceFilter, CallAnalytics };
|
||||
use client::Error as ClientError;
|
||||
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;
|
||||
use trace::FlatTransactionTraces;
|
||||
|
||||
/// 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,
|
||||
}
|
||||
// re-export
|
||||
pub use types::blockchain_info::BlockChainInfo;
|
||||
pub use types::block_status::BlockStatus;
|
||||
use evm::Factory as EvmFactory;
|
||||
use miner::{Miner, MinerService};
|
||||
|
||||
/// 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
|
||||
}
|
||||
const MAX_TX_QUEUE_SIZE: usize = 4096;
|
||||
|
||||
impl fmt::Display for BlockChainInfo {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
@@ -97,15 +88,20 @@ impl ClientReport {
|
||||
|
||||
/// Blockchain database client backed by a persistent database. Owns and manages a blockchain and a block queue.
|
||||
/// Call `import_block()` to import a block asynchronously; `flush_queue()` flushes the queue.
|
||||
pub struct Client<V = CanonVerifier> where V: Verifier {
|
||||
pub struct Client {
|
||||
chain: Arc<BlockChain>,
|
||||
tracedb: Arc<TraceDB<BlockChain>>,
|
||||
engine: Arc<Box<Engine>>,
|
||||
state_db: Mutex<Box<JournalDB>>,
|
||||
block_queue: BlockQueue,
|
||||
report: RwLock<ClientReport>,
|
||||
import_lock: Mutex<()>,
|
||||
panic_handler: Arc<PanicHandler>,
|
||||
verifier: PhantomData<V>,
|
||||
verifier: Box<Verifier>,
|
||||
vm_factory: Arc<EvmFactory>,
|
||||
miner: Arc<Miner>,
|
||||
io_channel: IoChannel<NetSyncMessage>,
|
||||
queue_transactions: AtomicUsize,
|
||||
}
|
||||
|
||||
const HISTORY: u64 = 1200;
|
||||
@@ -116,49 +112,80 @@ const HISTORY: u64 = 1200;
|
||||
// of which you actually want force an upgrade.
|
||||
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, 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
|
||||
}
|
||||
|
||||
impl<V> Client<V> where V: Verifier {
|
||||
/// 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 Client {
|
||||
/// Create a new client with given spec and DB path and custom verifier.
|
||||
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();
|
||||
pub fn new(
|
||||
config: ClientConfig,
|
||||
spec: Spec,
|
||||
path: &Path,
|
||||
miner: Arc<Miner>,
|
||||
message_channel: IoChannel<NetSyncMessage>)
|
||||
-> Result<Arc<Client>, ClientError>
|
||||
{
|
||||
let path = get_db_path(path, config.pruning, spec.genesis_header().hash());
|
||||
let gb = spec.genesis_block();
|
||||
let chain = Arc::new(BlockChain::new(config.blockchain, &gb, path));
|
||||
let mut state_path = path.to_path_buf();
|
||||
state_path.push("state");
|
||||
let chain = Arc::new(BlockChain::new(config.blockchain, &gb, &path));
|
||||
let tracedb = Arc::new(try!(TraceDB::new(config.tracing, &path, chain.clone())));
|
||||
|
||||
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);
|
||||
let mut state_db_config = match config.db_cache_size {
|
||||
None => DatabaseConfig::default(),
|
||||
Some(cache_size) => DatabaseConfig::with_cache(cache_size),
|
||||
};
|
||||
|
||||
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");
|
||||
if config.db_compaction == DatabaseCompactionProfile::HDD {
|
||||
state_db_config = state_db_config.compaction(CompactionProfile::hdd());
|
||||
}
|
||||
|
||||
let block_queue = BlockQueue::new(config.queue, engine.clone(), message_channel);
|
||||
let mut state_db = journaldb::new(
|
||||
&append_path(&path, "state"),
|
||||
config.pruning,
|
||||
state_db_config
|
||||
);
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
let engine = Arc::new(spec.engine);
|
||||
|
||||
let block_queue = BlockQueue::new(config.queue, engine.clone(), message_channel.clone());
|
||||
let panic_handler = PanicHandler::new_in_arc();
|
||||
panic_handler.forward_from(&block_queue);
|
||||
|
||||
Ok(Arc::new(Client {
|
||||
let client = Client {
|
||||
chain: chain,
|
||||
tracedb: tracedb,
|
||||
engine: engine,
|
||||
state_db: Mutex::new(state_db),
|
||||
block_queue: block_queue,
|
||||
report: RwLock::new(Default::default()),
|
||||
import_lock: Mutex::new(()),
|
||||
panic_handler: panic_handler,
|
||||
verifier: PhantomData,
|
||||
}))
|
||||
verifier: verification::new(config.verifier_type),
|
||||
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.
|
||||
@@ -181,7 +208,7 @@ impl<V> Client<V> where V: Verifier {
|
||||
last_hashes
|
||||
}
|
||||
|
||||
fn check_and_close_block(&self, block: &PreverifiedBlock) -> Result<ClosedBlock, ()> {
|
||||
fn check_and_close_block(&self, block: &PreverifiedBlock) -> Result<LockedBlock, ()> {
|
||||
let engine = self.engine.deref().deref();
|
||||
let header = &block.header;
|
||||
|
||||
@@ -193,7 +220,7 @@ impl<V> Client<V> where V: Verifier {
|
||||
}
|
||||
|
||||
// Verify Block Family
|
||||
let verify_family_result = V::verify_block_family(&header, &block.bytes, engine, self.chain.deref());
|
||||
let verify_family_result = self.verifier.verify_block_family(&header, &block.bytes, engine, self.chain.deref());
|
||||
if let Err(e) = verify_family_result {
|
||||
warn!(target: "client", "Stage 3 block verification failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e);
|
||||
return Err(());
|
||||
@@ -209,25 +236,25 @@ 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().spawn();
|
||||
let db = self.state_db.lock().unwrap().boxed_clone();
|
||||
|
||||
let enact_result = enact_verified(&block, engine, db, &parent, last_hashes);
|
||||
let enact_result = enact_verified(&block, engine, self.tracedb.tracing_enabled(), db, &parent, last_hashes, &self.vm_factory);
|
||||
if let Err(e) = enact_result {
|
||||
warn!(target: "client", "Block import failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e);
|
||||
return Err(());
|
||||
};
|
||||
|
||||
// Final Verification
|
||||
let closed_block = enact_result.unwrap();
|
||||
if let Err(e) = V::verify_block_final(&header, closed_block.block().header()) {
|
||||
let locked_block = enact_result.unwrap();
|
||||
if let Err(e) = self.verifier.verify_block_final(&header, locked_block.block().header()) {
|
||||
warn!(target: "client", "Stage 4 block verification failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e);
|
||||
return Err(());
|
||||
}
|
||||
|
||||
Ok(closed_block)
|
||||
Ok(locked_block)
|
||||
}
|
||||
|
||||
fn calculate_enacted_retracted(&self, import_results: Vec<ImportRoute>) -> (Vec<H256>, Vec<H256>) {
|
||||
fn calculate_enacted_retracted(&self, import_results: &[ImportRoute]) -> (Vec<H256>, Vec<H256>) {
|
||||
fn map_to_vec(map: Vec<(H256, bool)>) -> Vec<H256> {
|
||||
map.into_iter().map(|(k, _v)| k).collect()
|
||||
}
|
||||
@@ -237,12 +264,12 @@ impl<V> Client<V> where V: Verifier {
|
||||
// could be retracted in import `k+1`. This is why to understand if after all inserts
|
||||
// the block is enacted or retracted we iterate over all routes and at the end final state
|
||||
// will be in the hashmap
|
||||
let map = import_results.into_iter().fold(HashMap::new(), |mut map, route| {
|
||||
for hash in route.enacted {
|
||||
map.insert(hash, true);
|
||||
let map = import_results.iter().fold(HashMap::new(), |mut map, route| {
|
||||
for hash in &route.enacted {
|
||||
map.insert(hash.clone(), true);
|
||||
}
|
||||
for hash in route.retracted {
|
||||
map.insert(hash, false);
|
||||
for hash in &route.retracted {
|
||||
map.insert(hash.clone(), false);
|
||||
}
|
||||
map
|
||||
});
|
||||
@@ -255,17 +282,16 @@ 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 = 128;
|
||||
let max_blocks_to_import = 64;
|
||||
|
||||
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;
|
||||
|
||||
for block in blocks {
|
||||
let header = &block.header;
|
||||
|
||||
@@ -276,28 +302,12 @@ impl<V> Client<V> where V: Verifier {
|
||||
let closed_block = self.check_and_close_block(&block);
|
||||
if let Err(_) = closed_block {
|
||||
invalid_blocks.insert(header.hash());
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
let closed_block = closed_block.unwrap();
|
||||
imported_blocks.push(header.hash());
|
||||
|
||||
// Are we committing an era?
|
||||
let ancient = if header.number() >= HISTORY {
|
||||
let n = header.number() - HISTORY;
|
||||
Some((n, self.chain.block_hash(n).unwrap()))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// Commit results
|
||||
let closed_block = closed_block.unwrap();
|
||||
let receipts = closed_block.block().receipts().clone();
|
||||
closed_block.drain()
|
||||
.commit(header.number(), &header.hash(), ancient)
|
||||
.expect("State DB commit failed.");
|
||||
|
||||
// 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);
|
||||
let route = self.commit_block(closed_block, &header.hash(), &block.bytes);
|
||||
import_results.push(route);
|
||||
|
||||
self.report.write().unwrap().accrue_block(&block);
|
||||
@@ -318,28 +328,106 @@ 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);
|
||||
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,
|
||||
enacted: enacted,
|
||||
retracted: retracted,
|
||||
})).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if self.chain_info().best_block_hash != original_best {
|
||||
io.send(NetworkIoMessage::User(SyncMessage::NewChainHead)).unwrap();
|
||||
sealed: Vec::new(),
|
||||
})).unwrap_or_else(|e| warn!("Error sending IO notification: {:?}", e));
|
||||
}
|
||||
}
|
||||
|
||||
imported
|
||||
}
|
||||
|
||||
fn commit_block<B>(&self, block: B, hash: &H256, block_data: &Bytes) -> ImportRoute where B: IsBlock + Drain {
|
||||
let number = block.header().number();
|
||||
// Are we committing an era?
|
||||
let ancient = if number >= HISTORY {
|
||||
let n = number - HISTORY;
|
||||
Some((n, self.chain.block_hash(n).unwrap()))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// Commit results
|
||||
let receipts = block.receipts().to_owned();
|
||||
let traces = block.traces().clone().unwrap_or_else(Vec::new);
|
||||
let traces: Vec<FlatTransactionTraces> = traces.into_iter()
|
||||
.map(Into::into)
|
||||
.collect();
|
||||
|
||||
//let traces = From::from(block.traces().clone().unwrap_or_else(Vec::new));
|
||||
|
||||
// CHECK! I *think* this is fine, even if the state_root is equal to another
|
||||
// already-imported block of the same number.
|
||||
// TODO: Prove it with a test.
|
||||
block.drain().commit(number, hash, ancient).expect("State DB commit failed.");
|
||||
|
||||
// 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_data, receipts);
|
||||
self.tracedb.import(TraceImportRequest {
|
||||
traces: traces.into(),
|
||||
block_hash: hash.clone(),
|
||||
block_number: number,
|
||||
enacted: route.enacted.clone(),
|
||||
retracted: route.retracted.len()
|
||||
});
|
||||
route
|
||||
}
|
||||
|
||||
/// 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 txs = transactions.iter().filter_map(|bytes| UntrustedRlp::new(&bytes).as_val().ok()).collect();
|
||||
let results = self.miner.import_external_transactions(self, txs);
|
||||
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.
|
||||
match id.clone() {
|
||||
BlockID::Pending => return self.miner.pending_state().or_else(|| Some(self.state())),
|
||||
BlockID::Latest => 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().spawn(), HeaderView::new(&self.best_block_header()).state_root(), self.engine.account_start_nonce())
|
||||
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.")
|
||||
}
|
||||
|
||||
/// Get info on the cache.
|
||||
@@ -365,80 +453,80 @@ impl<V> Client<V> where V: Verifier {
|
||||
self.chain.configure_cache(pref_cache_size, max_cache_size);
|
||||
}
|
||||
|
||||
fn block_hash(chain: &BlockChain, id: BlockId) -> Option<H256> {
|
||||
/// Look up the block number for the given block ID.
|
||||
pub 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 | BlockID::Pending => Some(self.chain.best_block_number()),
|
||||
}
|
||||
}
|
||||
|
||||
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 | BlockID::Pending => Some(chain.best_block_hash()),
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
block_hash: hash,
|
||||
index: index,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<V> BlockChainClient for Client<V> where V: Verifier {
|
||||
// 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)
|
||||
}
|
||||
impl BlockChainClient for Client {
|
||||
fn call(&self, t: &SignedTransaction, analytics: CallAnalytics) -> Result<Executed, ExecutionError> {
|
||||
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 {
|
||||
number: view.number(),
|
||||
author: view.author(),
|
||||
timestamp: view.timestamp(),
|
||||
difficulty: view.difficulty(),
|
||||
last_hashes: last_hashes,
|
||||
gas_used: U256::zero(),
|
||||
gas_limit: U256::max_value(),
|
||||
};
|
||||
// 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 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);
|
||||
|
||||
// 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> {
|
||||
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();
|
||||
for tx in transactions {
|
||||
let import = b.push_transaction(tx, None);
|
||||
if let Err(e) = import {
|
||||
trace!("Error adding transaction to block: number={}. Error: {:?}", block_number, e);
|
||||
// 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()));
|
||||
}
|
||||
}
|
||||
|
||||
// And close
|
||||
let b = b.close();
|
||||
trace!("Sealing: number={}, hash={}, diff={}",
|
||||
b.block().header().number(),
|
||||
b.hash(),
|
||||
b.block().header().difficulty()
|
||||
);
|
||||
Some(b)
|
||||
ret
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -450,13 +538,18 @@ impl<V> BlockChainClient for Client<V> where V: Verifier {
|
||||
})
|
||||
}
|
||||
|
||||
fn block(&self, id: BlockId) -> Option<Bytes> {
|
||||
fn block(&self, id: BlockID) -> Option<Bytes> {
|
||||
if let &BlockID::Pending = &id {
|
||||
if let Some(block) = self.miner.pending_block() {
|
||||
return Some(block.rlp_bytes(Seal::Without));
|
||||
}
|
||||
}
|
||||
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),
|
||||
@@ -464,15 +557,20 @@ 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> {
|
||||
if let &BlockID::Pending = &id {
|
||||
if let Some(block) = self.miner.pending_block() {
|
||||
return Some(*block.header.difficulty() + self.block_total_difficulty(BlockID::Latest).expect("blocks in chain have details; qed"));
|
||||
}
|
||||
}
|
||||
Self::block_hash(&self.chain, id).and_then(|hash| self.chain.block_details(&hash)).map(|d| d.total_difficulty)
|
||||
}
|
||||
|
||||
fn nonce(&self, address: &Address) -> U256 {
|
||||
self.state().nonce(address)
|
||||
fn nonce(&self, address: &Address, id: BlockID) -> Option<U256> {
|
||||
self.state_at(id).map(|s| s.nonce(address))
|
||||
}
|
||||
|
||||
fn block_hash(&self, id: BlockId) -> Option<H256> {
|
||||
fn block_hash(&self, id: BlockID) -> Option<H256> {
|
||||
Self::block_hash(&self.chain, id)
|
||||
}
|
||||
|
||||
@@ -480,22 +578,66 @@ impl<V> BlockChainClient for Client<V> where V: Verifier {
|
||||
self.state().code(address)
|
||||
}
|
||||
|
||||
fn balance(&self, address: &Address) -> U256 {
|
||||
self.state().balance(address)
|
||||
fn balance(&self, address: &Address, id: BlockID) -> Option<U256> {
|
||||
self.state_at(id).map(|s| s.balance(address))
|
||||
}
|
||||
|
||||
fn storage_at(&self, address: &Address, position: &H256) -> H256 {
|
||||
self.state().storage_at(address, position)
|
||||
fn storage_at(&self, address: &Address, position: &H256, id: BlockID) -> Option<H256> {
|
||||
self.state_at(id).map(|s| s.storage_at(address, position))
|
||||
}
|
||||
|
||||
fn transaction(&self, id: TransactionId) -> Option<LocalizedTransaction> {
|
||||
match id {
|
||||
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
|
||||
})
|
||||
}.and_then(|address| self.chain.transaction(&address))
|
||||
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> {
|
||||
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> {
|
||||
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));
|
||||
|
||||
match (t, self.chain.transaction_receipt(&address)) {
|
||||
(Some(tx), Some(receipt)) => {
|
||||
let block_hash = tx.block_hash.clone();
|
||||
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,
|
||||
cumulative_gas_used: receipt.gas_used,
|
||||
gas_used: receipt.gas_used - prior_gas_used,
|
||||
contract_address: match tx.action {
|
||||
Action::Call(_) => None,
|
||||
Action::Create => Some(contract_address(&tx.sender().unwrap(), &tx.nonce))
|
||||
},
|
||||
logs: receipt.logs.into_iter().enumerate().map(|(i, log)| LocalizedLogEntry {
|
||||
entry: log,
|
||||
block_hash: block_hash.clone(),
|
||||
block_number: block_number,
|
||||
transaction_hash: transaction_hash.clone(),
|
||||
transaction_index: transaction_index,
|
||||
log_index: i
|
||||
}).collect()
|
||||
})
|
||||
},
|
||||
_ => None
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn tree_route(&self, from: &H256, to: &H256) -> Option<TreeRoute> {
|
||||
@@ -505,6 +647,10 @@ 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)
|
||||
}
|
||||
@@ -517,10 +663,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(x!(ImportError::AlreadyInChain));
|
||||
return Err(ImportError::AlreadyInChain.into());
|
||||
}
|
||||
if self.block_status(BlockId::Hash(header.parent_hash())) == BlockStatus::Unknown {
|
||||
return Err(x!(BlockError::UnknownParent(header.parent_hash())));
|
||||
if self.block_status(BlockID::Hash(header.parent_hash())) == BlockStatus::Unknown {
|
||||
return Err(BlockError::UnknownParent(header.parent_hash()).into());
|
||||
}
|
||||
}
|
||||
self.block_queue.import_block(bytes)
|
||||
@@ -544,7 +690,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
|
||||
@@ -580,7 +726,7 @@ impl<V> BlockChainClient for Client<V> where V: Verifier {
|
||||
.map(|(i, log)| LocalizedLogEntry {
|
||||
entry: log,
|
||||
block_hash: hash.clone(),
|
||||
block_number: number as usize,
|
||||
block_number: number,
|
||||
transaction_hash: hashes.get(index).cloned().unwrap_or_else(H256::new),
|
||||
transaction_index: index,
|
||||
log_index: log_index + i
|
||||
@@ -592,6 +738,132 @@ 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 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 pending_transactions(&self) -> Vec<SignedTransaction> {
|
||||
self.miner.pending_transactions()
|
||||
}
|
||||
}
|
||||
|
||||
impl MiningBlockChainClient for Client {
|
||||
fn prepare_open_block(&self, author: Address, gas_range_target: (U256, 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()),
|
||||
author,
|
||||
gas_range_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
|
||||
}
|
||||
|
||||
fn vm_factory(&self) -> &EvmFactory {
|
||||
&self.vm_factory
|
||||
}
|
||||
|
||||
fn import_sealed_block(&self, block: SealedBlock) -> ImportResult {
|
||||
let _import_lock = self.import_lock.lock();
|
||||
let _timer = PerfTimer::new("import_sealed_block");
|
||||
|
||||
let h = block.header().hash();
|
||||
let number = block.header().number();
|
||||
|
||||
let block_data = block.rlp_bytes();
|
||||
let route = self.commit_block(block, &h, &block_data);
|
||||
trace!(target: "client", "Imported sealed block #{} ({})", number, h);
|
||||
|
||||
{
|
||||
let (enacted, retracted) = self.calculate_enacted_retracted(&[route]);
|
||||
self.miner.chain_new_blocks(self, &[h.clone()], &[], &enacted, &retracted);
|
||||
|
||||
self.io_channel.send(NetworkIoMessage::User(SyncMessage::NewChainBlocks {
|
||||
imported: vec![h.clone()],
|
||||
invalid: vec![],
|
||||
enacted: enacted,
|
||||
retracted: retracted,
|
||||
sealed: vec![h.clone()],
|
||||
})).unwrap_or_else(|e| warn!("Error sending IO notification: {:?}", e));
|
||||
}
|
||||
|
||||
Ok(h)
|
||||
}
|
||||
}
|
||||
|
||||
impl MayPanic for Client {
|
||||
|
||||
@@ -15,9 +15,25 @@
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
pub use block_queue::BlockQueueConfig;
|
||||
pub use blockchain::BlockChainConfig;
|
||||
pub use blockchain::Config as BlockChainConfig;
|
||||
pub use trace::{Config as TraceConfig, Switch};
|
||||
pub use evm::VMType;
|
||||
pub use verification::VerifierType;
|
||||
use util::journaldb;
|
||||
|
||||
/// Client state db compaction profile
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum DatabaseCompactionProfile {
|
||||
/// Default compaction profile
|
||||
Default,
|
||||
/// HDD or other slow storage io compaction profile
|
||||
HDD,
|
||||
}
|
||||
|
||||
impl Default for DatabaseCompactionProfile {
|
||||
fn default() -> Self { DatabaseCompactionProfile::Default }
|
||||
}
|
||||
|
||||
/// Client configuration. Includes configs for all sub-systems.
|
||||
#[derive(Debug, Default)]
|
||||
pub struct ClientConfig {
|
||||
@@ -25,8 +41,18 @@ 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>,
|
||||
/// State db compaction profile
|
||||
pub db_compaction: DatabaseCompactionProfile,
|
||||
/// Type of block verifier used by client.
|
||||
pub verifier_type: VerifierType,
|
||||
}
|
||||
|
||||
23
ethcore/src/client/error.rs
Normal file
23
ethcore/src/client/error.rs
Normal file
@@ -0,0 +1,23 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,66 +18,124 @@
|
||||
|
||||
mod client;
|
||||
mod config;
|
||||
mod ids;
|
||||
mod error;
|
||||
mod test_client;
|
||||
mod trace;
|
||||
|
||||
pub use self::client::*;
|
||||
pub use self::config::{ClientConfig, BlockQueueConfig, BlockChainConfig};
|
||||
pub use self::ids::{BlockId, TransactionId};
|
||||
pub use self::config::{ClientConfig, DatabaseCompactionProfile, BlockQueueConfig, BlockChainConfig, Switch, VMType};
|
||||
pub use self::error::Error;
|
||||
pub use types::ids::*;
|
||||
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};
|
||||
|
||||
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::{ClosedBlock, SealedBlock};
|
||||
use header::BlockNumber;
|
||||
use block::{OpenBlock, SealedBlock};
|
||||
use header::{BlockNumber, Header};
|
||||
use transaction::{LocalizedTransaction, SignedTransaction};
|
||||
use log_entry::LocalizedLogEntry;
|
||||
use filter::Filter;
|
||||
use error::{ImportResult};
|
||||
use views::{BlockView};
|
||||
use error::{ImportResult, ExecutionError};
|
||||
use receipt::LocalizedReceipt;
|
||||
use trace::LocalizedTrace;
|
||||
use evm::Factory as EvmFactory;
|
||||
|
||||
/// 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>;
|
||||
|
||||
/// Get address nonce.
|
||||
fn nonce(&self, address: &Address) -> 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 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.
|
||||
fn balance(&self, address: &Address) -> U256;
|
||||
/// 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 value of the storage at given position.
|
||||
fn storage_at(&self, address: &Address, position: &H256) -> H256;
|
||||
/// 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 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>;
|
||||
|
||||
/// Get transaction receipt with given hash.
|
||||
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>;
|
||||
|
||||
@@ -99,22 +157,76 @@ 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>;
|
||||
/// 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>;
|
||||
|
||||
// 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>;
|
||||
/// 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;
|
||||
|
||||
/// Queue transactions for importing.
|
||||
fn queue_transactions(&self, transactions: Vec<Bytes>);
|
||||
|
||||
/// list all transactions
|
||||
fn pending_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(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Extended client interface used for mining
|
||||
pub trait MiningBlockChainClient : BlockChainClient {
|
||||
/// Returns OpenBlock prepared for closing.
|
||||
fn prepare_open_block(&self, author: Address, gas_range_target: (U256, U256), extra_data: Bytes)
|
||||
-> OpenBlock;
|
||||
|
||||
/// Returns EvmFactory.
|
||||
fn vm_factory(&self) -> &EvmFactory;
|
||||
|
||||
/// Import sealed block. Skips all verifications.
|
||||
fn import_sealed_block(&self, block: SealedBlock) -> ImportResult;
|
||||
}
|
||||
|
||||
@@ -16,19 +16,27 @@
|
||||
|
||||
//! Test client.
|
||||
|
||||
use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrder};
|
||||
use util::*;
|
||||
use transaction::{Transaction, LocalizedTransaction, SignedTransaction, Action};
|
||||
use blockchain::TreeRoute;
|
||||
use client::{BlockChainClient, BlockChainInfo, BlockStatus, BlockId, TransactionId};
|
||||
use client::{BlockChainClient, MiningBlockChainClient, BlockChainInfo, BlockStatus, BlockID,
|
||||
TransactionID, UncleID, TraceId, TraceFilter, LastHashes, CallAnalytics };
|
||||
use header::{Header as BlockHeader, BlockNumber};
|
||||
use filter::Filter;
|
||||
use log_entry::LocalizedLogEntry;
|
||||
use receipt::Receipt;
|
||||
use extras::BlockReceipts;
|
||||
use receipt::{Receipt, LocalizedReceipt};
|
||||
use blockchain::extras::BlockReceipts;
|
||||
use error::{ImportResult};
|
||||
use evm::Factory as EvmFactory;
|
||||
use miner::{Miner, MinerService};
|
||||
use spec::Spec;
|
||||
|
||||
use block_queue::BlockQueueInfo;
|
||||
use block::{SealedBlock, ClosedBlock};
|
||||
use block::{OpenBlock, SealedBlock};
|
||||
use executive::Executed;
|
||||
use error::{ExecutionError};
|
||||
use trace::LocalizedTrace;
|
||||
|
||||
/// Test client.
|
||||
pub struct TestBlockChainClient {
|
||||
@@ -44,10 +52,20 @@ 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.
|
||||
pub code: RwLock<HashMap<Address, Bytes>>,
|
||||
/// Execution result.
|
||||
pub execution_result: RwLock<Option<Executed>>,
|
||||
/// Transaction receipts.
|
||||
pub receipts: RwLock<HashMap<TransactionID, LocalizedReceipt>>,
|
||||
/// Block queue size.
|
||||
pub queue_size: AtomicUsize,
|
||||
/// Miner
|
||||
pub miner: Arc<Miner>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -80,19 +98,39 @@ 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::with_spec(Spec::new_test())),
|
||||
};
|
||||
client.add_blocks(1, EachBlockWith::Nothing); // add genesis block
|
||||
client.genesis_hash = client.last_hash.read().unwrap().clone();
|
||||
client
|
||||
}
|
||||
|
||||
/// Set the transaction receipt result
|
||||
pub fn set_transaction_receipt(&self, id: TransactionID, receipt: LocalizedReceipt) {
|
||||
self.receipts.write().unwrap().insert(id, receipt);
|
||||
}
|
||||
|
||||
/// Set the execution result.
|
||||
pub fn set_execution_result(&self, result: Executed) {
|
||||
*self.execution_result.write().unwrap() = Some(result);
|
||||
}
|
||||
|
||||
/// Set the balance of account `address` to `balance`.
|
||||
pub fn set_balance(&self, address: Address, balance: U256) {
|
||||
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);
|
||||
@@ -103,6 +141,11 @@ impl TestBlockChainClient {
|
||||
self.storage.write().unwrap().insert((address, position), value);
|
||||
}
|
||||
|
||||
/// Set block queue size for testing
|
||||
pub fn set_queue_size(&self, size: usize) {
|
||||
self.queue_size.store(size, AtomicOrder::Relaxed);
|
||||
}
|
||||
|
||||
/// Add blocks to test client.
|
||||
pub fn add_blocks(&self, count: usize, with: EachBlockWith) {
|
||||
let len = self.numbers.read().unwrap().len();
|
||||
@@ -111,6 +154,7 @@ impl TestBlockChainClient {
|
||||
header.difficulty = From::from(n);
|
||||
header.parent_hash = self.last_hash.read().unwrap().clone();
|
||||
header.number = n as BlockNumber;
|
||||
header.gas_limit = U256::from(1_000_000);
|
||||
let uncles = match with {
|
||||
EachBlockWith::Uncle | EachBlockWith::UncleAndTransaction => {
|
||||
let mut uncles = RlpStream::new_list(1);
|
||||
@@ -128,6 +172,8 @@ 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),
|
||||
@@ -140,7 +186,7 @@ impl TestBlockChainClient {
|
||||
txs.append(&signed_tx);
|
||||
txs.out()
|
||||
},
|
||||
_ => rlp::NULL_RLP.to_vec()
|
||||
_ => rlp::EMPTY_LIST_RLP.to_vec()
|
||||
};
|
||||
|
||||
let mut rlp = RlpStream::new_list(3);
|
||||
@@ -151,11 +197,23 @@ impl TestBlockChainClient {
|
||||
}
|
||||
}
|
||||
|
||||
/// TODO:
|
||||
/// Make a bad block by setting invalid extra data.
|
||||
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.parent_hash = H256::new();
|
||||
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 mut rlp = RlpStream::new_list(3);
|
||||
rlp.append(&header);
|
||||
rlp.append_raw(&rlp::NULL_RLP, 1);
|
||||
@@ -170,46 +228,91 @@ 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 | BlockID::Pending => self.numbers.read().unwrap().get(&(self.numbers.read().unwrap().len() - 1)).cloned()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl BlockChainClient for TestBlockChainClient {
|
||||
fn block_total_difficulty(&self, _id: BlockId) -> Option<U256> {
|
||||
Some(U256::zero())
|
||||
impl MiningBlockChainClient for TestBlockChainClient {
|
||||
fn prepare_open_block(&self, _author: Address, _gas_range_target: (U256, U256), _extra_data: Bytes) -> OpenBlock {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn block_hash(&self, _id: BlockId) -> Option<H256> {
|
||||
|
||||
fn vm_factory(&self) -> &EvmFactory {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn nonce(&self, _address: &Address) -> U256 {
|
||||
U256::zero()
|
||||
fn import_sealed_block(&self, _block: SealedBlock) -> ImportResult {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
impl BlockChainClient for TestBlockChainClient {
|
||||
fn call(&self, _t: &SignedTransaction, _analytics: CallAnalytics) -> Result<Executed, ExecutionError> {
|
||||
Ok(self.execution_result.read().unwrap().clone().unwrap())
|
||||
}
|
||||
|
||||
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 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 latest_nonce(&self, address: &Address) -> U256 {
|
||||
self.nonce(address, BlockID::Latest).unwrap()
|
||||
}
|
||||
|
||||
fn code(&self, address: &Address) -> Option<Bytes> {
|
||||
self.code.read().unwrap().get(address).cloned()
|
||||
}
|
||||
|
||||
fn balance(&self, address: &Address) -> U256 {
|
||||
self.balances.read().unwrap().get(address).cloned().unwrap_or_else(U256::zero)
|
||||
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 storage_at(&self, address: &Address, position: &H256) -> H256 {
|
||||
self.storage.read().unwrap().get(&(address.clone(), position.clone())).cloned().unwrap_or_else(H256::new)
|
||||
fn latest_balance(&self, address: &Address) -> U256 {
|
||||
self.balance(address, BlockID::Latest).unwrap()
|
||||
}
|
||||
|
||||
fn transaction(&self, _id: TransactionId) -> Option<LocalizedTransaction> {
|
||||
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 transaction(&self, _id: TransactionID) -> Option<LocalizedTransaction> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn blocks_with_bloom(&self, _bloom: &H2048, _from_block: BlockId, _to_block: BlockId) -> Option<Vec<BlockNumber>> {
|
||||
fn uncle(&self, _id: UncleID) -> Option<BlockHeader> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
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>> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
@@ -217,19 +320,15 @@ impl BlockChainClient for TestBlockChainClient {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn prepare_sealing(&self, _author: Address, _gas_floor_target: U256, _extra_data: Bytes, _transactions: Vec<SignedTransaction>) -> Option<ClosedBlock> {
|
||||
unimplemented!()
|
||||
fn last_hashes(&self) -> LastHashes {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn try_seal(&self, _block: ClosedBlock, _seal: Vec<Bytes>) -> Result<SealedBlock, ClosedBlock> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn block_header(&self, id: BlockId) -> Option<Bytes> {
|
||||
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);
|
||||
@@ -238,14 +337,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
|
||||
}
|
||||
}
|
||||
@@ -280,6 +379,10 @@ 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' ?
|
||||
@@ -352,7 +455,7 @@ impl BlockChainClient for TestBlockChainClient {
|
||||
|
||||
fn queue_info(&self) -> BlockQueueInfo {
|
||||
BlockQueueInfo {
|
||||
verified_queue_size: 0,
|
||||
verified_queue_size: self.queue_size.load(AtomicOrder::Relaxed),
|
||||
unverified_queue_size: 0,
|
||||
verifying_queue_size: 0,
|
||||
max_queue_size: 0,
|
||||
@@ -373,4 +476,30 @@ impl BlockChainClient for TestBlockChainClient {
|
||||
best_block_number: self.blocks.read().unwrap().len() as BlockNumber - 1,
|
||||
}
|
||||
}
|
||||
|
||||
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 queue_transactions(&self, transactions: Vec<Bytes>) {
|
||||
// import right here
|
||||
let txs = transactions.into_iter().filter_map(|bytes| UntrustedRlp::new(&bytes).as_val().ok()).collect();
|
||||
self.miner.import_external_transactions(self, txs);
|
||||
}
|
||||
|
||||
fn pending_transactions(&self) -> Vec<SignedTransaction> {
|
||||
self.miner.pending_transactions()
|
||||
}
|
||||
}
|
||||
|
||||
38
ethcore/src/client/trace.rs
Normal file
38
ethcore/src/client/trace.rs
Normal file
@@ -0,0 +1,38 @@
|
||||
|
||||
//! 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>,
|
||||
}
|
||||
@@ -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::*;
|
||||
|
||||
181
ethcore/src/db.rs
Normal file
181
ethcore/src/db.rs
Normal file
@@ -0,0 +1,181 @@
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,18 +14,20 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Consensus engine specification
|
||||
|
||||
use common::*;
|
||||
use account_provider::AccountProvider;
|
||||
use block::ExecutedBlock;
|
||||
use spec::Spec;
|
||||
use spec::CommonParams;
|
||||
use evm::Schedule;
|
||||
use evm::Factory;
|
||||
|
||||
/// A consensus mechanism for the chain. Generally either proof-of-work or proof-of-stake-based.
|
||||
/// Provides hooks into each of the major parts of block import.
|
||||
pub trait Engine : Sync + Send {
|
||||
/// The name of this engine.
|
||||
fn name(&self) -> &str;
|
||||
/// The version of this engine. Should be of the form
|
||||
/// The version of this engine. Should be of the form
|
||||
fn version(&self) -> SemanticVersion { SemanticVersion::new(0, 0, 0) }
|
||||
|
||||
/// The number of additional header fields required for this engine.
|
||||
@@ -35,37 +37,46 @@ pub trait Engine : Sync + Send {
|
||||
fn extra_info(&self, _header: &Header) -> HashMap<String, String> { HashMap::new() }
|
||||
|
||||
/// Get the general parameters of the chain.
|
||||
fn spec(&self) -> &Spec;
|
||||
|
||||
/// Get current EVM factory
|
||||
fn vm_factory(&self) -> &Factory;
|
||||
fn params(&self) -> &CommonParams;
|
||||
|
||||
/// Get the EVM schedule for the given `env_info`.
|
||||
fn schedule(&self, env_info: &EnvInfo) -> Schedule;
|
||||
|
||||
/// Builtin-contracts we would like to see in the chain.
|
||||
/// (In principle these are just hints for the engine since that has the last word on them.)
|
||||
fn builtins(&self) -> &BTreeMap<Address, Builtin>;
|
||||
|
||||
/// Some intrinsic operation parameters; by default they take their value from the `spec()`'s `engine_params`.
|
||||
fn maximum_extra_data_size(&self) -> usize { decode(&self.spec().engine_params.get("maximumExtraDataSize").unwrap()) }
|
||||
fn maximum_extra_data_size(&self) -> usize { self.params().maximum_extra_data_size }
|
||||
/// Maximum number of uncles a block is allowed to declare.
|
||||
fn maximum_uncle_count(&self) -> usize { 2 }
|
||||
/// The number of generations back that uncles can be.
|
||||
fn maximum_uncle_age(&self) -> usize { 6 }
|
||||
/// The nonce with which accounts begin.
|
||||
fn account_start_nonce(&self) -> U256 { decode(&self.spec().engine_params.get("accountStartNonce").unwrap()) }
|
||||
fn account_start_nonce(&self) -> U256 { self.params().account_start_nonce }
|
||||
|
||||
/// Block transformation functions, before the transactions.
|
||||
fn on_new_block(&self, _block: &mut ExecutedBlock) {}
|
||||
/// Block transformation functions, after the transactions.
|
||||
fn on_close_block(&self, _block: &mut ExecutedBlock) {}
|
||||
|
||||
/// Phase 1 quick block verification. Only does checks that are cheap. `block` (the header's full block)
|
||||
/// Attempt to seal the block internally.
|
||||
///
|
||||
/// If `Some` is returned, then you get a valid seal.
|
||||
///
|
||||
/// This operation is synchronous and may (quite reasonably) not be available, in which None will
|
||||
/// be returned.
|
||||
fn generate_seal(&self, _block: &ExecutedBlock, _accounts: Option<&AccountProvider>) -> Option<Vec<Bytes>> { None }
|
||||
|
||||
/// Phase 1 quick block verification. Only does checks that are cheap. `block` (the header's full block)
|
||||
/// may be provided for additional checks. Returns either a null `Ok` or a general error detailing the problem with import.
|
||||
fn verify_block_basic(&self, _header: &Header, _block: Option<&[u8]>) -> Result<(), Error> { Ok(()) }
|
||||
|
||||
/// Phase 2 verification. Perform costly checks such as transaction signatures. `block` (the header's full block)
|
||||
/// Phase 2 verification. Perform costly checks such as transaction signatures. `block` (the header's full block)
|
||||
/// may be provided for additional checks. Returns either a null `Ok` or a general error detailing the problem with import.
|
||||
fn verify_block_unordered(&self, _header: &Header, _block: Option<&[u8]>) -> Result<(), Error> { Ok(()) }
|
||||
|
||||
/// Phase 3 verification. Check block information against parent and uncles. `block` (the header's full block)
|
||||
/// Phase 3 verification. Check block information against parent and uncles. `block` (the header's full block)
|
||||
/// may be provided for additional checks. Returns either a null `Ok` or a general error detailing the problem with import.
|
||||
fn verify_block_family(&self, _header: &Header, _parent: &Header, _block: Option<&[u8]>) -> Result<(), Error> { Ok(()) }
|
||||
|
||||
@@ -85,7 +96,7 @@ pub trait Engine : Sync + Send {
|
||||
|
||||
/// Don't forget to call Super::populate_from_parent when subclassing & overriding.
|
||||
// TODO: consider including State in the params.
|
||||
fn populate_from_parent(&self, header: &mut Header, parent: &Header, _gas_floor_target: U256) {
|
||||
fn populate_from_parent(&self, header: &mut Header, parent: &Header, _gas_floor_target: U256, _gas_ceil_target: U256) {
|
||||
header.difficulty = parent.difficulty;
|
||||
header.gas_limit = parent.gas_limit;
|
||||
header.note_dirty();
|
||||
@@ -94,13 +105,13 @@ pub trait Engine : Sync + Send {
|
||||
// TODO: builtin contract routing - to do this properly, it will require removing the built-in configuration-reading logic
|
||||
// from Spec into here and removing the Spec::builtins field.
|
||||
/// Determine whether a particular address is a builtin contract.
|
||||
fn is_builtin(&self, a: &Address) -> bool { self.spec().builtins.contains_key(a) }
|
||||
fn is_builtin(&self, a: &Address) -> bool { self.builtins().contains_key(a) }
|
||||
/// Determine the code execution cost of the builtin contract with address `a`.
|
||||
/// Panics if `is_builtin(a)` is not true.
|
||||
fn cost_of_builtin(&self, a: &Address, input: &[u8]) -> U256 { self.spec().builtins.get(a).unwrap().cost(input.len()) }
|
||||
fn cost_of_builtin(&self, a: &Address, input: &[u8]) -> U256 { self.builtins().get(a).unwrap().cost(input.len()) }
|
||||
/// Execution the builtin contract `a` on `input` and return `output`.
|
||||
/// Panics if `is_builtin(a)` is not true.
|
||||
fn execute_builtin(&self, a: &Address, input: &[u8], output: &mut [u8]) { self.spec().builtins.get(a).unwrap().execute(input, output); }
|
||||
fn execute_builtin(&self, a: &Address, input: &[u8], output: &mut [u8]) { self.builtins().get(a).unwrap().execute(input, output); }
|
||||
|
||||
// TODO: sealing stuff - though might want to leave this for later.
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
use util::*;
|
||||
use header::BlockNumber;
|
||||
use ethjson;
|
||||
|
||||
/// Simple vector of hashes, should be at most 256 items large, can be smaller if being used
|
||||
/// for a block whose number is less than 257.
|
||||
@@ -46,25 +47,25 @@ impl Default for EnvInfo {
|
||||
number: 0,
|
||||
author: Address::new(),
|
||||
timestamp: 0,
|
||||
difficulty: x!(0),
|
||||
gas_limit: x!(0),
|
||||
difficulty: 0.into(),
|
||||
gas_limit: 0.into(),
|
||||
last_hashes: vec![],
|
||||
gas_used: x!(0),
|
||||
gas_used: 0.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromJson for EnvInfo {
|
||||
fn from_json(json: &Json) -> EnvInfo {
|
||||
let current_number: u64 = xjson!(&json["currentNumber"]);
|
||||
impl From<ethjson::vm::Env> for EnvInfo {
|
||||
fn from(e: ethjson::vm::Env) -> Self {
|
||||
let number = e.number.into();
|
||||
EnvInfo {
|
||||
number: current_number,
|
||||
author: xjson!(&json["currentCoinbase"]),
|
||||
difficulty: xjson!(&json["currentDifficulty"]),
|
||||
gas_limit: xjson!(&json["currentGasLimit"]),
|
||||
timestamp: xjson!(&json["currentTimestamp"]),
|
||||
last_hashes: (1..cmp::min(current_number + 1, 257)).map(|i| format!("{}", current_number - i).as_bytes().sha3()).collect(),
|
||||
gas_used: x!(0),
|
||||
number: number,
|
||||
author: e.author.into(),
|
||||
difficulty: e.difficulty.into(),
|
||||
gas_limit: e.gas_limit.into(),
|
||||
timestamp: e.timestamp.into(),
|
||||
last_hashes: (1..cmp::min(number + 1, 257)).map(|i| format!("{}", number - i).as_bytes().sha3()).collect(),
|
||||
gas_used: U256::zero(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -74,36 +75,32 @@ mod tests {
|
||||
extern crate rustc_serialize;
|
||||
|
||||
use super::*;
|
||||
use rustc_serialize::*;
|
||||
use util::from_json::FromJson;
|
||||
use util::hash::*;
|
||||
use util::numbers::U256;
|
||||
use std::str::FromStr;
|
||||
use ethjson;
|
||||
|
||||
#[test]
|
||||
fn it_serializes_form_json() {
|
||||
let env_info = EnvInfo::from_json(&json::Json::from_str(
|
||||
r#"
|
||||
{
|
||||
"currentCoinbase": "0x000000f00000000f000000000000f00000000f00",
|
||||
"currentNumber": 1112339,
|
||||
"currentDifficulty": 50000,
|
||||
"currentGasLimit" : 40000,
|
||||
"currentTimestamp" : 1100
|
||||
}
|
||||
"#
|
||||
).unwrap());
|
||||
let env_info = EnvInfo::from(ethjson::vm::Env {
|
||||
author: ethjson::hash::Address(Address::from_str("000000f00000000f000000000000f00000000f00").unwrap()),
|
||||
number: ethjson::uint::Uint(U256::from(1_112_339)),
|
||||
difficulty: ethjson::uint::Uint(U256::from(50_000)),
|
||||
gas_limit: ethjson::uint::Uint(U256::from(40_000)),
|
||||
timestamp: ethjson::uint::Uint(U256::from(1_100))
|
||||
});
|
||||
|
||||
assert_eq!(env_info.number, 1112339);
|
||||
assert_eq!(env_info.author, Address::from_str("000000f00000000f000000000000f00000000f00").unwrap());
|
||||
assert_eq!(env_info.gas_limit, x!(40000));
|
||||
assert_eq!(env_info.difficulty, x!(50000));
|
||||
assert_eq!(env_info.gas_used, x!(0));
|
||||
assert_eq!(env_info.gas_limit, 40000.into());
|
||||
assert_eq!(env_info.difficulty, 50000.into());
|
||||
assert_eq!(env_info.gas_used, 0.into());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_can_be_created_as_default() {
|
||||
let default_env_info = EnvInfo::default();
|
||||
|
||||
assert_eq!(default_env_info.difficulty, x!(0));
|
||||
assert_eq!(default_env_info.difficulty, 0.into());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,63 +19,69 @@
|
||||
use util::*;
|
||||
use header::BlockNumber;
|
||||
use basic_types::LogBloom;
|
||||
use client::Error as ClientError;
|
||||
|
||||
/// Result of executing the transaction.
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub enum ExecutionError {
|
||||
/// Returned when there gas paid for transaction execution is
|
||||
/// lower than base gas required.
|
||||
NotEnoughBaseGas {
|
||||
/// Absolute minimum gas required.
|
||||
required: U256,
|
||||
/// Gas provided.
|
||||
got: U256
|
||||
},
|
||||
/// Returned when block (gas_used + gas) > gas_limit.
|
||||
///
|
||||
/// If gas =< gas_limit, upstream may try to execute the transaction
|
||||
/// in next block.
|
||||
BlockGasLimitReached {
|
||||
/// Gas limit of block for transaction.
|
||||
gas_limit: U256,
|
||||
/// Gas used in block prior to transaction.
|
||||
gas_used: U256,
|
||||
/// Amount of gas in block.
|
||||
gas: U256
|
||||
},
|
||||
/// Returned when transaction nonce does not match state nonce.
|
||||
InvalidNonce {
|
||||
/// Nonce expected.
|
||||
expected: U256,
|
||||
/// Nonce found.
|
||||
got: U256
|
||||
},
|
||||
/// Returned when cost of transaction (value + gas_price * gas) exceeds
|
||||
/// current sender balance.
|
||||
NotEnoughCash {
|
||||
/// Minimum required balance.
|
||||
required: U512,
|
||||
/// Actual balance.
|
||||
got: U512
|
||||
},
|
||||
/// Returned when internal evm error occurs.
|
||||
Internal
|
||||
}
|
||||
pub use types::executed::ExecutionError;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, PartialEq)]
|
||||
/// Errors concerning transaction processing.
|
||||
pub enum TransactionError {
|
||||
/// Transaction is already imported to the queue
|
||||
AlreadyImported,
|
||||
/// Transaction is not valid anymore (state already has higher nonce)
|
||||
Old,
|
||||
/// Transaction has too low fee
|
||||
/// (there is already a transaction with the same sender-nonce but higher gas price)
|
||||
TooCheapToReplace,
|
||||
/// Transaction was not imported to the queue because limit has been reached.
|
||||
LimitReached,
|
||||
/// Transaction's gas price is below threshold.
|
||||
InsufficientGasPrice {
|
||||
/// Minimal expected gas price
|
||||
minimal: U256,
|
||||
/// Transaction gas price
|
||||
got: U256
|
||||
got: U256,
|
||||
},
|
||||
/// Sender doesn't have enough funds to pay for this transaction
|
||||
InsufficientBalance {
|
||||
/// Senders balance
|
||||
balance: U256,
|
||||
/// Transaction cost
|
||||
cost: U256,
|
||||
},
|
||||
/// Transactions gas is higher then current gas limit
|
||||
GasLimitExceeded {
|
||||
/// Current gas limit
|
||||
limit: U256,
|
||||
/// Declared transaction gas
|
||||
got: U256,
|
||||
},
|
||||
/// Transaction's gas limit (aka gas) is invalid.
|
||||
InvalidGasLimit(OutOfBounds<U256>),
|
||||
}
|
||||
|
||||
impl fmt::Display for TransactionError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
use self::TransactionError::*;
|
||||
let msg = match *self {
|
||||
AlreadyImported => "Already imported".into(),
|
||||
Old => "No longer valid".into(),
|
||||
TooCheapToReplace => "Gas price too low to replace".into(),
|
||||
LimitReached => "Transaction limit reached".into(),
|
||||
InsufficientGasPrice { minimal, got } =>
|
||||
format!("Insufficient gas price. Min={}, Given={}", minimal, got),
|
||||
InsufficientBalance { balance, cost } =>
|
||||
format!("Insufficient balance for transaction. Balance={}, Cost={}",
|
||||
balance, cost),
|
||||
GasLimitExceeded { limit, got } =>
|
||||
format!("Gas limit exceeded. Limit={}, Given={}", limit, got),
|
||||
InvalidGasLimit(ref err) => format!("Invalid gas limit. {}", err),
|
||||
};
|
||||
|
||||
f.write_fmt(format_args!("Transaction error ({})", msg))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
/// Errors concerning block processing.
|
||||
pub enum BlockError {
|
||||
@@ -114,6 +120,8 @@ pub enum BlockError {
|
||||
MismatchedH256SealElement(Mismatch<H256>),
|
||||
/// Proof-of-work aspect of seal, which we assume is a 256-bit value, is invalid.
|
||||
InvalidProofOfWork(OutOfBounds<U256>),
|
||||
/// Some low-level aspect of the seal is incorrect.
|
||||
InvalidSeal,
|
||||
/// Gas limit header field is invalid.
|
||||
InvalidGasLimit(OutOfBounds<U256>),
|
||||
/// Receipts trie root header field is invalid.
|
||||
@@ -135,7 +143,44 @@ pub enum BlockError {
|
||||
UnknownUncleParent(H256),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
impl fmt::Display for BlockError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
use self::BlockError::*;
|
||||
|
||||
let msg = match *self {
|
||||
TooManyUncles(ref oob) => format!("Block has too many uncles. {}", oob),
|
||||
ExtraDataOutOfBounds(ref oob) => format!("Extra block data too long. {}", oob),
|
||||
InvalidSealArity(ref mis) => format!("Block seal in incorrect format: {}", mis),
|
||||
TooMuchGasUsed(ref oob) => format!("Block has too much gas used. {}", oob),
|
||||
InvalidUnclesHash(ref mis) => format!("Block has invalid uncles hash: {}", mis),
|
||||
UncleTooOld(ref oob) => format!("Uncle block is too old. {}", oob),
|
||||
UncleIsBrother(ref oob) => format!("Uncle from same generation as block. {}", oob),
|
||||
UncleInChain(ref hash) => format!("Uncle {} already in chain", hash),
|
||||
UncleParentNotInChain(ref hash) => format!("Uncle {} has a parent not in the chain", hash),
|
||||
InvalidStateRoot(ref mis) => format!("Invalid state root in header: {}", mis),
|
||||
InvalidGasUsed(ref mis) => format!("Invalid gas used in header: {}", mis),
|
||||
InvalidTransactionsRoot(ref mis) => format!("Invalid transactions root in header: {}", mis),
|
||||
DifficultyOutOfBounds(ref oob) => format!("Invalid block difficulty: {}", oob),
|
||||
InvalidDifficulty(ref mis) => format!("Invalid block difficulty: {}", mis),
|
||||
MismatchedH256SealElement(ref mis) => format!("Seal element out of bounds: {}", mis),
|
||||
InvalidProofOfWork(ref oob) => format!("Block has invalid PoW: {}", oob),
|
||||
InvalidSeal => "Block has invalid seal.".into(),
|
||||
InvalidGasLimit(ref oob) => format!("Invalid gas limit: {}", oob),
|
||||
InvalidReceiptsRoot(ref mis) => format!("Invalid receipts trie root in header: {}", mis),
|
||||
InvalidTimestamp(ref oob) => format!("Invalid timestamp in header: {}", oob),
|
||||
InvalidLogBloom(ref oob) => format!("Invalid log bloom in header: {}", oob),
|
||||
InvalidParentHash(ref mis) => format!("Invalid parent hash: {}", mis),
|
||||
InvalidNumber(ref mis) => format!("Invalid number in header: {}", mis),
|
||||
RidiculousNumber(ref oob) => format!("Implausible block number. {}", oob),
|
||||
UnknownParent(ref hash) => format!("Unknown parent: {}", hash),
|
||||
UnknownUncleParent(ref hash) => format!("Unknown uncle parent: {}", hash),
|
||||
};
|
||||
|
||||
f.write_fmt(format_args!("Block error ({})", msg))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
/// Import to the block queue result
|
||||
pub enum ImportError {
|
||||
/// Already in the block chain.
|
||||
@@ -146,9 +191,23 @@ pub enum ImportError {
|
||||
KnownBad,
|
||||
}
|
||||
|
||||
impl fmt::Display for ImportError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let msg = match *self {
|
||||
ImportError::AlreadyInChain => "block already in chain",
|
||||
ImportError::AlreadyQueued => "block already in the block queue",
|
||||
ImportError::KnownBad => "block known to be bad",
|
||||
};
|
||||
|
||||
f.write_fmt(format_args!("Block import error ({})", msg))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
/// General error type which should be capable of representing all errors in ethcore.
|
||||
pub enum Error {
|
||||
/// Client configuration error.
|
||||
Client(ClientError),
|
||||
/// Error concerning a utility.
|
||||
Util(UtilError),
|
||||
/// Error concerning block processing.
|
||||
@@ -165,11 +224,37 @@ pub enum Error {
|
||||
PowHashInvalid,
|
||||
/// The value of the nonce or mishash is invalid.
|
||||
PowInvalid,
|
||||
/// Error concerning TrieDBs
|
||||
Trie(TrieError),
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Error::Client(ref err) => f.write_fmt(format_args!("{}", err)),
|
||||
Error::Util(ref err) => f.write_fmt(format_args!("{}", err)),
|
||||
Error::Block(ref err) => f.write_fmt(format_args!("{}", err)),
|
||||
Error::Execution(ref err) => f.write_fmt(format_args!("{}", err)),
|
||||
Error::Transaction(ref err) => f.write_fmt(format_args!("{}", err)),
|
||||
Error::Import(ref err) => f.write_fmt(format_args!("{}", err)),
|
||||
Error::UnknownEngineName(ref name) =>
|
||||
f.write_fmt(format_args!("Unknown engine name ({})", name)),
|
||||
Error::PowHashInvalid => f.write_str("Invalid or out of date PoW hash."),
|
||||
Error::PowInvalid => f.write_str("Invalid nonce or mishash"),
|
||||
Error::Trie(ref err) => f.write_fmt(format_args!("{}", err)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Result of import block operation.
|
||||
pub type ImportResult = Result<H256, Error>;
|
||||
|
||||
impl From<ClientError> for Error {
|
||||
fn from(err: ClientError) -> Error {
|
||||
Error::Client(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TransactionError> for Error {
|
||||
fn from(err: TransactionError) -> Error {
|
||||
Error::Transaction(err)
|
||||
@@ -218,6 +303,12 @@ impl From<IoError> for Error {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TrieError> for Error {
|
||||
fn from(err: TrieError) -> Error {
|
||||
Error::Trie(err)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: uncomment below once https://github.com/rust-lang/rust/issues/27336 sorted.
|
||||
/*#![feature(concat_idents)]
|
||||
macro_rules! assimilate {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user