Merge branch 'master' into pubsub-docs

This commit is contained in:
Tomasz Drwięga 2017-06-13 16:30:08 +02:00
commit 172300158d
No known key found for this signature in database
GPG Key ID: D066F497E62CAF66
41 changed files with 976 additions and 320 deletions

View File

@ -9,6 +9,7 @@ variables:
RUST_BACKTRACE: "1"
RUSTFLAGS: ""
CARGOFLAGS: ""
CI_SERVER_NAME: "GitLab CI"
cache:
key: "$CI_BUILD_STAGE/$CI_BUILD_REF_NAME"
untracked: true
@ -92,6 +93,7 @@ linux-snap:
paths:
- scripts/parity_*_amd64.snap
name: "stable-x86_64-unknown-snap-gnu_parity"
allow_failure: true
linux-stable-debian:
stage: build
image: parity/rust-debian:gitlab-ci
@ -433,6 +435,7 @@ darwin:
script: |
export COMMIT=$(git rev-parse HEAD)
export PLATFORM=x86_64-apple-darwin
rustup default stable
cargo build -j 8 --features final --release #$CARGOFLAGS
cargo build -j 8 --features final --release -p ethstore #$CARGOFLAGS
rm -rf parity.md5
@ -607,19 +610,6 @@ js-test:
tags:
- rust
- rust-stable
js-test-node_8:
stage: test
image: parity/rust-debian-node_8:gitlab-ci
before_script:
- git submodule update --init --recursive
- export JS_FILES_MODIFIED=$(git --no-pager diff --name-only $CI_BUILD_REF^ $CI_BUILD_REF | grep ^js/ | wc -l)
- if [ $JS_FILES_MODIFIED -eq 0 ]; then echo "Skipping JS deps install since no JS files modified."; else ./js/scripts/install-deps.sh;fi
script:
- if [ $JS_FILES_MODIFIED -eq 0 ]; then echo "Skipping JS lint since no JS files modified."; else ./js/scripts/lint.sh && ./js/scripts/test.sh && ./js/scripts/build.sh; fi
tags:
- rust
- rust-stable
allow_failure: true
test-rust-beta:
stage: test
only:

62
Cargo.lock generated
View File

@ -120,6 +120,11 @@ name = "bitflags"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bitflags"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "blastfig"
version = "0.3.3"
@ -800,6 +805,11 @@ name = "fnv"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "foreign-types"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "futures"
version = "0.1.11"
@ -942,7 +952,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)",
"native-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"native-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1366,13 +1376,13 @@ dependencies = [
[[package]]
name = "native-tls"
version = "0.1.0"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"openssl 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)",
"schannel 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"security-framework 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"security-framework-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl 0.9.13 (registry+https://github.com/rust-lang/crates.io-index)",
"schannel 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"security-framework 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"security-framework-sys 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1499,23 +1509,25 @@ dependencies = [
[[package]]
name = "openssl"
version = "0.9.3"
version = "0.9.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"foreign-types 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.13 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "openssl-sys"
version = "0.9.3"
version = "0.9.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
"gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1791,7 +1803,7 @@ dependencies = [
[[package]]
name = "parity-ui-precompiled"
version = "1.4.0"
source = "git+https://github.com/paritytech/js-precompiled.git#52ba0075a974e89a723e04c55dd5d5b9941d9a11"
source = "git+https://github.com/paritytech/js-precompiled.git#0811e57083d75d8e93e03ccd9bba3432703236ce"
dependencies = [
"parity-dapps-glue 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1887,7 +1899,7 @@ dependencies = [
[[package]]
name = "pkg-config"
version = "0.3.8"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -2184,7 +2196,7 @@ dependencies = [
[[package]]
name = "schannel"
version = "0.1.1"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2212,18 +2224,18 @@ dependencies = [
[[package]]
name = "security-framework"
version = "0.1.9"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"security-framework-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"security-framework-sys 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "security-framework-sys"
version = "0.1.9"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"core-foundation-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2857,6 +2869,7 @@ dependencies = [
"checksum bit-vec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5b97c2c8e8bbb4251754f559df8af22fb264853c7d009084a576cdf12565089d"
"checksum bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4f67931368edf3a9a51d29886d245f1c3db2f1ef0dcc9e35ff70341b78c10d23"
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
"checksum blastfig 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "09640e0509d97d5cdff03a9f5daf087a8e04c735c3b113a75139634a19cfc7b2"
"checksum bloomchain 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f421095d2a76fc24cd3fb3f912b90df06be7689912b1bdb423caefae59c258d"
"checksum bn 0.4.4 (git+https://github.com/paritytech/bn)" = "<none>"
@ -2888,6 +2901,7 @@ dependencies = [
"checksum fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1ee15a7050e5580b3712877157068ea713b245b080ff302ae2ca973cfcd9baa"
"checksum flate2 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "3eeb481e957304178d2e782f2da1257f1434dfecbae883bafb61ada2a9fea3bb"
"checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"
"checksum foreign-types 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e4056b9bd47f8ac5ba12be771f77a0dae796d1bbaaf5fd0b9c2d38b69b8a29d"
"checksum futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8e51e7f9c150ba7fd4cee9df8bf6ea3dea5b63b68955ddad19ccd35b71dcfb4d"
"checksum futures-cpupool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bb982bb25cd8fa5da6a8eb3a460354c984ff1113da82bcb4f0b0862b5795db82"
"checksum gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)" = "c07c758b972368e703a562686adb39125707cc1ef3399da8c019fc6c2498a75d"
@ -2945,7 +2959,7 @@ dependencies = [
"checksum multihash 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d14363c7695e2e5adbbb8fe139d806a19b8b13f02b9b1fb770fab0c12edaff58"
"checksum nanomsg 0.5.1 (git+https://github.com/paritytech/nanomsg.rs.git?branch=parity-1.7)" = "<none>"
"checksum nanomsg-sys 0.5.0 (git+https://github.com/paritytech/nanomsg.rs.git?branch=parity-1.7)" = "<none>"
"checksum native-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aa4e52995154bb6f0b41e4379a279482c9387c1632e3798ba4e511ef8c54ee09"
"checksum native-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1e94a2fc65a44729fe969cc973da87c1052ae3f000b2cb33029f14aeb85550d5"
"checksum net2 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)" = "bc01404e7568680f1259aa5729539f221cb1e6d047a0d9053cab4be8a73b5d67"
"checksum nodrop 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "52cd74cd09beba596430cc6e3091b74007169a56246e1262f0ba451ea95117b2"
"checksum nom 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6caab12c5f97aa316cb249725aa32115118e1522b445e26c257dd77cad5ffd4e"
@ -2960,8 +2974,8 @@ dependencies = [
"checksum number_prefix 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "084d05f4bf60621a9ac9bde941a410df548f4de9545f06e5ee9d3aef4b97cd77"
"checksum odds 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "b28c06e81b0f789122d415d6394b5fe849bde8067469f4c2980d3cdc10c78ec1"
"checksum ole32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2c49021782e5233cd243168edfa8037574afed4eba4bbaf538b3d8d1789d8c"
"checksum openssl 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "12be61c7eaa23228316ff02c39807e4c1b1af84ba81420f19fd58dade304b25c"
"checksum openssl-sys 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d2845e841700e7b04282ceaa115407ea84e0db918ae689ad9ceb6f06fa6046bd"
"checksum openssl 0.9.13 (registry+https://github.com/rust-lang/crates.io-index)" = "b34cd77cf91301fff3123fbd46b065c3b728b17a392835de34c397315dce5586"
"checksum openssl-sys 0.9.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e035022a50faa380bd7ccdbd184d946ce539ebdb0a358780de92a995882af97a"
"checksum order-stat 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "efa535d5117d3661134dbf1719b6f0ffe06f2375843b13935db186cd094105eb"
"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
"checksum parity-dapps-glue 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e1d06f6ee0fda786df3784a96ee3f0629f529b91cbfb7d142f6410e6bcd1ce2c"
@ -2974,7 +2988,7 @@ dependencies = [
"checksum phf_codegen 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)" = "8af7ae7c3f75a502292b491e5cc0a1f69e3407744abe6e57e2a3b712bb82f01d"
"checksum phf_generator 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)" = "db005608fd99800c8c74106a7c894cf582055b689aa14a79462cefdcb7dc1cc3"
"checksum phf_shared 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)" = "fee4d039930e4f45123c9b15976cf93a499847b6483dc09c42ea0ec4940f2aa6"
"checksum pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8cee804ecc7eaf201a4a207241472cc870e825206f6c031e3ee2a72fa425f2fa"
"checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
"checksum podio 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e5422a1ee1bc57cc47ae717b0137314258138f38fd5f3cea083f43a9725383a0"
"checksum pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2412f3332a07c7a2a50168988dcc184f32180a9758ad470390e5f55e089f6b6e"
"checksum primal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0e31b86efadeaeb1235452171a66689682783149a6249ff334a2c5d8218d00a4"
@ -3006,11 +3020,11 @@ dependencies = [
"checksum rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "6159e4e6e559c81bd706afe9c8fd68f547d3e851ce12e76b1de7914bab61691b"
"checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084"
"checksum rustc_version 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1e114e275f7c9b5d50bb52b28f9aac1921209f02aa6077c8b255e21eefaf8ffa"
"checksum schannel 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "167852e03fcd0029c3ddebb5afb0715b2996f6e262b2c2aceaa7cd84edd4b158"
"checksum schannel 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4e45ac5e9e4698c1c138d2972bedcd90b81fe1efeba805449d2bdd54512de5f9"
"checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d"
"checksum secur32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f412dfa83308d893101dd59c10d6fda8283465976c28c287c5c855bf8d216bc"
"checksum security-framework 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "52186fcf3b391c9f0ccdce9a2ac708f7cc81b3f89e149b34bd9279fb1b23f9fa"
"checksum security-framework-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c84067e6297c1f09514a8666d8bbc1268817ec4a6c0f30f12f6201e1f34bd2a1"
"checksum security-framework 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "42ddf098d78d0b64564b23ee6345d07573e7d10e52ad86875d89ddf5f8378a02"
"checksum security-framework-sys 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "5bacdada57ea62022500c457c8571c17dfb5e6240b7c8eac5916ffa8c7138a55"
"checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac"
"checksum semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2d5b7638a1f03815d94e88cb3b3c08e87f0db4d683ef499d1836aaf70a45623f"
"checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537"

View File

@ -138,166 +138,172 @@ pub fn get_tier_idx (tier: GasPriceTier) -> usize {
}
}
/// EVM instruction information.
#[derive(Copy, Clone, Default)]
pub struct InstructionInfo {
/// Mnemonic name.
pub name: &'static str,
/// Additional code bytes used. Used only for PUSHxx.
pub additional: usize,
/// Number of stack arguments.
pub args: usize,
/// Number of returned stack items.
pub ret: usize,
pub side_effects: bool,
/// Gas price tier.
pub tier: GasPriceTier
}
impl InstructionInfo {
pub fn new(name: &'static str, additional: usize, args: usize, ret: usize, side_effects: bool, tier: GasPriceTier) -> Self {
/// Create new instruction info.
pub fn new(name: &'static str, additional: usize, args: usize, ret: usize, tier: GasPriceTier) -> Self {
InstructionInfo {
name: name,
additional: additional,
args: args,
ret: ret,
side_effects: side_effects,
tier: tier
}
}
}
lazy_static! {
/// Static instruction table.
pub static ref INSTRUCTIONS: [InstructionInfo; 0x100] = {
let mut arr = [InstructionInfo::default(); 0x100];
arr[STOP as usize] = InstructionInfo::new("STOP", 0, 0, 0, true, GasPriceTier::Zero);
arr[ADD as usize] = InstructionInfo::new("ADD", 0, 2, 1, false, GasPriceTier::VeryLow);
arr[SUB as usize] = InstructionInfo::new("SUB", 0, 2, 1, false, GasPriceTier::VeryLow);
arr[MUL as usize] = InstructionInfo::new("MUL", 0, 2, 1, false, GasPriceTier::Low);
arr[DIV as usize] = InstructionInfo::new("DIV", 0, 2, 1, false, GasPriceTier::Low);
arr[SDIV as usize] = InstructionInfo::new("SDIV", 0, 2, 1, false, GasPriceTier::Low);
arr[MOD as usize] = InstructionInfo::new("MOD", 0, 2, 1, false, GasPriceTier::Low);
arr[SMOD as usize] = InstructionInfo::new("SMOD", 0, 2, 1, false, GasPriceTier::Low);
arr[EXP as usize] = InstructionInfo::new("EXP", 0, 2, 1, false, GasPriceTier::Special);
arr[NOT as usize] = InstructionInfo::new("NOT", 0, 1, 1, false, GasPriceTier::VeryLow);
arr[LT as usize] = InstructionInfo::new("LT", 0, 2, 1, false, GasPriceTier::VeryLow);
arr[GT as usize] = InstructionInfo::new("GT", 0, 2, 1, false, GasPriceTier::VeryLow);
arr[SLT as usize] = InstructionInfo::new("SLT", 0, 2, 1, false, GasPriceTier::VeryLow);
arr[SGT as usize] = InstructionInfo::new("SGT", 0, 2, 1, false, GasPriceTier::VeryLow);
arr[EQ as usize] = InstructionInfo::new("EQ", 0, 2, 1, false, GasPriceTier::VeryLow);
arr[ISZERO as usize] = InstructionInfo::new("ISZERO", 0, 1, 1, false, GasPriceTier::VeryLow);
arr[AND as usize] = InstructionInfo::new("AND", 0, 2, 1, false, GasPriceTier::VeryLow);
arr[OR as usize] = InstructionInfo::new("OR", 0, 2, 1, false, GasPriceTier::VeryLow);
arr[XOR as usize] = InstructionInfo::new("XOR", 0, 2, 1, false, GasPriceTier::VeryLow);
arr[BYTE as usize] = InstructionInfo::new("BYTE", 0, 2, 1, false, GasPriceTier::VeryLow);
arr[ADDMOD as usize] = InstructionInfo::new("ADDMOD", 0, 3, 1, false, GasPriceTier::Mid);
arr[MULMOD as usize] = InstructionInfo::new("MULMOD", 0, 3, 1, false, GasPriceTier::Mid);
arr[SIGNEXTEND as usize] = InstructionInfo::new("SIGNEXTEND", 0, 2, 1, false, GasPriceTier::Low);
arr[RETURNDATASIZE as usize] = InstructionInfo::new("RETURNDATASIZE", 0, 0, 1, false, GasPriceTier::Base);
arr[RETURNDATACOPY as usize] = InstructionInfo::new("RETURNDATACOPY", 0, 3, 0, true, GasPriceTier::VeryLow);
arr[SHA3 as usize] = InstructionInfo::new("SHA3", 0, 2, 1, false, GasPriceTier::Special);
arr[ADDRESS as usize] = InstructionInfo::new("ADDRESS", 0, 0, 1, false, GasPriceTier::Base);
arr[BALANCE as usize] = InstructionInfo::new("BALANCE", 0, 1, 1, false, GasPriceTier::Special);
arr[ORIGIN as usize] = InstructionInfo::new("ORIGIN", 0, 0, 1, false, GasPriceTier::Base);
arr[CALLER as usize] = InstructionInfo::new("CALLER", 0, 0, 1, false, GasPriceTier::Base);
arr[CALLVALUE as usize] = InstructionInfo::new("CALLVALUE", 0, 0, 1, false, GasPriceTier::Base);
arr[CALLDATALOAD as usize] = InstructionInfo::new("CALLDATALOAD", 0, 1, 1, false, GasPriceTier::VeryLow);
arr[CALLDATASIZE as usize] = InstructionInfo::new("CALLDATASIZE", 0, 0, 1, false, GasPriceTier::Base);
arr[CALLDATACOPY as usize] = InstructionInfo::new("CALLDATACOPY", 0, 3, 0, true, GasPriceTier::VeryLow);
arr[CODESIZE as usize] = InstructionInfo::new("CODESIZE", 0, 0, 1, false, GasPriceTier::Base);
arr[CODECOPY as usize] = InstructionInfo::new("CODECOPY", 0, 3, 0, true, GasPriceTier::VeryLow);
arr[GASPRICE as usize] = InstructionInfo::new("GASPRICE", 0, 0, 1, false, GasPriceTier::Base);
arr[EXTCODESIZE as usize] = InstructionInfo::new("EXTCODESIZE", 0, 1, 1, false, GasPriceTier::Special);
arr[EXTCODECOPY as usize] = InstructionInfo::new("EXTCODECOPY", 0, 4, 0, true, GasPriceTier::Special);
arr[BLOCKHASH as usize] = InstructionInfo::new("BLOCKHASH", 0, 1, 1, false, GasPriceTier::Ext);
arr[COINBASE as usize] = InstructionInfo::new("COINBASE", 0, 0, 1, false, GasPriceTier::Base);
arr[TIMESTAMP as usize] = InstructionInfo::new("TIMESTAMP", 0, 0, 1, false, GasPriceTier::Base);
arr[NUMBER as usize] = InstructionInfo::new("NUMBER", 0, 0, 1, false, GasPriceTier::Base);
arr[DIFFICULTY as usize] = InstructionInfo::new("DIFFICULTY", 0, 0, 1, false, GasPriceTier::Base);
arr[GASLIMIT as usize] = InstructionInfo::new("GASLIMIT", 0, 0, 1, false, GasPriceTier::Base);
arr[POP as usize] = InstructionInfo::new("POP", 0, 1, 0, false, GasPriceTier::Base);
arr[MLOAD as usize] = InstructionInfo::new("MLOAD", 0, 1, 1, false, GasPriceTier::VeryLow);
arr[MSTORE as usize] = InstructionInfo::new("MSTORE", 0, 2, 0, true, GasPriceTier::VeryLow);
arr[MSTORE8 as usize] = InstructionInfo::new("MSTORE8", 0, 2, 0, true, GasPriceTier::VeryLow);
arr[SLOAD as usize] = InstructionInfo::new("SLOAD", 0, 1, 1, false, GasPriceTier::Special);
arr[SSTORE as usize] = InstructionInfo::new("SSTORE", 0, 2, 0, true, GasPriceTier::Special);
arr[JUMP as usize] = InstructionInfo::new("JUMP", 0, 1, 0, true, GasPriceTier::Mid);
arr[JUMPI as usize] = InstructionInfo::new("JUMPI", 0, 2, 0, true, GasPriceTier::High);
arr[PC as usize] = InstructionInfo::new("PC", 0, 0, 1, false, GasPriceTier::Base);
arr[MSIZE as usize] = InstructionInfo::new("MSIZE", 0, 0, 1, false, GasPriceTier::Base);
arr[GAS as usize] = InstructionInfo::new("GAS", 0, 0, 1, false, GasPriceTier::Base);
arr[JUMPDEST as usize] = InstructionInfo::new("JUMPDEST", 0, 0, 0, true, GasPriceTier::Special);
arr[PUSH1 as usize] = InstructionInfo::new("PUSH1", 1, 0, 1, false, GasPriceTier::VeryLow);
arr[PUSH2 as usize] = InstructionInfo::new("PUSH2", 2, 0, 1, false, GasPriceTier::VeryLow);
arr[PUSH3 as usize] = InstructionInfo::new("PUSH3", 3, 0, 1, false, GasPriceTier::VeryLow);
arr[PUSH4 as usize] = InstructionInfo::new("PUSH4", 4, 0, 1, false, GasPriceTier::VeryLow);
arr[PUSH5 as usize] = InstructionInfo::new("PUSH5", 5, 0, 1, false, GasPriceTier::VeryLow);
arr[PUSH6 as usize] = InstructionInfo::new("PUSH6", 6, 0, 1, false, GasPriceTier::VeryLow);
arr[PUSH7 as usize] = InstructionInfo::new("PUSH7", 7, 0, 1, false, GasPriceTier::VeryLow);
arr[PUSH8 as usize] = InstructionInfo::new("PUSH8", 8, 0, 1, false, GasPriceTier::VeryLow);
arr[PUSH9 as usize] = InstructionInfo::new("PUSH9", 9, 0, 1, false, GasPriceTier::VeryLow);
arr[PUSH10 as usize] = InstructionInfo::new("PUSH10", 10, 0, 1, false, GasPriceTier::VeryLow);
arr[PUSH11 as usize] = InstructionInfo::new("PUSH11", 11, 0, 1, false, GasPriceTier::VeryLow);
arr[PUSH12 as usize] = InstructionInfo::new("PUSH12", 12, 0, 1, false, GasPriceTier::VeryLow);
arr[PUSH13 as usize] = InstructionInfo::new("PUSH13", 13, 0, 1, false, GasPriceTier::VeryLow);
arr[PUSH14 as usize] = InstructionInfo::new("PUSH14", 14, 0, 1, false, GasPriceTier::VeryLow);
arr[PUSH15 as usize] = InstructionInfo::new("PUSH15", 15, 0, 1, false, GasPriceTier::VeryLow);
arr[PUSH16 as usize] = InstructionInfo::new("PUSH16", 16, 0, 1, false, GasPriceTier::VeryLow);
arr[PUSH17 as usize] = InstructionInfo::new("PUSH17", 17, 0, 1, false, GasPriceTier::VeryLow);
arr[PUSH18 as usize] = InstructionInfo::new("PUSH18", 18, 0, 1, false, GasPriceTier::VeryLow);
arr[PUSH19 as usize] = InstructionInfo::new("PUSH19", 19, 0, 1, false, GasPriceTier::VeryLow);
arr[PUSH20 as usize] = InstructionInfo::new("PUSH20", 20, 0, 1, false, GasPriceTier::VeryLow);
arr[PUSH21 as usize] = InstructionInfo::new("PUSH21", 21, 0, 1, false, GasPriceTier::VeryLow);
arr[PUSH22 as usize] = InstructionInfo::new("PUSH22", 22, 0, 1, false, GasPriceTier::VeryLow);
arr[PUSH23 as usize] = InstructionInfo::new("PUSH23", 23, 0, 1, false, GasPriceTier::VeryLow);
arr[PUSH24 as usize] = InstructionInfo::new("PUSH24", 24, 0, 1, false, GasPriceTier::VeryLow);
arr[PUSH25 as usize] = InstructionInfo::new("PUSH25", 25, 0, 1, false, GasPriceTier::VeryLow);
arr[PUSH26 as usize] = InstructionInfo::new("PUSH26", 26, 0, 1, false, GasPriceTier::VeryLow);
arr[PUSH27 as usize] = InstructionInfo::new("PUSH27", 27, 0, 1, false, GasPriceTier::VeryLow);
arr[PUSH28 as usize] = InstructionInfo::new("PUSH28", 28, 0, 1, false, GasPriceTier::VeryLow);
arr[PUSH29 as usize] = InstructionInfo::new("PUSH29", 29, 0, 1, false, GasPriceTier::VeryLow);
arr[PUSH30 as usize] = InstructionInfo::new("PUSH30", 30, 0, 1, false, GasPriceTier::VeryLow);
arr[PUSH31 as usize] = InstructionInfo::new("PUSH31", 31, 0, 1, false, GasPriceTier::VeryLow);
arr[PUSH32 as usize] = InstructionInfo::new("PUSH32", 32, 0, 1, false, GasPriceTier::VeryLow);
arr[DUP1 as usize] = InstructionInfo::new("DUP1", 0, 1, 2, false, GasPriceTier::VeryLow);
arr[DUP2 as usize] = InstructionInfo::new("DUP2", 0, 2, 3, false, GasPriceTier::VeryLow);
arr[DUP3 as usize] = InstructionInfo::new("DUP3", 0, 3, 4, false, GasPriceTier::VeryLow);
arr[DUP4 as usize] = InstructionInfo::new("DUP4", 0, 4, 5, false, GasPriceTier::VeryLow);
arr[DUP5 as usize] = InstructionInfo::new("DUP5", 0, 5, 6, false, GasPriceTier::VeryLow);
arr[DUP6 as usize] = InstructionInfo::new("DUP6", 0, 6, 7, false, GasPriceTier::VeryLow);
arr[DUP7 as usize] = InstructionInfo::new("DUP7", 0, 7, 8, false, GasPriceTier::VeryLow);
arr[DUP8 as usize] = InstructionInfo::new("DUP8", 0, 8, 9, false, GasPriceTier::VeryLow);
arr[DUP9 as usize] = InstructionInfo::new("DUP9", 0, 9, 10, false, GasPriceTier::VeryLow);
arr[DUP10 as usize] = InstructionInfo::new("DUP10", 0, 10, 11, false, GasPriceTier::VeryLow);
arr[DUP11 as usize] = InstructionInfo::new("DUP11", 0, 11, 12, false, GasPriceTier::VeryLow);
arr[DUP12 as usize] = InstructionInfo::new("DUP12", 0, 12, 13, false, GasPriceTier::VeryLow);
arr[DUP13 as usize] = InstructionInfo::new("DUP13", 0, 13, 14, false, GasPriceTier::VeryLow);
arr[DUP14 as usize] = InstructionInfo::new("DUP14", 0, 14, 15, false, GasPriceTier::VeryLow);
arr[DUP15 as usize] = InstructionInfo::new("DUP15", 0, 15, 16, false, GasPriceTier::VeryLow);
arr[DUP16 as usize] = InstructionInfo::new("DUP16", 0, 16, 17, false, GasPriceTier::VeryLow);
arr[SWAP1 as usize] = InstructionInfo::new("SWAP1", 0, 2, 2, false, GasPriceTier::VeryLow);
arr[SWAP2 as usize] = InstructionInfo::new("SWAP2", 0, 3, 3, false, GasPriceTier::VeryLow);
arr[SWAP3 as usize] = InstructionInfo::new("SWAP3", 0, 4, 4, false, GasPriceTier::VeryLow);
arr[SWAP4 as usize] = InstructionInfo::new("SWAP4", 0, 5, 5, false, GasPriceTier::VeryLow);
arr[SWAP5 as usize] = InstructionInfo::new("SWAP5", 0, 6, 6, false, GasPriceTier::VeryLow);
arr[SWAP6 as usize] = InstructionInfo::new("SWAP6", 0, 7, 7, false, GasPriceTier::VeryLow);
arr[SWAP7 as usize] = InstructionInfo::new("SWAP7", 0, 8, 8, false, GasPriceTier::VeryLow);
arr[SWAP8 as usize] = InstructionInfo::new("SWAP8", 0, 9, 9, false, GasPriceTier::VeryLow);
arr[SWAP9 as usize] = InstructionInfo::new("SWAP9", 0, 10, 10, false, GasPriceTier::VeryLow);
arr[SWAP10 as usize] = InstructionInfo::new("SWAP10", 0, 11, 11, false, GasPriceTier::VeryLow);
arr[SWAP11 as usize] = InstructionInfo::new("SWAP11", 0, 12, 12, false, GasPriceTier::VeryLow);
arr[SWAP12 as usize] = InstructionInfo::new("SWAP12", 0, 13, 13, false, GasPriceTier::VeryLow);
arr[SWAP13 as usize] = InstructionInfo::new("SWAP13", 0, 14, 14, false, GasPriceTier::VeryLow);
arr[SWAP14 as usize] = InstructionInfo::new("SWAP14", 0, 15, 15, false, GasPriceTier::VeryLow);
arr[SWAP15 as usize] = InstructionInfo::new("SWAP15", 0, 16, 16, false, GasPriceTier::VeryLow);
arr[SWAP16 as usize] = InstructionInfo::new("SWAP16", 0, 17, 17, false, GasPriceTier::VeryLow);
arr[LOG0 as usize] = InstructionInfo::new("LOG0", 0, 2, 0, true, GasPriceTier::Special);
arr[LOG1 as usize] = InstructionInfo::new("LOG1", 0, 3, 0, true, GasPriceTier::Special);
arr[LOG2 as usize] = InstructionInfo::new("LOG2", 0, 4, 0, true, GasPriceTier::Special);
arr[LOG3 as usize] = InstructionInfo::new("LOG3", 0, 5, 0, true, GasPriceTier::Special);
arr[LOG4 as usize] = InstructionInfo::new("LOG4", 0, 6, 0, true, GasPriceTier::Special);
arr[CREATE as usize] = InstructionInfo::new("CREATE", 0, 3, 1, true, GasPriceTier::Special);
arr[CALL as usize] = InstructionInfo::new("CALL", 0, 7, 1, true, GasPriceTier::Special);
arr[CALLCODE as usize] = InstructionInfo::new("CALLCODE", 0, 7, 1, true, GasPriceTier::Special);
arr[RETURN as usize] = InstructionInfo::new("RETURN", 0, 2, 0, true, GasPriceTier::Zero);
arr[DELEGATECALL as usize] = InstructionInfo::new("DELEGATECALL", 0, 6, 1, true, GasPriceTier::Special);
arr[SUICIDE as usize] = InstructionInfo::new("SUICIDE", 0, 1, 0, true, GasPriceTier::Special);
arr[CREATE2 as usize] = InstructionInfo::new("CREATE2", 0, 3, 1, true, GasPriceTier::Special);
arr[REVERT as usize] = InstructionInfo::new("REVERT", 0, 2, 0, true, GasPriceTier::Zero);
arr[STOP as usize] = InstructionInfo::new("STOP", 0, 0, 0, GasPriceTier::Zero);
arr[ADD as usize] = InstructionInfo::new("ADD", 0, 2, 1, GasPriceTier::VeryLow);
arr[SUB as usize] = InstructionInfo::new("SUB", 0, 2, 1, GasPriceTier::VeryLow);
arr[MUL as usize] = InstructionInfo::new("MUL", 0, 2, 1, GasPriceTier::Low);
arr[DIV as usize] = InstructionInfo::new("DIV", 0, 2, 1, GasPriceTier::Low);
arr[SDIV as usize] = InstructionInfo::new("SDIV", 0, 2, 1, GasPriceTier::Low);
arr[MOD as usize] = InstructionInfo::new("MOD", 0, 2, 1, GasPriceTier::Low);
arr[SMOD as usize] = InstructionInfo::new("SMOD", 0, 2, 1, GasPriceTier::Low);
arr[EXP as usize] = InstructionInfo::new("EXP", 0, 2, 1, GasPriceTier::Special);
arr[NOT as usize] = InstructionInfo::new("NOT", 0, 1, 1, GasPriceTier::VeryLow);
arr[LT as usize] = InstructionInfo::new("LT", 0, 2, 1, GasPriceTier::VeryLow);
arr[GT as usize] = InstructionInfo::new("GT", 0, 2, 1, GasPriceTier::VeryLow);
arr[SLT as usize] = InstructionInfo::new("SLT", 0, 2, 1, GasPriceTier::VeryLow);
arr[SGT as usize] = InstructionInfo::new("SGT", 0, 2, 1, GasPriceTier::VeryLow);
arr[EQ as usize] = InstructionInfo::new("EQ", 0, 2, 1, GasPriceTier::VeryLow);
arr[ISZERO as usize] = InstructionInfo::new("ISZERO", 0, 1, 1, GasPriceTier::VeryLow);
arr[AND as usize] = InstructionInfo::new("AND", 0, 2, 1, GasPriceTier::VeryLow);
arr[OR as usize] = InstructionInfo::new("OR", 0, 2, 1, GasPriceTier::VeryLow);
arr[XOR as usize] = InstructionInfo::new("XOR", 0, 2, 1, GasPriceTier::VeryLow);
arr[BYTE as usize] = InstructionInfo::new("BYTE", 0, 2, 1, GasPriceTier::VeryLow);
arr[ADDMOD as usize] = InstructionInfo::new("ADDMOD", 0, 3, 1, GasPriceTier::Mid);
arr[MULMOD as usize] = InstructionInfo::new("MULMOD", 0, 3, 1, GasPriceTier::Mid);
arr[SIGNEXTEND as usize] = InstructionInfo::new("SIGNEXTEND", 0, 2, 1, GasPriceTier::Low);
arr[RETURNDATASIZE as usize] = InstructionInfo::new("RETURNDATASIZE", 0, 0, 1, GasPriceTier::Base);
arr[RETURNDATACOPY as usize] = InstructionInfo::new("RETURNDATACOPY", 0, 3, 0, GasPriceTier::VeryLow);
arr[SHA3 as usize] = InstructionInfo::new("SHA3", 0, 2, 1, GasPriceTier::Special);
arr[ADDRESS as usize] = InstructionInfo::new("ADDRESS", 0, 0, 1, GasPriceTier::Base);
arr[BALANCE as usize] = InstructionInfo::new("BALANCE", 0, 1, 1, GasPriceTier::Special);
arr[ORIGIN as usize] = InstructionInfo::new("ORIGIN", 0, 0, 1, GasPriceTier::Base);
arr[CALLER as usize] = InstructionInfo::new("CALLER", 0, 0, 1, GasPriceTier::Base);
arr[CALLVALUE as usize] = InstructionInfo::new("CALLVALUE", 0, 0, 1, GasPriceTier::Base);
arr[CALLDATALOAD as usize] = InstructionInfo::new("CALLDATALOAD", 0, 1, 1, GasPriceTier::VeryLow);
arr[CALLDATASIZE as usize] = InstructionInfo::new("CALLDATASIZE", 0, 0, 1, GasPriceTier::Base);
arr[CALLDATACOPY as usize] = InstructionInfo::new("CALLDATACOPY", 0, 3, 0, GasPriceTier::VeryLow);
arr[CODESIZE as usize] = InstructionInfo::new("CODESIZE", 0, 0, 1, GasPriceTier::Base);
arr[CODECOPY as usize] = InstructionInfo::new("CODECOPY", 0, 3, 0, GasPriceTier::VeryLow);
arr[GASPRICE as usize] = InstructionInfo::new("GASPRICE", 0, 0, 1, GasPriceTier::Base);
arr[EXTCODESIZE as usize] = InstructionInfo::new("EXTCODESIZE", 0, 1, 1, GasPriceTier::Special);
arr[EXTCODECOPY as usize] = InstructionInfo::new("EXTCODECOPY", 0, 4, 0, GasPriceTier::Special);
arr[BLOCKHASH as usize] = InstructionInfo::new("BLOCKHASH", 0, 1, 1, GasPriceTier::Ext);
arr[COINBASE as usize] = InstructionInfo::new("COINBASE", 0, 0, 1, GasPriceTier::Base);
arr[TIMESTAMP as usize] = InstructionInfo::new("TIMESTAMP", 0, 0, 1, GasPriceTier::Base);
arr[NUMBER as usize] = InstructionInfo::new("NUMBER", 0, 0, 1, GasPriceTier::Base);
arr[DIFFICULTY as usize] = InstructionInfo::new("DIFFICULTY", 0, 0, 1, GasPriceTier::Base);
arr[GASLIMIT as usize] = InstructionInfo::new("GASLIMIT", 0, 0, 1, GasPriceTier::Base);
arr[POP as usize] = InstructionInfo::new("POP", 0, 1, 0, GasPriceTier::Base);
arr[MLOAD as usize] = InstructionInfo::new("MLOAD", 0, 1, 1, GasPriceTier::VeryLow);
arr[MSTORE as usize] = InstructionInfo::new("MSTORE", 0, 2, 0, GasPriceTier::VeryLow);
arr[MSTORE8 as usize] = InstructionInfo::new("MSTORE8", 0, 2, 0, GasPriceTier::VeryLow);
arr[SLOAD as usize] = InstructionInfo::new("SLOAD", 0, 1, 1, GasPriceTier::Special);
arr[SSTORE as usize] = InstructionInfo::new("SSTORE", 0, 2, 0, GasPriceTier::Special);
arr[JUMP as usize] = InstructionInfo::new("JUMP", 0, 1, 0, GasPriceTier::Mid);
arr[JUMPI as usize] = InstructionInfo::new("JUMPI", 0, 2, 0, GasPriceTier::High);
arr[PC as usize] = InstructionInfo::new("PC", 0, 0, 1, GasPriceTier::Base);
arr[MSIZE as usize] = InstructionInfo::new("MSIZE", 0, 0, 1, GasPriceTier::Base);
arr[GAS as usize] = InstructionInfo::new("GAS", 0, 0, 1, GasPriceTier::Base);
arr[JUMPDEST as usize] = InstructionInfo::new("JUMPDEST", 0, 0, 0, GasPriceTier::Special);
arr[PUSH1 as usize] = InstructionInfo::new("PUSH1", 1, 0, 1, GasPriceTier::VeryLow);
arr[PUSH2 as usize] = InstructionInfo::new("PUSH2", 2, 0, 1, GasPriceTier::VeryLow);
arr[PUSH3 as usize] = InstructionInfo::new("PUSH3", 3, 0, 1, GasPriceTier::VeryLow);
arr[PUSH4 as usize] = InstructionInfo::new("PUSH4", 4, 0, 1, GasPriceTier::VeryLow);
arr[PUSH5 as usize] = InstructionInfo::new("PUSH5", 5, 0, 1, GasPriceTier::VeryLow);
arr[PUSH6 as usize] = InstructionInfo::new("PUSH6", 6, 0, 1, GasPriceTier::VeryLow);
arr[PUSH7 as usize] = InstructionInfo::new("PUSH7", 7, 0, 1, GasPriceTier::VeryLow);
arr[PUSH8 as usize] = InstructionInfo::new("PUSH8", 8, 0, 1, GasPriceTier::VeryLow);
arr[PUSH9 as usize] = InstructionInfo::new("PUSH9", 9, 0, 1, GasPriceTier::VeryLow);
arr[PUSH10 as usize] = InstructionInfo::new("PUSH10", 10, 0, 1, GasPriceTier::VeryLow);
arr[PUSH11 as usize] = InstructionInfo::new("PUSH11", 11, 0, 1, GasPriceTier::VeryLow);
arr[PUSH12 as usize] = InstructionInfo::new("PUSH12", 12, 0, 1, GasPriceTier::VeryLow);
arr[PUSH13 as usize] = InstructionInfo::new("PUSH13", 13, 0, 1, GasPriceTier::VeryLow);
arr[PUSH14 as usize] = InstructionInfo::new("PUSH14", 14, 0, 1, GasPriceTier::VeryLow);
arr[PUSH15 as usize] = InstructionInfo::new("PUSH15", 15, 0, 1, GasPriceTier::VeryLow);
arr[PUSH16 as usize] = InstructionInfo::new("PUSH16", 16, 0, 1, GasPriceTier::VeryLow);
arr[PUSH17 as usize] = InstructionInfo::new("PUSH17", 17, 0, 1, GasPriceTier::VeryLow);
arr[PUSH18 as usize] = InstructionInfo::new("PUSH18", 18, 0, 1, GasPriceTier::VeryLow);
arr[PUSH19 as usize] = InstructionInfo::new("PUSH19", 19, 0, 1, GasPriceTier::VeryLow);
arr[PUSH20 as usize] = InstructionInfo::new("PUSH20", 20, 0, 1, GasPriceTier::VeryLow);
arr[PUSH21 as usize] = InstructionInfo::new("PUSH21", 21, 0, 1, GasPriceTier::VeryLow);
arr[PUSH22 as usize] = InstructionInfo::new("PUSH22", 22, 0, 1, GasPriceTier::VeryLow);
arr[PUSH23 as usize] = InstructionInfo::new("PUSH23", 23, 0, 1, GasPriceTier::VeryLow);
arr[PUSH24 as usize] = InstructionInfo::new("PUSH24", 24, 0, 1, GasPriceTier::VeryLow);
arr[PUSH25 as usize] = InstructionInfo::new("PUSH25", 25, 0, 1, GasPriceTier::VeryLow);
arr[PUSH26 as usize] = InstructionInfo::new("PUSH26", 26, 0, 1, GasPriceTier::VeryLow);
arr[PUSH27 as usize] = InstructionInfo::new("PUSH27", 27, 0, 1, GasPriceTier::VeryLow);
arr[PUSH28 as usize] = InstructionInfo::new("PUSH28", 28, 0, 1, GasPriceTier::VeryLow);
arr[PUSH29 as usize] = InstructionInfo::new("PUSH29", 29, 0, 1, GasPriceTier::VeryLow);
arr[PUSH30 as usize] = InstructionInfo::new("PUSH30", 30, 0, 1, GasPriceTier::VeryLow);
arr[PUSH31 as usize] = InstructionInfo::new("PUSH31", 31, 0, 1, GasPriceTier::VeryLow);
arr[PUSH32 as usize] = InstructionInfo::new("PUSH32", 32, 0, 1, GasPriceTier::VeryLow);
arr[DUP1 as usize] = InstructionInfo::new("DUP1", 0, 1, 2, GasPriceTier::VeryLow);
arr[DUP2 as usize] = InstructionInfo::new("DUP2", 0, 2, 3, GasPriceTier::VeryLow);
arr[DUP3 as usize] = InstructionInfo::new("DUP3", 0, 3, 4, GasPriceTier::VeryLow);
arr[DUP4 as usize] = InstructionInfo::new("DUP4", 0, 4, 5, GasPriceTier::VeryLow);
arr[DUP5 as usize] = InstructionInfo::new("DUP5", 0, 5, 6, GasPriceTier::VeryLow);
arr[DUP6 as usize] = InstructionInfo::new("DUP6", 0, 6, 7, GasPriceTier::VeryLow);
arr[DUP7 as usize] = InstructionInfo::new("DUP7", 0, 7, 8, GasPriceTier::VeryLow);
arr[DUP8 as usize] = InstructionInfo::new("DUP8", 0, 8, 9, GasPriceTier::VeryLow);
arr[DUP9 as usize] = InstructionInfo::new("DUP9", 0, 9, 10, GasPriceTier::VeryLow);
arr[DUP10 as usize] = InstructionInfo::new("DUP10", 0, 10, 11, GasPriceTier::VeryLow);
arr[DUP11 as usize] = InstructionInfo::new("DUP11", 0, 11, 12, GasPriceTier::VeryLow);
arr[DUP12 as usize] = InstructionInfo::new("DUP12", 0, 12, 13, GasPriceTier::VeryLow);
arr[DUP13 as usize] = InstructionInfo::new("DUP13", 0, 13, 14, GasPriceTier::VeryLow);
arr[DUP14 as usize] = InstructionInfo::new("DUP14", 0, 14, 15, GasPriceTier::VeryLow);
arr[DUP15 as usize] = InstructionInfo::new("DUP15", 0, 15, 16, GasPriceTier::VeryLow);
arr[DUP16 as usize] = InstructionInfo::new("DUP16", 0, 16, 17, GasPriceTier::VeryLow);
arr[SWAP1 as usize] = InstructionInfo::new("SWAP1", 0, 2, 2, GasPriceTier::VeryLow);
arr[SWAP2 as usize] = InstructionInfo::new("SWAP2", 0, 3, 3, GasPriceTier::VeryLow);
arr[SWAP3 as usize] = InstructionInfo::new("SWAP3", 0, 4, 4, GasPriceTier::VeryLow);
arr[SWAP4 as usize] = InstructionInfo::new("SWAP4", 0, 5, 5, GasPriceTier::VeryLow);
arr[SWAP5 as usize] = InstructionInfo::new("SWAP5", 0, 6, 6, GasPriceTier::VeryLow);
arr[SWAP6 as usize] = InstructionInfo::new("SWAP6", 0, 7, 7, GasPriceTier::VeryLow);
arr[SWAP7 as usize] = InstructionInfo::new("SWAP7", 0, 8, 8, GasPriceTier::VeryLow);
arr[SWAP8 as usize] = InstructionInfo::new("SWAP8", 0, 9, 9, GasPriceTier::VeryLow);
arr[SWAP9 as usize] = InstructionInfo::new("SWAP9", 0, 10, 10, GasPriceTier::VeryLow);
arr[SWAP10 as usize] = InstructionInfo::new("SWAP10", 0, 11, 11, GasPriceTier::VeryLow);
arr[SWAP11 as usize] = InstructionInfo::new("SWAP11", 0, 12, 12, GasPriceTier::VeryLow);
arr[SWAP12 as usize] = InstructionInfo::new("SWAP12", 0, 13, 13, GasPriceTier::VeryLow);
arr[SWAP13 as usize] = InstructionInfo::new("SWAP13", 0, 14, 14, GasPriceTier::VeryLow);
arr[SWAP14 as usize] = InstructionInfo::new("SWAP14", 0, 15, 15, GasPriceTier::VeryLow);
arr[SWAP15 as usize] = InstructionInfo::new("SWAP15", 0, 16, 16, GasPriceTier::VeryLow);
arr[SWAP16 as usize] = InstructionInfo::new("SWAP16", 0, 17, 17, GasPriceTier::VeryLow);
arr[LOG0 as usize] = InstructionInfo::new("LOG0", 0, 2, 0, GasPriceTier::Special);
arr[LOG1 as usize] = InstructionInfo::new("LOG1", 0, 3, 0, GasPriceTier::Special);
arr[LOG2 as usize] = InstructionInfo::new("LOG2", 0, 4, 0, GasPriceTier::Special);
arr[LOG3 as usize] = InstructionInfo::new("LOG3", 0, 5, 0, GasPriceTier::Special);
arr[LOG4 as usize] = InstructionInfo::new("LOG4", 0, 6, 0, GasPriceTier::Special);
arr[CREATE as usize] = InstructionInfo::new("CREATE", 0, 3, 1, GasPriceTier::Special);
arr[CALL as usize] = InstructionInfo::new("CALL", 0, 7, 1, GasPriceTier::Special);
arr[CALLCODE as usize] = InstructionInfo::new("CALLCODE", 0, 7, 1, GasPriceTier::Special);
arr[RETURN as usize] = InstructionInfo::new("RETURN", 0, 2, 0, GasPriceTier::Zero);
arr[DELEGATECALL as usize] = InstructionInfo::new("DELEGATECALL", 0, 6, 1, GasPriceTier::Special);
arr[SUICIDE as usize] = InstructionInfo::new("SUICIDE", 0, 1, 0, GasPriceTier::Special);
arr[CREATE2 as usize] = InstructionInfo::new("CREATE2", 0, 3, 1, GasPriceTier::Special);
arr[REVERT as usize] = InstructionInfo::new("REVERT", 0, 2, 0, GasPriceTier::Zero);
arr
};
}

View File

@ -89,9 +89,10 @@ impl Memory for Vec<u8> {
}
fn write_slice(&mut self, offset: U256, slice: &[u8]) {
let off = offset.low_u64() as usize;
self[off..off+slice.len()].copy_from_slice(slice);
if !slice.is_empty() {
let off = offset.low_u64() as usize;
self[off..off+slice.len()].copy_from_slice(slice);
}
}
fn write(&mut self, offset: U256, value: U256) {
@ -183,5 +184,12 @@ mod tests {
assert_eq!(mem.read_slice(U256::from(0), U256::from(7)), "a67890g".as_bytes());
}
// write empty slice out of bounds
{
let slice = [];
mem.write_slice(U256::from(0x1000), &slice);
assert_eq!(mem.size(), 32);
}
}
}

View File

@ -1,6 +1,6 @@
{
"name": "parity.js",
"version": "1.7.87",
"version": "1.7.89",
"main": "release/index.js",
"jsnext:main": "src/index.js",
"author": "Parity Team <admin@parity.io>",
@ -159,6 +159,7 @@
},
"dependencies": {
"@parity/wordlist": "1.0.1",
"arraybuffer-loader": "0.2.2",
"babel-runtime": "6.23.0",
"base32.js": "0.1.0",
"bignumber.js": "3.0.1",
@ -218,7 +219,6 @@
"redux-thunk": "2.1.0",
"rlp": "2.0.0",
"scryptsy": "2.0.0",
"secp256k1": "3.2.5",
"solc": "ngotchac/solc-js",
"store": "1.3.20",
"sw-toolbox": "^3.6.0",

View File

@ -23,7 +23,7 @@ import { Db, Eth, Parity, Net, Personal, Shh, Signer, Trace, Web3 } from './rpc'
import Subscriptions from './subscriptions';
import util from './util';
import { isFunction } from './util/types';
// import { LocalAccountsMiddleware } from './local';
import { LocalAccountsMiddleware } from './local';
export default class Api extends EventEmitter {
constructor (transport, allowSubscriptions = true) {
@ -54,9 +54,9 @@ export default class Api extends EventEmitter {
const middleware = this.parity
.nodeKind()
.then((nodeKind) => {
// if (nodeKind.availability === 'public') {
// return LocalAccountsMiddleware;
// }
if (nodeKind.availability === 'public') {
return LocalAccountsMiddleware;
}
return null;
})

View File

@ -17,9 +17,9 @@
import { createKeyObject, decryptPrivateKey } from '../ethkey';
export default class Account {
constructor (persist, data) {
constructor (persist, data = {}) {
const {
keyObject,
keyObject = null,
meta = {},
name = ''
} = data;
@ -41,6 +41,15 @@ export default class Account {
});
}
export () {
const exported = Object.assign({}, this._keyObject);
exported.meta = JSON.stringify(this._meta);
exported.name = this._name;
return exported;
}
get address () {
return `0x${this._keyObject.address.toLowerCase()}`;
}
@ -66,6 +75,10 @@ export default class Account {
}
get uuid () {
if (!this._keyObject) {
return null;
}
return this._keyObject.id;
}

View File

@ -17,23 +17,74 @@
import Account from './account';
import localStore from 'store';
import { debounce } from 'lodash';
import { decryptPrivateKey } from '../ethkey';
const NULL_ADDRESS = '0x0000000000000000000000000000000000000000';
const LS_STORE_KEY = '_parity::localAccounts';
export default class Accounts {
persist = debounce(() => {
this._lastState = JSON.stringify(this);
localStore.set(LS_STORE_KEY, this);
}, 100);
constructor (data = localStore.get(LS_STORE_KEY) || {}) {
this._lastState = JSON.stringify(data);
window.addEventListener('storage', ({ key, newValue }) => {
if (key !== LS_STORE_KEY) {
return;
}
if (newValue !== this._lastState) {
console.log('Data changed in a second tab, syncing state');
this.restore(JSON.parse(newValue));
}
});
this.restore(data);
}
restore (data) {
const {
last = NULL_ADDRESS,
store = []
dappsDefault = NULL_ADDRESS,
store = {}
} = data;
this.persist = debounce(() => {
localStore.set(LS_STORE_KEY, this);
}, 100);
this._last = last;
this._store = store.map((data) => new Account(this.persist, data));
this._dappsDefaultAddress = dappsDefault;
this._store = {};
if (Array.isArray(store)) {
// Recover older version that stored accounts as an array
store.forEach((data) => {
const account = new Account(this.persist, data);
this._store[account.address] = account;
});
} else {
Object.keys(store).forEach((key) => {
this._store[key] = new Account(this.persist, store[key]);
});
}
}
_addAccount = (account) => {
const { address } = account;
if (address in this._store && this._store[address].uuid) {
throw new Error(`Account ${address} already exists!`);
}
this._store[address] = account;
this.lastAddress = address;
this.persist();
return account.address;
}
create (secret, password) {
@ -41,20 +92,19 @@ export default class Accounts {
return Account
.fromPrivateKey(this.persist, privateKey, password)
.then((account) => {
const { address } = account;
.then(this._addAccount);
}
if (this._store.find((account) => account.address === address)) {
throw new Error(`Account ${address} already exists!`);
restoreFromWallet (wallet, password) {
return decryptPrivateKey(wallet, password)
.then((privateKey) => {
if (!privateKey) {
throw new Error('Invalid password');
}
this._store.push(account);
this.lastAddress = address;
this.persist();
return account.address;
});
return Account.fromPrivateKey(this.persist, privateKey, password);
})
.then(this._addAccount);
}
set lastAddress (value) {
@ -65,20 +115,48 @@ export default class Accounts {
return this._last;
}
get dappsDefaultAddress () {
if (this._dappsDefaultAddress === NULL_ADDRESS) {
return this._last;
}
if (this._dappsDefaultAddress in this._store) {
return this._dappsDefaultAddress;
}
return NULL_ADDRESS;
}
set dappsDefaultAddress (value) {
this._dappsDefaultAddress = value.toLowerCase();
}
get (address) {
address = address.toLowerCase();
this.lastAddress = address;
const account = this._store.find((account) => account.address === address);
const account = this._store[address];
if (!account) {
throw new Error(`Account not found: ${address}`);
}
this.lastAddress = address;
return account;
}
getLazyCreate (address) {
address = address.toLowerCase();
this.lastAddress = address;
if (!(address in this._store)) {
this._store[address] = new Account(this.persist);
}
return this._store[address];
}
remove (address, password) {
address = address.toLowerCase();
@ -108,26 +186,20 @@ export default class Accounts {
removeUnsafe (address) {
address = address.toLowerCase();
const index = this._store.findIndex((account) => account.address === address);
if (index === -1) {
return;
}
this._store.splice(index, 1);
delete this._store[address];
this.persist();
}
mapArray (mapper) {
return this._store.map(mapper);
addresses () {
return Object.keys(this._store);
}
mapObject (mapper) {
map (mapper) {
const result = {};
this._store.forEach((account) => {
result[account.address] = mapper(account);
Object.keys(this._store).forEach((key) => {
result[key] = mapper(this._store[key]);
});
return result;
@ -136,6 +208,7 @@ export default class Accounts {
toJSON () {
return {
last: this._last,
dappsDefault: this._dappsDefaultAddress,
store: this._store
};
}

View File

@ -0,0 +1,147 @@
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
/* global WebAssembly */
import wasmBuffer from './ethkey.wasm.js';
const NOOP = () => {};
// WASM memory setup
const WASM_PAGE_SIZE = 65536;
const STATIC_BASE = 1024;
const STATICTOP = STATIC_BASE + WASM_PAGE_SIZE * 2;
const STACK_BASE = align(STATICTOP + 16);
const STACKTOP = STACK_BASE;
const TOTAL_STACK = 5 * 1024 * 1024;
const TOTAL_MEMORY = 16777216;
const STACK_MAX = STACK_BASE + TOTAL_STACK;
const DYNAMIC_BASE = STACK_MAX + 64;
const DYNAMICTOP_PTR = STACK_MAX;
function mockWebAssembly () {
function throwWasmError () {
throw new Error('Missing WebAssembly support');
}
// Simple mock replacement
return {
Memory: class { buffer = new ArrayBuffer(2048) },
Table: class {},
Module: class {},
Instance: class {
exports = {
'_input_ptr': () => 0,
'_secret_ptr': () => 0,
'_public_ptr': () => 0,
'_address_ptr': () => 0,
'_ecpointg': NOOP,
'_brain': throwWasmError,
'_verify_secret': throwWasmError
}
}
};
}
const { Memory, Table, Module, Instance } = typeof WebAssembly !== 'undefined' ? WebAssembly : mockWebAssembly();
const wasmMemory = new Memory({
initial: TOTAL_MEMORY / WASM_PAGE_SIZE,
maximum: TOTAL_MEMORY / WASM_PAGE_SIZE
});
const wasmTable = new Table({
initial: 8,
maximum: 8,
element: 'anyfunc'
});
// TypedArray views into the memory
const wasmMemoryU8 = new Uint8Array(wasmMemory.buffer);
const wasmMemoryU32 = new Uint32Array(wasmMemory.buffer);
// Keep DYNAMIC_BASE in memory
wasmMemoryU32[DYNAMICTOP_PTR >> 2] = align(DYNAMIC_BASE);
function align (mem) {
const ALIGN_SIZE = 16;
return (Math.ceil(mem / ALIGN_SIZE) * ALIGN_SIZE) | 0;
}
export function slice (ptr, len) {
return wasmMemoryU8.subarray(ptr, ptr + len);
}
// Required by emscripten
function abort (what) {
throw new Error(what || 'WASM abort');
}
// Required by emscripten
function abortOnCannotGrowMemory () {
abort(`Cannot enlarge memory arrays.`);
}
// Required by emscripten
function enlargeMemory () {
abortOnCannotGrowMemory();
}
// Required by emscripten
function getTotalMemory () {
return TOTAL_MEMORY;
}
// Required by emscripten - used to perform memcpy on large data
function memcpy (dest, src, len) {
wasmMemoryU8.set(wasmMemoryU8.subarray(src, src + len), dest);
return dest;
}
// Synchronously compile WASM from the buffer
const module = new Module(wasmBuffer);
// Instantiated WASM module
const instance = new Instance(module, {
global: {},
env: {
DYNAMICTOP_PTR,
STACKTOP,
STACK_MAX,
abort,
enlargeMemory,
getTotalMemory,
abortOnCannotGrowMemory,
___lock: NOOP,
___syscall6: () => 0,
___setErrNo: (no) => no,
_abort: abort,
___syscall140: () => 0,
_emscripten_memcpy_big: memcpy,
___syscall54: () => 0,
___unlock: NOOP,
_llvm_trap: abort,
___syscall146: () => 0,
'memory': wasmMemory,
'table': wasmTable,
tableBase: 0,
memoryBase: STATIC_BASE
}
});
export const extern = instance.exports;

File diff suppressed because one or more lines are too long

View File

@ -17,13 +17,12 @@
import workerPool from './workerPool';
export function createKeyObject (key, password) {
return workerPool.getWorker().action('createKeyObject', { key, password })
return workerPool.action('createKeyObject', { key, password })
.then((obj) => JSON.parse(obj));
}
export function decryptPrivateKey (keyObject, password) {
return workerPool
.getWorker()
.action('decryptPrivateKey', { keyObject, password })
.then((privateKey) => {
if (privateKey) {
@ -40,9 +39,9 @@ export function phraseToAddress (phrase) {
}
export function phraseToWallet (phrase) {
return workerPool.getWorker().action('phraseToWallet', phrase);
return workerPool.action('phraseToWallet', phrase);
}
export function verifySecret (secret) {
return workerPool.getWorker().action('verifySecret', secret);
return workerPool.action('verifySecret', secret);
}

View File

@ -17,7 +17,8 @@
import { randomPhrase } from '@parity/wordlist';
import { phraseToAddress, phraseToWallet } from './';
describe('api/local/ethkey', () => {
// TODO: Skipping until Node.js 8.0 comes out and we can test WebAssembly
describe.skip('api/local/ethkey', () => {
describe('phraseToAddress', function () {
this.timeout(30000);

View File

@ -14,9 +14,8 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import secp256k1 from 'secp256k1';
import { keccak_256 as keccak256 } from 'js-sha3';
import { bytesToHex } from '~/api/util/format';
import { extern, slice } from './ethkey.js';
const isWorker = typeof self !== 'undefined';
@ -42,43 +41,40 @@ function route ({ action, payload }) {
return null;
}
const input = slice(extern._input_ptr(), 1024);
const secret = slice(extern._secret_ptr(), 32);
const publicKey = slice(extern._public_ptr(), 64);
const address = slice(extern._address_ptr(), 20);
extern._ecpointg();
const actions = {
phraseToWallet (phrase) {
let secret = keccak256.array(phrase);
const phraseUtf8 = Buffer.from(phrase, 'utf8');
for (let i = 0; i < 16384; i++) {
secret = keccak256.array(secret);
if (phraseUtf8.length > input.length) {
throw new Error('Phrase is too long!');
}
while (true) {
secret = keccak256.array(secret);
input.set(phraseUtf8);
const secretBuf = Buffer.from(secret);
extern._brain(phraseUtf8.length);
if (secp256k1.privateKeyVerify(secretBuf)) {
// No compression, slice out last 64 bytes
const publicBuf = secp256k1.publicKeyCreate(secretBuf, false).slice(-64);
const address = keccak256.array(publicBuf).slice(12);
const wallet = {
secret: bytesToHex(secret),
public: bytesToHex(publicKey),
address: bytesToHex(address)
};
if (address[0] !== 0) {
continue;
}
const wallet = {
secret: bytesToHex(secretBuf),
public: bytesToHex(publicBuf),
address: bytesToHex(address)
};
return wallet;
}
}
return wallet;
},
verifySecret (secret) {
const key = Buffer.from(secret.slice(2), 'hex');
verifySecret (key) {
const keyBuf = Buffer.from(key.slice(2), 'hex');
return secp256k1.privateKeyVerify(key);
secret.set(keyBuf);
return extern._verify_secret();
},
createKeyObject ({ key, password }) {
@ -112,7 +108,8 @@ self.onmessage = function ({ data }) {
postMessage([null, result]);
} catch (err) {
postMessage([err, null]);
console.error(err);
postMessage([err.toString(), null]);
}
};

View File

@ -38,7 +38,8 @@ class WorkerContainer {
this.busy = false;
if (err) {
reject(err);
// `err` ought to be a String
reject(new Error(err));
} else {
resolve(result);
}
@ -48,20 +49,56 @@ class WorkerContainer {
}
class WorkerPool {
pool = [];
pool = [
new WorkerContainer(),
new WorkerContainer()
];
getWorker () {
queue = [];
_getContainer () {
return this.pool.find((container) => !container.busy);
}
action (action, payload) {
let container = this.pool.find((container) => !container.busy);
let promise;
// const start = Date.now();
if (container) {
return container;
promise = container.action(action, payload);
} else {
promise = new Promise((resolve, reject) => {
this.queue.push([action, payload, resolve]);
});
}
container = new WorkerContainer();
return promise
.catch((err) => {
this.processQueue();
this.pool.push(container);
throw err;
})
.then((result) => {
this.processQueue();
return container;
// console.log('Work done in ', Date.now() - start);
return result;
});
}
processQueue () {
let container = this._getContainer();
while (container && this.queue.length > 0) {
const [action, payload, resolve] = this.queue.shift();
resolve(container.action(action, payload));
container = this._getContainer();
}
}
}

View File

@ -29,7 +29,7 @@ export default class LocalAccountsMiddleware extends Middleware {
const register = this.register.bind(this);
register('eth_accounts', () => {
return accounts.mapArray((account) => account.address);
return accounts.addresses();
});
register('eth_coinbase', () => {
@ -37,13 +37,13 @@ export default class LocalAccountsMiddleware extends Middleware {
});
register('parity_accountsInfo', () => {
return accounts.mapObject(({ name }) => {
return accounts.map(({ name }) => {
return { name };
});
});
register('parity_allAccountsInfo', () => {
return accounts.mapObject(({ name, meta, uuid }) => {
return accounts.map(({ name, meta, uuid }) => {
return { name, meta, uuid };
});
});
@ -68,10 +68,31 @@ export default class LocalAccountsMiddleware extends Middleware {
return transactions.hash(id) || Promise.resolve(null);
});
register('parity_dappsList', () => {
return [];
});
register('parity_defaultAccount', () => {
return accounts.lastAddress;
});
register('parity_exportAccount', ([address, password]) => {
const account = accounts.get(address);
if (!password) {
password = '';
}
return account.isValidPassword(password)
.then((isValid) => {
if (!isValid) {
throw new Error('Invalid password');
}
return account.export();
});
});
register('parity_generateSecretPhrase', () => {
return randomPhrase(12);
});
@ -80,6 +101,10 @@ export default class LocalAccountsMiddleware extends Middleware {
return [];
});
register('parity_getNewDappsDefaultAddress', () => {
return accounts.lastAddress;
});
register('parity_hardwareAccountsInfo', () => {
return {};
});
@ -102,18 +127,30 @@ export default class LocalAccountsMiddleware extends Middleware {
});
});
register('parity_newAccountFromWallet', ([json, password]) => {
if (!password) {
password = '';
}
return accounts.restoreFromWallet(JSON.parse(json), password);
});
register('parity_setAccountMeta', ([address, meta]) => {
accounts.get(address).meta = meta;
accounts.getLazyCreate(address).meta = meta;
return true;
});
register('parity_setAccountName', ([address, name]) => {
accounts.get(address).name = name;
accounts.getLazyCreate(address).name = name;
return true;
});
register('parity_setNewDappsDefaultAddress', ([address]) => {
accounts.dappsDefaultAddress = address;
});
register('parity_postTransaction', ([tx]) => {
if (!tx.from) {
tx.from = accounts.lastAddress;
@ -137,10 +174,32 @@ export default class LocalAccountsMiddleware extends Middleware {
return [];
});
register('parity_listOpenedVaults', () => {
return [];
});
register('parity_listRecentDapps', () => {
return {};
});
register('parity_listVaults', () => {
return [];
});
register('parity_wsUrl', () => {
// This is a hack, will be replaced by a `hostname` setting on the node itself
return `${window.location.hostname}:8546`;
});
register('parity_dappsUrl', () => {
// This is a hack, will be replaced by a `hostname` setting on the node itself
return `${window.location.hostname}:8545`;
});
register('parity_hashContent', () => {
throw new Error('Functionality unavailable on a public wallet.');
});
register('parity_killAccount', ([address, password]) => {
return accounts.remove(address, password);
});
@ -204,6 +263,10 @@ export default class LocalAccountsMiddleware extends Middleware {
});
});
register('signer_generateAuthorizationToken', () => {
return '';
});
register('signer_rejectRequest', ([id]) => {
return transactions.reject(id);
});

View File

@ -32,7 +32,8 @@ class MockedTransport extends JsonRpcBase {
}
}
describe('api/local/LocalAccountsMiddleware', function () {
// Skip till all CI runs on Node 8+
describe.skip('api/local/LocalAccountsMiddleware', function () {
this.timeout(30000);
let transport;
@ -71,7 +72,9 @@ describe('api/local/LocalAccountsMiddleware', function () {
'parity_phraseToAddress',
'parity_useLocalAccounts',
'parity_listGethAccounts',
'parity_listOpenedVaults',
'parity_listRecentDapps',
'parity_listVaults',
'parity_killAccount',
'parity_testPassword',
'signer_confirmRequest',

View File

@ -70,7 +70,7 @@ export default class TnC extends Component {
<p>We recommend any groups handling large or important transactions to maintain a voluntary 24 hour waiting period on any ether deposited. In case the integrity of the network is at risk due to issues in the clients, we will endeavour to publish patches in a timely fashion to address the issues. We will endeavour to provide solutions within the voluntary 24 hour waiting period.</p>
<h3>Use of Parity by you</h3>
<p>You agree to use Party only for purposes that are permitted by (a) these Terms and (b) any applicable law, regulation or generally accepted practices or guidelines in the relevant jurisdictions (including any laws regarding the export of data or software to and from the United Kingdom or other relevant countries).</p>
<p>You agree to use Parity only for purposes that are permitted by (a) these Terms and (b) any applicable law, regulation or generally accepted practices or guidelines in the relevant jurisdictions (including any laws regarding the export of data or software to and from the United Kingdom or other relevant countries).</p>
<p>You agree that you will not engage in any activity that interferes with or disrupts Paritys or Paritys Products functioning (or the networks which are connected to Parity).</p>
<p>Unless you have been specifically permitted to do so in a separate agreement with Parity, you agree that you will not reproduce, duplicate, copy, sell, trade or resell the Paritys Products for any purpose unless than in accordance to the terms of the software licence terms available here: <a href='https://www.gnu.org/licenses/gpl-3.0.txt' target='_blank'>https://www.gnu.org/licenses/gpl-3.0.txt</a> (“Software Licence Terms”).</p>
<p>You agree that you are solely responsible for (and that Parity has no responsibility to you or to any third party for) any breach of your obligations under these terms and for the consequences (including any loss or damage which Parity may suffer) of any such breach.</p>

View File

@ -41,6 +41,7 @@ class Accounts extends Component {
static propTypes = {
accounts: PropTypes.object.isRequired,
accountsInfo: PropTypes.object.isRequired,
availability: PropTypes.string.isRequired,
hasAccounts: PropTypes.bool.isRequired,
setVisibleAccounts: PropTypes.func.isRequired
}
@ -249,21 +250,7 @@ class Accounts extends Component {
renderActionbar () {
const buttons = [
<Link
to='/vaults'
key='vaults'
>
<Button
icon={ <KeyIcon /> }
label={
<FormattedMessage
id='accounts.button.vaults'
defaultMessage='vaults'
/>
}
onClick={ this.onVaultsClick }
/>
</Link>,
this.renderVaultsButton(),
<Button
key='newAccount'
icon={ <AddIcon /> }
@ -275,17 +262,7 @@ class Accounts extends Component {
}
onClick={ this.onNewAccountClick }
/>,
<Button
key='newWallet'
icon={ <AddIcon /> }
label={
<FormattedMessage
id='accounts.button.newWallet'
defaultMessage='wallet'
/>
}
onClick={ this.onNewWalletClick }
/>,
this.renderNewWalletButton(),
<Button
key='restoreAccount'
icon={ <AddIcon /> }
@ -370,6 +347,50 @@ class Accounts extends Component {
);
}
renderVaultsButton () {
if (this.props.availability !== 'personal') {
return null;
}
return (
<Link
to='/vaults'
key='vaults'
>
<Button
icon={ <KeyIcon /> }
label={
<FormattedMessage
id='accounts.button.vaults'
defaultMessage='vaults'
/>
}
onClick={ this.onVaultsClick }
/>
</Link>
);
}
renderNewWalletButton () {
if (this.props.availability !== 'personal') {
return null;
}
return (
<Button
key='newWallet'
icon={ <AddIcon /> }
label={
<FormattedMessage
id='accounts.button.newWallet'
defaultMessage='wallet'
/>
}
onClick={ this.onNewWalletClick }
/>
);
}
renderNewWalletDialog () {
const { accounts } = this.props;
const { newWalletDialog } = this.state;
@ -474,10 +495,12 @@ class Accounts extends Component {
function mapStateToProps (state) {
const { accounts, accountsInfo, hasAccounts } = state.personal;
const { availability = 'unknown' } = state.nodeStatus.nodeKind || {};
return {
accounts,
accountsInfo,
availability,
hasAccounts
};
}

View File

@ -60,6 +60,11 @@ function createRedux () {
},
balances: {
balances: {}
},
nodeStatus: {
nodeKind: {
'availability': 'personal'
}
}
};
}

View File

@ -99,11 +99,19 @@ function mapStateToProps (initState) {
}));
return (state) => {
const { availability = 'unknown' } = state.nodeStatus.nodeKind || {};
const { views } = state.settings;
const viewIds = Object
.keys(views)
.filter((id) => views[id].fixed || views[id].active);
.filter((id) => {
const view = views[id];
const isEnabled = view.fixed || view.active;
const isAllowed = !view.onlyPersonal || availability === 'personal';
return isEnabled && isAllowed;
});
if (isEqual(viewIds, filteredViewIds)) {
return { views: filteredViews };

View File

@ -33,6 +33,11 @@ function createStore () {
views: {
settings: { fixed: true }
}
},
nodeStatus: {
nodeKind: {
'availability': 'personal'
}
}
};
}

View File

@ -63,7 +63,8 @@
"author": "Parity Team <admin@parity.io>",
"version": "1.0.0",
"visible": false,
"secure": true
"secure": true,
"onlyPersonal": true
},
{
"id": "0xae74ad174b95cdbd01c88ac5b73a296d33e9088fc2a200e76bcedf3a94a7815d",
@ -94,6 +95,7 @@
"version": "1.0.0",
"visible": true,
"skipBuild": true,
"skipHistory": true
"skipHistory": true,
"onlyPersonal": true
}
]

View File

@ -34,10 +34,11 @@ import styles from './dapps.css';
class Dapps extends Component {
static contextTypes = {
api: PropTypes.object.isRequired
}
};
static propTypes = {
accounts: PropTypes.object.isRequired
accounts: PropTypes.object.isRequired,
availability: PropTypes.string.isRequired
};
store = DappsStore.get(this.context.api);
@ -133,6 +134,10 @@ class Dapps extends Component {
}
renderApp = (app) => {
if (app.onlyPersonal && this.props.availability !== 'personal') {
return null;
}
return (
<DappCard
app={ app }
@ -156,6 +161,7 @@ class Dapps extends Component {
function mapStateToProps (state) {
const { accounts } = state.personal;
const { availability = 'unknown' } = state.nodeStatus.nodeKind || {};
/**
* Do not show the Wallet Accounts in the Dapps
@ -165,7 +171,8 @@ function mapStateToProps (state) {
const _accounts = omitBy(accounts, (account) => account.wallet);
return {
accounts: _accounts
accounts: _accounts,
availability
};
}

View File

@ -16,6 +16,7 @@
import { observer } from 'mobx-react';
import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import { FormattedMessage } from 'react-intl';
import HistoryStore from '~/mobx/historyStore';
@ -32,11 +33,15 @@ import Urls from './Urls';
import styles from './home.css';
@observer
export default class Home extends Component {
class Home extends Component {
static contextTypes = {
api: PropTypes.object.isRequired
};
static propTypes = {
availability: PropTypes.string.isRequired
};
dappsStore = DappsStore.get(this.context.api);
extensionStore = ExtensionStore.get();
webStore = WebStore.get(this.context.api);
@ -49,6 +54,13 @@ export default class Home extends Component {
}
render () {
const urls = this.props.availability !== 'personal' ? null : (
<Urls
extensionStore={ this.extensionStore }
store={ this.webStore }
/>
);
return (
<Page
className={ styles.body }
@ -60,10 +72,7 @@ export default class Home extends Component {
}
>
<News />
<Urls
extensionStore={ this.extensionStore }
store={ this.webStore }
/>
{ urls }
<div className={ styles.row }>
<div className={ styles.column }>
<Dapps
@ -79,3 +88,16 @@ export default class Home extends Component {
);
}
}
function mapStateToProps (initState) {
return (state) => {
const { availability = 'unknown' } = state.nodeStatus.nodeKind || {};
return { availability };
};
}
export default connect(
mapStateToProps,
null
)(Home);

View File

@ -25,6 +25,25 @@ const TEST_APP_HISTORY = [];
let api;
let component;
let instance;
let store;
function createStore () {
store = {
dispatch: sinon.stub(),
subscribe: sinon.stub(),
getState: () => {
return {
nodeStatus: {
nodeKind: {
'availability': 'personal'
}
}
};
}
};
return store;
}
function createApi () {
api = {
@ -41,10 +60,14 @@ function render () {
<Home />,
{
context: {
api: createApi()
store: createStore()
}
}
);
).find('Home').shallow({
context: {
api: createApi()
}
});
instance = component.instance();
return component;

View File

@ -59,6 +59,7 @@ const defaultViews = {
contracts: {
active: false,
onlyPersonal: true,
icon: <ContactsIcon />,
route: '/contracts',
value: 'contract'
@ -66,6 +67,7 @@ const defaultViews = {
status: {
active: false,
onlyPersonal: true,
icon: <StatusIcon />,
route: '/status',
value: 'status'

View File

@ -30,7 +30,8 @@ import styles from './views.css';
class Views extends Component {
static propTypes = {
settings: PropTypes.object.isRequired,
toggleView: PropTypes.func.isRequired
toggleView: PropTypes.func.isRequired,
availability: PropTypes.string.isRequired
}
render () {
@ -168,6 +169,10 @@ class Views extends Component {
const toggle = () => toggleView(id);
const view = settings.views[id];
if (view.onlyPersonal && this.props.availability !== 'personal') {
return null;
}
return (
<div className={ styles.view } key={ id }>
<Checkbox
@ -196,8 +201,9 @@ class Views extends Component {
function mapStateToProps (state) {
const { settings } = state;
const { availability = 'unknown' } = state.nodeStatus.nodeKind || {};
return { settings };
return { settings, availability };
}
function mapDispatchToProps (dispatch) {

3
js/wasm/README.md Normal file
View File

@ -0,0 +1,3 @@
# WASM modules
- `ethkey` -> `/js/src/api/local/ethkey/ethkey.wasm`

2
js/wasm/ethkey/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
target
Cargo.lock

17
js/wasm/ethkey/Cargo.toml Normal file
View File

@ -0,0 +1,17 @@
[package]
description = "Parity ethkey WASM module."
name = "parity-ethkey-wasm"
version = "1.7.0"
license = "GPL-3.0"
authors = ["Parity Technologies <admin@parity.io>"]
[workspace]
members = []
[dependencies]
tiny-keccak = "1.0"
tiny-secp256k1 = "0.1"
libc = { version = "0.2.14", default-features = false }
[profile.release]
panic = "abort"

View File

@ -0,0 +1,5 @@
const fs = require('fs');
const file = fs.readFileSync('./ethkey.opt.wasm', { encoding: 'base64' });
fs.writeFileSync('../../src/api/local/ethkey/ethkey.wasm.js', `module.exports = new Buffer('${file}', 'base64');\n`);

16
js/wasm/ethkey/build.sh Executable file
View File

@ -0,0 +1,16 @@
# Remove previous build to avoid name conflicts
rm -rf target/wasm32-unknown-emscripten/*
# Build using nightly rustc + emscripten
rustup run nightly cargo build --release --target=wasm32-unknown-emscripten
# Copy final WASM file over
cp ./target/wasm32-unknown-emscripten/release/deps/parity_ethkey_wasm-*.wasm ./ethkey.wasm
# Create a Base64-encoded JS version of the wasm file for easy inclusion in Webpack
node base64ify
# Copy Base64-encoded JS version to src
cp ./ethkey.wasm.js ../../src/api/local/ethkey/ethkey.wasm.js
# rm -f ./ethkey.wasm ./ethkey.opt.wasm ./ethkey.wasm.js

Binary file not shown.

BIN
js/wasm/ethkey/ethkey.wasm Normal file

Binary file not shown.

153
js/wasm/ethkey/src/main.rs Normal file
View File

@ -0,0 +1,153 @@
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
#![feature(lang_items, core_intrinsics)]
#![feature(start)]
#![feature(link_args)]
#![no_std]
use core::intrinsics;
// Pull in the system libc library for what crt0.o likely requires.
extern crate libc;
extern crate tiny_keccak;
extern crate tiny_secp256k1;
use tiny_secp256k1::{is_valid_secret, create_public_key, ECPointG};
// #[link_args = "-s EXPORTED_FUNCTIONS=['_input_ptr','_secret_ptr','_public_ptr','_address_ptr','_ecpointg','_verify_secret','_brain']"]
// extern {}
use tiny_keccak::Keccak;
pub trait Keccak256<T: Sized> {
fn keccak256(&self) -> T;
}
impl Keccak256<[u8; 32]> for [u8] {
#[inline]
fn keccak256(&self) -> [u8; 32] {
let mut keccak = Keccak::new_keccak256();
let mut result = [0u8; 32];
keccak.update(self);
keccak.finalize(&mut result);
result
}
}
static mut INPUT: [u8; 1024] = [0; 1024];
static mut SECRET: [u8; 32] = [0; 32];
static mut PUBLIC: [u8; 64] = [0; 64];
static mut ADDRESS: [u8; 20] = [0; 20];
static mut G: Option<ECPointG> = None;
#[no_mangle]
pub extern "C" fn ecpointg() -> &'static ECPointG {
let g = unsafe { &G };
if let Some(ref g) = *g {
return g;
}
unsafe { G = Some(ECPointG::new()) };
g.as_ref().expect("value set above; qed")
}
#[no_mangle]
pub extern "C" fn input_ptr() -> *const u8 {
unsafe { INPUT.as_ptr() }
}
#[no_mangle]
pub extern "C" fn secret_ptr() -> *const u8 {
unsafe { SECRET.as_ptr() }
}
#[no_mangle]
pub extern "C" fn public_ptr() -> *const u8 {
unsafe { PUBLIC.as_ptr() }
}
#[no_mangle]
pub extern "C" fn address_ptr() -> *const u8 {
unsafe { ADDRESS.as_ptr() }
}
#[no_mangle]
pub extern "C" fn verify_secret() -> bool {
is_valid_secret(unsafe { &SECRET })
}
#[no_mangle]
pub extern "C" fn brain(input_len: usize) {
let data = unsafe { &INPUT[..input_len] };
let mut secret_out = unsafe { &mut SECRET };
let mut public_out = unsafe { &mut PUBLIC };
let mut address_out = unsafe { &mut ADDRESS };
let g = ecpointg();
let mut secret = data.keccak256();
let mut i = 0;
loop {
secret = secret.keccak256();
match i > 16384 {
false => i += 1,
true => {
if let Some(public) = create_public_key(g, &secret) {
let public = &public[1..];
let hash = public.keccak256();
address_out.copy_from_slice(&hash[12..]);
if address_out[0] == 0 {
public_out.copy_from_slice(&public);
secret_out.copy_from_slice(&secret);
return;
}
}
}
}
}
}
// Entry point for this program.
#[start]
fn start(_argc: isize, _argv: *const *const u8) -> isize {
0
}
// These functions are used by the compiler, but not
// for a bare-bones hello world. These are normally
// provided by libstd.
#[lang = "eh_personality"]
#[no_mangle]
pub extern fn rust_eh_personality() {
}
// This function may be needed based on the compilation target.
#[lang = "eh_unwind_resume"]
#[no_mangle]
pub extern fn rust_eh_unwind_resume() {
}
#[lang = "panic_fmt"]
#[no_mangle]
pub extern fn rust_begin_panic(_msg: core::fmt::Arguments,
_file: &'static str,
_line: u32) -> ! {
unsafe { intrinsics::abort() }
}

View File

@ -139,7 +139,6 @@ module.exports = {
resolve: {
alias: {
'~': path.resolve(__dirname, '../src'),
'secp256k1': path.resolve(__dirname, '../node_modules/secp256k1/js'),
'keythereum': path.resolve(__dirname, '../node_modules/keythereum/dist/keythereum')
},
modules: [

View File

@ -42,7 +42,6 @@ module.exports = {
resolve: {
alias: {
'~': path.resolve(__dirname, '../src'),
'secp256k1': path.resolve(__dirname, '../node_modules/secp256k1/js'),
'keythereum': path.resolve(__dirname, '../node_modules/keythereum/dist/keythereum')
}
},

View File

@ -840,6 +840,7 @@ impl Configuration {
hosts: self.ws_hosts(),
origins: self.ws_origins(),
signer_path: self.directories().signer.into(),
support_token_api: !self.args.flag_public_node,
ui_address: ui.address(),
};
@ -1247,6 +1248,7 @@ mod tests {
hosts: Some(vec![]),
signer_path: expected.into(),
ui_address: Some(("127.0.0.1".to_owned(), 8180)),
support_token_api: true
}, UiConfiguration {
enabled: true,
interface: "127.0.0.1".into(),

View File

@ -141,6 +141,7 @@ pub struct WsConfiguration {
pub origins: Option<Vec<String>>,
pub hosts: Option<Vec<String>>,
pub signer_path: PathBuf,
pub support_token_api: bool,
pub ui_address: Option<(String, u16)>,
}
@ -155,6 +156,7 @@ impl Default for WsConfiguration {
origins: Some(vec!["chrome-extension://*".into()]),
hosts: Some(Vec::new()),
signer_path: replace_home(&data_dir, "$BASE/signer").into(),
support_token_api: true,
ui_address: Some(("127.0.0.1".to_owned(), 8180)),
}
}
@ -207,9 +209,14 @@ pub fn new_ws<D: rpc_apis::Dependencies>(
let allowed_origins = into_domains(with_domain(conf.origins, domain, &[ui_address]));
let allowed_hosts = into_domains(with_domain(conf.hosts, domain, &[Some(ws_address)]));
let signer_path = conf.signer_path;
let signer_path = conf.ui_address.map(move |_| ::signer::codes_path(&signer_path));
let path = signer_path.as_ref().map(|p| p.as_path());
let signer_path;
let path = match conf.support_token_api && conf.ui_address.is_some() {
true => {
signer_path = ::signer::codes_path(&conf.signer_path);
Some(signer_path.as_path())
},
false => None
};
let start_result = rpc::start_ws(
&addr,
handler,

View File

@ -307,6 +307,11 @@ impl<C, M, S: ?Sized, U> Parity for ParityClient<C, M, S, U> where
}
fn local_transactions(&self) -> Result<BTreeMap<H256, LocalTransactionStatus>, Error> {
// Return nothing if accounts are disabled (running as public node)
if self.accounts.is_none() {
return Ok(BTreeMap::new());
}
let transactions = self.miner.local_transactions();
let block_number = self.client.chain_info().best_block_number;
Ok(transactions

View File

@ -21,7 +21,7 @@ if ! type $KCOV > /dev/null; then
fi
. ./scripts/targets.sh
cargo test $TARGETS --no-run || exit $?
RUSTFLAGS="-C link-dead-code" cargo test $TARGETS --no-run || exit $?
KCOV_TARGET="target/cov"
@ -31,14 +31,7 @@ EXCLUDE="/usr/lib,\
$HOME/.cargo,\
$HOME/.multirust,\
rocksdb,\
secp256k1,\
util/json-tests,\
util/src/network/tests,\
ethcore/src/evm/tests,\
ethstore/tests,\
target/debug/build,\
target/release/build,\
*.db
secp256k1
"
rm -rf $KCOV_TARGET