Merge branch 'master' into new-ui
This commit is contained in:
commit
a2735308b9
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)",
|
||||||
@ -585,6 +586,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"
|
||||||
@ -1067,7 +1078,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#6472a9dce16c267a3acec2ee6fd01d1bf8de4913"
|
source = "git+https://github.com/ethcore/rust-rocksdb#dd597245bfcb621c6ffc45478e1fda0b05d2f409"
|
||||||
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)",
|
||||||
@ -1076,7 +1087,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#6472a9dce16c267a3acec2ee6fd01d1bf8de4913"
|
source = "git+https://github.com/ethcore/rust-rocksdb#dd597245bfcb621c6ffc45478e1fda0b05d2f409"
|
||||||
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" }
|
||||||
|
@ -18,10 +18,10 @@ branches:
|
|||||||
install:
|
install:
|
||||||
- git submodule update --init --recursive
|
- git submodule update --init --recursive
|
||||||
- ps: Install-Product node 6
|
- ps: Install-Product node 6
|
||||||
- ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-1.9.0-x86_64-pc-windows-msvc.exe"
|
- ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-1.10.0-x86_64-pc-windows-msvc.exe"
|
||||||
- ps: Start-FileDownload "https://github.com/ethcore/win-build/raw/master/SimpleFC.dll" -FileName nsis\SimpleFC.dll
|
- ps: Start-FileDownload "https://github.com/ethcore/win-build/raw/master/SimpleFC.dll" -FileName nsis\SimpleFC.dll
|
||||||
- ps: Start-FileDownload "https://github.com/ethcore/win-build/raw/master/vc_redist.x64.exe" -FileName nsis\vc_redist.x64.exe
|
- ps: Start-FileDownload "https://github.com/ethcore/win-build/raw/master/vc_redist.x64.exe" -FileName nsis\vc_redist.x64.exe
|
||||||
- rust-1.9.0-x86_64-pc-windows-msvc.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust"
|
- rust-1.10.0-x86_64-pc-windows-msvc.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust"
|
||||||
- SET PATH=%PATH%;C:\Program Files (x86)\Rust\bin;C:\Program Files (x86)\NSIS;C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Bin
|
- SET PATH=%PATH%;C:\Program Files (x86)\Rust\bin;C:\Program Files (x86)\NSIS;C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Bin
|
||||||
- rustc -V
|
- rustc -V
|
||||||
- cargo -V
|
- cargo -V
|
||||||
|
@ -271,11 +271,12 @@ fn hash_compute(light: &Light, full_size: usize, header_hash: &H256, nonce: u64)
|
|||||||
|
|
||||||
let page_size = 4 * MIX_WORDS;
|
let page_size = 4 * MIX_WORDS;
|
||||||
let num_full_pages = (full_size / page_size) as u32;
|
let num_full_pages = (full_size / page_size) as u32;
|
||||||
|
let cache: &[Node] = &light.cache; // deref once for better performance
|
||||||
|
|
||||||
for i in 0..(ETHASH_ACCESSES as u32) {
|
for i in 0..(ETHASH_ACCESSES as u32) {
|
||||||
let index = fnv_hash(f_mix.get_unchecked(0).as_words().get_unchecked(0) ^ i, *mix.get_unchecked(0).as_words().get_unchecked((i as usize) % MIX_WORDS)) % num_full_pages;
|
let index = fnv_hash(f_mix.get_unchecked(0).as_words().get_unchecked(0) ^ i, *mix.get_unchecked(0).as_words().get_unchecked((i as usize) % MIX_WORDS)) % num_full_pages;
|
||||||
for n in 0..MIX_NODES {
|
for n in 0..MIX_NODES {
|
||||||
let tmp_node = calculate_dag_item(index * MIX_NODES as u32 + n as u32, light);
|
let tmp_node = calculate_dag_item(index * MIX_NODES as u32 + n as u32, cache);
|
||||||
for w in 0..NODE_WORDS {
|
for w in 0..NODE_WORDS {
|
||||||
*mix.get_unchecked_mut(n).as_words_mut().get_unchecked_mut(w) = fnv_hash(*mix.get_unchecked(n).as_words().get_unchecked(w), *tmp_node.as_words().get_unchecked(w));
|
*mix.get_unchecked_mut(n).as_words_mut().get_unchecked_mut(w) = fnv_hash(*mix.get_unchecked(n).as_words().get_unchecked(w), *tmp_node.as_words().get_unchecked(w));
|
||||||
}
|
}
|
||||||
@ -306,18 +307,17 @@ fn hash_compute(light: &Light, full_size: usize, header_hash: &H256, nonce: u64)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn calculate_dag_item(node_index: u32, light: &Light) -> Node {
|
fn calculate_dag_item(node_index: u32, cache: &[Node]) -> Node {
|
||||||
unsafe {
|
unsafe {
|
||||||
let num_parent_nodes = light.cache.len();
|
let num_parent_nodes = cache.len();
|
||||||
let cache_nodes = &light.cache;
|
let init = cache.get_unchecked(node_index as usize % num_parent_nodes);
|
||||||
let init = cache_nodes.get_unchecked(node_index as usize % num_parent_nodes);
|
|
||||||
let mut ret = init.clone();
|
let mut ret = init.clone();
|
||||||
*ret.as_words_mut().get_unchecked_mut(0) ^= node_index;
|
*ret.as_words_mut().get_unchecked_mut(0) ^= node_index;
|
||||||
sha3::sha3_512(ret.bytes.as_mut_ptr(), ret.bytes.len(), ret.bytes.as_ptr(), ret.bytes.len());
|
sha3::sha3_512(ret.bytes.as_mut_ptr(), ret.bytes.len(), ret.bytes.as_ptr(), ret.bytes.len());
|
||||||
|
|
||||||
for i in 0..ETHASH_DATASET_PARENTS {
|
for i in 0..ETHASH_DATASET_PARENTS {
|
||||||
let parent_index = fnv_hash(node_index ^ i, *ret.as_words().get_unchecked(i as usize % NODE_WORDS)) % num_parent_nodes as u32;
|
let parent_index = fnv_hash(node_index ^ i, *ret.as_words().get_unchecked(i as usize % NODE_WORDS)) % num_parent_nodes as u32;
|
||||||
let parent = cache_nodes.get_unchecked(parent_index as usize);
|
let parent = cache.get_unchecked(parent_index as usize);
|
||||||
for w in 0..NODE_WORDS {
|
for w in 0..NODE_WORDS {
|
||||||
*ret.as_words_mut().get_unchecked_mut(w) = fnv_hash(*ret.as_words().get_unchecked(w), *parent.as_words().get_unchecked(w));
|
*ret.as_words_mut().get_unchecked_mut(w) = fnv_hash(*ret.as_words().get_unchecked(w), *parent.as_words().get_unchecked(w));
|
||||||
}
|
}
|
||||||
|
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"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 99afe8f5aad7bca5d0f1b1685390a4dea32d73c3
|
Subproject commit ac5475d676536cb945f98e9ff98384c01abd0599
|
@ -35,6 +35,8 @@ pub struct Account {
|
|||||||
code_hash: Option<H256>,
|
code_hash: Option<H256>,
|
||||||
// Code cache of the account.
|
// Code cache of the account.
|
||||||
code_cache: Bytes,
|
code_cache: Bytes,
|
||||||
|
// Account is new or has been modified
|
||||||
|
dirty: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Account {
|
impl Account {
|
||||||
@ -47,7 +49,8 @@ impl Account {
|
|||||||
storage_root: SHA3_NULL_RLP,
|
storage_root: SHA3_NULL_RLP,
|
||||||
storage_overlay: RefCell::new(storage.into_iter().map(|(k, v)| (k, (Filth::Dirty, v))).collect()),
|
storage_overlay: RefCell::new(storage.into_iter().map(|(k, v)| (k, (Filth::Dirty, v))).collect()),
|
||||||
code_hash: Some(code.sha3()),
|
code_hash: Some(code.sha3()),
|
||||||
code_cache: code
|
code_cache: code,
|
||||||
|
dirty: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +62,8 @@ impl Account {
|
|||||||
storage_root: SHA3_NULL_RLP,
|
storage_root: SHA3_NULL_RLP,
|
||||||
storage_overlay: RefCell::new(pod.storage.into_iter().map(|(k, v)| (k, (Filth::Dirty, v))).collect()),
|
storage_overlay: RefCell::new(pod.storage.into_iter().map(|(k, v)| (k, (Filth::Dirty, v))).collect()),
|
||||||
code_hash: Some(pod.code.sha3()),
|
code_hash: Some(pod.code.sha3()),
|
||||||
code_cache: pod.code
|
code_cache: pod.code,
|
||||||
|
dirty: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,6 +76,7 @@ impl Account {
|
|||||||
storage_overlay: RefCell::new(HashMap::new()),
|
storage_overlay: RefCell::new(HashMap::new()),
|
||||||
code_hash: Some(SHA3_EMPTY),
|
code_hash: Some(SHA3_EMPTY),
|
||||||
code_cache: vec![],
|
code_cache: vec![],
|
||||||
|
dirty: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,6 +90,7 @@ impl Account {
|
|||||||
storage_overlay: RefCell::new(HashMap::new()),
|
storage_overlay: RefCell::new(HashMap::new()),
|
||||||
code_hash: Some(r.val_at(3)),
|
code_hash: Some(r.val_at(3)),
|
||||||
code_cache: vec![],
|
code_cache: vec![],
|
||||||
|
dirty: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,6 +104,7 @@ impl Account {
|
|||||||
storage_overlay: RefCell::new(HashMap::new()),
|
storage_overlay: RefCell::new(HashMap::new()),
|
||||||
code_hash: None,
|
code_hash: None,
|
||||||
code_cache: vec![],
|
code_cache: vec![],
|
||||||
|
dirty: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,6 +113,7 @@ impl Account {
|
|||||||
pub fn init_code(&mut self, code: Bytes) {
|
pub fn init_code(&mut self, code: Bytes) {
|
||||||
assert!(self.code_hash.is_none());
|
assert!(self.code_hash.is_none());
|
||||||
self.code_cache = code;
|
self.code_cache = code;
|
||||||
|
self.dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reset this account's code to the given code.
|
/// Reset this account's code to the given code.
|
||||||
@ -117,6 +125,7 @@ impl Account {
|
|||||||
/// Set (and cache) the contents of the trie's storage at `key` to `value`.
|
/// Set (and cache) the contents of the trie's storage at `key` to `value`.
|
||||||
pub fn set_storage(&mut self, key: H256, value: H256) {
|
pub fn set_storage(&mut self, key: H256, value: H256) {
|
||||||
self.storage_overlay.borrow_mut().insert(key, (Filth::Dirty, value));
|
self.storage_overlay.borrow_mut().insert(key, (Filth::Dirty, value));
|
||||||
|
self.dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get (and cache) the contents of the trie's storage at `key`.
|
/// Get (and cache) the contents of the trie's storage at `key`.
|
||||||
@ -172,6 +181,10 @@ impl Account {
|
|||||||
!self.code_cache.is_empty() || (self.code_cache.is_empty() && self.code_hash == Some(SHA3_EMPTY))
|
!self.code_cache.is_empty() || (self.code_cache.is_empty() && self.code_hash == Some(SHA3_EMPTY))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Is this a new or modified account?
|
||||||
|
pub fn is_dirty(&self) -> bool {
|
||||||
|
self.dirty
|
||||||
|
}
|
||||||
/// Provide a database to get `code_hash`. Should not be called if it is a contract without code.
|
/// Provide a database to get `code_hash`. Should not be called if it is a contract without code.
|
||||||
pub fn cache_code(&mut self, db: &AccountDB) -> bool {
|
pub fn cache_code(&mut self, db: &AccountDB) -> bool {
|
||||||
// TODO: fill out self.code_cache;
|
// TODO: fill out self.code_cache;
|
||||||
@ -201,16 +214,23 @@ impl Account {
|
|||||||
pub fn storage_overlay(&self) -> Ref<HashMap<H256, (Filth, H256)>> { self.storage_overlay.borrow() }
|
pub fn storage_overlay(&self) -> Ref<HashMap<H256, (Filth, H256)>> { self.storage_overlay.borrow() }
|
||||||
|
|
||||||
/// Increment the nonce of the account by one.
|
/// Increment the nonce of the account by one.
|
||||||
pub fn inc_nonce(&mut self) { self.nonce = self.nonce + U256::from(1u8); }
|
pub fn inc_nonce(&mut self) {
|
||||||
|
self.nonce = self.nonce + U256::from(1u8);
|
||||||
|
self.dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
/// Increment the nonce of the account by one.
|
/// Increment the nonce of the account by one.
|
||||||
pub fn add_balance(&mut self, x: &U256) { self.balance = self.balance + *x; }
|
pub fn add_balance(&mut self, x: &U256) {
|
||||||
|
self.balance = self.balance + *x;
|
||||||
|
self.dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
/// Increment the nonce of the account by one.
|
/// Increment the nonce of the account by one.
|
||||||
/// Panics if balance is less than `x`
|
/// Panics if balance is less than `x`
|
||||||
pub fn sub_balance(&mut self, x: &U256) {
|
pub fn sub_balance(&mut self, x: &U256) {
|
||||||
assert!(self.balance >= *x);
|
assert!(self.balance >= *x);
|
||||||
self.balance = self.balance - *x;
|
self.balance = self.balance - *x;
|
||||||
|
self.dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Commit the `storage_overlay` to the backing DB and update `storage_root`.
|
/// Commit the `storage_overlay` to the backing DB and update `storage_root`.
|
||||||
|
@ -494,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())
|
||||||
|
@ -359,6 +359,12 @@ impl BlockChain {
|
|||||||
bc
|
bc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if the given parent block has given child
|
||||||
|
/// (though not necessarily a part of the canon chain).
|
||||||
|
fn is_known_child(&self, parent: &H256, hash: &H256) -> bool {
|
||||||
|
self.extras_db.read_with_cache(&self.block_details, parent).map_or(false, |d| d.children.contains(hash))
|
||||||
|
}
|
||||||
|
|
||||||
/// Set the cache configuration.
|
/// Set the cache configuration.
|
||||||
pub fn configure_cache(&self, pref_cache_size: usize, max_cache_size: usize) {
|
pub fn configure_cache(&self, pref_cache_size: usize, max_cache_size: usize) {
|
||||||
self.pref_cache_size.store(pref_cache_size, AtomicOrder::Relaxed);
|
self.pref_cache_size.store(pref_cache_size, AtomicOrder::Relaxed);
|
||||||
@ -463,7 +469,7 @@ impl BlockChain {
|
|||||||
let header = block.header_view();
|
let header = block.header_view();
|
||||||
let hash = header.sha3();
|
let hash = header.sha3();
|
||||||
|
|
||||||
if self.is_known(&hash) {
|
if self.is_known_child(&header.parent_hash(), &hash) {
|
||||||
return ImportRoute::none();
|
return ImportRoute::none();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -488,7 +494,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 +501,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 +530,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 +1195,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
|
||||||
@ -145,6 +145,7 @@ pub struct Client {
|
|||||||
notify: RwLock<Option<Weak<ChainNotify>>>,
|
notify: RwLock<Option<Weak<ChainNotify>>>,
|
||||||
queue_transactions: AtomicUsize,
|
queue_transactions: AtomicUsize,
|
||||||
previous_enode: Mutex<Option<String>>,
|
previous_enode: Mutex<Option<String>>,
|
||||||
|
last_hashes: RwLock<VecDeque<H256>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
const HISTORY: u64 = 1200;
|
const HISTORY: u64 = 1200;
|
||||||
@ -232,6 +233,7 @@ impl Client {
|
|||||||
notify: RwLock::new(None),
|
notify: RwLock::new(None),
|
||||||
queue_transactions: AtomicUsize::new(0),
|
queue_transactions: AtomicUsize::new(0),
|
||||||
previous_enode: Mutex::new(None),
|
previous_enode: Mutex::new(None),
|
||||||
|
last_hashes: RwLock::new(VecDeque::new()),
|
||||||
};
|
};
|
||||||
Ok(Arc::new(client))
|
Ok(Arc::new(client))
|
||||||
}
|
}
|
||||||
@ -253,6 +255,14 @@ impl Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn build_last_hashes(&self, parent_hash: H256) -> LastHashes {
|
fn build_last_hashes(&self, parent_hash: H256) -> LastHashes {
|
||||||
|
{
|
||||||
|
let hashes = self.last_hashes.read();
|
||||||
|
if hashes.front().map_or(false, |h| h == &parent_hash) {
|
||||||
|
let mut res = Vec::from(hashes.clone());
|
||||||
|
res.resize(256, H256::default());
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
let mut last_hashes = LastHashes::new();
|
let mut last_hashes = LastHashes::new();
|
||||||
last_hashes.resize(256, H256::new());
|
last_hashes.resize(256, H256::new());
|
||||||
last_hashes[0] = parent_hash;
|
last_hashes[0] = parent_hash;
|
||||||
@ -264,6 +274,8 @@ impl Client {
|
|||||||
None => break,
|
None => break,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let mut cached_hashes = self.last_hashes.write();
|
||||||
|
*cached_hashes = VecDeque::from(last_hashes.clone());
|
||||||
last_hashes
|
last_hashes
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -418,6 +430,7 @@ impl Client {
|
|||||||
|
|
||||||
fn commit_block<B>(&self, block: B, hash: &H256, block_data: &[u8]) -> ImportRoute where B: IsBlock + Drain {
|
fn commit_block<B>(&self, block: B, hash: &H256, block_data: &[u8]) -> ImportRoute where B: IsBlock + Drain {
|
||||||
let number = block.header().number();
|
let number = block.header().number();
|
||||||
|
let parent = block.header().parent_hash().clone();
|
||||||
// Are we committing an era?
|
// Are we committing an era?
|
||||||
let ancient = if number >= HISTORY {
|
let ancient = if number >= HISTORY {
|
||||||
let n = number - HISTORY;
|
let n = number - HISTORY;
|
||||||
@ -445,9 +458,20 @@ impl Client {
|
|||||||
enacted: route.enacted.clone(),
|
enacted: route.enacted.clone(),
|
||||||
retracted: route.retracted.len()
|
retracted: route.retracted.len()
|
||||||
});
|
});
|
||||||
|
self.update_last_hashes(&parent, hash);
|
||||||
route
|
route
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_last_hashes(&self, parent: &H256, hash: &H256) {
|
||||||
|
let mut hashes = self.last_hashes.write();
|
||||||
|
if hashes.front().map_or(false, |h| h == parent) {
|
||||||
|
if hashes.len() > 255 {
|
||||||
|
hashes.pop_back();
|
||||||
|
}
|
||||||
|
hashes.push_front(hash.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Import transactions from the IO queue
|
/// Import transactions from the IO queue
|
||||||
pub fn import_queued_transactions(&self, transactions: &[Bytes]) -> usize {
|
pub fn import_queued_transactions(&self, transactions: &[Bytes]) -> usize {
|
||||||
let _timer = PerfTimer::new("import_queued_transactions");
|
let _timer = PerfTimer::new("import_queued_transactions");
|
||||||
@ -608,18 +632,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)]
|
||||||
@ -687,7 +699,7 @@ 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 &BlockID::Pending = &id {
|
||||||
if let Some(block) = self.miner.pending_block() {
|
if let Some(block) = self.miner.pending_block() {
|
||||||
return Some(block.rlp_bytes(Seal::Without));
|
return Some(block.rlp_bytes(Seal::Without));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -708,7 +720,7 @@ impl BlockChainClient for Client {
|
|||||||
if let &BlockID::Pending = &id {
|
if let &BlockID::Pending = &id {
|
||||||
if let Some(block) = self.miner.pending_block() {
|
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"));
|
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)
|
||||||
}
|
}
|
||||||
|
@ -59,8 +59,6 @@ pub enum TransactionError {
|
|||||||
},
|
},
|
||||||
/// Transaction's gas limit (aka gas) is invalid.
|
/// Transaction's gas limit (aka gas) is invalid.
|
||||||
InvalidGasLimit(OutOfBounds<U256>),
|
InvalidGasLimit(OutOfBounds<U256>),
|
||||||
/// Transaction is invalid for some other reason.
|
|
||||||
DAORescue,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for TransactionError {
|
impl fmt::Display for TransactionError {
|
||||||
@ -79,7 +77,6 @@ impl fmt::Display for TransactionError {
|
|||||||
GasLimitExceeded { limit, got } =>
|
GasLimitExceeded { limit, got } =>
|
||||||
format!("Gas limit exceeded. Limit={}, Given={}", limit, got),
|
format!("Gas limit exceeded. Limit={}, Given={}", limit, got),
|
||||||
InvalidGasLimit(ref err) => format!("Invalid gas limit. {}", err),
|
InvalidGasLimit(ref err) => format!("Invalid gas limit. {}", err),
|
||||||
DAORescue => "Transaction is invalid due to the DAO rescue.".into(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
f.write_fmt(format_args!("Transaction error ({})", msg))
|
f.write_fmt(format_args!("Transaction error ({})", msg))
|
||||||
|
@ -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")) }
|
||||||
|
|
||||||
|
@ -80,8 +80,6 @@ pub struct Schedule {
|
|||||||
pub tx_data_non_zero_gas: usize,
|
pub tx_data_non_zero_gas: usize,
|
||||||
/// Gas price for copying memory
|
/// Gas price for copying memory
|
||||||
pub copy_gas: usize,
|
pub copy_gas: usize,
|
||||||
/// DAO Rescue softfork block
|
|
||||||
pub reject_dao_transactions: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Schedule {
|
impl Schedule {
|
||||||
@ -128,7 +126,6 @@ impl Schedule {
|
|||||||
tx_data_zero_gas: 4,
|
tx_data_zero_gas: 4,
|
||||||
tx_data_non_zero_gas: 68,
|
tx_data_non_zero_gas: 68,
|
||||||
copy_gas: 3,
|
copy_gas: 3,
|
||||||
reject_dao_transactions: false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -116,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;
|
||||||
@ -775,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 {
|
||||||
|
@ -232,36 +232,10 @@ impl State {
|
|||||||
let options = TransactOptions { tracing: tracing, vm_tracing: false, check_nonce: true };
|
let options = TransactOptions { tracing: tracing, vm_tracing: false, check_nonce: true };
|
||||||
let e = try!(Executive::new(self, env_info, engine, vm_factory).transact(t, options));
|
let e = try!(Executive::new(self, env_info, engine, vm_factory).transact(t, options));
|
||||||
|
|
||||||
let broken_dao = H256::from("6a5d24750f78441e56fec050dc52fe8e911976485b7472faac7464a176a67caa");
|
|
||||||
|
|
||||||
// dao attack soft fork
|
|
||||||
if engine.schedule(&env_info).reject_dao_transactions {
|
|
||||||
let whitelisted = if let Action::Call(to) = t.action {
|
|
||||||
to == Address::from("Da4a4626d3E16e094De3225A751aAb7128e96526") ||
|
|
||||||
to == Address::from("2ba9D006C1D72E67A70b5526Fc6b4b0C0fd6D334")
|
|
||||||
} else { false };
|
|
||||||
if !whitelisted {
|
|
||||||
// collect all the addresses which have changed.
|
|
||||||
let addresses = self.cache.borrow().iter().map(|(addr, _)| addr.clone()).collect::<Vec<_>>();
|
|
||||||
|
|
||||||
for a in &addresses {
|
|
||||||
if self.code(a).map_or(false, |c| c.sha3() == broken_dao) {
|
|
||||||
// Figure out if the balance has been reduced.
|
|
||||||
let maybe_original = self.trie_factory
|
|
||||||
.readonly(self.db.as_hashdb(), &self.root)
|
|
||||||
.expect(SEC_TRIE_DB_UNWRAP_STR)
|
|
||||||
.get(&a).map(Account::from_rlp);
|
|
||||||
if maybe_original.map_or(false, |original| *original.balance() > self.balance(a)) {
|
|
||||||
return Err(Error::Transaction(TransactionError::DAORescue));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO uncomment once to_pod() works correctly.
|
// TODO uncomment once to_pod() works correctly.
|
||||||
// trace!("Applied transaction. Diff:\n{}\n", state_diff::diff_pod(&old, &self.to_pod()));
|
// trace!("Applied transaction. Diff:\n{}\n", state_diff::diff_pod(&old, &self.to_pod()));
|
||||||
self.commit();
|
self.commit();
|
||||||
|
self.clear();
|
||||||
let receipt = Receipt::new(self.root().clone(), e.cumulative_gas_used, e.logs);
|
let receipt = Receipt::new(self.root().clone(), e.cumulative_gas_used, e.logs);
|
||||||
// trace!("Transaction receipt: {:?}", receipt);
|
// trace!("Transaction receipt: {:?}", receipt);
|
||||||
Ok(ApplyOutcome{receipt: receipt, trace: e.trace})
|
Ok(ApplyOutcome{receipt: receipt, trace: e.trace})
|
||||||
@ -275,12 +249,12 @@ impl State {
|
|||||||
// TODO: is this necessary or can we dispense with the `ref mut a` for just `a`?
|
// TODO: is this necessary or can we dispense with the `ref mut a` for just `a`?
|
||||||
for (address, ref mut a) in accounts.iter_mut() {
|
for (address, ref mut a) in accounts.iter_mut() {
|
||||||
match a {
|
match a {
|
||||||
&mut&mut Some(ref mut account) => {
|
&mut&mut Some(ref mut account) if account.is_dirty() => {
|
||||||
let mut account_db = AccountDBMut::new(db, address);
|
let mut account_db = AccountDBMut::new(db, address);
|
||||||
account.commit_storage(trie_factory, &mut account_db);
|
account.commit_storage(trie_factory, &mut account_db);
|
||||||
account.commit_code(&mut account_db);
|
account.commit_code(&mut account_db);
|
||||||
}
|
}
|
||||||
&mut&mut None => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,8 +262,9 @@ impl State {
|
|||||||
let mut trie = trie_factory.from_existing(db, root).unwrap();
|
let mut trie = trie_factory.from_existing(db, root).unwrap();
|
||||||
for (address, ref a) in accounts.iter() {
|
for (address, ref a) in accounts.iter() {
|
||||||
match **a {
|
match **a {
|
||||||
Some(ref account) => trie.insert(address, &account.rlp()),
|
Some(ref account) if account.is_dirty() => trie.insert(address, &account.rlp()),
|
||||||
None => trie.remove(address),
|
None => trie.remove(address),
|
||||||
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -301,6 +276,11 @@ impl State {
|
|||||||
Self::commit_into(&self.trie_factory, self.db.as_hashdb_mut(), &mut self.root, self.cache.borrow_mut().deref_mut());
|
Self::commit_into(&self.trie_factory, self.db.as_hashdb_mut(), &mut self.root, self.cache.borrow_mut().deref_mut());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Clear state cache
|
||||||
|
pub fn clear(&mut self) {
|
||||||
|
self.cache.borrow_mut().clear();
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[cfg(feature = "json-tests")]
|
#[cfg(feature = "json-tests")]
|
||||||
/// Populate the state from `accounts`.
|
/// Populate the state from `accounts`.
|
||||||
|
@ -30,6 +30,7 @@ use miner::Miner;
|
|||||||
pub enum ChainEra {
|
pub enum ChainEra {
|
||||||
Frontier,
|
Frontier,
|
||||||
Homestead,
|
Homestead,
|
||||||
|
DaoHardfork,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TestEngine {
|
pub struct TestEngine {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
PARITY_DEB_URL=https://github.com/ethcore/parity/releases/download/v1.2.1/parity_linux_1.2.1-0_amd64.deb
|
PARITY_DEB_URL=https://github.com/ethcore/parity/releases/download/v1.2.2/parity_linux_1.2.2-0_amd64.deb
|
||||||
|
|
||||||
|
|
||||||
function run_installer()
|
function run_installer()
|
||||||
|
@ -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;
|
||||||
@ -82,7 +83,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,
|
use ethcore::client::{BlockID, BlockChainClient, ClientConfig, get_db_path, BlockImportError,
|
||||||
ChainNotify, Mode};
|
ChainNotify, Mode};
|
||||||
@ -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(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,7 +170,6 @@ fn transaction_error(error: EthcoreError) -> Error {
|
|||||||
format!("Transaction cost exceeds current gas limit. Limit: {}, got: {}. Try decreasing supplied gas.", limit, got)
|
format!("Transaction cost exceeds current gas limit. Limit: {}, got: {}. Try decreasing supplied gas.", limit, got)
|
||||||
},
|
},
|
||||||
InvalidGasLimit(_) => "Supplied gas is beyond limit.".into(),
|
InvalidGasLimit(_) => "Supplied gas is beyond limit.".into(),
|
||||||
DAORescue => "Transaction removes funds from a DAO.".into(),
|
|
||||||
};
|
};
|
||||||
Error {
|
Error {
|
||||||
code: ErrorCode::ServerError(error_codes::TRANSACTION_ERROR),
|
code: ErrorCode::ServerError(error_codes::TRANSACTION_ERROR),
|
||||||
|
@ -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": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -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> {
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -177,16 +177,13 @@ impl Database {
|
|||||||
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 {
|
if let Some(cache_size) = config.cache_size {
|
||||||
block_opts.set_cache(Cache::new(cache_size * 1024 * 256));
|
block_opts.set_cache(Cache::new(cache_size * 1024 * 1024));
|
||||||
opts.set_write_buffer_size(cache_size * 1024 * 256);
|
|
||||||
}
|
}
|
||||||
} else if let Some(cache_size) = config.cache_size {
|
} else if let Some(cache_size) = config.cache_size {
|
||||||
let mut block_opts = BlockBasedOptions::new();
|
let mut block_opts = BlockBasedOptions::new();
|
||||||
// half goes to read cache
|
// half goes to read cache
|
||||||
block_opts.set_cache(Cache::new(cache_size * 1024 * 256));
|
block_opts.set_cache(Cache::new(cache_size * 1024 * 1024));
|
||||||
opts.set_block_based_table_factory(&block_opts);
|
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();
|
let mut write_opts = WriteOptions::new();
|
||||||
@ -207,12 +204,12 @@ impl Database {
|
|||||||
|
|
||||||
/// 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.
|
||||||
pub fn put(&self, key: &[u8], value: &[u8]) -> Result<(), String> {
|
pub fn put(&self, key: &[u8], value: &[u8]) -> Result<(), String> {
|
||||||
self.db.put(key, value)
|
self.db.put_opt(key, value, &self.write_opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Delete value by key.
|
/// Delete value by key.
|
||||||
pub fn delete(&self, key: &[u8]) -> Result<(), String> {
|
pub fn delete(&self, key: &[u8]) -> Result<(), String> {
|
||||||
self.db.delete(key)
|
self.db.delete_opt(key, &self.write_opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Commit transaction to database.
|
/// Commit transaction to database.
|
||||||
|
@ -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(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user