Merge branch 'master' into sync-svc
This commit is contained in:
commit
be25e930e5
18
.travis.yml
18
.travis.yml
@ -1,6 +1,7 @@
|
|||||||
sudo: required
|
sudo: required
|
||||||
dist: trusty
|
dist: trusty
|
||||||
language: rust
|
language: rust
|
||||||
|
|
||||||
branches:
|
branches:
|
||||||
only:
|
only:
|
||||||
- master
|
- master
|
||||||
@ -51,14 +52,15 @@ addons:
|
|||||||
|
|
||||||
install:
|
install:
|
||||||
- rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && (cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`) && source ~/.nvm/nvm.sh && nvm install $TRAVIS_NODE_VERSION
|
- rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && (cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`) && source ~/.nvm/nvm.sh && nvm install $TRAVIS_NODE_VERSION
|
||||||
- (true && [ "$RUN_COVERAGE" = "false" ]) ||
|
- ([ "$RUN_COVERAGE" = "false" ]) || (test -x $KCOV_CMD) || (
|
||||||
(wget https://github.com/SimonKagstrom/kcov/archive/master.tar.gz &&
|
wget https://github.com/SimonKagstrom/kcov/archive/master.tar.gz &&
|
||||||
tar xzf master.tar.gz &&
|
tar xzf master.tar.gz &&
|
||||||
mkdir -p kcov-master/build &&
|
mkdir -p kcov-master/build &&
|
||||||
cd kcov-master/build &&
|
cd kcov-master/build &&
|
||||||
cmake .. &&
|
cmake .. &&
|
||||||
make && make install DESTDIR=../tmp &&
|
make && make install DESTDIR=../tmp &&
|
||||||
cd)
|
cd
|
||||||
|
)
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- if [ "$RUN_TESTS" = "true" ]; then ./test.sh; fi
|
- if [ "$RUN_TESTS" = "true" ]; then ./test.sh; fi
|
||||||
|
15
Cargo.lock
generated
15
Cargo.lock
generated
@ -21,6 +21,7 @@ dependencies = [
|
|||||||
"ethsync 1.3.0",
|
"ethsync 1.3.0",
|
||||||
"fdlimit 0.1.0",
|
"fdlimit 0.1.0",
|
||||||
"hyper 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hyper 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"isatty 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"json-ipc-server 0.2.4 (git+https://github.com/ethcore/json-ipc-server.git)",
|
"json-ipc-server 0.2.4 (git+https://github.com/ethcore/json-ipc-server.git)",
|
||||||
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -586,6 +587,16 @@ dependencies = [
|
|||||||
"xmltree 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"xmltree 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "isatty"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itertools"
|
name = "itertools"
|
||||||
version = "0.4.13"
|
version = "0.4.13"
|
||||||
@ -1068,7 +1079,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "rocksdb"
|
name = "rocksdb"
|
||||||
version = "0.4.5"
|
version = "0.4.5"
|
||||||
source = "git+https://github.com/ethcore/rust-rocksdb#9be41e05923616dfa28741c58b22776d479751e6"
|
source = "git+https://github.com/ethcore/rust-rocksdb#6472a9dce16c267a3acec2ee6fd01d1bf8de4913"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rocksdb-sys 0.3.0 (git+https://github.com/ethcore/rust-rocksdb)",
|
"rocksdb-sys 0.3.0 (git+https://github.com/ethcore/rust-rocksdb)",
|
||||||
@ -1077,7 +1088,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "rocksdb-sys"
|
name = "rocksdb-sys"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
source = "git+https://github.com/ethcore/rust-rocksdb#9be41e05923616dfa28741c58b22776d479751e6"
|
source = "git+https://github.com/ethcore/rust-rocksdb#6472a9dce16c267a3acec2ee6fd01d1bf8de4913"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gcc 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gcc 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -24,6 +24,7 @@ semver = "0.2"
|
|||||||
ansi_term = "0.7"
|
ansi_term = "0.7"
|
||||||
lazy_static = "0.2"
|
lazy_static = "0.2"
|
||||||
regex = "0.1"
|
regex = "0.1"
|
||||||
|
isatty = "0.1"
|
||||||
ctrlc = { git = "https://github.com/ethcore/rust-ctrlc.git" }
|
ctrlc = { git = "https://github.com/ethcore/rust-ctrlc.git" }
|
||||||
fdlimit = { path = "util/fdlimit" }
|
fdlimit = { path = "util/fdlimit" }
|
||||||
ethcore = { path = "ethcore" }
|
ethcore = { path = "ethcore" }
|
||||||
|
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 } } } }
|
||||||
|
}
|
||||||
|
}
|
26728
ethcore/res/ethereum/frontier-dogmatic.json
Normal file
26728
ethcore/res/ethereum/frontier-dogmatic.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -9,7 +9,127 @@
|
|||||||
"durationLimit": "0x0d",
|
"durationLimit": "0x0d",
|
||||||
"blockReward": "0x4563918244F40000",
|
"blockReward": "0x4563918244F40000",
|
||||||
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
||||||
"frontierCompatibilityModeLimit": "0x118c30"
|
"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"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -9,7 +9,127 @@
|
|||||||
"durationLimit": "0x0d",
|
"durationLimit": "0x0d",
|
||||||
"blockReward": "0x4563918244F40000",
|
"blockReward": "0x4563918244F40000",
|
||||||
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
||||||
"frontierCompatibilityModeLimit": "0x118c30"
|
"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"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1,42 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Frontier (Test)",
|
|
||||||
"engine": {
|
|
||||||
"Ethash": {
|
|
||||||
"params": {
|
|
||||||
"gasLimitBoundDivisor": "0x0400",
|
|
||||||
"minimumDifficulty": "0x020000",
|
|
||||||
"difficultyBoundDivisor": "0x0800",
|
|
||||||
"durationLimit": "0x0d",
|
|
||||||
"blockReward": "0x4563918244F40000",
|
|
||||||
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
|
||||||
"frontierCompatibilityModeLimit": "0x118c30"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"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 } } } }
|
|
||||||
}
|
|
||||||
}
|
|
@ -9,7 +9,7 @@
|
|||||||
"durationLimit": "0x0d",
|
"durationLimit": "0x0d",
|
||||||
"blockReward": "0x4563918244F40000",
|
"blockReward": "0x4563918244F40000",
|
||||||
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
||||||
"frontierCompatibilityModeLimit": 0
|
"frontierCompatibilityModeLimit": "0x0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1,42 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Homestead (Test)",
|
|
||||||
"engine": {
|
|
||||||
"Ethash": {
|
|
||||||
"params": {
|
|
||||||
"gasLimitBoundDivisor": "0x0400",
|
|
||||||
"minimumDifficulty": "0x020000",
|
|
||||||
"difficultyBoundDivisor": "0x0800",
|
|
||||||
"durationLimit": "0x0d",
|
|
||||||
"blockReward": "0x4563918244F40000",
|
|
||||||
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
|
||||||
"frontierCompatibilityModeLimit": 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"params": {
|
|
||||||
"accountStartNonce": "0x00",
|
|
||||||
"maximumExtraDataSize": "0x20",
|
|
||||||
"minGasLimit": "0x1388",
|
|
||||||
"networkID" : "0x1"
|
|
||||||
},
|
|
||||||
"genesis": {
|
|
||||||
"seal": {
|
|
||||||
"ethereum": {
|
|
||||||
"nonce": "0x0000000000000042",
|
|
||||||
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"difficulty": "0x400000000",
|
|
||||||
"author": "0x0000000000000000000000000000000000000000",
|
|
||||||
"timestamp": "0x00",
|
|
||||||
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
||||||
"extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa",
|
|
||||||
"gasLimit": "0x1388"
|
|
||||||
},
|
|
||||||
"accounts": {
|
|
||||||
"0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
|
|
||||||
"0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
|
|
||||||
"0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
|
|
||||||
"0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }
|
|
||||||
}
|
|
||||||
}
|
|
@ -8,8 +8,7 @@
|
|||||||
"difficultyBoundDivisor": "0x0800",
|
"difficultyBoundDivisor": "0x0800",
|
||||||
"durationLimit": "0x08",
|
"durationLimit": "0x08",
|
||||||
"blockReward": "0x14D1120D7B160000",
|
"blockReward": "0x14D1120D7B160000",
|
||||||
"registrar": "5e70c0bbcd5636e0f9f9316e9f8633feb64d4050",
|
"registrar": "5e70c0bbcd5636e0f9f9316e9f8633feb64d4050"
|
||||||
"frontierCompatibilityModeLimit": "0xffffffffffffffff"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -39,8 +39,18 @@ impl Block {
|
|||||||
pub fn is_good(b: &[u8]) -> bool {
|
pub fn is_good(b: &[u8]) -> bool {
|
||||||
UntrustedRlp::new(b).as_val::<Block>().is_ok()
|
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 {
|
impl Decodable for Block {
|
||||||
fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder {
|
fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder {
|
||||||
if decoder.as_raw().len() != try!(decoder.as_rlp().payload_info()).total() {
|
if decoder.as_raw().len() != try!(decoder.as_rlp().payload_info()).total() {
|
||||||
@ -140,9 +150,12 @@ impl ExecutedBlock {
|
|||||||
|
|
||||||
/// Trait for a object that is a `ExecutedBlock`.
|
/// Trait for a object that is a `ExecutedBlock`.
|
||||||
pub trait IsBlock {
|
pub trait IsBlock {
|
||||||
/// Get the block associated with this object.
|
/// Get the `ExecutedBlock` associated with this object.
|
||||||
fn block(&self) -> &ExecutedBlock;
|
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.
|
/// Get the header associated with this object's block.
|
||||||
fn header(&self) -> &Header { &self.block().base.header }
|
fn header(&self) -> &Header { &self.block().base.header }
|
||||||
|
|
||||||
@ -481,10 +494,12 @@ pub fn enact(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut b = try!(OpenBlock::new(engine, vm_factory, trie_factory, tracing, db, parent, last_hashes, header.author().clone(), (3141562.into(), 31415620.into()), header.extra_data().clone()));
|
let mut b = try!(OpenBlock::new(engine, vm_factory, trie_factory, tracing, db, parent, last_hashes, Address::new(), (3141562.into(), 31415620.into()), vec![]));
|
||||||
b.set_difficulty(*header.difficulty());
|
b.set_difficulty(*header.difficulty());
|
||||||
b.set_gas_limit(*header.gas_limit());
|
b.set_gas_limit(*header.gas_limit());
|
||||||
b.set_timestamp(header.timestamp());
|
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 t in transactions { try!(b.push_transaction(t.clone(), None)); }
|
||||||
for u in uncles { try!(b.push_uncle(u.clone())); }
|
for u in uncles { try!(b.push_uncle(u.clone())); }
|
||||||
Ok(b.close_and_lock())
|
Ok(b.close_and_lock())
|
||||||
|
@ -488,7 +488,6 @@ impl BlockChain {
|
|||||||
/// Applies extras update.
|
/// Applies extras update.
|
||||||
fn apply_update(&self, update: ExtrasUpdate) {
|
fn apply_update(&self, update: ExtrasUpdate) {
|
||||||
let batch = DBTransaction::new();
|
let batch = DBTransaction::new();
|
||||||
batch.put(b"best", &update.info.hash).unwrap();
|
|
||||||
|
|
||||||
{
|
{
|
||||||
for hash in update.block_details.keys().cloned() {
|
for hash in update.block_details.keys().cloned() {
|
||||||
@ -496,29 +495,27 @@ impl BlockChain {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut write_details = self.block_details.write();
|
let mut write_details = self.block_details.write();
|
||||||
batch.extend_with_cache(write_details.deref_mut(), update.block_details, CacheUpdatePolicy::Overwrite);
|
batch.extend_with_cache(&mut *write_details, update.block_details, CacheUpdatePolicy::Overwrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut write_receipts = self.block_receipts.write();
|
let mut write_receipts = self.block_receipts.write();
|
||||||
batch.extend_with_cache(write_receipts.deref_mut(), update.block_receipts, CacheUpdatePolicy::Remove);
|
batch.extend_with_cache(&mut *write_receipts, update.block_receipts, CacheUpdatePolicy::Remove);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut write_blocks_blooms = self.blocks_blooms.write();
|
let mut write_blocks_blooms = self.blocks_blooms.write();
|
||||||
batch.extend_with_cache(write_blocks_blooms.deref_mut(), update.blocks_blooms, CacheUpdatePolicy::Remove);
|
batch.extend_with_cache(&mut *write_blocks_blooms, update.blocks_blooms, CacheUpdatePolicy::Remove);
|
||||||
}
|
}
|
||||||
|
|
||||||
// These cached values must be updated last and togeterh
|
// These cached values must be updated last and togeterh
|
||||||
{
|
{
|
||||||
let mut best_block = self.best_block.write();
|
|
||||||
let mut write_hashes = self.block_hashes.write();
|
|
||||||
let mut write_txs = self.transaction_addresses.write();
|
|
||||||
|
|
||||||
// update best block
|
// update best block
|
||||||
match update.info.location {
|
match update.info.location {
|
||||||
BlockLocation::Branch => (),
|
BlockLocation::Branch => (),
|
||||||
_ => {
|
_ => {
|
||||||
|
batch.put(b"best", &update.info.hash).unwrap();
|
||||||
|
let mut best_block = self.best_block.write();
|
||||||
*best_block = BestBlock {
|
*best_block = BestBlock {
|
||||||
hash: update.info.hash,
|
hash: update.info.hash,
|
||||||
number: update.info.number,
|
number: update.info.number,
|
||||||
@ -527,8 +524,11 @@ impl BlockChain {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
batch.extend_with_cache(write_hashes.deref_mut(), update.block_hashes, CacheUpdatePolicy::Remove);
|
let mut write_hashes = self.block_hashes.write();
|
||||||
batch.extend_with_cache(write_txs.deref_mut(), update.transactions_addresses, CacheUpdatePolicy::Remove);
|
let mut write_txs = self.transaction_addresses.write();
|
||||||
|
|
||||||
|
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
|
// update extras database
|
||||||
self.extras_db.write(batch).unwrap();
|
self.extras_db.write(batch).unwrap();
|
||||||
@ -1189,4 +1189,31 @@ mod tests {
|
|||||||
assert_eq!(blocks_b2, vec![2]);
|
assert_eq!(blocks_b2, vec![2]);
|
||||||
assert_eq!(blocks_ba, vec![3]);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ use util::rlp::{RlpStream, Rlp, UntrustedRlp};
|
|||||||
use util::journaldb;
|
use util::journaldb;
|
||||||
use util::journaldb::JournalDB;
|
use util::journaldb::JournalDB;
|
||||||
use util::kvdb::*;
|
use util::kvdb::*;
|
||||||
use util::{Applyable, Stream, View, PerfTimer, Itertools, Colour};
|
use util::{Stream, View, PerfTimer, Itertools};
|
||||||
use util::{Mutex, RwLock};
|
use util::{Mutex, RwLock};
|
||||||
|
|
||||||
// other
|
// other
|
||||||
@ -44,6 +44,7 @@ use error::{ImportError, ExecutionError, BlockError, ImportResult};
|
|||||||
use header::BlockNumber;
|
use header::BlockNumber;
|
||||||
use state::State;
|
use state::State;
|
||||||
use spec::Spec;
|
use spec::Spec;
|
||||||
|
use basic_types::Seal;
|
||||||
use engine::Engine;
|
use engine::Engine;
|
||||||
use views::HeaderView;
|
use views::HeaderView;
|
||||||
use service::ClientIoMessage;
|
use service::ClientIoMessage;
|
||||||
@ -462,8 +463,10 @@ impl Client {
|
|||||||
/// Otherwise, this can fail (but may not) if the DB prunes state.
|
/// Otherwise, this can fail (but may not) if the DB prunes state.
|
||||||
pub fn state_at(&self, id: BlockID) -> Option<State> {
|
pub fn state_at(&self, id: BlockID) -> Option<State> {
|
||||||
// fast path for latest state.
|
// fast path for latest state.
|
||||||
if let BlockID::Latest = id.clone() {
|
match id.clone() {
|
||||||
return Some(self.state())
|
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()) {
|
let block_number = match self.block_number(id.clone()) {
|
||||||
@ -556,7 +559,7 @@ impl Client {
|
|||||||
BlockID::Number(number) => Some(number),
|
BlockID::Number(number) => Some(number),
|
||||||
BlockID::Hash(ref hash) => self.chain.block_number(hash),
|
BlockID::Hash(ref hash) => self.chain.block_number(hash),
|
||||||
BlockID::Earliest => Some(0),
|
BlockID::Earliest => Some(0),
|
||||||
BlockID::Latest => Some(self.chain.best_block_number())
|
BlockID::Latest | BlockID::Pending => Some(self.chain.best_block_number()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -565,7 +568,7 @@ impl Client {
|
|||||||
BlockID::Hash(hash) => Some(hash),
|
BlockID::Hash(hash) => Some(hash),
|
||||||
BlockID::Number(number) => chain.block_hash(number),
|
BlockID::Number(number) => chain.block_hash(number),
|
||||||
BlockID::Earliest => chain.block_hash(0),
|
BlockID::Earliest => chain.block_hash(0),
|
||||||
BlockID::Latest => Some(chain.best_block_hash())
|
BlockID::Latest | BlockID::Pending => Some(chain.best_block_hash()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -605,18 +608,6 @@ impl Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Notify us that the network has been started.
|
|
||||||
pub fn network_started(&self, url: &str) {
|
|
||||||
let mut previous_enode = self.previous_enode.lock();
|
|
||||||
if let Some(ref u) = *previous_enode {
|
|
||||||
if u == url {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*previous_enode = Some(url.into());
|
|
||||||
info!(target: "mode", "Public node URL: {}", url.apply(Colour::White.bold()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Ipc)]
|
#[derive(Ipc)]
|
||||||
@ -683,6 +674,11 @@ impl BlockChainClient for Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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::block_hash(&self.chain, id).and_then(|hash| {
|
||||||
self.chain.block(&hash)
|
self.chain.block(&hash)
|
||||||
})
|
})
|
||||||
@ -697,6 +693,11 @@ impl BlockChainClient for Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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)
|
Self::block_hash(&self.chain, id).and_then(|hash| self.chain.block_details(&hash)).map(|d| d.total_difficulty)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,7 +241,7 @@ impl TestBlockChainClient {
|
|||||||
BlockID::Hash(hash) => Some(hash),
|
BlockID::Hash(hash) => Some(hash),
|
||||||
BlockID::Number(n) => self.numbers.read().get(&(n as usize)).cloned(),
|
BlockID::Number(n) => self.numbers.read().get(&(n as usize)).cloned(),
|
||||||
BlockID::Earliest => self.numbers.read().get(&0).cloned(),
|
BlockID::Earliest => self.numbers.read().get(&0).cloned(),
|
||||||
BlockID::Latest => self.numbers.read().get(&(self.numbers.read().len() - 1)).cloned()
|
BlockID::Latest | BlockID::Pending => self.numbers.read().get(&(self.numbers.read().len() - 1)).cloned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,12 @@ pub struct EthashParams {
|
|||||||
pub registrar: Address,
|
pub registrar: Address,
|
||||||
/// Homestead transition block number.
|
/// Homestead transition block number.
|
||||||
pub frontier_compatibility_mode_limit: u64,
|
pub frontier_compatibility_mode_limit: u64,
|
||||||
|
/// DAO hard-fork transition block (X).
|
||||||
|
pub dao_hardfork_transition: u64,
|
||||||
|
/// DAO hard-fork refund contract address (C).
|
||||||
|
pub dao_hardfork_beneficiary: Address,
|
||||||
|
/// DAO hard-fork DAO accounts list (L)
|
||||||
|
pub dao_hardfork_accounts: Vec<Address>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ethjson::spec::EthashParams> for EthashParams {
|
impl From<ethjson::spec::EthashParams> for EthashParams {
|
||||||
@ -49,8 +55,11 @@ impl From<ethjson::spec::EthashParams> for EthashParams {
|
|||||||
difficulty_bound_divisor: p.difficulty_bound_divisor.into(),
|
difficulty_bound_divisor: p.difficulty_bound_divisor.into(),
|
||||||
duration_limit: p.duration_limit.into(),
|
duration_limit: p.duration_limit.into(),
|
||||||
block_reward: p.block_reward.into(),
|
block_reward: p.block_reward.into(),
|
||||||
registrar: p.registrar.into(),
|
registrar: p.registrar.map(Into::into).unwrap_or(Address::new()),
|
||||||
frontier_compatibility_mode_limit: p.frontier_compatibility_mode_limit.into(),
|
frontier_compatibility_mode_limit: p.frontier_compatibility_mode_limit.map(Into::into).unwrap_or(0),
|
||||||
|
dao_hardfork_transition: p.dao_hardfork_transition.map(Into::into).unwrap_or(0x7fffffffffffffff),
|
||||||
|
dao_hardfork_beneficiary: p.dao_hardfork_beneficiary.map(Into::into).unwrap_or(Address::new()),
|
||||||
|
dao_hardfork_accounts: p.dao_hardfork_accounts.unwrap_or(vec![]).into_iter().map(Into::into).collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -119,10 +128,27 @@ impl Engine for Ethash {
|
|||||||
(header.gas_used * 6.into() / 5.into()) / bound_divisor))
|
(header.gas_used * 6.into() / 5.into()) / bound_divisor))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
if header.number >= self.ethash_params.dao_hardfork_transition &&
|
||||||
|
header.number <= self.ethash_params.dao_hardfork_transition + 9 {
|
||||||
|
header.extra_data = b"dao-hard-fork"[..].to_owned();
|
||||||
|
}
|
||||||
header.note_dirty();
|
header.note_dirty();
|
||||||
// info!("ethash: populate_from_parent #{}: difficulty={} and gas_limit={}", header.number, header.difficulty, header.gas_limit);
|
// info!("ethash: populate_from_parent #{}: difficulty={} and gas_limit={}", header.number, header.difficulty, header.gas_limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_new_block(&self, block: &mut ExecutedBlock) {
|
||||||
|
if block.fields().header.number == self.ethash_params.dao_hardfork_transition {
|
||||||
|
// TODO: enable trigger function maybe?
|
||||||
|
// if block.fields().header.gas_limit <= 4_000_000.into() {
|
||||||
|
let mut state = block.fields_mut().state;
|
||||||
|
for child in self.ethash_params.dao_hardfork_accounts.iter() {
|
||||||
|
let b = state.balance(child);
|
||||||
|
state.transfer_balance(child, &self.ethash_params.dao_hardfork_beneficiary, &b);
|
||||||
|
}
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Apply the block reward on finalisation of the block.
|
/// 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).
|
/// 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) {
|
fn on_close_block(&self, block: &mut ExecutedBlock) {
|
||||||
@ -164,6 +190,17 @@ impl Engine for Ethash {
|
|||||||
if difficulty < header.difficulty {
|
if difficulty < header.difficulty {
|
||||||
return Err(From::from(BlockError::InvalidProofOfWork(OutOfBounds { min: Some(header.difficulty), max: None, found: difficulty })));
|
return Err(From::from(BlockError::InvalidProofOfWork(OutOfBounds { min: Some(header.difficulty), max: None, found: difficulty })));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if header.number >= self.ethash_params.dao_hardfork_transition &&
|
||||||
|
header.number <= self.ethash_params.dao_hardfork_transition + 9 &&
|
||||||
|
header.extra_data[..] != b"dao-hard-fork"[..] {
|
||||||
|
return Err(From::from(BlockError::ExtraDataOutOfBounds(OutOfBounds { min: None, max: None, found: 0 })));
|
||||||
|
}
|
||||||
|
|
||||||
|
if header.gas_limit > 0x7fffffffffffffffu64.into() {
|
||||||
|
return Err(From::from(BlockError::InvalidGasLimit(OutOfBounds { min: None, max: Some(0x7fffffffffffffffu64.into()), found: header.gas_limit })));
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,12 +37,20 @@ pub fn new_frontier() -> Spec {
|
|||||||
Spec::load(include_bytes!("../../res/ethereum/frontier.json"))
|
Spec::load(include_bytes!("../../res/ethereum/frontier.json"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a new Frontier mainnet chain spec without the DAO hardfork.
|
||||||
|
pub fn new_frontier_dogmatic() -> Spec {
|
||||||
|
Spec::load(include_bytes!("../../res/ethereum/frontier-dogmatic.json"))
|
||||||
|
}
|
||||||
|
|
||||||
/// Create a new Frontier chain spec as though it never changes to Homestead.
|
/// Create a new Frontier chain spec as though it never changes to Homestead.
|
||||||
pub fn new_frontier_test() -> Spec { Spec::load(include_bytes!("../../res/ethereum/frontier_test.json")) }
|
pub fn new_frontier_test() -> Spec { Spec::load(include_bytes!("../../res/ethereum/frontier_test.json")) }
|
||||||
|
|
||||||
/// Create a new Homestead chain spec as though it never changed from Frontier.
|
/// Create a new Homestead chain spec as though it never changed from Frontier.
|
||||||
pub fn new_homestead_test() -> Spec { Spec::load(include_bytes!("../../res/ethereum/homestead_test.json")) }
|
pub fn new_homestead_test() -> Spec { Spec::load(include_bytes!("../../res/ethereum/homestead_test.json")) }
|
||||||
|
|
||||||
|
/// Create a new Frontier/Homestead/DAO chain spec with transition points at #5 and #8.
|
||||||
|
pub fn new_daohardfork_test() -> Spec { Spec::load(include_bytes!("../../res/ethereum/daohardfork_test.json")) }
|
||||||
|
|
||||||
/// Create a new Frontier main net chain spec without genesis accounts.
|
/// Create a new Frontier main net chain spec without genesis accounts.
|
||||||
pub fn new_mainnet_like() -> Spec { Spec::load(include_bytes!("../../res/ethereum/frontier_like_test.json")) }
|
pub fn new_mainnet_like() -> Spec { Spec::load(include_bytes!("../../res/ethereum/frontier_like_test.json")) }
|
||||||
|
|
||||||
|
@ -48,6 +48,7 @@ pub fn json_chain_test(json_data: &[u8], era: ChainEra) -> Vec<String> {
|
|||||||
let mut spec = match era {
|
let mut spec = match era {
|
||||||
ChainEra::Frontier => ethereum::new_frontier_test(),
|
ChainEra::Frontier => ethereum::new_frontier_test(),
|
||||||
ChainEra::Homestead => ethereum::new_homestead_test(),
|
ChainEra::Homestead => ethereum::new_homestead_test(),
|
||||||
|
ChainEra::DaoHardfork => ethereum::new_daohardfork_test(),
|
||||||
};
|
};
|
||||||
spec.set_genesis_state(state);
|
spec.set_genesis_state(state);
|
||||||
spec.overwrite_genesis_params(genesis);
|
spec.overwrite_genesis_params(genesis);
|
||||||
@ -84,26 +85,43 @@ pub fn json_chain_test(json_data: &[u8], era: ChainEra) -> Vec<String> {
|
|||||||
failed
|
failed
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_json_test(json_data: &[u8]) -> Vec<String> {
|
mod frontier_era_tests {
|
||||||
json_chain_test(json_data, ChainEra::Frontier)
|
use tests::helpers::*;
|
||||||
|
use super::json_chain_test;
|
||||||
|
|
||||||
|
fn do_json_test(json_data: &[u8]) -> Vec<String> {
|
||||||
|
json_chain_test(json_data, ChainEra::Frontier)
|
||||||
|
}
|
||||||
|
|
||||||
|
declare_test!{BlockchainTests_bcBlockGasLimitTest, "BlockchainTests/bcBlockGasLimitTest"}
|
||||||
|
declare_test!{BlockchainTests_bcForkBlockTest, "BlockchainTests/bcForkBlockTest"}
|
||||||
|
declare_test!{BlockchainTests_bcForkStressTest, "BlockchainTests/bcForkStressTest"}
|
||||||
|
declare_test!{BlockchainTests_bcForkUncle, "BlockchainTests/bcForkUncle"}
|
||||||
|
declare_test!{BlockchainTests_bcGasPricerTest, "BlockchainTests/bcGasPricerTest"}
|
||||||
|
declare_test!{BlockchainTests_bcInvalidHeaderTest, "BlockchainTests/bcInvalidHeaderTest"}
|
||||||
|
// TODO [ToDr] Ignored because of incorrect JSON (https://github.com/ethereum/tests/pull/113)
|
||||||
|
declare_test!{ignore => BlockchainTests_bcInvalidRLPTest, "BlockchainTests/bcInvalidRLPTest"}
|
||||||
|
declare_test!{BlockchainTests_bcMultiChainTest, "BlockchainTests/bcMultiChainTest"}
|
||||||
|
declare_test!{BlockchainTests_bcRPC_API_Test, "BlockchainTests/bcRPC_API_Test"}
|
||||||
|
declare_test!{BlockchainTests_bcStateTest, "BlockchainTests/bcStateTest"}
|
||||||
|
declare_test!{BlockchainTests_bcTotalDifficultyTest, "BlockchainTests/bcTotalDifficultyTest"}
|
||||||
|
declare_test!{BlockchainTests_bcUncleHeaderValiditiy, "BlockchainTests/bcUncleHeaderValiditiy"}
|
||||||
|
declare_test!{BlockchainTests_bcUncleTest, "BlockchainTests/bcUncleTest"}
|
||||||
|
declare_test!{BlockchainTests_bcValidBlockTest, "BlockchainTests/bcValidBlockTest"}
|
||||||
|
declare_test!{BlockchainTests_bcWalletTest, "BlockchainTests/bcWalletTest"}
|
||||||
|
|
||||||
|
declare_test!{BlockchainTests_RandomTests_bl10251623GO, "BlockchainTests/RandomTests/bl10251623GO"}
|
||||||
|
declare_test!{BlockchainTests_RandomTests_bl201507071825GO, "BlockchainTests/RandomTests/bl201507071825GO"}
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_test!{BlockchainTests_bcBlockGasLimitTest, "BlockchainTests/bcBlockGasLimitTest"}
|
mod daohardfork_tests {
|
||||||
declare_test!{BlockchainTests_bcForkBlockTest, "BlockchainTests/bcForkBlockTest"}
|
use tests::helpers::*;
|
||||||
declare_test!{BlockchainTests_bcForkStressTest, "BlockchainTests/bcForkStressTest"}
|
use super::json_chain_test;
|
||||||
declare_test!{BlockchainTests_bcForkUncle, "BlockchainTests/bcForkUncle"}
|
|
||||||
declare_test!{BlockchainTests_bcGasPricerTest, "BlockchainTests/bcGasPricerTest"}
|
|
||||||
declare_test!{BlockchainTests_bcInvalidHeaderTest, "BlockchainTests/bcInvalidHeaderTest"}
|
|
||||||
// TODO [ToDr] Ignored because of incorrect JSON (https://github.com/ethereum/tests/pull/113)
|
|
||||||
declare_test!{ignore => BlockchainTests_bcInvalidRLPTest, "BlockchainTests/bcInvalidRLPTest"}
|
|
||||||
declare_test!{BlockchainTests_bcMultiChainTest, "BlockchainTests/bcMultiChainTest"}
|
|
||||||
declare_test!{BlockchainTests_bcRPC_API_Test, "BlockchainTests/bcRPC_API_Test"}
|
|
||||||
declare_test!{BlockchainTests_bcStateTest, "BlockchainTests/bcStateTest"}
|
|
||||||
declare_test!{BlockchainTests_bcTotalDifficultyTest, "BlockchainTests/bcTotalDifficultyTest"}
|
|
||||||
declare_test!{BlockchainTests_bcUncleHeaderValiditiy, "BlockchainTests/bcUncleHeaderValiditiy"}
|
|
||||||
declare_test!{BlockchainTests_bcUncleTest, "BlockchainTests/bcUncleTest"}
|
|
||||||
declare_test!{BlockchainTests_bcValidBlockTest, "BlockchainTests/bcValidBlockTest"}
|
|
||||||
declare_test!{BlockchainTests_bcWalletTest, "BlockchainTests/bcWalletTest"}
|
|
||||||
|
|
||||||
declare_test!{BlockchainTests_RandomTests_bl10251623GO, "BlockchainTests/RandomTests/bl10251623GO"}
|
fn do_json_test(json_data: &[u8]) -> Vec<String> {
|
||||||
declare_test!{BlockchainTests_RandomTests_bl201507071825GO, "BlockchainTests/RandomTests/bl201507071825GO"}
|
json_chain_test(json_data, ChainEra::DaoHardfork)
|
||||||
|
}
|
||||||
|
|
||||||
|
declare_test!{BlockchainTests_TestNetwork_bcSimpleTransitionTest, "BlockchainTests/TestNetwork/bcSimpleTransitionTest"}
|
||||||
|
declare_test!{BlockchainTests_TestNetwork_bcTheDaoTest, "BlockchainTests/TestNetwork/bcTheDaoTest"}
|
||||||
|
}
|
||||||
|
@ -30,8 +30,9 @@ pub fn json_chain_test(json_data: &[u8], era: ChainEra) -> Vec<String> {
|
|||||||
let mut failed = Vec::new();
|
let mut failed = Vec::new();
|
||||||
let engine = match era {
|
let engine = match era {
|
||||||
ChainEra::Frontier => ethereum::new_mainnet_like().engine,
|
ChainEra::Frontier => ethereum::new_mainnet_like().engine,
|
||||||
ChainEra::Homestead => ethereum::new_homestead_test().engine
|
ChainEra::Homestead => ethereum::new_homestead_test().engine,
|
||||||
};
|
ChainEra::DaoHardfork => ethereum::new_daohardfork_test().engine,
|
||||||
|
};
|
||||||
|
|
||||||
for (name, test) in tests.into_iter() {
|
for (name, test) in tests.into_iter() {
|
||||||
let mut fail = false;
|
let mut fail = false;
|
||||||
|
@ -22,8 +22,9 @@ use util::*;
|
|||||||
use util::using_queue::{UsingQueue, GetAction};
|
use util::using_queue::{UsingQueue, GetAction};
|
||||||
use account_provider::AccountProvider;
|
use account_provider::AccountProvider;
|
||||||
use views::{BlockView, HeaderView};
|
use views::{BlockView, HeaderView};
|
||||||
|
use state::State;
|
||||||
use client::{MiningBlockChainClient, Executive, Executed, EnvInfo, TransactOptions, BlockID, CallAnalytics};
|
use client::{MiningBlockChainClient, Executive, Executed, EnvInfo, TransactOptions, BlockID, CallAnalytics};
|
||||||
use block::{ClosedBlock, IsBlock};
|
use block::{ClosedBlock, IsBlock, Block};
|
||||||
use error::*;
|
use error::*;
|
||||||
use transaction::SignedTransaction;
|
use transaction::SignedTransaction;
|
||||||
use receipt::Receipt;
|
use receipt::Receipt;
|
||||||
@ -115,7 +116,7 @@ impl GasPriceCalibrator {
|
|||||||
let wei_per_usd: f32 = 1.0e18 / usd_per_eth;
|
let wei_per_usd: f32 = 1.0e18 / usd_per_eth;
|
||||||
let gas_per_tx: f32 = 21000.0;
|
let gas_per_tx: f32 = 21000.0;
|
||||||
let wei_per_gas: f32 = wei_per_usd * usd_per_tx / gas_per_tx;
|
let wei_per_gas: f32 = wei_per_usd * usd_per_tx / gas_per_tx;
|
||||||
info!(target: "miner", "Updated conversion rate to Ξ1 = {} ({} wei/gas)", format!("US${}", usd_per_eth).apply(Colour::White.bold()), format!("{}", wei_per_gas).apply(Colour::Yellow.bold()));
|
info!(target: "miner", "Updated conversion rate to Ξ1 = {} ({} wei/gas)", Colour::White.bold().paint(format!("US${}", usd_per_eth)), Colour::Yellow.bold().paint(format!("{}", wei_per_gas)));
|
||||||
set_price(U256::from_dec_str(&format!("{:.0}", wei_per_gas)).unwrap());
|
set_price(U256::from_dec_str(&format!("{:.0}", wei_per_gas)).unwrap());
|
||||||
}) {
|
}) {
|
||||||
self.next_calibration = Instant::now() + self.options.recalibration_period;
|
self.next_calibration = Instant::now() + self.options.recalibration_period;
|
||||||
@ -226,6 +227,16 @@ impl Miner {
|
|||||||
self.options.force_sealing || !self.options.new_work_notify.is_empty()
|
self.options.force_sealing || !self.options.new_work_notify.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get `Some` `clone()` of the current pending block's state or `None` if we're not sealing.
|
||||||
|
pub fn pending_state(&self) -> Option<State> {
|
||||||
|
self.sealing_work.lock().peek_last_ref().map(|b| b.block().fields().state.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get `Some` `clone()` of the current pending block's state or `None` if we're not sealing.
|
||||||
|
pub fn pending_block(&self) -> Option<Block> {
|
||||||
|
self.sealing_work.lock().peek_last_ref().map(|b| b.base().clone())
|
||||||
|
}
|
||||||
|
|
||||||
/// Prepares new block for sealing including top transactions from queue.
|
/// Prepares new block for sealing including top transactions from queue.
|
||||||
#[cfg_attr(feature="dev", allow(match_same_arms))]
|
#[cfg_attr(feature="dev", allow(match_same_arms))]
|
||||||
#[cfg_attr(feature="dev", allow(cyclomatic_complexity))]
|
#[cfg_attr(feature="dev", allow(cyclomatic_complexity))]
|
||||||
@ -764,7 +775,7 @@ impl MinerService for Miner {
|
|||||||
let n = sealed.header().number();
|
let n = sealed.header().number();
|
||||||
let h = sealed.header().hash();
|
let h = sealed.header().hash();
|
||||||
try!(chain.import_sealed_block(sealed));
|
try!(chain.import_sealed_block(sealed));
|
||||||
info!(target: "miner", "Mined block imported OK. #{}: {}", format!("{}", n).apply(Colour::White.bold()), h.hex().apply(Colour::White.bold()));
|
info!(target: "miner", "Mined block imported OK. #{}: {}", Colour::White.bold().paint(format!("{}", n)), Colour::White.bold().paint(h.hex()));
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ impl ClientService {
|
|||||||
let io_service = try!(IoService::<ClientIoMessage>::start());
|
let io_service = try!(IoService::<ClientIoMessage>::start());
|
||||||
panic_handler.forward_from(&io_service);
|
panic_handler.forward_from(&io_service);
|
||||||
|
|
||||||
info!("Configured for {} using {} engine", spec.name.clone().apply(Colour::White.bold()), spec.engine.name().apply(Colour::Yellow.bold()));
|
info!("Configured for {} using {} engine", Colour::White.bold().paint(spec.name.clone()), Colour::Yellow.bold().paint(spec.engine.name()));
|
||||||
let client = try!(Client::new(config, spec, db_path, miner, io_service.channel()));
|
let client = try!(Client::new(config, spec, db_path, miner, io_service.channel()));
|
||||||
panic_handler.forward_from(client.deref());
|
panic_handler.forward_from(client.deref());
|
||||||
let client_io = Arc::new(ClientIoHandler {
|
let client_io = Arc::new(ClientIoHandler {
|
||||||
|
@ -30,6 +30,7 @@ use miner::Miner;
|
|||||||
pub enum ChainEra {
|
pub enum ChainEra {
|
||||||
Frontier,
|
Frontier,
|
||||||
Homestead,
|
Homestead,
|
||||||
|
DaoHardfork,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TestEngine {
|
pub struct TestEngine {
|
||||||
|
@ -33,7 +33,9 @@ pub enum BlockID {
|
|||||||
/// Earliest block (genesis).
|
/// Earliest block (genesis).
|
||||||
Earliest,
|
Earliest,
|
||||||
/// Latest mined block.
|
/// Latest mined block.
|
||||||
Latest
|
Latest,
|
||||||
|
/// Pending block.
|
||||||
|
Pending,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Uniquely identifies transaction.
|
/// Uniquely identifies transaction.
|
||||||
|
@ -53,7 +53,10 @@ mod tests {
|
|||||||
"durationLimit": "0x0d",
|
"durationLimit": "0x0d",
|
||||||
"blockReward": "0x4563918244F40000",
|
"blockReward": "0x4563918244F40000",
|
||||||
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
||||||
"frontierCompatibilityModeLimit" : "0x"
|
"frontierCompatibilityModeLimit" : "0x",
|
||||||
|
"daoHardforkTransition": "0xffffffffffffffff",
|
||||||
|
"daoHardforkBeneficiary": "0x0000000000000000000000000000000000000000",
|
||||||
|
"daoHardforkAccounts": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}"#;
|
}"#;
|
||||||
|
@ -19,29 +19,38 @@
|
|||||||
use uint::Uint;
|
use uint::Uint;
|
||||||
use hash::Address;
|
use hash::Address;
|
||||||
|
|
||||||
/// Ethash params deserialization.
|
/// Deserializable doppelganger of EthashParams.
|
||||||
#[derive(Debug, PartialEq, Deserialize)]
|
#[derive(Debug, PartialEq, Deserialize)]
|
||||||
pub struct EthashParams {
|
pub struct EthashParams {
|
||||||
/// Gas limit divisor.
|
/// See main EthashParams docs.
|
||||||
#[serde(rename="gasLimitBoundDivisor")]
|
#[serde(rename="gasLimitBoundDivisor")]
|
||||||
pub gas_limit_bound_divisor: Uint,
|
pub gas_limit_bound_divisor: Uint,
|
||||||
/// Minimum difficulty.
|
/// See main EthashParams docs.
|
||||||
#[serde(rename="minimumDifficulty")]
|
#[serde(rename="minimumDifficulty")]
|
||||||
pub minimum_difficulty: Uint,
|
pub minimum_difficulty: Uint,
|
||||||
/// Difficulty bound divisor.
|
/// See main EthashParams docs.
|
||||||
#[serde(rename="difficultyBoundDivisor")]
|
#[serde(rename="difficultyBoundDivisor")]
|
||||||
pub difficulty_bound_divisor: Uint,
|
pub difficulty_bound_divisor: Uint,
|
||||||
/// Block duration.
|
/// See main EthashParams docs.
|
||||||
#[serde(rename="durationLimit")]
|
#[serde(rename="durationLimit")]
|
||||||
pub duration_limit: Uint,
|
pub duration_limit: Uint,
|
||||||
/// Block reward.
|
/// See main EthashParams docs.
|
||||||
#[serde(rename="blockReward")]
|
#[serde(rename="blockReward")]
|
||||||
pub block_reward: Uint,
|
pub block_reward: Uint,
|
||||||
/// Namereg contract address.
|
/// See main EthashParams docs.
|
||||||
pub registrar: Address,
|
pub registrar: Option<Address>,
|
||||||
/// Homestead transition block number.
|
/// See main EthashParams docs.
|
||||||
#[serde(rename="frontierCompatibilityModeLimit")]
|
#[serde(rename="frontierCompatibilityModeLimit")]
|
||||||
pub frontier_compatibility_mode_limit: Uint,
|
pub frontier_compatibility_mode_limit: Option<Uint>,
|
||||||
|
/// See main EthashParams docs.
|
||||||
|
#[serde(rename="daoHardforkTransition")]
|
||||||
|
pub dao_hardfork_transition: Option<Uint>,
|
||||||
|
/// See main EthashParams docs.
|
||||||
|
#[serde(rename="daoHardforkBeneficiary")]
|
||||||
|
pub dao_hardfork_beneficiary: Option<Address>,
|
||||||
|
/// See main EthashParams docs.
|
||||||
|
#[serde(rename="daoHardforkAccounts")]
|
||||||
|
pub dao_hardfork_accounts: Option<Vec<Address>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ethash engine deserialization.
|
/// Ethash engine deserialization.
|
||||||
@ -66,7 +75,46 @@ mod tests {
|
|||||||
"durationLimit": "0x0d",
|
"durationLimit": "0x0d",
|
||||||
"blockReward": "0x4563918244F40000",
|
"blockReward": "0x4563918244F40000",
|
||||||
"registrar": "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
"registrar": "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
||||||
"frontierCompatibilityModeLimit": "0x42"
|
"frontierCompatibilityModeLimit": "0x42",
|
||||||
|
"daoHardforkTransition": "0x08",
|
||||||
|
"daoHardforkBeneficiary": "0xabcabcabcabcabcabcabcabcabcabcabcabcabca",
|
||||||
|
"daoHardforkAccounts": [
|
||||||
|
"0x304a554a310c7e546dfe434669c62820b7d83490",
|
||||||
|
"0x914d1b8b43e92723e64fd0a06f5bdb8dd9b10c79",
|
||||||
|
"0xfe24cdd8648121a43a7c86d289be4dd2951ed49f",
|
||||||
|
"0x17802f43a0137c506ba92291391a8a8f207f487d",
|
||||||
|
"0xb136707642a4ea12fb4bae820f03d2562ebff487",
|
||||||
|
"0xdbe9b615a3ae8709af8b93336ce9b477e4ac0940",
|
||||||
|
"0xf14c14075d6c4ed84b86798af0956deef67365b5",
|
||||||
|
"0xca544e5c4687d109611d0f8f928b53a25af72448",
|
||||||
|
"0xaeeb8ff27288bdabc0fa5ebb731b6f409507516c",
|
||||||
|
"0xcbb9d3703e651b0d496cdefb8b92c25aeb2171f7",
|
||||||
|
"0xaccc230e8a6e5be9160b8cdf2864dd2a001c28b6",
|
||||||
|
"0x2b3455ec7fedf16e646268bf88846bd7a2319bb2",
|
||||||
|
"0x4613f3bca5c44ea06337a9e439fbc6d42e501d0a",
|
||||||
|
"0xd343b217de44030afaa275f54d31a9317c7f441e",
|
||||||
|
"0x84ef4b2357079cd7a7c69fd7a37cd0609a679106",
|
||||||
|
"0xda2fef9e4a3230988ff17df2165440f37e8b1708",
|
||||||
|
"0xf4c64518ea10f995918a454158c6b61407ea345c",
|
||||||
|
"0x7602b46df5390e432ef1c307d4f2c9ff6d65cc97",
|
||||||
|
"0xbb9bc244d798123fde783fcc1c72d3bb8c189413",
|
||||||
|
"0x807640a13483f8ac783c557fcdf27be11ea4ac7a"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}"#;
|
||||||
|
|
||||||
|
let _deserialized: Ethash = serde_json::from_str(s).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ethash_deserialization_missing_optionals() {
|
||||||
|
let s = r#"{
|
||||||
|
"params": {
|
||||||
|
"gasLimitBoundDivisor": "0x0400",
|
||||||
|
"minimumDifficulty": "0x020000",
|
||||||
|
"difficultyBoundDivisor": "0x0800",
|
||||||
|
"durationLimit": "0x0d",
|
||||||
|
"blockReward": "0x4563918244F40000"
|
||||||
}
|
}
|
||||||
}"#;
|
}"#;
|
||||||
|
|
||||||
|
@ -63,7 +63,10 @@ mod tests {
|
|||||||
"durationLimit": "0x0d",
|
"durationLimit": "0x0d",
|
||||||
"blockReward": "0x4563918244F40000",
|
"blockReward": "0x4563918244F40000",
|
||||||
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
||||||
"frontierCompatibilityModeLimit" : "0x"
|
"frontierCompatibilityModeLimit" : "0x",
|
||||||
|
"daoHardforkTransition": "0xffffffffffffffff",
|
||||||
|
"daoHardforkBeneficiary": "0x0000000000000000000000000000000000000000",
|
||||||
|
"daoHardforkAccounts": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -47,18 +47,13 @@ Operating Options:
|
|||||||
[default: 3600].
|
[default: 3600].
|
||||||
--chain CHAIN Specify the blockchain type. CHAIN may be either a
|
--chain CHAIN Specify the blockchain type. CHAIN may be either a
|
||||||
JSON chain specification file or olympic, frontier,
|
JSON chain specification file or olympic, frontier,
|
||||||
homestead, mainnet, morden, or testnet
|
homestead, mainnet, morden, homestead-dogmatic, or
|
||||||
[default: homestead].
|
testnet [default: homestead].
|
||||||
-d --db-path PATH Specify the database & configuration directory path
|
-d --db-path PATH Specify the database & configuration directory path
|
||||||
[default: $HOME/.parity].
|
[default: $HOME/.parity].
|
||||||
--keys-path PATH Specify the path for JSON key files to be found
|
--keys-path PATH Specify the path for JSON key files to be found
|
||||||
[default: $HOME/.parity/keys].
|
[default: $HOME/.parity/keys].
|
||||||
--identity NAME Specify your node's name.
|
--identity NAME Specify your node's name.
|
||||||
--fork POLICY Specifies the client's fork policy. POLICY must be
|
|
||||||
one of:
|
|
||||||
dogmatic - sticks rigidly to the standard chain.
|
|
||||||
none - goes with whatever fork is decided but
|
|
||||||
votes for none. [default: none].
|
|
||||||
|
|
||||||
Account Options:
|
Account Options:
|
||||||
--unlock ACCOUNTS Unlock ACCOUNTS for the duration of the execution.
|
--unlock ACCOUNTS Unlock ACCOUNTS for the duration of the execution.
|
||||||
@ -145,7 +140,7 @@ Sealing/Mining Options:
|
|||||||
none - never reseal on new transactions;
|
none - never reseal on new transactions;
|
||||||
own - reseal only on a new local transaction;
|
own - reseal only on a new local transaction;
|
||||||
ext - reseal only on a new external transaction;
|
ext - reseal only on a new external transaction;
|
||||||
all - reseal on all new transactions [default: all].
|
all - reseal on all new transactions [default: own].
|
||||||
--reseal-min-period MS Specify the minimum time between reseals from
|
--reseal-min-period MS Specify the minimum time between reseals from
|
||||||
incoming transactions. MS is time measured in
|
incoming transactions. MS is time measured in
|
||||||
milliseconds [default: 2000].
|
milliseconds [default: 2000].
|
||||||
@ -292,7 +287,6 @@ pub struct Args {
|
|||||||
pub flag_chain: String,
|
pub flag_chain: String,
|
||||||
pub flag_db_path: String,
|
pub flag_db_path: String,
|
||||||
pub flag_identity: String,
|
pub flag_identity: String,
|
||||||
pub flag_fork: String,
|
|
||||||
pub flag_unlock: Option<String>,
|
pub flag_unlock: Option<String>,
|
||||||
pub flag_password: Vec<String>,
|
pub flag_password: Vec<String>,
|
||||||
pub flag_cache: Option<usize>,
|
pub flag_cache: Option<usize>,
|
||||||
|
@ -46,12 +46,6 @@ pub struct Directories {
|
|||||||
pub signer: String,
|
pub signer: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Eq, PartialEq, Debug)]
|
|
||||||
pub enum Policy {
|
|
||||||
None,
|
|
||||||
Dogmatic,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Configuration {
|
impl Configuration {
|
||||||
pub fn parse() -> Self {
|
pub fn parse() -> Self {
|
||||||
Configuration {
|
Configuration {
|
||||||
@ -131,14 +125,6 @@ impl Configuration {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn policy(&self) -> Policy {
|
|
||||||
match self.args.flag_fork.as_str() {
|
|
||||||
"none" => Policy::None,
|
|
||||||
"dogmatic" => Policy::Dogmatic,
|
|
||||||
x => die!("{}: Invalid value given for --policy option. Use --help for more info.", x)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn gas_floor_target(&self) -> U256 {
|
pub fn gas_floor_target(&self) -> U256 {
|
||||||
let d = &self.args.flag_gas_floor_target;
|
let d = &self.args.flag_gas_floor_target;
|
||||||
U256::from_dec_str(d).unwrap_or_else(|_| {
|
U256::from_dec_str(d).unwrap_or_else(|_| {
|
||||||
@ -195,7 +181,7 @@ impl Configuration {
|
|||||||
let wei_per_usd: f32 = 1.0e18 / usd_per_eth;
|
let wei_per_usd: f32 = 1.0e18 / usd_per_eth;
|
||||||
let gas_per_tx: f32 = 21000.0;
|
let gas_per_tx: f32 = 21000.0;
|
||||||
let wei_per_gas: f32 = wei_per_usd * usd_per_tx / gas_per_tx;
|
let wei_per_gas: f32 = wei_per_usd * usd_per_tx / gas_per_tx;
|
||||||
info!("Using a fixed conversion rate of Ξ1 = {} ({} wei/gas)", format!("US${}", usd_per_eth).apply(White.bold()), format!("{}", wei_per_gas).apply(Yellow.bold()));
|
info!("Using a fixed conversion rate of Ξ1 = {} ({} wei/gas)", White.bold().paint(format!("US${}", usd_per_eth)), Yellow.bold().paint(format!("{}", wei_per_gas)));
|
||||||
GasPricer::Fixed(U256::from_dec_str(&format!("{:.0}", wei_per_gas)).unwrap())
|
GasPricer::Fixed(U256::from_dec_str(&format!("{:.0}", wei_per_gas)).unwrap())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -214,6 +200,7 @@ impl Configuration {
|
|||||||
pub fn spec(&self) -> Spec {
|
pub fn spec(&self) -> Spec {
|
||||||
match self.chain().as_str() {
|
match self.chain().as_str() {
|
||||||
"frontier" | "homestead" | "mainnet" => ethereum::new_frontier(),
|
"frontier" | "homestead" | "mainnet" => ethereum::new_frontier(),
|
||||||
|
"homestead-dogmatic" => ethereum::new_frontier_dogmatic(),
|
||||||
"morden" | "testnet" => ethereum::new_morden(),
|
"morden" | "testnet" => ethereum::new_morden(),
|
||||||
"olympic" => ethereum::new_olympic(),
|
"olympic" => ethereum::new_olympic(),
|
||||||
f => Spec::load(contents(f).unwrap_or_else(|_| {
|
f => Spec::load(contents(f).unwrap_or_else(|_| {
|
||||||
|
@ -20,6 +20,7 @@ use self::ansi_term::Style;
|
|||||||
|
|
||||||
use std::time::{Instant, Duration};
|
use std::time::{Instant, Duration};
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
|
use isatty::{stdout_isatty};
|
||||||
use ethsync::{SyncStatus, NetworkConfiguration};
|
use ethsync::{SyncStatus, NetworkConfiguration};
|
||||||
use util::{Uint, RwLock};
|
use util::{Uint, RwLock};
|
||||||
use ethcore::client::*;
|
use ethcore::client::*;
|
||||||
@ -91,7 +92,7 @@ impl Informant {
|
|||||||
let mut write_report = self.report.write();
|
let mut write_report = self.report.write();
|
||||||
let report = client.report();
|
let report = client.report();
|
||||||
|
|
||||||
let paint = |c: Style, t: String| match self.with_color {
|
let paint = |c: Style, t: String| match self.with_color && stdout_isatty() {
|
||||||
true => format!("{}", c.paint(t)),
|
true => format!("{}", c.paint(t)),
|
||||||
false => t,
|
false => t,
|
||||||
};
|
};
|
||||||
|
@ -53,6 +53,7 @@ extern crate ansi_term;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
extern crate regex;
|
extern crate regex;
|
||||||
|
extern crate isatty;
|
||||||
|
|
||||||
#[cfg(feature = "dapps")]
|
#[cfg(feature = "dapps")]
|
||||||
extern crate ethcore_dapps;
|
extern crate ethcore_dapps;
|
||||||
@ -83,7 +84,7 @@ use std::thread::sleep;
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use rustc_serialize::hex::FromHex;
|
use rustc_serialize::hex::FromHex;
|
||||||
use ctrlc::CtrlC;
|
use ctrlc::CtrlC;
|
||||||
use util::{H256, ToPretty, PayloadInfo, Bytes, Colour, Applyable, version, journaldb};
|
use util::{H256, ToPretty, PayloadInfo, Bytes, Colour, version, journaldb};
|
||||||
use util::panics::{MayPanic, ForwardPanic, PanicHandler};
|
use util::panics::{MayPanic, ForwardPanic, PanicHandler};
|
||||||
use ethcore::client::{BlockID, BlockChainClient, ClientConfig, get_db_path, BlockImportError, Mode};
|
use ethcore::client::{BlockID, BlockChainClient, ClientConfig, get_db_path, BlockImportError, Mode};
|
||||||
use ethcore::error::{ImportError};
|
use ethcore::error::{ImportError};
|
||||||
@ -101,7 +102,7 @@ use rpc::RpcServer;
|
|||||||
use signer::{SignerServer, new_token};
|
use signer::{SignerServer, new_token};
|
||||||
use dapps::WebappServer;
|
use dapps::WebappServer;
|
||||||
use io_handler::ClientIoHandler;
|
use io_handler::ClientIoHandler;
|
||||||
use configuration::{Policy, Configuration};
|
use configuration::{Configuration};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let conf = Configuration::parse();
|
let conf = Configuration::parse();
|
||||||
@ -179,7 +180,7 @@ fn execute_upgrades(conf: &Configuration, spec: &Spec, client_config: &ClientCon
|
|||||||
let db_path = get_db_path(Path::new(&conf.path()), client_config.pruning, spec.genesis_header().hash());
|
let db_path = get_db_path(Path::new(&conf.path()), client_config.pruning, spec.genesis_header().hash());
|
||||||
let result = migrate(&db_path, client_config.pruning);
|
let result = migrate(&db_path, client_config.pruning);
|
||||||
if let Err(err) = result {
|
if let Err(err) = result {
|
||||||
die_with_message(&format!("{}", err));
|
die_with_message(&format!("{} DB path: {}", err, db_path.to_string_lossy()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,18 +193,18 @@ fn execute_client(conf: Configuration, spec: Spec, client_config: ClientConfig)
|
|||||||
// Raise fdlimit
|
// Raise fdlimit
|
||||||
unsafe { ::fdlimit::raise_fd_limit(); }
|
unsafe { ::fdlimit::raise_fd_limit(); }
|
||||||
|
|
||||||
info!("Starting {}", format!("{}", version()).apply(Colour::White.bold()));
|
info!("Starting {}", Colour::White.bold().paint(format!("{}", version())));
|
||||||
info!("Using state DB journalling strategy {}", match client_config.pruning {
|
info!("Using state DB journalling strategy {}", Colour::White.bold().paint(match client_config.pruning {
|
||||||
journaldb::Algorithm::Archive => "archive",
|
journaldb::Algorithm::Archive => "archive",
|
||||||
journaldb::Algorithm::EarlyMerge => "light",
|
journaldb::Algorithm::EarlyMerge => "light",
|
||||||
journaldb::Algorithm::OverlayRecent => "fast",
|
journaldb::Algorithm::OverlayRecent => "fast",
|
||||||
journaldb::Algorithm::RefCounted => "basic",
|
journaldb::Algorithm::RefCounted => "basic",
|
||||||
}.apply(Colour::White.bold()));
|
}));
|
||||||
|
|
||||||
// Display warning about using experimental journaldb types
|
// Display warning about using experimental journaldb types
|
||||||
match client_config.pruning {
|
match client_config.pruning {
|
||||||
journaldb::Algorithm::EarlyMerge | journaldb::Algorithm::RefCounted => {
|
journaldb::Algorithm::EarlyMerge | journaldb::Algorithm::RefCounted => {
|
||||||
warn!("Your chosen strategy is {}! You can re-run with --pruning to change.", "unstable".apply(Colour::Red.bold()));
|
warn!("Your chosen strategy is {}! You can re-run with --pruning to change.", Colour::Red.bold().paint("unstable"));
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
@ -214,11 +215,6 @@ fn execute_client(conf: Configuration, spec: Spec, client_config: ClientConfig)
|
|||||||
warn!("NOTE that Signer will not ask you to confirm transactions from unlocked account.");
|
warn!("NOTE that Signer will not ask you to confirm transactions from unlocked account.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check fork settings.
|
|
||||||
if conf.policy() != Policy::None {
|
|
||||||
warn!("Value given for --policy, yet no proposed forks exist. Ignoring.");
|
|
||||||
}
|
|
||||||
|
|
||||||
let net_settings = conf.net_settings(&spec);
|
let net_settings = conf.net_settings(&spec);
|
||||||
let sync_config = conf.sync_config(&spec);
|
let sync_config = conf.sync_config(&spec);
|
||||||
|
|
||||||
|
@ -37,11 +37,15 @@ const VERSION_FILE_NAME: &'static str = "db_version";
|
|||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// Returned when current version cannot be read or guessed.
|
/// Returned when current version cannot be read or guessed.
|
||||||
UnknownDatabaseVersion,
|
UnknownDatabaseVersion,
|
||||||
/// Returned when migration is not possible.
|
/// Migration does not support existing pruning algorithm.
|
||||||
|
UnsuportedPruningMethod,
|
||||||
|
/// Existing DB is newer than the known one.
|
||||||
|
FutureDBVersion,
|
||||||
|
/// Migration is not possible.
|
||||||
MigrationImpossible,
|
MigrationImpossible,
|
||||||
/// Returned when migration unexpectadly failed.
|
/// Migration unexpectadly failed.
|
||||||
MigrationFailed,
|
MigrationFailed,
|
||||||
/// Returned when migration was completed succesfully,
|
/// Migration was completed succesfully,
|
||||||
/// but there was a problem with io.
|
/// but there was a problem with io.
|
||||||
Io(IoError),
|
Io(IoError),
|
||||||
}
|
}
|
||||||
@ -50,9 +54,11 @@ impl Display for Error {
|
|||||||
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
|
||||||
let out = match *self {
|
let out = match *self {
|
||||||
Error::UnknownDatabaseVersion => "Current database version cannot be read".into(),
|
Error::UnknownDatabaseVersion => "Current database version cannot be read".into(),
|
||||||
Error::MigrationImpossible => format!("Migration to version {} is not possible", CURRENT_VERSION),
|
Error::UnsuportedPruningMethod => "Unsupported pruning method for database migration. Delete DB and resync.".into(),
|
||||||
Error::MigrationFailed => "Migration unexpectedly failed".into(),
|
Error::FutureDBVersion => "Database was created with newer client version. Upgrade your client or delete DB and resync.".into(),
|
||||||
Error::Io(ref err) => format!("Unexpected io error: {}", err),
|
Error::MigrationImpossible => format!("Database migration to version {} is not possible.", CURRENT_VERSION),
|
||||||
|
Error::MigrationFailed => "Database migration unexpectedly failed".into(),
|
||||||
|
Error::Io(ref err) => format!("Unexpected io error on DB migration: {}.", err),
|
||||||
};
|
};
|
||||||
|
|
||||||
write!(f, "{}", out)
|
write!(f, "{}", out)
|
||||||
@ -159,7 +165,7 @@ fn state_database_migrations(pruning: Algorithm) -> Result<MigrationManager, Err
|
|||||||
let res = match pruning {
|
let res = match pruning {
|
||||||
Algorithm::Archive => manager.add_migration(migrations::state::ArchiveV7::default()),
|
Algorithm::Archive => manager.add_migration(migrations::state::ArchiveV7::default()),
|
||||||
Algorithm::OverlayRecent => manager.add_migration(migrations::state::OverlayRecentV7::default()),
|
Algorithm::OverlayRecent => manager.add_migration(migrations::state::OverlayRecentV7::default()),
|
||||||
_ => die!("Unsupported pruning method for migration. Delete DB and resync"),
|
_ => return Err(Error::UnsuportedPruningMethod),
|
||||||
};
|
};
|
||||||
|
|
||||||
try!(res.map_err(|_| Error::MigrationImpossible));
|
try!(res.map_err(|_| Error::MigrationImpossible));
|
||||||
@ -207,12 +213,14 @@ pub fn migrate(path: &Path, pruning: Algorithm) -> Result<(), Error> {
|
|||||||
|
|
||||||
// migrate the databases.
|
// migrate the databases.
|
||||||
// main db directory may already exists, so let's check if we have blocks dir
|
// main db directory may already exists, so let's check if we have blocks dir
|
||||||
if version != CURRENT_VERSION && exists(&blocks_database_path(path)) {
|
if version < CURRENT_VERSION && exists(&blocks_database_path(path)) {
|
||||||
println!("Migrating database from version {} to {}", version, CURRENT_VERSION);
|
println!("Migrating database from version {} to {}", version, CURRENT_VERSION);
|
||||||
try!(migrate_database(version, blocks_database_path(path), try!(blocks_database_migrations())));
|
try!(migrate_database(version, blocks_database_path(path), try!(blocks_database_migrations())));
|
||||||
try!(migrate_database(version, extras_database_path(path), try!(extras_database_migrations())));
|
try!(migrate_database(version, extras_database_path(path), try!(extras_database_migrations())));
|
||||||
try!(migrate_database(version, state_database_path(path), try!(state_database_migrations(pruning))));
|
try!(migrate_database(version, state_database_path(path), try!(state_database_migrations(pruning))));
|
||||||
println!("Migration finished");
|
println!("Migration finished");
|
||||||
|
} else if version > CURRENT_VERSION {
|
||||||
|
return Err(Error::FutureDBVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
// update version file.
|
// update version file.
|
||||||
|
@ -19,11 +19,12 @@ use std::env;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
use isatty::{stderr_isatty};
|
||||||
use time;
|
use time;
|
||||||
use env_logger::LogBuilder;
|
use env_logger::LogBuilder;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use util::RotatingLogger;
|
use util::RotatingLogger;
|
||||||
use util::log::{Applyable, Colour};
|
use util::log::Colour;
|
||||||
|
|
||||||
/// Sets up the logger
|
/// Sets up the logger
|
||||||
pub fn setup_log(init: &Option<String>, enable_color: bool, log_to_file: &Option<String>) -> Arc<RotatingLogger> {
|
pub fn setup_log(init: &Option<String>, enable_color: bool, log_to_file: &Option<String>) -> Arc<RotatingLogger> {
|
||||||
@ -47,19 +48,26 @@ pub fn setup_log(init: &Option<String>, enable_color: bool, log_to_file: &Option
|
|||||||
builder.parse(s);
|
builder.parse(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
let logs = Arc::new(RotatingLogger::new(levels, enable_color));
|
let enable_color = enable_color && stderr_isatty();
|
||||||
|
let logs = Arc::new(RotatingLogger::new(levels));
|
||||||
let logger = logs.clone();
|
let logger = logs.clone();
|
||||||
let maybe_file = log_to_file.as_ref().map(|f| File::create(f).unwrap_or_else(|_| die!("Cannot write to log file given: {}", f)));
|
let maybe_file = log_to_file.as_ref().map(|f| File::create(f).unwrap_or_else(|_| die!("Cannot write to log file given: {}", f)));
|
||||||
let format = move |record: &LogRecord| {
|
let format = move |record: &LogRecord| {
|
||||||
let timestamp = time::strftime("%Y-%m-%d %H:%M:%S %Z", &time::now()).unwrap();
|
let timestamp = time::strftime("%Y-%m-%d %H:%M:%S %Z", &time::now()).unwrap();
|
||||||
|
|
||||||
let format = if max_log_level() <= LogLevelFilter::Info {
|
let with_color = if max_log_level() <= LogLevelFilter::Info {
|
||||||
format!("{}{}", timestamp.apply(Colour::Black.bold()), record.args())
|
format!("{}{}", Colour::Black.bold().paint(timestamp), record.args())
|
||||||
} else {
|
} else {
|
||||||
format!("{}{}:{}: {}", timestamp.apply(Colour::Black.bold()), record.level(), record.target(), record.args())
|
format!("{}{}:{}: {}", Colour::Black.bold().paint(timestamp), record.level(), record.target(), record.args())
|
||||||
|
};
|
||||||
|
|
||||||
|
let removed_color = kill_color(with_color.as_ref());
|
||||||
|
|
||||||
|
let ret = match enable_color {
|
||||||
|
true => with_color,
|
||||||
|
false => removed_color.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let removed_color = kill_color(format.as_ref());
|
|
||||||
if let Some(mut file) = maybe_file.as_ref() {
|
if let Some(mut file) = maybe_file.as_ref() {
|
||||||
// ignore errors - there's nothing we can do
|
// ignore errors - there's nothing we can do
|
||||||
let _ = file.write_all(removed_color.as_bytes());
|
let _ = file.write_all(removed_color.as_bytes());
|
||||||
@ -67,7 +75,7 @@ pub fn setup_log(init: &Option<String>, enable_color: bool, log_to_file: &Option
|
|||||||
}
|
}
|
||||||
logger.append(removed_color);
|
logger.append(removed_color);
|
||||||
|
|
||||||
format
|
ret
|
||||||
};
|
};
|
||||||
builder.format(format);
|
builder.format(format);
|
||||||
builder.init().unwrap();
|
builder.init().unwrap();
|
||||||
@ -84,7 +92,7 @@ fn kill_color(s: &str) -> String {
|
|||||||
#[test]
|
#[test]
|
||||||
fn should_remove_colour() {
|
fn should_remove_colour() {
|
||||||
let before = "test";
|
let before = "test";
|
||||||
let after = kill_color(&before.apply(Colour::Red.bold()));
|
let after = kill_color(&Colour::Red.bold().paint(before));
|
||||||
assert_eq!(after, "test");
|
assert_eq!(after, "test");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,6 @@ use std::path::PathBuf;
|
|||||||
use ansi_term::Colour;
|
use ansi_term::Colour;
|
||||||
use util::panics::{ForwardPanic, PanicHandler};
|
use util::panics::{ForwardPanic, PanicHandler};
|
||||||
use util::path::restrict_permissions_owner;
|
use util::path::restrict_permissions_owner;
|
||||||
use util::Applyable;
|
|
||||||
use rpc_apis;
|
use rpc_apis;
|
||||||
use ethcore_signer as signer;
|
use ethcore_signer as signer;
|
||||||
use die::*;
|
use die::*;
|
||||||
@ -60,7 +59,7 @@ pub fn new_token(path: String) -> io::Result<()> {
|
|||||||
let mut codes = try!(signer::AuthCodes::from_file(&path));
|
let mut codes = try!(signer::AuthCodes::from_file(&path));
|
||||||
let code = try!(codes.generate_new());
|
let code = try!(codes.generate_new());
|
||||||
try!(codes.to_file(&path));
|
try!(codes.to_file(&path));
|
||||||
println!("This key code will authorise your System Signer UI: {}", code.apply(Colour::White.bold()));
|
info!("This key code will authorise your System Signer UI: {}", Colour::White.bold().paint(code));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
extern crate ethash;
|
extern crate ethash;
|
||||||
|
|
||||||
|
use std::io::{Write};
|
||||||
|
use std::process::{Command, Stdio};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::{Instant, Duration};
|
use std::time::{Instant, Duration};
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
@ -28,7 +30,7 @@ use jsonrpc_core::*;
|
|||||||
use util::numbers::*;
|
use util::numbers::*;
|
||||||
use util::sha3::*;
|
use util::sha3::*;
|
||||||
use util::rlp::{encode, decode, UntrustedRlp, View};
|
use util::rlp::{encode, decode, UntrustedRlp, View};
|
||||||
use util::Mutex;
|
use util::{FromHex, Mutex};
|
||||||
use ethcore::account_provider::AccountProvider;
|
use ethcore::account_provider::AccountProvider;
|
||||||
use ethcore::client::{MiningBlockChainClient, BlockID, TransactionID, UncleID};
|
use ethcore::client::{MiningBlockChainClient, BlockID, TransactionID, UncleID};
|
||||||
use ethcore::header::Header as BlockHeader;
|
use ethcore::header::Header as BlockHeader;
|
||||||
@ -255,6 +257,12 @@ impl<C, S: ?Sized, M, EM> EthClient<C, S, M, EM> where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
static SOLC: &'static str = "solc.exe";
|
||||||
|
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
static SOLC: &'static str = "solc";
|
||||||
|
|
||||||
impl<C, S: ?Sized, M, EM> Eth for EthClient<C, S, M, EM> where
|
impl<C, S: ?Sized, M, EM> Eth for EthClient<C, S, M, EM> where
|
||||||
C: MiningBlockChainClient + 'static,
|
C: MiningBlockChainClient + 'static,
|
||||||
S: SyncProvider + 'static,
|
S: SyncProvider + 'static,
|
||||||
@ -508,7 +516,13 @@ impl<C, S: ?Sized, M, EM> Eth for EthClient<C, S, M, EM> where
|
|||||||
fn compilers(&self, params: Params) -> Result<Value, Error> {
|
fn compilers(&self, params: Params) -> Result<Value, Error> {
|
||||||
try!(self.active());
|
try!(self.active());
|
||||||
match params {
|
match params {
|
||||||
Params::None => to_value(&(&[] as &[String])),
|
Params::None => {
|
||||||
|
let mut compilers = vec![];
|
||||||
|
if Command::new(SOLC).output().is_ok() {
|
||||||
|
compilers.push("solidity".to_owned())
|
||||||
|
}
|
||||||
|
to_value(&compilers)
|
||||||
|
}
|
||||||
_ => Err(Error::invalid_params())
|
_ => Err(Error::invalid_params())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -647,8 +661,28 @@ impl<C, S: ?Sized, M, EM> Eth for EthClient<C, S, M, EM> where
|
|||||||
rpc_unimplemented!()
|
rpc_unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compile_solidity(&self, _: Params) -> Result<Value, Error> {
|
fn compile_solidity(&self, params: Params) -> Result<Value, Error> {
|
||||||
try!(self.active());
|
try!(self.active());
|
||||||
rpc_unimplemented!()
|
from_params::<(String, )>(params)
|
||||||
|
.and_then(|(code, )| {
|
||||||
|
let maybe_child = Command::new(SOLC)
|
||||||
|
.arg("--bin")
|
||||||
|
.arg("--optimize")
|
||||||
|
.stdin(Stdio::piped())
|
||||||
|
.stdout(Stdio::piped())
|
||||||
|
.stderr(Stdio::null())
|
||||||
|
.spawn();
|
||||||
|
if let Ok(mut child) = maybe_child {
|
||||||
|
if let Ok(_) = child.stdin.as_mut().expect("we called child.stdin(Stdio::piped()) before spawn; qed").write_all(code.as_bytes()) {
|
||||||
|
if let Ok(output) = child.wait_with_output() {
|
||||||
|
let s = String::from_utf8_lossy(&output.stdout);
|
||||||
|
if let Some(hex) = s.lines().skip_while(|ref l| !l.contains("Binary")).skip(1).next() {
|
||||||
|
return to_value(&Bytes::new(hex.from_hex().unwrap_or(vec![])));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(Error::invalid_params())
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -201,7 +201,10 @@ const TRANSACTION_COUNT_SPEC: &'static [u8] = br#"{
|
|||||||
"durationLimit": "0x0d",
|
"durationLimit": "0x0d",
|
||||||
"blockReward": "0x4563918244F40000",
|
"blockReward": "0x4563918244F40000",
|
||||||
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
||||||
"frontierCompatibilityModeLimit": "0xffffffffffffffff"
|
"frontierCompatibilityModeLimit": "0xffffffffffffffff",
|
||||||
|
"daoHardforkTransition": "0xffffffffffffffff",
|
||||||
|
"daoHardforkBeneficiary": "0x0000000000000000000000000000000000000000",
|
||||||
|
"daoHardforkAccounts": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -707,6 +707,11 @@ fn rpc_eth_compilers() {
|
|||||||
assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
|
assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// These tests are incorrect: their output is undefined as long as eth_getCompilers is [].
|
||||||
|
// Will ignore for now, but should probably be replaced by more substantial tests which check
|
||||||
|
// the output of eth_getCompilers to determine whether to test. CI systems can then be preinstalled
|
||||||
|
// with solc/serpent/lllc and they'll be proper again.
|
||||||
|
#[ignore]
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_eth_compile_lll() {
|
fn rpc_eth_compile_lll() {
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "eth_compileLLL", "params": [], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "eth_compileLLL", "params": [], "id": 1}"#;
|
||||||
@ -715,6 +720,7 @@ fn rpc_eth_compile_lll() {
|
|||||||
assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
|
assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ignore]
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_eth_compile_solidity() {
|
fn rpc_eth_compile_solidity() {
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "eth_compileSolidity", "params": [], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "eth_compileSolidity", "params": [], "id": 1}"#;
|
||||||
@ -723,6 +729,7 @@ fn rpc_eth_compile_solidity() {
|
|||||||
assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
|
assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ignore]
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_eth_compile_serpent() {
|
fn rpc_eth_compile_serpent() {
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "eth_compileSerpent", "params": [], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "eth_compileSerpent", "params": [], "id": 1}"#;
|
||||||
|
@ -32,7 +32,7 @@ fn client_service() -> Arc<TestBlockChainClient> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn logger() -> Arc<RotatingLogger> {
|
fn logger() -> Arc<RotatingLogger> {
|
||||||
Arc::new(RotatingLogger::new("rpc=trace".to_owned(), false))
|
Arc::new(RotatingLogger::new("rpc=trace".to_owned()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn settings() -> Arc<NetworkSettings> {
|
fn settings() -> Arc<NetworkSettings> {
|
||||||
|
@ -28,7 +28,7 @@ pub enum BlockNumber {
|
|||||||
/// Earliest block (genesis)
|
/// Earliest block (genesis)
|
||||||
Earliest,
|
Earliest,
|
||||||
/// Pending block (being mined)
|
/// Pending block (being mined)
|
||||||
Pending
|
Pending,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Deserialize for BlockNumber {
|
impl Deserialize for BlockNumber {
|
||||||
@ -63,8 +63,8 @@ impl Into<BlockID> for BlockNumber {
|
|||||||
match self {
|
match self {
|
||||||
BlockNumber::Num(n) => BlockID::Number(n),
|
BlockNumber::Num(n) => BlockID::Number(n),
|
||||||
BlockNumber::Earliest => BlockID::Earliest,
|
BlockNumber::Earliest => BlockID::Earliest,
|
||||||
// TODO: change this once blockid support pendingst,
|
BlockNumber::Latest => BlockID::Latest,
|
||||||
BlockNumber::Pending | BlockNumber::Latest => BlockID::Latest,
|
BlockNumber::Pending => BlockID::Pending,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -87,7 +87,7 @@ mod tests {
|
|||||||
assert_eq!(BlockID::Number(100), BlockNumber::Num(100).into());
|
assert_eq!(BlockID::Number(100), BlockNumber::Num(100).into());
|
||||||
assert_eq!(BlockID::Earliest, BlockNumber::Earliest.into());
|
assert_eq!(BlockID::Earliest, BlockNumber::Earliest.into());
|
||||||
assert_eq!(BlockID::Latest, BlockNumber::Latest.into());
|
assert_eq!(BlockID::Latest, BlockNumber::Latest.into());
|
||||||
assert_eq!(BlockID::Latest, BlockNumber::Pending.into());
|
assert_eq!(BlockID::Pending, BlockNumber::Pending.into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,5 @@ parity-dapps-signer = { git = "https://github.com/ethcore/parity-ui.git", versio
|
|||||||
clippy = { version = "0.0.79", optional = true}
|
clippy = { version = "0.0.79", optional = true}
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["ui"]
|
|
||||||
dev = ["clippy"]
|
dev = ["clippy"]
|
||||||
ui = ["parity-dapps-signer"]
|
ui = ["parity-dapps-signer"]
|
||||||
|
@ -295,7 +295,7 @@ impl JournalDB for OverlayRecentDB {
|
|||||||
}
|
}
|
||||||
// update the overlay
|
// update the overlay
|
||||||
for k in overlay_deletions {
|
for k in overlay_deletions {
|
||||||
journal_overlay.backing_overlay.remove(&OverlayRecentDB::to_short_key(&k));
|
journal_overlay.backing_overlay.remove_and_purge(&OverlayRecentDB::to_short_key(&k));
|
||||||
}
|
}
|
||||||
// apply canon deletions
|
// apply canon deletions
|
||||||
for k in canon_deletions {
|
for k in canon_deletions {
|
||||||
@ -303,7 +303,6 @@ impl JournalDB for OverlayRecentDB {
|
|||||||
try!(batch.delete(&k));
|
try!(batch.delete(&k));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
journal_overlay.backing_overlay.purge();
|
|
||||||
}
|
}
|
||||||
journal_overlay.journal.remove(&end_era);
|
journal_overlay.journal.remove(&end_era);
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,8 @@
|
|||||||
//! Key-Value store abstraction with `RocksDB` backend.
|
//! Key-Value store abstraction with `RocksDB` backend.
|
||||||
|
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use rocksdb::{DB, Writable, WriteBatch, IteratorMode, DBVector, DBIterator,
|
use rocksdb::{DB, Writable, WriteBatch, WriteOptions, IteratorMode, DBVector, DBIterator,
|
||||||
IndexType, Options, DBCompactionStyle, BlockBasedOptions, Direction};
|
IndexType, Options, DBCompactionStyle, BlockBasedOptions, Direction, Cache};
|
||||||
|
|
||||||
const DB_BACKGROUND_FLUSHES: i32 = 2;
|
const DB_BACKGROUND_FLUSHES: i32 = 2;
|
||||||
const DB_BACKGROUND_COMPACTIONS: i32 = 2;
|
const DB_BACKGROUND_COMPACTIONS: i32 = 2;
|
||||||
@ -144,6 +144,7 @@ impl<'a> Iterator for DatabaseIterator {
|
|||||||
/// Key-Value database.
|
/// Key-Value database.
|
||||||
pub struct Database {
|
pub struct Database {
|
||||||
db: DB,
|
db: DB,
|
||||||
|
write_opts: WriteOptions,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Database {
|
impl Database {
|
||||||
@ -169,36 +170,28 @@ impl Database {
|
|||||||
|
|
||||||
opts.set_max_background_flushes(DB_BACKGROUND_FLUSHES);
|
opts.set_max_background_flushes(DB_BACKGROUND_FLUSHES);
|
||||||
opts.set_max_background_compactions(DB_BACKGROUND_COMPACTIONS);
|
opts.set_max_background_compactions(DB_BACKGROUND_COMPACTIONS);
|
||||||
if let Some(cache_size) = config.cache_size {
|
|
||||||
// half goes to read cache
|
|
||||||
opts.set_block_cache_size_mb(cache_size as u64 / 2);
|
|
||||||
// quarter goes to each of the two write buffers
|
|
||||||
opts.set_write_buffer_size(cache_size * 1024 * 256);
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
opts.set_bytes_per_sync(8388608);
|
|
||||||
opts.set_disable_data_sync(false);
|
|
||||||
opts.set_block_cache_size_mb(1024);
|
|
||||||
opts.set_table_cache_num_shard_bits(6);
|
|
||||||
opts.set_max_write_buffer_number(32);
|
|
||||||
opts.set_write_buffer_size(536870912);
|
|
||||||
opts.set_target_file_size_base(1073741824);
|
|
||||||
opts.set_min_write_buffer_number_to_merge(4);
|
|
||||||
opts.set_level_zero_stop_writes_trigger(2000);
|
|
||||||
opts.set_level_zero_slowdown_writes_trigger(0);
|
|
||||||
opts.set_compaction_style(DBUniversalCompaction);
|
|
||||||
opts.set_max_background_compactions(4);
|
|
||||||
opts.set_max_background_flushes(4);
|
|
||||||
opts.set_filter_deletes(false);
|
|
||||||
opts.set_disable_auto_compactions(false);
|
|
||||||
*/
|
|
||||||
|
|
||||||
if let Some(size) = config.prefix_size {
|
if let Some(size) = config.prefix_size {
|
||||||
let mut block_opts = BlockBasedOptions::new();
|
let mut block_opts = BlockBasedOptions::new();
|
||||||
block_opts.set_index_type(IndexType::HashSearch);
|
block_opts.set_index_type(IndexType::HashSearch);
|
||||||
opts.set_block_based_table_factory(&block_opts);
|
opts.set_block_based_table_factory(&block_opts);
|
||||||
opts.set_prefix_extractor_fixed_size(size);
|
opts.set_prefix_extractor_fixed_size(size);
|
||||||
|
if let Some(cache_size) = config.cache_size {
|
||||||
|
block_opts.set_cache(Cache::new(cache_size * 1024 * 256));
|
||||||
|
opts.set_write_buffer_size(cache_size * 1024 * 256);
|
||||||
|
}
|
||||||
|
} else if let Some(cache_size) = config.cache_size {
|
||||||
|
let mut block_opts = BlockBasedOptions::new();
|
||||||
|
// half goes to read cache
|
||||||
|
block_opts.set_cache(Cache::new(cache_size * 1024 * 256));
|
||||||
|
opts.set_block_based_table_factory(&block_opts);
|
||||||
|
// quarter goes to each of the two write buffers
|
||||||
|
opts.set_write_buffer_size(cache_size * 1024 * 256);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut write_opts = WriteOptions::new();
|
||||||
|
write_opts.disable_wal(true);
|
||||||
|
|
||||||
let db = match DB::open(&opts, path) {
|
let db = match DB::open(&opts, path) {
|
||||||
Ok(db) => db,
|
Ok(db) => db,
|
||||||
Err(ref s) if s.starts_with("Corruption:") => {
|
Err(ref s) if s.starts_with("Corruption:") => {
|
||||||
@ -209,7 +202,7 @@ impl Database {
|
|||||||
},
|
},
|
||||||
Err(s) => { return Err(s); }
|
Err(s) => { return Err(s); }
|
||||||
};
|
};
|
||||||
Ok(Database { db: db })
|
Ok(Database { db: db, write_opts: write_opts, })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Insert a key-value pair in the transaction. Any existing value value will be overwritten.
|
/// Insert a key-value pair in the transaction. Any existing value value will be overwritten.
|
||||||
@ -224,7 +217,7 @@ impl Database {
|
|||||||
|
|
||||||
/// Commit transaction to database.
|
/// Commit transaction to database.
|
||||||
pub fn write(&self, tr: DBTransaction) -> Result<(), String> {
|
pub fn write(&self, tr: DBTransaction) -> Result<(), String> {
|
||||||
self.db.write(tr.batch)
|
self.db.write_opt(tr.batch, &self.write_opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get value by key.
|
/// Get value by key.
|
||||||
|
@ -17,35 +17,13 @@
|
|||||||
//! Common log helper functions
|
//! Common log helper functions
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::borrow::Cow;
|
|
||||||
use rlog::LogLevelFilter;
|
use rlog::LogLevelFilter;
|
||||||
use env_logger::LogBuilder;
|
use env_logger::LogBuilder;
|
||||||
use std::sync::atomic::{Ordering, AtomicBool};
|
|
||||||
use arrayvec::ArrayVec;
|
use arrayvec::ArrayVec;
|
||||||
pub use ansi_term::{Colour, Style};
|
pub use ansi_term::{Colour, Style};
|
||||||
|
|
||||||
use parking_lot::{RwLock, RwLockReadGuard};
|
use parking_lot::{RwLock, RwLockReadGuard};
|
||||||
|
|
||||||
lazy_static! {
|
|
||||||
static ref USE_COLOR: AtomicBool = AtomicBool::new(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Something which can be apply()ed.
|
|
||||||
pub trait Applyable: AsRef<str> {
|
|
||||||
/// Apply the style `c` to ourself, returning us styled in that manner.
|
|
||||||
fn apply(&self, c: Style) -> Cow<str>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: AsRef<str>> Applyable for T {
|
|
||||||
fn apply(&self, c: Style) -> Cow<str> {
|
|
||||||
let s = self.as_ref();
|
|
||||||
match USE_COLOR.load(Ordering::Relaxed) {
|
|
||||||
true => Cow::Owned(format!("{}", c.paint(s))),
|
|
||||||
false => Cow::Borrowed(s),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref LOG_DUMMY: bool = {
|
static ref LOG_DUMMY: bool = {
|
||||||
let mut builder = LogBuilder::new();
|
let mut builder = LogBuilder::new();
|
||||||
@ -81,8 +59,7 @@ impl RotatingLogger {
|
|||||||
|
|
||||||
/// Creates new `RotatingLogger` with given levels.
|
/// Creates new `RotatingLogger` with given levels.
|
||||||
/// It does not enforce levels - it's just read only.
|
/// It does not enforce levels - it's just read only.
|
||||||
pub fn new(levels: String, enable_color: bool) -> Self {
|
pub fn new(levels: String) -> Self {
|
||||||
USE_COLOR.store(enable_color, Ordering::Relaxed);
|
|
||||||
RotatingLogger {
|
RotatingLogger {
|
||||||
levels: levels,
|
levels: levels,
|
||||||
logs: RwLock::new(ArrayVec::<[_; LOG_SIZE]>::new()),
|
logs: RwLock::new(ArrayVec::<[_; LOG_SIZE]>::new()),
|
||||||
@ -111,7 +88,7 @@ mod test {
|
|||||||
use super::RotatingLogger;
|
use super::RotatingLogger;
|
||||||
|
|
||||||
fn logger() -> RotatingLogger {
|
fn logger() -> RotatingLogger {
|
||||||
RotatingLogger::new("test".to_owned(), false)
|
RotatingLogger::new("test".to_owned())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -24,6 +24,7 @@ use hashdb::*;
|
|||||||
use heapsize::*;
|
use heapsize::*;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::collections::hash_map::Entry;
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
|
|
||||||
#[derive(Debug,Clone)]
|
#[derive(Debug,Clone)]
|
||||||
@ -162,6 +163,24 @@ impl MemoryDB {
|
|||||||
pub fn mem_used(&self) -> usize {
|
pub fn mem_used(&self) -> usize {
|
||||||
self.data.heap_size_of_children()
|
self.data.heap_size_of_children()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Remove an element and delete it from storage if reference count reaches zero.
|
||||||
|
pub fn remove_and_purge(&mut self, key: &H256) {
|
||||||
|
if key == &SHA3_NULL_RLP {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
match self.data.entry(key.clone()) {
|
||||||
|
Entry::Occupied(mut entry) =>
|
||||||
|
if entry.get().1 == 1 {
|
||||||
|
entry.remove();
|
||||||
|
} else {
|
||||||
|
entry.get_mut().1 -= 1;
|
||||||
|
},
|
||||||
|
Entry::Vacant(entry) => {
|
||||||
|
entry.insert((Bytes::new(), -1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static NULL_RLP_STATIC: [u8; 1] = [0x80; 1];
|
static NULL_RLP_STATIC: [u8; 1] = [0x80; 1];
|
||||||
@ -269,3 +288,28 @@ fn memorydb_denote() {
|
|||||||
|
|
||||||
assert_eq!(m.get(&hash).unwrap(), b"Hello world!");
|
assert_eq!(m.get(&hash).unwrap(), b"Hello world!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn memorydb_remove_and_purge() {
|
||||||
|
let hello_bytes = b"Hello world!";
|
||||||
|
let hello_key = hello_bytes.sha3();
|
||||||
|
|
||||||
|
let mut m = MemoryDB::new();
|
||||||
|
m.remove(&hello_key);
|
||||||
|
assert_eq!(m.raw(&hello_key).unwrap().1, -1);
|
||||||
|
m.purge();
|
||||||
|
assert_eq!(m.raw(&hello_key).unwrap().1, -1);
|
||||||
|
m.insert(hello_bytes);
|
||||||
|
assert_eq!(m.raw(&hello_key).unwrap().1, 0);
|
||||||
|
m.purge();
|
||||||
|
assert_eq!(m.raw(&hello_key), None);
|
||||||
|
|
||||||
|
let mut m = MemoryDB::new();
|
||||||
|
m.remove_and_purge(&hello_key);
|
||||||
|
assert_eq!(m.raw(&hello_key).unwrap().1, -1);
|
||||||
|
m.insert(hello_bytes);
|
||||||
|
m.insert(hello_bytes);
|
||||||
|
assert_eq!(m.raw(&hello_key).unwrap().1, 1);
|
||||||
|
m.remove_and_purge(&hello_key);
|
||||||
|
assert_eq!(m.raw(&hello_key), None);
|
||||||
|
}
|
||||||
|
@ -21,10 +21,25 @@ use network::error::NetworkError;
|
|||||||
use network::host::{Host, NetworkContext, NetworkIoMessage, ProtocolId};
|
use network::host::{Host, NetworkContext, NetworkIoMessage, ProtocolId};
|
||||||
use network::stats::NetworkStats;
|
use network::stats::NetworkStats;
|
||||||
use io::*;
|
use io::*;
|
||||||
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use ansi_term::Colour;
|
||||||
|
|
||||||
|
struct HostHandler {
|
||||||
|
public_url: RwLock<Option<String>>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IoHandler<NetworkIoMessage> for HostHandler {
|
||||||
|
fn message(&self, _io: &IoContext<NetworkIoMessage>, message: &NetworkIoMessage) {
|
||||||
|
if let NetworkIoMessage::NetworkStarted(ref public_url) = *message {
|
||||||
|
let mut url = self.public_url.write();
|
||||||
|
if url.as_ref().map(|uref| uref != public_url).unwrap_or(true) {
|
||||||
|
info!(target: "network", "Public node URL: {}", Colour::White.bold().paint(public_url.as_ref()));
|
||||||
|
}
|
||||||
|
*url = Some(public_url.to_owned());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// IO Service with networking
|
/// IO Service with networking
|
||||||
/// `Message` defines a notification data type.
|
/// `Message` defines a notification data type.
|
||||||
@ -34,12 +49,14 @@ pub struct NetworkService {
|
|||||||
host: RwLock<Option<Arc<Host>>>,
|
host: RwLock<Option<Arc<Host>>>,
|
||||||
stats: Arc<NetworkStats>,
|
stats: Arc<NetworkStats>,
|
||||||
panic_handler: Arc<PanicHandler>,
|
panic_handler: Arc<PanicHandler>,
|
||||||
|
host_handler: Arc<HostHandler>,
|
||||||
config: NetworkConfiguration,
|
config: NetworkConfiguration,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NetworkService {
|
impl NetworkService {
|
||||||
/// Starts IO event loop
|
/// Starts IO event loop
|
||||||
pub fn new(config: NetworkConfiguration) -> Result<NetworkService, UtilError> {
|
pub fn new(config: NetworkConfiguration) -> Result<NetworkService, UtilError> {
|
||||||
|
let host_handler = Arc::new(HostHandler { public_url: RwLock::new(None) });
|
||||||
let panic_handler = PanicHandler::new_in_arc();
|
let panic_handler = PanicHandler::new_in_arc();
|
||||||
let io_service = try!(IoService::<NetworkIoMessage>::start());
|
let io_service = try!(IoService::<NetworkIoMessage>::start());
|
||||||
panic_handler.forward_from(&io_service);
|
panic_handler.forward_from(&io_service);
|
||||||
@ -53,6 +70,7 @@ impl NetworkService {
|
|||||||
panic_handler: panic_handler,
|
panic_handler: panic_handler,
|
||||||
host: RwLock::new(None),
|
host: RwLock::new(None),
|
||||||
config: config,
|
config: config,
|
||||||
|
host_handler: host_handler,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,6 +124,11 @@ impl NetworkService {
|
|||||||
try!(self.io_service.register_handler(h.clone()));
|
try!(self.io_service.register_handler(h.clone()));
|
||||||
*host = Some(h);
|
*host = Some(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.host_handler.public_url.read().is_none() {
|
||||||
|
try!(self.io_service.register_handler(self.host_handler.clone()));
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,10 +54,14 @@ impl<'db> FatDBMut<'db> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'db> TrieMut for FatDBMut<'db> {
|
impl<'db> TrieMut for FatDBMut<'db> {
|
||||||
fn root(&self) -> &H256 {
|
fn root(&mut self) -> &H256 {
|
||||||
self.raw.root()
|
self.raw.root()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_empty(&self) -> bool {
|
||||||
|
self.raw.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
fn contains(&self, key: &[u8]) -> bool {
|
fn contains(&self, key: &[u8]) -> bool {
|
||||||
self.raw.contains(&key.sha3())
|
self.raw.contains(&key.sha3())
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,6 @@ pub mod sectriedb;
|
|||||||
pub mod sectriedbmut;
|
pub mod sectriedbmut;
|
||||||
|
|
||||||
mod fatdb;
|
mod fatdb;
|
||||||
|
|
||||||
mod fatdbmut;
|
mod fatdbmut;
|
||||||
|
|
||||||
pub use self::trietraits::{Trie, TrieMut};
|
pub use self::trietraits::{Trie, TrieMut};
|
||||||
|
@ -25,11 +25,11 @@ pub enum Node<'a> {
|
|||||||
/// Null trie node; could be an empty root or an empty branch entry.
|
/// Null trie node; could be an empty root or an empty branch entry.
|
||||||
Empty,
|
Empty,
|
||||||
/// Leaf node; has key slice and value. Value may not be empty.
|
/// Leaf node; has key slice and value. Value may not be empty.
|
||||||
Leaf(NibbleSlice<'a>, &'a[u8]),
|
Leaf(NibbleSlice<'a>, &'a [u8]),
|
||||||
/// Extension node; has key slice and node data. Data may not be null.
|
/// Extension node; has key slice and node data. Data may not be null.
|
||||||
Extension(NibbleSlice<'a>, &'a[u8]),
|
Extension(NibbleSlice<'a>, &'a [u8]),
|
||||||
/// Branch node; has array of 16 child nodes (each possibly null) and an optional immediate node data.
|
/// Branch node; has array of 16 child nodes (each possibly null) and an optional immediate node data.
|
||||||
Branch([&'a[u8]; 16], Option<&'a [u8]>)
|
Branch([&'a [u8]; 16], Option<&'a [u8]>)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Node<'a> {
|
impl<'a> Node<'a> {
|
||||||
|
@ -51,7 +51,13 @@ impl<'db> SecTrieDBMut<'db> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'db> TrieMut for SecTrieDBMut<'db> {
|
impl<'db> TrieMut for SecTrieDBMut<'db> {
|
||||||
fn root(&self) -> &H256 { self.raw.root() }
|
fn root(&mut self) -> &H256 {
|
||||||
|
self.raw.root()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_empty(&self) -> bool {
|
||||||
|
self.raw.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
fn contains(&self, key: &[u8]) -> bool {
|
fn contains(&self, key: &[u8]) -> bool {
|
||||||
self.raw.contains(&key.sha3())
|
self.raw.contains(&key.sha3())
|
||||||
|
@ -88,8 +88,7 @@ impl<'db> TrieDB<'db> {
|
|||||||
pub fn to_map(hashes: Vec<H256>) -> HashMap<H256, u32> {
|
pub fn to_map(hashes: Vec<H256>) -> HashMap<H256, u32> {
|
||||||
let mut r: HashMap<H256, u32> = HashMap::new();
|
let mut r: HashMap<H256, u32> = HashMap::new();
|
||||||
for h in hashes.into_iter() {
|
for h in hashes.into_iter() {
|
||||||
let c = *r.get(&h).unwrap_or(&0);
|
*r.entry(h).or_insert(0) += 1;
|
||||||
r.insert(h, c + 1);
|
|
||||||
}
|
}
|
||||||
r
|
r
|
||||||
}
|
}
|
||||||
@ -184,7 +183,7 @@ impl<'db> TrieDB<'db> {
|
|||||||
|
|
||||||
/// Return optional data for a key given as a `NibbleSlice`. Returns `None` if no data exists.
|
/// Return optional data for a key given as a `NibbleSlice`. Returns `None` if no data exists.
|
||||||
fn do_lookup<'a, 'key>(&'a self, key: &NibbleSlice<'key>) -> Option<&'a [u8]> where 'a: 'key {
|
fn do_lookup<'a, 'key>(&'a self, key: &NibbleSlice<'key>) -> Option<&'a [u8]> where 'a: 'key {
|
||||||
let root_rlp = self.db.get(&self.root).expect("Trie root not found!");
|
let root_rlp = self.root_data();
|
||||||
self.get_from_node(&root_rlp, key)
|
self.get_from_node(&root_rlp, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -18,7 +18,7 @@ use hash::H256;
|
|||||||
use rlp::SHA3_NULL_RLP;
|
use rlp::SHA3_NULL_RLP;
|
||||||
|
|
||||||
/// Trie-Item type.
|
/// Trie-Item type.
|
||||||
pub type TrieItem<'a> = (Vec<u8>, &'a[u8]);
|
pub type TrieItem<'a> = (Vec<u8>, &'a [u8]);
|
||||||
|
|
||||||
/// A key-value datastore implemented as a database-backed modified Merkle tree.
|
/// A key-value datastore implemented as a database-backed modified Merkle tree.
|
||||||
pub trait Trie {
|
pub trait Trie {
|
||||||
@ -41,10 +41,10 @@ pub trait Trie {
|
|||||||
/// A key-value datastore implemented as a database-backed modified Merkle tree.
|
/// A key-value datastore implemented as a database-backed modified Merkle tree.
|
||||||
pub trait TrieMut {
|
pub trait TrieMut {
|
||||||
/// Return the root of the trie.
|
/// Return the root of the trie.
|
||||||
fn root(&self) -> &H256;
|
fn root(&mut self) -> &H256;
|
||||||
|
|
||||||
/// Is the trie empty?
|
/// Is the trie empty?
|
||||||
fn is_empty(&self) -> bool { *self.root() == SHA3_NULL_RLP }
|
fn is_empty(&self) -> bool;
|
||||||
|
|
||||||
/// Does the trie contain a given key?
|
/// Does the trie contain a given key?
|
||||||
fn contains(&self, key: &[u8]) -> bool;
|
fn contains(&self, key: &[u8]) -> bool;
|
||||||
|
Loading…
Reference in New Issue
Block a user