Merge branch 'master' into itertools
This commit is contained in:
commit
a247d5b2dc
30
Cargo.lock
generated
30
Cargo.lock
generated
@ -125,7 +125,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bigint"
|
name = "bigint"
|
||||||
version = "3.0.0"
|
version = "4.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -301,6 +301,7 @@ dependencies = [
|
|||||||
"ethcore-util 1.8.0",
|
"ethcore-util 1.8.0",
|
||||||
"ethjson 0.1.0",
|
"ethjson 0.1.0",
|
||||||
"rlp 0.2.0",
|
"rlp 0.2.0",
|
||||||
|
"rlp_derive 0.1.0",
|
||||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -526,6 +527,7 @@ dependencies = [
|
|||||||
"price-info 1.7.0",
|
"price-info 1.7.0",
|
||||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rlp 0.2.0",
|
"rlp 0.2.0",
|
||||||
|
"rlp_derive 0.1.0",
|
||||||
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -542,7 +544,7 @@ dependencies = [
|
|||||||
name = "ethcore-bigint"
|
name = "ethcore-bigint"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bigint 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bigint 4.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -652,6 +654,7 @@ dependencies = [
|
|||||||
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rlp 0.2.0",
|
"rlp 0.2.0",
|
||||||
|
"rlp_derive 0.1.0",
|
||||||
"serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"smallvec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"smallvec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -2054,7 +2057,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "parity-ui-precompiled"
|
name = "parity-ui-precompiled"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
source = "git+https://github.com/paritytech/js-precompiled.git#04b109bd8485b26d0f8ef8df6afab69d8fe4878b"
|
source = "git+https://github.com/paritytech/js-precompiled.git#f4bde8f5b102e7da7c2440c04945fac86e75cff5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"parity-dapps-glue 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parity-dapps-glue 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@ -2306,7 +2309,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "0.3.10"
|
version = "0.3.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2397,6 +2400,15 @@ dependencies = [
|
|||||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rlp_derive"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rlp 0.2.0",
|
||||||
|
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rocksdb"
|
name = "rocksdb"
|
||||||
version = "0.4.5"
|
version = "0.4.5"
|
||||||
@ -2454,7 +2466,7 @@ dependencies = [
|
|||||||
name = "rpc-cli"
|
name = "rpc-cli"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bigint 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bigint 4.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethcore-util 1.8.0",
|
"ethcore-util 1.8.0",
|
||||||
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parity-rpc 1.8.0",
|
"parity-rpc 1.8.0",
|
||||||
@ -2589,7 +2601,7 @@ name = "serde_derive"
|
|||||||
version = "1.0.9"
|
version = "1.0.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quote 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@ -2731,7 +2743,7 @@ name = "syn"
|
|||||||
version = "0.11.11"
|
version = "0.11.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quote 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@ -3232,7 +3244,7 @@ dependencies = [
|
|||||||
"checksum backtrace-sys 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3a0d842ea781ce92be2bf78a9b38883948542749640b8378b3b2f03d1fd9f1ff"
|
"checksum backtrace-sys 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3a0d842ea781ce92be2bf78a9b38883948542749640b8378b3b2f03d1fd9f1ff"
|
||||||
"checksum base-x 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2f59103b47307f76e03bef1633aec7fa9e29bfb5aa6daf5a334f94233c71f6c1"
|
"checksum base-x 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2f59103b47307f76e03bef1633aec7fa9e29bfb5aa6daf5a334f94233c71f6c1"
|
||||||
"checksum base32 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1b9605ba46d61df0410d8ac686b0007add8172eba90e8e909c347856fe794d8c"
|
"checksum base32 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1b9605ba46d61df0410d8ac686b0007add8172eba90e8e909c347856fe794d8c"
|
||||||
"checksum bigint 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d0673c930652d3d4d6dcd5c45b5db4fa5f8f33994d7323618c43c083b223e8c"
|
"checksum bigint 4.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2b45beaa0727835a98df09295d4250afc52c3f7d375d560997ae942c95b98ceb"
|
||||||
"checksum bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e103c8b299b28a9c6990458b7013dc4a8356a9b854c51b9883241f5866fac36e"
|
"checksum bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e103c8b299b28a9c6990458b7013dc4a8356a9b854c51b9883241f5866fac36e"
|
||||||
"checksum bit-set 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e6e1e6fb1c9e3d6fcdec57216a74eaa03e41f52a22f13a16438251d8e88b89da"
|
"checksum bit-set 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e6e1e6fb1c9e3d6fcdec57216a74eaa03e41f52a22f13a16438251d8e88b89da"
|
||||||
"checksum bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9bf6104718e80d7b26a68fdbacff3481cfc05df670821affc7e9cbc1884400c"
|
"checksum bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9bf6104718e80d7b26a68fdbacff3481cfc05df670821affc7e9cbc1884400c"
|
||||||
@ -3385,7 +3397,7 @@ dependencies = [
|
|||||||
"checksum quasi_macros 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29cec87bc2816766d7e4168302d505dd06b0a825aed41b00633d296e922e02dd"
|
"checksum quasi_macros 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29cec87bc2816766d7e4168302d505dd06b0a825aed41b00633d296e922e02dd"
|
||||||
"checksum quick-error 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0aad603e8d7fb67da22dbdf1f4b826ce8829e406124109e73cf1b2454b93a71c"
|
"checksum quick-error 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0aad603e8d7fb67da22dbdf1f4b826ce8829e406124109e73cf1b2454b93a71c"
|
||||||
"checksum quine-mc_cluskey 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6683b0e23d80813b1a535841f0048c1537d3f86d63c999e8373b39a9b0eb74a"
|
"checksum quine-mc_cluskey 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6683b0e23d80813b1a535841f0048c1537d3f86d63c999e8373b39a9b0eb74a"
|
||||||
"checksum quote 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)" = "6732e32663c9c271bfc7c1823486b471f18c47a2dbf87c066897b7b51afc83be"
|
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
|
||||||
"checksum rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2791d88c6defac799c3f20d74f094ca33b9332612d9aef9078519c82e4fe04a5"
|
"checksum rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2791d88c6defac799c3f20d74f094ca33b9332612d9aef9078519c82e4fe04a5"
|
||||||
"checksum rayon 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8c83adcb08e5b922e804fe1918142b422602ef11f2fd670b0b52218cb5984a20"
|
"checksum rayon 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8c83adcb08e5b922e804fe1918142b422602ef11f2fd670b0b52218cb5984a20"
|
||||||
"checksum rayon-core 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "767d91bacddf07d442fe39257bf04fd95897d1c47c545d009f6beb03efd038f8"
|
"checksum rayon-core 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "767d91bacddf07d442fe39257bf04fd95897d1c47c545d009f6beb03efd038f8"
|
||||||
|
@ -47,6 +47,7 @@ num_cpus = "1.2"
|
|||||||
price-info = { path = "../price-info" }
|
price-info = { path = "../price-info" }
|
||||||
rand = "0.3"
|
rand = "0.3"
|
||||||
rlp = { path = "../util/rlp" }
|
rlp = { path = "../util/rlp" }
|
||||||
|
rlp_derive = { path = "../util/rlp_derive" }
|
||||||
rust-crypto = "0.2.34"
|
rust-crypto = "0.2.34"
|
||||||
rustc-hex = "1.0"
|
rustc-hex = "1.0"
|
||||||
semver = "0.6"
|
semver = "0.6"
|
||||||
|
@ -21,6 +21,7 @@ ethcore-devtools = { path = "../../devtools" }
|
|||||||
evm = { path = "../evm" }
|
evm = { path = "../evm" }
|
||||||
vm = { path = "../vm" }
|
vm = { path = "../vm" }
|
||||||
rlp = { path = "../../util/rlp" }
|
rlp = { path = "../../util/rlp" }
|
||||||
|
rlp_derive = { path = "../../util/rlp_derive" }
|
||||||
time = "0.1"
|
time = "0.1"
|
||||||
smallvec = "0.4"
|
smallvec = "0.4"
|
||||||
futures = "0.1"
|
futures = "0.1"
|
||||||
|
@ -76,6 +76,8 @@ extern crate futures;
|
|||||||
extern crate itertools;
|
extern crate itertools;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
extern crate rlp;
|
extern crate rlp;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate rlp_derive;
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
extern crate smallvec;
|
extern crate smallvec;
|
||||||
extern crate stats;
|
extern crate stats;
|
||||||
|
@ -650,7 +650,7 @@ pub mod header {
|
|||||||
use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp};
|
use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp};
|
||||||
|
|
||||||
/// Potentially incomplete headers request.
|
/// Potentially incomplete headers request.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)]
|
||||||
pub struct Incomplete {
|
pub struct Incomplete {
|
||||||
/// Start block.
|
/// Start block.
|
||||||
pub start: Field<HashOrNumber>,
|
pub start: Field<HashOrNumber>,
|
||||||
@ -662,27 +662,6 @@ pub mod header {
|
|||||||
pub reverse: bool,
|
pub reverse: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for Incomplete {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
Ok(Incomplete {
|
|
||||||
start: rlp.val_at(0)?,
|
|
||||||
skip: rlp.val_at(1)?,
|
|
||||||
max: rlp.val_at(2)?,
|
|
||||||
reverse: rlp.val_at(3)?
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Encodable for Incomplete {
|
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
s.begin_list(4)
|
|
||||||
.append(&self.start)
|
|
||||||
.append(&self.skip)
|
|
||||||
.append(&self.max)
|
|
||||||
.append(&self.reverse);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl super::IncompleteRequest for Incomplete {
|
impl super::IncompleteRequest for Incomplete {
|
||||||
type Complete = Complete;
|
type Complete = Complete;
|
||||||
type Response = Response;
|
type Response = Response;
|
||||||
@ -784,26 +763,12 @@ pub mod header_proof {
|
|||||||
use util::{Bytes, U256, H256};
|
use util::{Bytes, U256, H256};
|
||||||
|
|
||||||
/// Potentially incomplete header proof request.
|
/// Potentially incomplete header proof request.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)]
|
||||||
pub struct Incomplete {
|
pub struct Incomplete {
|
||||||
/// Block number.
|
/// Block number.
|
||||||
pub num: Field<u64>,
|
pub num: Field<u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for Incomplete {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
Ok(Incomplete {
|
|
||||||
num: rlp.val_at(0)?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Encodable for Incomplete {
|
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
s.begin_list(1).append(&self.num);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl super::IncompleteRequest for Incomplete {
|
impl super::IncompleteRequest for Incomplete {
|
||||||
type Complete = Complete;
|
type Complete = Complete;
|
||||||
type Response = Response;
|
type Response = Response;
|
||||||
@ -889,30 +854,15 @@ pub mod header_proof {
|
|||||||
/// Request and response for transaction index.
|
/// Request and response for transaction index.
|
||||||
pub mod transaction_index {
|
pub mod transaction_index {
|
||||||
use super::{Field, NoSuchOutput, OutputKind, Output};
|
use super::{Field, NoSuchOutput, OutputKind, Output};
|
||||||
use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp};
|
|
||||||
use util::H256;
|
use util::H256;
|
||||||
|
|
||||||
/// Potentially incomplete transaction index request.
|
/// Potentially incomplete transaction index request.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)]
|
||||||
pub struct Incomplete {
|
pub struct Incomplete {
|
||||||
/// Transaction hash to get index for.
|
/// Transaction hash to get index for.
|
||||||
pub hash: Field<H256>,
|
pub hash: Field<H256>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for Incomplete {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
Ok(Incomplete {
|
|
||||||
hash: rlp.val_at(0)?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Encodable for Incomplete {
|
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
s.begin_list(1).append(&self.hash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl super::IncompleteRequest for Incomplete {
|
impl super::IncompleteRequest for Incomplete {
|
||||||
type Complete = Complete;
|
type Complete = Complete;
|
||||||
type Response = Response;
|
type Response = Response;
|
||||||
@ -959,7 +909,7 @@ pub mod transaction_index {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The output of a request for transaction index.
|
/// The output of a request for transaction index.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)]
|
||||||
pub struct Response {
|
pub struct Response {
|
||||||
/// Block number.
|
/// Block number.
|
||||||
pub num: u64,
|
pub num: u64,
|
||||||
@ -976,55 +926,21 @@ pub mod transaction_index {
|
|||||||
f(1, Output::Hash(self.hash));
|
f(1, Output::Hash(self.hash));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for Response {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
Ok(Response {
|
|
||||||
num: rlp.val_at(0)?,
|
|
||||||
hash: rlp.val_at(1)?,
|
|
||||||
index: rlp.val_at(2)?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Encodable for Response {
|
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
s.begin_list(3)
|
|
||||||
.append(&self.num)
|
|
||||||
.append(&self.hash)
|
|
||||||
.append(&self.index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Request and response for block receipts
|
/// Request and response for block receipts
|
||||||
pub mod block_receipts {
|
pub mod block_receipts {
|
||||||
use super::{Field, NoSuchOutput, OutputKind, Output};
|
use super::{Field, NoSuchOutput, OutputKind, Output};
|
||||||
use ethcore::receipt::Receipt;
|
use ethcore::receipt::Receipt;
|
||||||
use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp};
|
|
||||||
use util::H256;
|
use util::H256;
|
||||||
|
|
||||||
/// Potentially incomplete block receipts request.
|
/// Potentially incomplete block receipts request.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)]
|
||||||
pub struct Incomplete {
|
pub struct Incomplete {
|
||||||
/// Block hash to get receipts for.
|
/// Block hash to get receipts for.
|
||||||
pub hash: Field<H256>,
|
pub hash: Field<H256>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for Incomplete {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
Ok(Incomplete {
|
|
||||||
hash: rlp.val_at(0)?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Encodable for Incomplete {
|
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
s.begin_list(1).append(&self.hash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl super::IncompleteRequest for Incomplete {
|
impl super::IncompleteRequest for Incomplete {
|
||||||
type Complete = Complete;
|
type Complete = Complete;
|
||||||
type Response = Response;
|
type Response = Response;
|
||||||
@ -1068,7 +984,7 @@ pub mod block_receipts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The output of a request for block receipts.
|
/// The output of a request for block receipts.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq, RlpEncodableWrapper, RlpDecodableWrapper)]
|
||||||
pub struct Response {
|
pub struct Response {
|
||||||
/// The block receipts.
|
/// The block receipts.
|
||||||
pub receipts: Vec<Receipt>
|
pub receipts: Vec<Receipt>
|
||||||
@ -1078,20 +994,6 @@ pub mod block_receipts {
|
|||||||
/// Fill reusable outputs by providing them to the function.
|
/// Fill reusable outputs by providing them to the function.
|
||||||
fn fill_outputs<F>(&self, _: F) where F: FnMut(usize, Output) {}
|
fn fill_outputs<F>(&self, _: F) where F: FnMut(usize, Output) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for Response {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
Ok(Response {
|
|
||||||
receipts: rlp.as_list()?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Encodable for Response {
|
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
s.append_list(&self.receipts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Request and response for a block body
|
/// Request and response for a block body
|
||||||
@ -1102,26 +1004,12 @@ pub mod block_body {
|
|||||||
use util::H256;
|
use util::H256;
|
||||||
|
|
||||||
/// Potentially incomplete block body request.
|
/// Potentially incomplete block body request.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)]
|
||||||
pub struct Incomplete {
|
pub struct Incomplete {
|
||||||
/// Block hash to get receipts for.
|
/// Block hash to get receipts for.
|
||||||
pub hash: Field<H256>,
|
pub hash: Field<H256>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for Incomplete {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
Ok(Incomplete {
|
|
||||||
hash: rlp.val_at(0)?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Encodable for Incomplete {
|
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
s.begin_list(1).append(&self.hash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl super::IncompleteRequest for Incomplete {
|
impl super::IncompleteRequest for Incomplete {
|
||||||
type Complete = Complete;
|
type Complete = Complete;
|
||||||
type Response = Response;
|
type Response = Response;
|
||||||
@ -1201,11 +1089,10 @@ pub mod block_body {
|
|||||||
/// A request for an account proof.
|
/// A request for an account proof.
|
||||||
pub mod account {
|
pub mod account {
|
||||||
use super::{Field, NoSuchOutput, OutputKind, Output};
|
use super::{Field, NoSuchOutput, OutputKind, Output};
|
||||||
use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp};
|
|
||||||
use util::{Bytes, U256, H256};
|
use util::{Bytes, U256, H256};
|
||||||
|
|
||||||
/// Potentially incomplete request for an account proof.
|
/// Potentially incomplete request for an account proof.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)]
|
||||||
pub struct Incomplete {
|
pub struct Incomplete {
|
||||||
/// Block hash to request state proof for.
|
/// Block hash to request state proof for.
|
||||||
pub block_hash: Field<H256>,
|
pub block_hash: Field<H256>,
|
||||||
@ -1213,23 +1100,6 @@ pub mod account {
|
|||||||
pub address_hash: Field<H256>,
|
pub address_hash: Field<H256>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for Incomplete {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
Ok(Incomplete {
|
|
||||||
block_hash: rlp.val_at(0)?,
|
|
||||||
address_hash: rlp.val_at(1)?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Encodable for Incomplete {
|
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
s.begin_list(2)
|
|
||||||
.append(&self.block_hash)
|
|
||||||
.append(&self.address_hash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl super::IncompleteRequest for Incomplete {
|
impl super::IncompleteRequest for Incomplete {
|
||||||
type Complete = Complete;
|
type Complete = Complete;
|
||||||
type Response = Response;
|
type Response = Response;
|
||||||
@ -1292,7 +1162,7 @@ pub mod account {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The output of a request for an account state proof.
|
/// The output of a request for an account state proof.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)]
|
||||||
pub struct Response {
|
pub struct Response {
|
||||||
/// Inclusion/exclusion proof
|
/// Inclusion/exclusion proof
|
||||||
pub proof: Vec<Bytes>,
|
pub proof: Vec<Bytes>,
|
||||||
@ -1313,39 +1183,15 @@ pub mod account {
|
|||||||
f(1, Output::Hash(self.storage_root));
|
f(1, Output::Hash(self.storage_root));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for Response {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
Ok(Response {
|
|
||||||
proof: rlp.list_at(0)?,
|
|
||||||
nonce: rlp.val_at(1)?,
|
|
||||||
balance: rlp.val_at(2)?,
|
|
||||||
code_hash: rlp.val_at(3)?,
|
|
||||||
storage_root: rlp.val_at(4)?
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Encodable for Response {
|
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
s.begin_list(5)
|
|
||||||
.append_list::<Vec<u8>,_>(&self.proof[..])
|
|
||||||
.append(&self.nonce)
|
|
||||||
.append(&self.balance)
|
|
||||||
.append(&self.code_hash)
|
|
||||||
.append(&self.storage_root);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A request for a storage proof.
|
/// A request for a storage proof.
|
||||||
pub mod storage {
|
pub mod storage {
|
||||||
use super::{Field, NoSuchOutput, OutputKind, Output};
|
use super::{Field, NoSuchOutput, OutputKind, Output};
|
||||||
use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp};
|
|
||||||
use util::{Bytes, H256};
|
use util::{Bytes, H256};
|
||||||
|
|
||||||
/// Potentially incomplete request for an storage proof.
|
/// Potentially incomplete request for an storage proof.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)]
|
||||||
pub struct Incomplete {
|
pub struct Incomplete {
|
||||||
/// Block hash to request state proof for.
|
/// Block hash to request state proof for.
|
||||||
pub block_hash: Field<H256>,
|
pub block_hash: Field<H256>,
|
||||||
@ -1355,25 +1201,6 @@ pub mod storage {
|
|||||||
pub key_hash: Field<H256>,
|
pub key_hash: Field<H256>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for Incomplete {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
Ok(Incomplete {
|
|
||||||
block_hash: rlp.val_at(0)?,
|
|
||||||
address_hash: rlp.val_at(1)?,
|
|
||||||
key_hash: rlp.val_at(2)?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Encodable for Incomplete {
|
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
s.begin_list(3)
|
|
||||||
.append(&self.block_hash)
|
|
||||||
.append(&self.address_hash)
|
|
||||||
.append(&self.key_hash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl super::IncompleteRequest for Incomplete {
|
impl super::IncompleteRequest for Incomplete {
|
||||||
type Complete = Complete;
|
type Complete = Complete;
|
||||||
type Response = Response;
|
type Response = Response;
|
||||||
@ -1450,7 +1277,7 @@ pub mod storage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The output of a request for an account state proof.
|
/// The output of a request for an account state proof.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)]
|
||||||
pub struct Response {
|
pub struct Response {
|
||||||
/// Inclusion/exclusion proof
|
/// Inclusion/exclusion proof
|
||||||
pub proof: Vec<Bytes>,
|
pub proof: Vec<Bytes>,
|
||||||
@ -1464,33 +1291,15 @@ pub mod storage {
|
|||||||
f(0, Output::Hash(self.value));
|
f(0, Output::Hash(self.value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for Response {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
Ok(Response {
|
|
||||||
proof: rlp.list_at(0)?,
|
|
||||||
value: rlp.val_at(1)?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Encodable for Response {
|
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
s.begin_list(2)
|
|
||||||
.append_list::<Vec<u8>,_>(&self.proof[..])
|
|
||||||
.append(&self.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A request for contract code.
|
/// A request for contract code.
|
||||||
pub mod contract_code {
|
pub mod contract_code {
|
||||||
use super::{Field, NoSuchOutput, OutputKind, Output};
|
use super::{Field, NoSuchOutput, OutputKind, Output};
|
||||||
use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp};
|
|
||||||
use util::{Bytes, H256};
|
use util::{Bytes, H256};
|
||||||
|
|
||||||
/// Potentially incomplete contract code request.
|
/// Potentially incomplete contract code request.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)]
|
||||||
pub struct Incomplete {
|
pub struct Incomplete {
|
||||||
/// The block hash to request the state for.
|
/// The block hash to request the state for.
|
||||||
pub block_hash: Field<H256>,
|
pub block_hash: Field<H256>,
|
||||||
@ -1498,23 +1307,6 @@ pub mod contract_code {
|
|||||||
pub code_hash: Field<H256>,
|
pub code_hash: Field<H256>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for Incomplete {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
Ok(Incomplete {
|
|
||||||
block_hash: rlp.val_at(0)?,
|
|
||||||
code_hash: rlp.val_at(1)?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Encodable for Incomplete {
|
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
s.begin_list(2)
|
|
||||||
.append(&self.block_hash)
|
|
||||||
.append(&self.code_hash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl super::IncompleteRequest for Incomplete {
|
impl super::IncompleteRequest for Incomplete {
|
||||||
type Complete = Complete;
|
type Complete = Complete;
|
||||||
type Response = Response;
|
type Response = Response;
|
||||||
@ -1573,7 +1365,7 @@ pub mod contract_code {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The output of a request for
|
/// The output of a request for
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq, RlpEncodableWrapper, RlpDecodableWrapper)]
|
||||||
pub struct Response {
|
pub struct Response {
|
||||||
/// The requested code.
|
/// The requested code.
|
||||||
pub code: Bytes,
|
pub code: Bytes,
|
||||||
@ -1583,21 +1375,6 @@ pub mod contract_code {
|
|||||||
/// Fill reusable outputs by providing them to the function.
|
/// Fill reusable outputs by providing them to the function.
|
||||||
fn fill_outputs<F>(&self, _: F) where F: FnMut(usize, Output) {}
|
fn fill_outputs<F>(&self, _: F) where F: FnMut(usize, Output) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for Response {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
|
|
||||||
Ok(Response {
|
|
||||||
code: rlp.as_val()?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Encodable for Response {
|
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
s.append(&self.code);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A request for proof of execution.
|
/// A request for proof of execution.
|
||||||
@ -1608,7 +1385,7 @@ pub mod execution {
|
|||||||
use util::{Bytes, Address, U256, H256, DBValue};
|
use util::{Bytes, Address, U256, H256, DBValue};
|
||||||
|
|
||||||
/// Potentially incomplete execution proof request.
|
/// Potentially incomplete execution proof request.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)]
|
||||||
pub struct Incomplete {
|
pub struct Incomplete {
|
||||||
/// The block hash to request the state for.
|
/// The block hash to request the state for.
|
||||||
pub block_hash: Field<H256>,
|
pub block_hash: Field<H256>,
|
||||||
@ -1626,38 +1403,6 @@ pub mod execution {
|
|||||||
pub data: Bytes,
|
pub data: Bytes,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for Incomplete {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
Ok(Incomplete {
|
|
||||||
block_hash: rlp.val_at(0)?,
|
|
||||||
from: rlp.val_at(1)?,
|
|
||||||
action: rlp.val_at(2)?,
|
|
||||||
gas: rlp.val_at(3)?,
|
|
||||||
gas_price: rlp.val_at(4)?,
|
|
||||||
value: rlp.val_at(5)?,
|
|
||||||
data: rlp.val_at(6)?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Encodable for Incomplete {
|
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
s.begin_list(7)
|
|
||||||
.append(&self.block_hash)
|
|
||||||
.append(&self.from);
|
|
||||||
|
|
||||||
match self.action {
|
|
||||||
Action::Create => s.append_empty_data(),
|
|
||||||
Action::Call(ref addr) => s.append(addr),
|
|
||||||
};
|
|
||||||
|
|
||||||
s.append(&self.gas)
|
|
||||||
.append(&self.gas_price)
|
|
||||||
.append(&self.value)
|
|
||||||
.append(&self.data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl super::IncompleteRequest for Incomplete {
|
impl super::IncompleteRequest for Incomplete {
|
||||||
type Complete = Complete;
|
type Complete = Complete;
|
||||||
type Response = Response;
|
type Response = Response;
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 330f748b1eece451f460224b48d515489dd86f5c
|
Subproject commit 85e76c5ea2a54c6c54e35014643b5080a50460c5
|
@ -25,11 +25,9 @@ use engines::epoch::{Transition as EpochTransition};
|
|||||||
use header::BlockNumber;
|
use header::BlockNumber;
|
||||||
use receipt::Receipt;
|
use receipt::Receipt;
|
||||||
|
|
||||||
use rlp::*;
|
use util::{HeapSizeOf, H256, H264, U256};
|
||||||
use util::*;
|
|
||||||
use util::kvdb::PREFIX_LEN as DB_PREFIX_LEN;
|
use util::kvdb::PREFIX_LEN as DB_PREFIX_LEN;
|
||||||
|
|
||||||
|
|
||||||
/// Represents index of extra data in database
|
/// Represents index of extra data in database
|
||||||
#[derive(Copy, Debug, Hash, Eq, PartialEq, Clone)]
|
#[derive(Copy, Debug, Hash, Eq, PartialEq, Clone)]
|
||||||
pub enum ExtrasIndex {
|
pub enum ExtrasIndex {
|
||||||
@ -184,7 +182,7 @@ impl Key<EpochTransitions> for u64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Familial details concerning a block
|
/// Familial details concerning a block
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, RlpEncodable, RlpDecodable)]
|
||||||
pub struct BlockDetails {
|
pub struct BlockDetails {
|
||||||
/// Block number
|
/// Block number
|
||||||
pub number: BlockNumber,
|
pub number: BlockNumber,
|
||||||
@ -202,30 +200,8 @@ impl HeapSizeOf for BlockDetails {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for BlockDetails {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
let details = BlockDetails {
|
|
||||||
number: rlp.val_at(0)?,
|
|
||||||
total_difficulty: rlp.val_at(1)?,
|
|
||||||
parent: rlp.val_at(2)?,
|
|
||||||
children: rlp.list_at(3)?,
|
|
||||||
};
|
|
||||||
Ok(details)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Encodable for BlockDetails {
|
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
s.begin_list(4);
|
|
||||||
s.append(&self.number);
|
|
||||||
s.append(&self.total_difficulty);
|
|
||||||
s.append(&self.parent);
|
|
||||||
s.append_list(&self.children);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Represents address of certain transaction within block
|
/// Represents address of certain transaction within block
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone, RlpEncodable, RlpDecodable)]
|
||||||
pub struct TransactionAddress {
|
pub struct TransactionAddress {
|
||||||
/// Block hash
|
/// Block hash
|
||||||
pub block_hash: H256,
|
pub block_hash: H256,
|
||||||
@ -237,27 +213,8 @@ impl HeapSizeOf for TransactionAddress {
|
|||||||
fn heap_size_of_children(&self) -> usize { 0 }
|
fn heap_size_of_children(&self) -> usize { 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for TransactionAddress {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
let tx_address = TransactionAddress {
|
|
||||||
block_hash: rlp.val_at(0)?,
|
|
||||||
index: rlp.val_at(1)?,
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(tx_address)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Encodable for TransactionAddress {
|
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
s.begin_list(2);
|
|
||||||
s.append(&self.block_hash);
|
|
||||||
s.append(&self.index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Contains all block receipts.
|
/// Contains all block receipts.
|
||||||
#[derive(Clone)]
|
#[derive(Clone, RlpEncodableWrapper, RlpDecodableWrapper)]
|
||||||
pub struct BlockReceipts {
|
pub struct BlockReceipts {
|
||||||
pub receipts: Vec<Receipt>,
|
pub receipts: Vec<Receipt>,
|
||||||
}
|
}
|
||||||
@ -270,20 +227,6 @@ impl BlockReceipts {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for BlockReceipts {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
Ok(BlockReceipts {
|
|
||||||
receipts: rlp.as_list()?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Encodable for BlockReceipts {
|
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
s.append_list(&self.receipts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl HeapSizeOf for BlockReceipts {
|
impl HeapSizeOf for BlockReceipts {
|
||||||
fn heap_size_of_children(&self) -> usize {
|
fn heap_size_of_children(&self) -> usize {
|
||||||
self.receipts.heap_size_of_children()
|
self.receipts.heap_size_of_children()
|
||||||
@ -291,27 +234,12 @@ impl HeapSizeOf for BlockReceipts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Candidate transitions to an epoch with specific number.
|
/// Candidate transitions to an epoch with specific number.
|
||||||
#[derive(Clone)]
|
#[derive(Clone, RlpEncodable, RlpDecodable)]
|
||||||
pub struct EpochTransitions {
|
pub struct EpochTransitions {
|
||||||
pub number: u64,
|
pub number: u64,
|
||||||
pub candidates: Vec<EpochTransition>,
|
pub candidates: Vec<EpochTransition>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Encodable for EpochTransitions {
|
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
s.begin_list(2).append(&self.number).append_list(&self.candidates);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Decodable for EpochTransitions {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
Ok(EpochTransitions {
|
|
||||||
number: rlp.val_at(0)?,
|
|
||||||
candidates: rlp.list_at(1)?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use rlp::*;
|
use rlp::*;
|
||||||
|
@ -15,12 +15,11 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use bloomchain as bc;
|
use bloomchain as bc;
|
||||||
use rlp::*;
|
|
||||||
use util::HeapSizeOf;
|
use util::HeapSizeOf;
|
||||||
use basic_types::LogBloom;
|
use basic_types::LogBloom;
|
||||||
|
|
||||||
/// Helper structure representing bloom of the trace.
|
/// Helper structure representing bloom of the trace.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, RlpEncodableWrapper, RlpDecodableWrapper)]
|
||||||
pub struct Bloom(LogBloom);
|
pub struct Bloom(LogBloom);
|
||||||
|
|
||||||
impl From<LogBloom> for Bloom {
|
impl From<LogBloom> for Bloom {
|
||||||
@ -43,18 +42,6 @@ impl Into<bc::Bloom> for Bloom {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for Bloom {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
LogBloom::decode(rlp).map(Bloom)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Encodable for Bloom {
|
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
Encodable::rlp_append(&self.0, s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl HeapSizeOf for Bloom {
|
impl HeapSizeOf for Bloom {
|
||||||
fn heap_size_of_children(&self) -> usize {
|
fn heap_size_of_children(&self) -> usize {
|
||||||
0
|
0
|
||||||
|
@ -16,14 +16,12 @@
|
|||||||
|
|
||||||
//! Epoch verifiers and transitions.
|
//! Epoch verifiers and transitions.
|
||||||
|
|
||||||
|
use util::H256;
|
||||||
use error::Error;
|
use error::Error;
|
||||||
use header::Header;
|
use header::Header;
|
||||||
|
|
||||||
use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp};
|
|
||||||
use util::H256;
|
|
||||||
|
|
||||||
/// A full epoch transition.
|
/// A full epoch transition.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, RlpEncodable, RlpDecodable)]
|
||||||
pub struct Transition {
|
pub struct Transition {
|
||||||
/// Block hash at which the transition occurred.
|
/// Block hash at which the transition occurred.
|
||||||
pub block_hash: H256,
|
pub block_hash: H256,
|
||||||
@ -33,46 +31,14 @@ pub struct Transition {
|
|||||||
pub proof: Vec<u8>,
|
pub proof: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Encodable for Transition {
|
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
s.begin_list(3)
|
|
||||||
.append(&self.block_hash)
|
|
||||||
.append(&self.block_number)
|
|
||||||
.append(&self.proof);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Decodable for Transition {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
Ok(Transition {
|
|
||||||
block_hash: rlp.val_at(0)?,
|
|
||||||
block_number: rlp.val_at(1)?,
|
|
||||||
proof: rlp.val_at(2)?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An epoch transition pending a finality proof.
|
/// An epoch transition pending a finality proof.
|
||||||
/// Not all transitions need one.
|
/// Not all transitions need one.
|
||||||
|
#[derive(RlpEncodableWrapper, RlpDecodableWrapper)]
|
||||||
pub struct PendingTransition {
|
pub struct PendingTransition {
|
||||||
/// "transition/epoch" proof from the engine.
|
/// "transition/epoch" proof from the engine.
|
||||||
pub proof: Vec<u8>,
|
pub proof: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Encodable for PendingTransition {
|
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
s.append(&self.proof);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Decodable for PendingTransition {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
Ok(PendingTransition {
|
|
||||||
proof: rlp.as_val()?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Verifier for all blocks within an epoch with self-contained state.
|
/// Verifier for all blocks within an epoch with self-contained state.
|
||||||
///
|
///
|
||||||
/// See docs on `Engine` relating to proving functions for more details.
|
/// See docs on `Engine` relating to proving functions for more details.
|
||||||
|
@ -101,6 +101,9 @@ extern crate num;
|
|||||||
extern crate price_info;
|
extern crate price_info;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
extern crate rlp;
|
extern crate rlp;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate rlp_derive;
|
||||||
extern crate rustc_hex;
|
extern crate rustc_hex;
|
||||||
extern crate semver;
|
extern crate semver;
|
||||||
extern crate stats;
|
extern crate stats;
|
||||||
|
@ -27,7 +27,7 @@ use std::path::{Path, PathBuf};
|
|||||||
|
|
||||||
use util::Bytes;
|
use util::Bytes;
|
||||||
use util::hash::H256;
|
use util::hash::H256;
|
||||||
use rlp::{self, Encodable, RlpStream, UntrustedRlp};
|
use rlp::{RlpStream, UntrustedRlp};
|
||||||
|
|
||||||
use super::ManifestData;
|
use super::ManifestData;
|
||||||
|
|
||||||
@ -49,24 +49,9 @@ pub trait SnapshotWriter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// (hash, len, offset)
|
// (hash, len, offset)
|
||||||
|
#[derive(RlpEncodable, RlpDecodable)]
|
||||||
struct ChunkInfo(H256, u64, u64);
|
struct ChunkInfo(H256, u64, u64);
|
||||||
|
|
||||||
impl Encodable for ChunkInfo {
|
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
s.begin_list(3);
|
|
||||||
s.append(&self.0).append(&self.1).append(&self.2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl rlp::Decodable for ChunkInfo {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, rlp::DecoderError> {
|
|
||||||
let hash = rlp.val_at(0)?;
|
|
||||||
let len = rlp.val_at(1)?;
|
|
||||||
let off = rlp.val_at(2)?;
|
|
||||||
Ok(ChunkInfo(hash, len, off))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A packed snapshot writer. This writes snapshots to a single concatenated file.
|
/// A packed snapshot writer. This writes snapshots to a single concatenated file.
|
||||||
///
|
///
|
||||||
/// The file format is very simple and consists of three parts:
|
/// The file format is very simple and consists of three parts:
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
use bloomchain::Bloom;
|
use bloomchain::Bloom;
|
||||||
use bloomchain::group::{BloomGroup, GroupPosition};
|
use bloomchain::group::{BloomGroup, GroupPosition};
|
||||||
use rlp::*;
|
|
||||||
use basic_types::LogBloom;
|
use basic_types::LogBloom;
|
||||||
|
|
||||||
/// Helper structure representing bloom of the trace.
|
/// Helper structure representing bloom of the trace.
|
||||||
#[derive(Clone)]
|
#[derive(Clone, RlpEncodableWrapper, RlpDecodableWrapper)]
|
||||||
pub struct BlockTracesBloom(LogBloom);
|
pub struct BlockTracesBloom(LogBloom);
|
||||||
|
|
||||||
impl From<LogBloom> for BlockTracesBloom {
|
impl From<LogBloom> for BlockTracesBloom {
|
||||||
@ -28,7 +27,7 @@ impl Into<Bloom> for BlockTracesBloom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Represents group of X consecutive blooms.
|
/// Represents group of X consecutive blooms.
|
||||||
#[derive(Clone)]
|
#[derive(Clone, RlpEncodableWrapper, RlpDecodableWrapper)]
|
||||||
pub struct BlockTracesBloomGroup {
|
pub struct BlockTracesBloomGroup {
|
||||||
blooms: Vec<BlockTracesBloom>,
|
blooms: Vec<BlockTracesBloom>,
|
||||||
}
|
}
|
||||||
@ -59,34 +58,6 @@ impl Into<BloomGroup> for BlockTracesBloomGroup {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for BlockTracesBloom {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
LogBloom::decode(rlp).map(BlockTracesBloom)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Encodable for BlockTracesBloom {
|
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
Encodable::rlp_append(&self.0, s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Decodable for BlockTracesBloomGroup {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
let blooms = rlp.as_list()?;
|
|
||||||
let group = BlockTracesBloomGroup {
|
|
||||||
blooms: blooms
|
|
||||||
};
|
|
||||||
Ok(group)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Encodable for BlockTracesBloomGroup {
|
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
s.append_list(&self.blooms);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Represents `BloomGroup` position in database.
|
/// Represents `BloomGroup` position in database.
|
||||||
#[derive(PartialEq, Eq, Hash, Clone, Debug)]
|
#[derive(PartialEq, Eq, Hash, Clone, Debug)]
|
||||||
pub struct TraceGroupPosition {
|
pub struct TraceGroupPosition {
|
||||||
|
@ -77,7 +77,7 @@ impl Decodable for FlatTrace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Represents all traces produced by a single transaction.
|
/// Represents all traces produced by a single transaction.
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone, RlpEncodableWrapper, RlpDecodableWrapper)]
|
||||||
pub struct FlatTransactionTraces(Vec<FlatTrace>);
|
pub struct FlatTransactionTraces(Vec<FlatTrace>);
|
||||||
|
|
||||||
impl From<Vec<FlatTrace>> for FlatTransactionTraces {
|
impl From<Vec<FlatTrace>> for FlatTransactionTraces {
|
||||||
@ -99,18 +99,6 @@ impl FlatTransactionTraces {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Encodable for FlatTransactionTraces {
|
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
s.append_list(&self.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Decodable for FlatTransactionTraces {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
Ok(FlatTransactionTraces(rlp.as_list()?))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Into<Vec<FlatTrace>> for FlatTransactionTraces {
|
impl Into<Vec<FlatTrace>> for FlatTransactionTraces {
|
||||||
fn into(self) -> Vec<FlatTrace> {
|
fn into(self) -> Vec<FlatTrace> {
|
||||||
self.0
|
self.0
|
||||||
@ -118,7 +106,7 @@ impl Into<Vec<FlatTrace>> for FlatTransactionTraces {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Represents all traces produced by transactions in a single block.
|
/// Represents all traces produced by transactions in a single block.
|
||||||
#[derive(Debug, PartialEq, Clone, Default)]
|
#[derive(Debug, PartialEq, Clone, Default, RlpEncodableWrapper, RlpDecodableWrapper)]
|
||||||
pub struct FlatBlockTraces(Vec<FlatTransactionTraces>);
|
pub struct FlatBlockTraces(Vec<FlatTransactionTraces>);
|
||||||
|
|
||||||
impl HeapSizeOf for FlatBlockTraces {
|
impl HeapSizeOf for FlatBlockTraces {
|
||||||
@ -140,18 +128,6 @@ impl FlatBlockTraces {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Encodable for FlatBlockTraces {
|
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
s.append_list(&self.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Decodable for FlatBlockTraces {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
Ok(FlatBlockTraces(rlp.as_list()?))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Into<Vec<FlatTransactionTraces>> for FlatBlockTraces {
|
impl Into<Vec<FlatTransactionTraces>> for FlatBlockTraces {
|
||||||
fn into(self) -> Vec<FlatTransactionTraces> {
|
fn into(self) -> Vec<FlatTransactionTraces> {
|
||||||
self.0
|
self.0
|
||||||
|
@ -27,7 +27,7 @@ use evm::CallType;
|
|||||||
use super::error::Error;
|
use super::error::Error;
|
||||||
|
|
||||||
/// `Call` result.
|
/// `Call` result.
|
||||||
#[derive(Debug, Clone, PartialEq, Default)]
|
#[derive(Debug, Clone, PartialEq, Default, RlpEncodable, RlpDecodable)]
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
#[cfg_attr(feature = "ipc", binary)]
|
||||||
pub struct CallResult {
|
pub struct CallResult {
|
||||||
/// Gas used by call.
|
/// Gas used by call.
|
||||||
@ -36,27 +36,8 @@ pub struct CallResult {
|
|||||||
pub output: Bytes,
|
pub output: Bytes,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Encodable for CallResult {
|
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
s.begin_list(2);
|
|
||||||
s.append(&self.gas_used);
|
|
||||||
s.append(&self.output);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Decodable for CallResult {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
let res = CallResult {
|
|
||||||
gas_used: rlp.val_at(0)?,
|
|
||||||
output: rlp.val_at(1)?,
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(res)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// `Create` result.
|
/// `Create` result.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, RlpEncodable, RlpDecodable)]
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
#[cfg_attr(feature = "ipc", binary)]
|
||||||
pub struct CreateResult {
|
pub struct CreateResult {
|
||||||
/// Gas used by create.
|
/// Gas used by create.
|
||||||
@ -67,27 +48,6 @@ pub struct CreateResult {
|
|||||||
pub address: Address,
|
pub address: Address,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Encodable for CreateResult {
|
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
s.begin_list(3);
|
|
||||||
s.append(&self.gas_used);
|
|
||||||
s.append(&self.code);
|
|
||||||
s.append(&self.address);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Decodable for CreateResult {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
let res = CreateResult {
|
|
||||||
gas_used: rlp.val_at(0)?,
|
|
||||||
code: rlp.val_at(1)?,
|
|
||||||
address: rlp.val_at(2)?,
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(res)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CreateResult {
|
impl CreateResult {
|
||||||
/// Returns bloom.
|
/// Returns bloom.
|
||||||
pub fn bloom(&self) -> LogBloom {
|
pub fn bloom(&self) -> LogBloom {
|
||||||
@ -96,7 +56,7 @@ impl CreateResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Description of a _call_ action, either a `CALL` operation or a message transction.
|
/// Description of a _call_ action, either a `CALL` operation or a message transction.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, RlpEncodable, RlpDecodable)]
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
#[cfg_attr(feature = "ipc", binary)]
|
||||||
pub struct Call {
|
pub struct Call {
|
||||||
/// The sending account.
|
/// The sending account.
|
||||||
@ -126,33 +86,6 @@ impl From<ActionParams> for Call {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Encodable for Call {
|
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
s.begin_list(6);
|
|
||||||
s.append(&self.from);
|
|
||||||
s.append(&self.to);
|
|
||||||
s.append(&self.value);
|
|
||||||
s.append(&self.gas);
|
|
||||||
s.append(&self.input);
|
|
||||||
s.append(&self.call_type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Decodable for Call {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
let res = Call {
|
|
||||||
from: rlp.val_at(0)?,
|
|
||||||
to: rlp.val_at(1)?,
|
|
||||||
value: rlp.val_at(2)?,
|
|
||||||
gas: rlp.val_at(3)?,
|
|
||||||
input: rlp.val_at(4)?,
|
|
||||||
call_type: rlp.val_at(5)?,
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(res)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Call {
|
impl Call {
|
||||||
/// Returns call action bloom.
|
/// Returns call action bloom.
|
||||||
/// The bloom contains from and to addresses.
|
/// The bloom contains from and to addresses.
|
||||||
@ -163,7 +96,7 @@ impl Call {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Description of a _create_ action, either a `CREATE` operation or a create transction.
|
/// Description of a _create_ action, either a `CREATE` operation or a create transction.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, RlpEncodable, RlpDecodable)]
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
#[cfg_attr(feature = "ipc", binary)]
|
||||||
pub struct Create {
|
pub struct Create {
|
||||||
/// The address of the creator.
|
/// The address of the creator.
|
||||||
@ -187,29 +120,6 @@ impl From<ActionParams> for Create {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Encodable for Create {
|
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
s.begin_list(4);
|
|
||||||
s.append(&self.from);
|
|
||||||
s.append(&self.value);
|
|
||||||
s.append(&self.gas);
|
|
||||||
s.append(&self.init);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Decodable for Create {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
let res = Create {
|
|
||||||
from: rlp.val_at(0)?,
|
|
||||||
value: rlp.val_at(1)?,
|
|
||||||
gas: rlp.val_at(2)?,
|
|
||||||
init: rlp.val_at(3)?,
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(res)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Create {
|
impl Create {
|
||||||
/// Returns bloom create action bloom.
|
/// Returns bloom create action bloom.
|
||||||
/// The bloom contains only from address.
|
/// The bloom contains only from address.
|
||||||
@ -219,7 +129,7 @@ impl Create {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Suicide action.
|
/// Suicide action.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, RlpEncodable, RlpDecodable)]
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
#[cfg_attr(feature = "ipc", binary)]
|
||||||
pub struct Suicide {
|
pub struct Suicide {
|
||||||
/// Suicided address.
|
/// Suicided address.
|
||||||
@ -238,28 +148,6 @@ impl Suicide {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Encodable for Suicide {
|
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
s.begin_list(3);
|
|
||||||
s.append(&self.address);
|
|
||||||
s.append(&self.refund_address);
|
|
||||||
s.append(&self.balance);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Decodable for Suicide {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
let res = Suicide {
|
|
||||||
address: rlp.val_at(0)?,
|
|
||||||
refund_address: rlp.val_at(1)?,
|
|
||||||
balance: rlp.val_at(2)?,
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(res)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Description of an action that we trace; will be either a call or a create.
|
/// Description of an action that we trace; will be either a call or a create.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
#[cfg_attr(feature = "ipc", binary)]
|
||||||
@ -394,7 +282,7 @@ impl Res {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, RlpEncodable, RlpDecodable)]
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
#[cfg_attr(feature = "ipc", binary)]
|
||||||
/// A diff of some chunk of memory.
|
/// A diff of some chunk of memory.
|
||||||
pub struct MemoryDiff {
|
pub struct MemoryDiff {
|
||||||
@ -404,24 +292,7 @@ pub struct MemoryDiff {
|
|||||||
pub data: Bytes,
|
pub data: Bytes,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Encodable for MemoryDiff {
|
#[derive(Debug, Clone, PartialEq, RlpEncodable, RlpDecodable)]
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
s.begin_list(2);
|
|
||||||
s.append(&self.offset);
|
|
||||||
s.append(&self.data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Decodable for MemoryDiff {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
Ok(MemoryDiff {
|
|
||||||
offset: rlp.val_at(0)?,
|
|
||||||
data: rlp.val_at(1)?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
#[cfg_attr(feature = "ipc", binary)]
|
||||||
/// A diff of some storage value.
|
/// A diff of some storage value.
|
||||||
pub struct StorageDiff {
|
pub struct StorageDiff {
|
||||||
@ -431,24 +302,7 @@ pub struct StorageDiff {
|
|||||||
pub value: U256,
|
pub value: U256,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Encodable for StorageDiff {
|
#[derive(Debug, Clone, PartialEq, RlpEncodable, RlpDecodable)]
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
s.begin_list(2);
|
|
||||||
s.append(&self.location);
|
|
||||||
s.append(&self.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Decodable for StorageDiff {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
Ok(StorageDiff {
|
|
||||||
location: rlp.val_at(0)?,
|
|
||||||
value: rlp.val_at(1)?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
#[cfg_attr(feature = "ipc", binary)]
|
||||||
/// A record of an executed VM operation.
|
/// A record of an executed VM operation.
|
||||||
pub struct VMExecutedOperation {
|
pub struct VMExecutedOperation {
|
||||||
@ -462,28 +316,7 @@ pub struct VMExecutedOperation {
|
|||||||
pub store_diff: Option<StorageDiff>,
|
pub store_diff: Option<StorageDiff>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Encodable for VMExecutedOperation {
|
#[derive(Debug, Clone, PartialEq, Default, RlpEncodable, RlpDecodable)]
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
s.begin_list(4);
|
|
||||||
s.append(&self.gas_used);
|
|
||||||
s.append_list(&self.stack_push);
|
|
||||||
s.append(&self.mem_diff);
|
|
||||||
s.append(&self.store_diff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Decodable for VMExecutedOperation {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
Ok(VMExecutedOperation {
|
|
||||||
gas_used: rlp.val_at(0)?,
|
|
||||||
stack_push: rlp.list_at(1)?,
|
|
||||||
mem_diff: rlp.val_at(2)?,
|
|
||||||
store_diff: rlp.val_at(3)?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Default)]
|
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
#[cfg_attr(feature = "ipc", binary)]
|
||||||
/// A record of the execution of a single VM operation.
|
/// A record of the execution of a single VM operation.
|
||||||
pub struct VMOperation {
|
pub struct VMOperation {
|
||||||
@ -497,30 +330,7 @@ pub struct VMOperation {
|
|||||||
pub executed: Option<VMExecutedOperation>,
|
pub executed: Option<VMExecutedOperation>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Encodable for VMOperation {
|
#[derive(Debug, Clone, PartialEq, Default, RlpEncodable, RlpDecodable)]
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
s.begin_list(4);
|
|
||||||
s.append(&self.pc);
|
|
||||||
s.append(&self.instruction);
|
|
||||||
s.append(&self.gas_cost);
|
|
||||||
s.append(&self.executed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Decodable for VMOperation {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
let res = VMOperation {
|
|
||||||
pc: rlp.val_at(0)?,
|
|
||||||
instruction: rlp.val_at(1)?,
|
|
||||||
gas_cost: rlp.val_at(2)?,
|
|
||||||
executed: rlp.val_at(3)?,
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(res)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Default)]
|
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
#[cfg_attr(feature = "ipc", binary)]
|
||||||
/// A record of a full VM trace for a CALL/CREATE.
|
/// A record of a full VM trace for a CALL/CREATE.
|
||||||
pub struct VMTrace {
|
pub struct VMTrace {
|
||||||
@ -534,26 +344,3 @@ pub struct VMTrace {
|
|||||||
/// Thre is a 1:1 correspondance between these and a CALL/CREATE/CALLCODE/DELEGATECALL instruction.
|
/// Thre is a 1:1 correspondance between these and a CALL/CREATE/CALLCODE/DELEGATECALL instruction.
|
||||||
pub subs: Vec<VMTrace>,
|
pub subs: Vec<VMTrace>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Encodable for VMTrace {
|
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
s.begin_list(4);
|
|
||||||
s.append(&self.parent_step);
|
|
||||||
s.append(&self.code);
|
|
||||||
s.append_list(&self.operations);
|
|
||||||
s.append_list(&self.subs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Decodable for VMTrace {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
let res = VMTrace {
|
|
||||||
parent_step: rlp.val_at(0)?,
|
|
||||||
code: rlp.val_at(1)?,
|
|
||||||
operations: rlp.list_at(2)?,
|
|
||||||
subs: rlp.list_at(3)?,
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(res)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -56,6 +56,15 @@ impl Decodable for Action {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Encodable for Action {
|
||||||
|
fn rlp_append(&self, s: &mut RlpStream) {
|
||||||
|
match *self {
|
||||||
|
Action::Create => s.append_internal(&""),
|
||||||
|
Action::Call(ref addr) => s.append_internal(addr),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Transaction activation condition.
|
/// Transaction activation condition.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum Condition {
|
pub enum Condition {
|
||||||
@ -90,10 +99,7 @@ impl Transaction {
|
|||||||
s.append(&self.nonce);
|
s.append(&self.nonce);
|
||||||
s.append(&self.gas_price);
|
s.append(&self.gas_price);
|
||||||
s.append(&self.gas);
|
s.append(&self.gas);
|
||||||
match self.action {
|
s.append(&self.action);
|
||||||
Action::Create => s.append_empty_data(),
|
|
||||||
Action::Call(ref to) => s.append(to)
|
|
||||||
};
|
|
||||||
s.append(&self.value);
|
s.append(&self.value);
|
||||||
s.append(&self.data);
|
s.append(&self.data);
|
||||||
if let Some(n) = network_id {
|
if let Some(n) = network_id {
|
||||||
@ -308,10 +314,7 @@ impl UnverifiedTransaction {
|
|||||||
s.append(&self.nonce);
|
s.append(&self.nonce);
|
||||||
s.append(&self.gas_price);
|
s.append(&self.gas_price);
|
||||||
s.append(&self.gas);
|
s.append(&self.gas);
|
||||||
match self.action {
|
s.append(&self.action);
|
||||||
Action::Create => s.append_empty_data(),
|
|
||||||
Action::Call(ref to) => s.append(to)
|
|
||||||
};
|
|
||||||
s.append(&self.value);
|
s.append(&self.value);
|
||||||
s.append(&self.data);
|
s.append(&self.data);
|
||||||
s.append(&self.v);
|
s.append(&self.v);
|
||||||
|
@ -6,6 +6,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rlp = { path = "../../util/rlp" }
|
rlp = { path = "../../util/rlp" }
|
||||||
|
rlp_derive = { path = "../../util/rlp_derive" }
|
||||||
ethcore-util = { path = "../../util" }
|
ethcore-util = { path = "../../util" }
|
||||||
ethjson = { path = "../../json" }
|
ethjson = { path = "../../json" }
|
||||||
bloomable = { path = "../../util/bloomable" }
|
bloomable = { path = "../../util/bloomable" }
|
||||||
|
@ -16,11 +16,10 @@
|
|||||||
|
|
||||||
//! Basic account type -- the decoded RLP from the state trie.
|
//! Basic account type -- the decoded RLP from the state trie.
|
||||||
|
|
||||||
use rlp::*;
|
|
||||||
use util::{U256, H256};
|
use util::{U256, H256};
|
||||||
|
|
||||||
/// Basic account type.
|
/// Basic account type.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)]
|
||||||
pub struct BasicAccount {
|
pub struct BasicAccount {
|
||||||
/// Nonce of the account.
|
/// Nonce of the account.
|
||||||
pub nonce: U256,
|
pub nonce: U256,
|
||||||
@ -31,24 +30,3 @@ pub struct BasicAccount {
|
|||||||
/// Code hash of the account.
|
/// Code hash of the account.
|
||||||
pub code_hash: H256,
|
pub code_hash: H256,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Encodable for BasicAccount {
|
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
s.begin_list(4)
|
|
||||||
.append(&self.nonce)
|
|
||||||
.append(&self.balance)
|
|
||||||
.append(&self.storage_root)
|
|
||||||
.append(&self.code_hash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Decodable for BasicAccount {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
Ok(BasicAccount {
|
|
||||||
nonce: rlp.val_at(0)?,
|
|
||||||
balance: rlp.val_at(1)?,
|
|
||||||
storage_root: rlp.val_at(2)?,
|
|
||||||
code_hash: rlp.val_at(3)?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
extern crate ethcore_util as util;
|
extern crate ethcore_util as util;
|
||||||
extern crate ethjson;
|
extern crate ethjson;
|
||||||
extern crate rlp;
|
extern crate rlp;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate rlp_derive;
|
||||||
extern crate bloomable;
|
extern crate bloomable;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use util::{H256, Address, Bytes, HeapSizeOf, Hashable};
|
use util::{H256, Address, Bytes, HeapSizeOf, Hashable};
|
||||||
use bloomable::Bloomable;
|
use bloomable::Bloomable;
|
||||||
use rlp::*;
|
|
||||||
|
|
||||||
use {BlockNumber};
|
use {BlockNumber};
|
||||||
use ethjson;
|
use ethjson;
|
||||||
@ -27,7 +26,7 @@ use ethjson;
|
|||||||
pub type LogBloom = ::util::H2048;
|
pub type LogBloom = ::util::H2048;
|
||||||
|
|
||||||
/// A record of execution for a `LOG` operation.
|
/// A record of execution for a `LOG` operation.
|
||||||
#[derive(Default, Debug, Clone, PartialEq, Eq)]
|
#[derive(Default, Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)]
|
||||||
pub struct LogEntry {
|
pub struct LogEntry {
|
||||||
/// The address of the contract executing at the point of the `LOG` operation.
|
/// The address of the contract executing at the point of the `LOG` operation.
|
||||||
pub address: Address,
|
pub address: Address,
|
||||||
@ -37,26 +36,6 @@ pub struct LogEntry {
|
|||||||
pub data: Bytes,
|
pub data: Bytes,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Encodable for LogEntry {
|
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
s.begin_list(3);
|
|
||||||
s.append(&self.address);
|
|
||||||
s.append_list(&self.topics);
|
|
||||||
s.append(&self.data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Decodable for LogEntry {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
|
||||||
let entry = LogEntry {
|
|
||||||
address: rlp.val_at(0)?,
|
|
||||||
topics: rlp.list_at(1)?,
|
|
||||||
data: rlp.val_at(2)?,
|
|
||||||
};
|
|
||||||
Ok(entry)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl HeapSizeOf for LogEntry {
|
impl HeapSizeOf for LogEntry {
|
||||||
fn heap_size_of_children(&self) -> usize {
|
fn heap_size_of_children(&self) -> usize {
|
||||||
self.topics.heap_size_of_children() + self.data.heap_size_of_children()
|
self.topics.heap_size_of_children() + self.data.heap_size_of_children()
|
||||||
|
@ -17,8 +17,9 @@
|
|||||||
//! Wasm env module bindings
|
//! Wasm env module bindings
|
||||||
|
|
||||||
use parity_wasm::elements::ValueType::*;
|
use parity_wasm::elements::ValueType::*;
|
||||||
use parity_wasm::interpreter::UserFunctionDescriptor;
|
use parity_wasm::interpreter::{self, UserFunctionDescriptor};
|
||||||
use parity_wasm::interpreter::UserFunctionDescriptor::*;
|
use parity_wasm::interpreter::UserFunctionDescriptor::*;
|
||||||
|
use super::runtime::Runtime;
|
||||||
|
|
||||||
pub const SIGNATURES: &'static [UserFunctionDescriptor] = &[
|
pub const SIGNATURES: &'static [UserFunctionDescriptor] = &[
|
||||||
Static(
|
Static(
|
||||||
@ -93,4 +94,17 @@ pub const SIGNATURES: &'static [UserFunctionDescriptor] = &[
|
|||||||
&[I32; 0],
|
&[I32; 0],
|
||||||
None
|
None
|
||||||
),
|
),
|
||||||
|
|
||||||
|
Static(
|
||||||
|
"_llvm_bswap_i64",
|
||||||
|
&[I32; 2],
|
||||||
|
Some(I32)
|
||||||
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
pub fn native_bindings<'a>(runtime: &'a mut Runtime) -> interpreter::UserFunctions<'a> {
|
||||||
|
interpreter::UserFunctions {
|
||||||
|
executor: runtime,
|
||||||
|
functions: ::std::borrow::Cow::from(SIGNATURES),
|
||||||
|
}
|
||||||
|
}
|
@ -32,8 +32,6 @@ mod result;
|
|||||||
mod tests;
|
mod tests;
|
||||||
mod env;
|
mod env;
|
||||||
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
const DEFAULT_STACK_SPACE: u32 = 5 * 1024 * 1024;
|
const DEFAULT_STACK_SPACE: u32 = 5 * 1024 * 1024;
|
||||||
|
|
||||||
use parity_wasm::{interpreter, elements};
|
use parity_wasm::{interpreter, elements};
|
||||||
@ -89,6 +87,7 @@ impl vm::Vm for WasmInterpreter {
|
|||||||
DEFAULT_STACK_SPACE,
|
DEFAULT_STACK_SPACE,
|
||||||
params.gas.low_u64(),
|
params.gas.low_u64(),
|
||||||
RuntimeContext::new(params.address, params.sender),
|
RuntimeContext::new(params.address, params.sender),
|
||||||
|
&self.program,
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut cursor = ::std::io::Cursor::new(&*code);
|
let mut cursor = ::std::io::Cursor::new(&*code);
|
||||||
@ -112,16 +111,8 @@ impl vm::Vm for WasmInterpreter {
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
{
|
{
|
||||||
let execution_params = interpreter::ExecutionParams::with_external(
|
let execution_params = runtime.execution_params()
|
||||||
"env".into(),
|
.add_argument(interpreter::RuntimeValue::I32(d_ptr.as_raw() as i32));
|
||||||
Arc::new(
|
|
||||||
interpreter::env_native_module(env_instance, native_bindings(&mut runtime))
|
|
||||||
.map_err(|err| {
|
|
||||||
// todo: prefer explicit panic here also?
|
|
||||||
vm::Error::Wasm(format!("Error instantiating native bindings: {:?}", err))
|
|
||||||
})?
|
|
||||||
)
|
|
||||||
).add_argument(interpreter::RuntimeValue::I32(d_ptr.as_raw() as i32));
|
|
||||||
|
|
||||||
let module_instance = self.program.add_module("contract", contract_module, Some(&execution_params.externals))
|
let module_instance = self.program.add_module("contract", contract_module, Some(&execution_params.externals))
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
@ -158,13 +149,6 @@ impl vm::Vm for WasmInterpreter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn native_bindings<'a>(runtime: &'a mut Runtime) -> interpreter::UserFunctions<'a> {
|
|
||||||
interpreter::UserFunctions {
|
|
||||||
executor: runtime,
|
|
||||||
functions: ::std::borrow::Cow::from(env::SIGNATURES),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<runtime::Error> for vm::Error {
|
impl From<runtime::Error> for vm::Error {
|
||||||
fn from(err: runtime::Error) -> vm::Error {
|
fn from(err: runtime::Error) -> vm::Error {
|
||||||
vm::Error::Wasm(format!("WASM runtime-error: {:?}", err))
|
vm::Error::Wasm(format!("WASM runtime-error: {:?}", err))
|
||||||
|
@ -72,24 +72,26 @@ impl RuntimeContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Runtime enviroment data for wasm contract execution
|
/// Runtime enviroment data for wasm contract execution
|
||||||
pub struct Runtime<'a> {
|
pub struct Runtime<'a, 'b> {
|
||||||
gas_counter: u64,
|
gas_counter: u64,
|
||||||
gas_limit: u64,
|
gas_limit: u64,
|
||||||
dynamic_top: u32,
|
dynamic_top: u32,
|
||||||
ext: &'a mut vm::Ext,
|
ext: &'a mut vm::Ext,
|
||||||
memory: Arc<interpreter::MemoryInstance>,
|
memory: Arc<interpreter::MemoryInstance>,
|
||||||
context: RuntimeContext,
|
context: RuntimeContext,
|
||||||
|
instance: &'b interpreter::ProgramInstance,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Runtime<'a> {
|
impl<'a, 'b> Runtime<'a, 'b> {
|
||||||
/// New runtime for wasm contract with specified params
|
/// New runtime for wasm contract with specified params
|
||||||
pub fn with_params<'b>(
|
pub fn with_params<'c, 'd>(
|
||||||
ext: &'b mut vm::Ext,
|
ext: &'c mut vm::Ext,
|
||||||
memory: Arc<interpreter::MemoryInstance>,
|
memory: Arc<interpreter::MemoryInstance>,
|
||||||
stack_space: u32,
|
stack_space: u32,
|
||||||
gas_limit: u64,
|
gas_limit: u64,
|
||||||
context: RuntimeContext,
|
context: RuntimeContext,
|
||||||
) -> Runtime<'b> {
|
program_instance: &'d interpreter::ProgramInstance,
|
||||||
|
) -> Runtime<'c, 'd> {
|
||||||
Runtime {
|
Runtime {
|
||||||
gas_counter: 0,
|
gas_counter: 0,
|
||||||
gas_limit: gas_limit,
|
gas_limit: gas_limit,
|
||||||
@ -97,6 +99,7 @@ impl<'a> Runtime<'a> {
|
|||||||
memory: memory,
|
memory: memory,
|
||||||
ext: ext,
|
ext: ext,
|
||||||
context: context,
|
context: context,
|
||||||
|
instance: program_instance,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -449,9 +452,58 @@ impl<'a> Runtime<'a> {
|
|||||||
|
|
||||||
Ok(Some(0i32.into()))
|
Ok(Some(0i32.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn bswap_32(x: u32) -> u32 {
|
||||||
|
x >> 24 | x >> 8 & 0xff00 | x << 8 & 0xff0000 | x << 24
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bitswap_i64(&mut self, context: interpreter::CallerContext)
|
||||||
|
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
|
||||||
|
{
|
||||||
|
let x1 = context.value_stack.pop_as::<i32>()?;
|
||||||
|
let x2 = context.value_stack.pop_as::<i32>()?;
|
||||||
|
|
||||||
|
let result = ((Runtime::bswap_32(x2 as u32) as u64) << 32
|
||||||
|
| Runtime::bswap_32(x1 as u32) as u64) as i64;
|
||||||
|
|
||||||
|
self.return_i64(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn return_i64(&mut self, val: i64) -> Result<Option<interpreter::RuntimeValue>, interpreter::Error> {
|
||||||
|
let uval = val as u64;
|
||||||
|
let hi = (uval >> 32) as i32;
|
||||||
|
let lo = (uval << 32 >> 32) as i32;
|
||||||
|
|
||||||
|
let target = self.instance.module("contract")
|
||||||
|
.ok_or(interpreter::Error::Trap("Error locating main execution entry".to_owned()))?;
|
||||||
|
target.execute_export(
|
||||||
|
"setTempRet0",
|
||||||
|
self.execution_params().add_argument(
|
||||||
|
interpreter::RuntimeValue::I32(hi).into()
|
||||||
|
),
|
||||||
|
)?;
|
||||||
|
Ok(Some(
|
||||||
|
(lo).into()
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn execution_params(&mut self) -> interpreter::ExecutionParams {
|
||||||
|
use super::env;
|
||||||
|
|
||||||
|
let env_instance = self.instance.module("env")
|
||||||
|
.expect("Env module always exists; qed");
|
||||||
|
|
||||||
|
interpreter::ExecutionParams::with_external(
|
||||||
|
"env".into(),
|
||||||
|
Arc::new(
|
||||||
|
interpreter::env_native_module(env_instance, env::native_bindings(self))
|
||||||
|
.expect("Env module always exists; qed")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> interpreter::UserFunctionExecutor for Runtime<'a> {
|
impl<'a, 'b> interpreter::UserFunctionExecutor for Runtime<'a, 'b> {
|
||||||
fn execute(&mut self, name: &str, context: interpreter::CallerContext)
|
fn execute(&mut self, name: &str, context: interpreter::CallerContext)
|
||||||
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
|
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
|
||||||
{
|
{
|
||||||
@ -494,6 +546,9 @@ impl<'a> interpreter::UserFunctionExecutor for Runtime<'a> {
|
|||||||
"_emscripten_memcpy_big" => {
|
"_emscripten_memcpy_big" => {
|
||||||
self.mem_copy(context)
|
self.mem_copy(context)
|
||||||
},
|
},
|
||||||
|
"_llvm_bswap_i64" => {
|
||||||
|
self.bitswap_i64(context)
|
||||||
|
},
|
||||||
_ => {
|
_ => {
|
||||||
trace!(target: "wasm", "Trapped due to unhandled function: '{}'", name);
|
trace!(target: "wasm", "Trapped due to unhandled function: '{}'", name);
|
||||||
self.user_trap(context)
|
self.user_trap(context)
|
||||||
|
@ -414,3 +414,37 @@ fn storage_read() {
|
|||||||
assert_eq!(gas_left, U256::from(99682));
|
assert_eq!(gas_left, U256::from(99682));
|
||||||
assert_eq!(Address::from(&result[12..32]), address);
|
assert_eq!(Address::from(&result[12..32]), address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Tests that contract's ability to read from a storage
|
||||||
|
// Test prepopulates address into storage, than executes a contract which read that address from storage and write this address into result
|
||||||
|
#[test]
|
||||||
|
fn math_add() {
|
||||||
|
::ethcore_logger::init_log();
|
||||||
|
let code = load_sample!("math.wasm");
|
||||||
|
|
||||||
|
let mut params = ActionParams::default();
|
||||||
|
params.gas = U256::from(100_000);
|
||||||
|
params.code = Some(Arc::new(code));
|
||||||
|
|
||||||
|
let mut args = [0u8; 64];
|
||||||
|
let arg_a = U256::from_dec_str("999999999999999999999999999999").unwrap();
|
||||||
|
let arg_b = U256::from_dec_str("888888888888888888888888888888").unwrap();
|
||||||
|
arg_a.to_big_endian(&mut args[0..32]);
|
||||||
|
arg_b.to_big_endian(&mut args[32..64]);
|
||||||
|
params.data = Some(args.to_vec());
|
||||||
|
|
||||||
|
let (gas_left, result) = {
|
||||||
|
let mut interpreter = wasm_interpreter();
|
||||||
|
let result = interpreter.exec(params, &mut FakeExt::new()).expect("Interpreter to execute without any errors");
|
||||||
|
match result {
|
||||||
|
GasLeft::Known(_) => { panic!("storage_read should return payload"); },
|
||||||
|
GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let sum: U256 = (&result[..]).into();
|
||||||
|
|
||||||
|
assert_eq!(gas_left, U256::from(96284));
|
||||||
|
assert_eq!(sum, U256::from_dec_str("1888888888888888888888888888887").unwrap());
|
||||||
|
}
|
||||||
|
@ -116,6 +116,9 @@ impl trace::VMTracer for Informant {
|
|||||||
self.stack.extend_from_slice(stack_push);
|
self.stack.extend_from_slice(stack_push);
|
||||||
|
|
||||||
if let Some((pos, data)) = mem_diff {
|
if let Some((pos, data)) = mem_diff {
|
||||||
|
if self.memory.len() < (pos + data.len()) {
|
||||||
|
self.memory.resize(pos + data.len(), 0);
|
||||||
|
}
|
||||||
self.memory[pos..pos + data.len()].copy_from_slice(data);
|
self.memory[pos..pos + data.len()].copy_from_slice(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,9 +47,9 @@ EVM implementation for Parity.
|
|||||||
Copyright 2016, 2017 Parity Technologies (UK) Ltd
|
Copyright 2016, 2017 Parity Technologies (UK) Ltd
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
evmbin stats [options]
|
parity-evm stats [options]
|
||||||
evmbin [options]
|
parity-evm [options]
|
||||||
evmbin [-h | --help]
|
parity-evm [-h | --help]
|
||||||
|
|
||||||
Transaction options:
|
Transaction options:
|
||||||
--code CODE Contract code as hex (without 0x).
|
--code CODE Contract code as hex (without 0x).
|
||||||
@ -116,7 +116,7 @@ struct Args {
|
|||||||
flag_gas: Option<String>,
|
flag_gas: Option<String>,
|
||||||
flag_gas_price: Option<String>,
|
flag_gas_price: Option<String>,
|
||||||
flag_input: Option<String>,
|
flag_input: Option<String>,
|
||||||
flag_spec: Option<String>,
|
flag_chain: Option<String>,
|
||||||
flag_json: bool,
|
flag_json: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,7 +164,7 @@ impl Args {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn spec(&self) -> Result<spec::Spec, String> {
|
pub fn spec(&self) -> Result<spec::Spec, String> {
|
||||||
Ok(match self.flag_spec {
|
Ok(match self.flag_chain {
|
||||||
Some(ref filename) => {
|
Some(ref filename) => {
|
||||||
let file = fs::File::open(filename).map_err(|e| format!("{}", e))?;
|
let file = fs::File::open(filename).map_err(|e| format!("{}", e))?;
|
||||||
spec::Spec::load(::std::env::temp_dir(), file)?
|
spec::Spec::load(::std::env::temp_dir(), file)?
|
||||||
@ -188,3 +188,37 @@ fn die<T: fmt::Display>(msg: T) -> ! {
|
|||||||
println!("{}", msg);
|
println!("{}", msg);
|
||||||
::std::process::exit(-1)
|
::std::process::exit(-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use docopt::Docopt;
|
||||||
|
use super::{Args, USAGE};
|
||||||
|
|
||||||
|
fn run<T: AsRef<str>>(args: &[T]) -> Args {
|
||||||
|
Docopt::new(USAGE).and_then(|d| d.argv(args.into_iter()).deserialize()).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_parse_all_the_options() {
|
||||||
|
let args = run(&[
|
||||||
|
"parity-evm",
|
||||||
|
"--json",
|
||||||
|
"--gas", "1",
|
||||||
|
"--gas-price", "2",
|
||||||
|
"--from", "0000000000000000000000000000000000000003",
|
||||||
|
"--to", "0000000000000000000000000000000000000004",
|
||||||
|
"--code", "05",
|
||||||
|
"--input", "06",
|
||||||
|
"--chain", "./testfile",
|
||||||
|
]);
|
||||||
|
|
||||||
|
assert_eq!(args.flag_json, true);
|
||||||
|
assert_eq!(args.gas(), Ok(1.into()));
|
||||||
|
assert_eq!(args.gas_price(), Ok(2.into()));
|
||||||
|
assert_eq!(args.from(), Ok(3.into()));
|
||||||
|
assert_eq!(args.to(), Ok(4.into()));
|
||||||
|
assert_eq!(args.code(), Ok(Some(vec![05])));
|
||||||
|
assert_eq!(args.data(), Ok(Some(vec![06])));
|
||||||
|
assert_eq!(args.flag_chain, Some("./testfile".to_owned()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
2
js/package-lock.json
generated
2
js/package-lock.json
generated
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "parity.js",
|
"name": "parity.js",
|
||||||
"version": "1.8.14",
|
"version": "1.8.15",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "parity.js",
|
"name": "parity.js",
|
||||||
"version": "1.8.14",
|
"version": "1.8.15",
|
||||||
"main": "release/index.js",
|
"main": "release/index.js",
|
||||||
"jsnext:main": "src/index.js",
|
"jsnext:main": "src/index.js",
|
||||||
"author": "Parity Team <admin@parity.io>",
|
"author": "Parity Team <admin@parity.io>",
|
||||||
|
@ -325,7 +325,8 @@ export default class SecureApi extends Api {
|
|||||||
_fetchSettings () {
|
_fetchSettings () {
|
||||||
return Promise
|
return Promise
|
||||||
.all([
|
.all([
|
||||||
this._uiApi.parity.dappsUrl(),
|
// ignore dapps disabled errors
|
||||||
|
this._uiApi.parity.dappsUrl().catch(() => null),
|
||||||
this._uiApi.parity.wsUrl()
|
this._uiApi.parity.wsUrl()
|
||||||
])
|
])
|
||||||
.then(([dappsUrl, wsUrl]) => {
|
.then(([dappsUrl, wsUrl]) => {
|
||||||
|
@ -94,7 +94,7 @@ impl From<UiConfiguration> for HttpConfiguration {
|
|||||||
enabled: conf.enabled,
|
enabled: conf.enabled,
|
||||||
interface: conf.interface,
|
interface: conf.interface,
|
||||||
port: conf.port,
|
port: conf.port,
|
||||||
apis: rpc_apis::ApiSet::SafeContext,
|
apis: rpc_apis::ApiSet::UnsafeContext,
|
||||||
cors: None,
|
cors: None,
|
||||||
hosts: conf.hosts,
|
hosts: conf.hosts,
|
||||||
server_threads: None,
|
server_threads: None,
|
||||||
|
@ -245,17 +245,27 @@ impl<C: Send + Sync + 'static> EthPubSub for EthPubSubClient<C> {
|
|||||||
kind: pubsub::Kind,
|
kind: pubsub::Kind,
|
||||||
params: Trailing<pubsub::Params>,
|
params: Trailing<pubsub::Params>,
|
||||||
) {
|
) {
|
||||||
match (kind, params.into()) {
|
let error = match (kind, params.into()) {
|
||||||
(pubsub::Kind::NewHeads, None) => {
|
(pubsub::Kind::NewHeads, None) => {
|
||||||
self.heads_subscribers.write().push(subscriber)
|
self.heads_subscribers.write().push(subscriber);
|
||||||
|
return;
|
||||||
},
|
},
|
||||||
(pubsub::Kind::Logs, Some(pubsub::Params::Logs(filter))) => {
|
(pubsub::Kind::Logs, Some(pubsub::Params::Logs(filter))) => {
|
||||||
self.logs_subscribers.write().push(subscriber, filter.into());
|
self.logs_subscribers.write().push(subscriber, filter.into());
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
(pubsub::Kind::NewHeads, _) => {
|
||||||
|
errors::invalid_params("newHeads", "Expected no parameters.")
|
||||||
|
},
|
||||||
|
(pubsub::Kind::Logs, _) => {
|
||||||
|
errors::invalid_params("logs", "Expected a filter object.")
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
let _ = subscriber.reject(errors::unimplemented(None));
|
errors::unimplemented(None)
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
|
let _ = subscriber.reject(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unsubscribe(&self, id: SubscriptionId) -> BoxFuture<bool, Error> {
|
fn unsubscribe(&self, id: SubscriptionId) -> BoxFuture<bool, Error> {
|
||||||
|
@ -214,7 +214,7 @@ impl<T: Serialize> Serialize for Rich<T> {
|
|||||||
// and serialize
|
// and serialize
|
||||||
value.serialize(serializer)
|
value.serialize(serializer)
|
||||||
} else {
|
} else {
|
||||||
Err(S::Error::custom("Unserializable structures."))
|
Err(S::Error::custom("Unserializable structures: expected objects"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,8 +79,12 @@ impl<'a> Visitor<'a> for BlockNumberVisitor {
|
|||||||
"latest" => Ok(BlockNumber::Latest),
|
"latest" => Ok(BlockNumber::Latest),
|
||||||
"earliest" => Ok(BlockNumber::Earliest),
|
"earliest" => Ok(BlockNumber::Earliest),
|
||||||
"pending" => Ok(BlockNumber::Pending),
|
"pending" => Ok(BlockNumber::Pending),
|
||||||
_ if value.starts_with("0x") => u64::from_str_radix(&value[2..], 16).map(BlockNumber::Num).map_err(|_| Error::custom("invalid block number")),
|
_ if value.starts_with("0x") => u64::from_str_radix(&value[2..], 16).map(BlockNumber::Num).map_err(|e| {
|
||||||
_ => value.parse::<u64>().map(BlockNumber::Num).map_err(|_| Error::custom("invalid block number"))
|
Error::custom(format!("Invalid block number: {}", e))
|
||||||
|
}),
|
||||||
|
_ => value.parse::<u64>().map(BlockNumber::Num).map_err(|e| {
|
||||||
|
Error::custom(format!("Invalid block number: {}", e))
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,9 +81,9 @@ impl<'a> Visitor<'a> for BytesVisitor {
|
|||||||
);
|
);
|
||||||
Ok(Bytes::new(Vec::new()))
|
Ok(Bytes::new(Vec::new()))
|
||||||
} else if value.len() >= 2 && &value[0..2] == "0x" && value.len() & 1 == 0 {
|
} else if value.len() >= 2 && &value[0..2] == "0x" && value.len() & 1 == 0 {
|
||||||
Ok(Bytes::new(FromHex::from_hex(&value[2..]).map_err(|_| Error::custom("invalid hex"))?))
|
Ok(Bytes::new(FromHex::from_hex(&value[2..]).map_err(|e| Error::custom(format!("Invalid hex: {}", e)))?))
|
||||||
} else {
|
} else {
|
||||||
Err(Error::custom("invalid format"))
|
Err(Error::custom("Invalid bytes format. Expected a 0x-prefixed hex string with even length"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ impl<'a> Visitor<'a> for DerivationTypeVisitor {
|
|||||||
match value {
|
match value {
|
||||||
"soft" => Ok(DerivationType::Soft),
|
"soft" => Ok(DerivationType::Soft),
|
||||||
"hard" => Ok(DerivationType::Hard),
|
"hard" => Ok(DerivationType::Hard),
|
||||||
_ => Err(Error::custom("invalid derivation type")),
|
v => Err(Error::custom(format!("invalid derivation type: {:?}", v))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ impl<'a, T> Deserialize<'a> for VariadicValue<T> where T: DeserializeOwned {
|
|||||||
|
|
||||||
from_value(v.clone()).map(VariadicValue::Single)
|
from_value(v.clone()).map(VariadicValue::Single)
|
||||||
.or_else(|_| from_value(v).map(VariadicValue::Multiple))
|
.or_else(|_| from_value(v).map(VariadicValue::Multiple))
|
||||||
.map_err(|_| D::Error::custom("Invalid type."))
|
.map_err(|err| D::Error::custom(format!("Invalid variadic value type: {}", err)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,8 +47,12 @@ impl<'a> Visitor<'a> for IndexVisitor {
|
|||||||
|
|
||||||
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> where E: Error {
|
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> where E: Error {
|
||||||
match value {
|
match value {
|
||||||
_ if value.starts_with("0x") => usize::from_str_radix(&value[2..], 16).map(Index).map_err(|_| Error::custom("invalid index")),
|
_ if value.starts_with("0x") => usize::from_str_radix(&value[2..], 16).map(Index).map_err(|e| {
|
||||||
_ => value.parse::<usize>().map(Index).map_err(|_| Error::custom("invalid index")),
|
Error::custom(format!("Invalid index: {}", e))
|
||||||
|
}),
|
||||||
|
_ => value.parse::<usize>().map(Index).map_err(|e| {
|
||||||
|
Error::custom(format!("Invalid index: {}", e))
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ impl<'a> Deserialize<'a> for Params {
|
|||||||
}
|
}
|
||||||
|
|
||||||
from_value(v.clone()).map(Params::Logs)
|
from_value(v.clone()).map(Params::Logs)
|
||||||
.map_err(|_| D::Error::custom("Invalid type."))
|
.map_err(|e| D::Error::custom(format!("Invalid Pub-Sub parameters: {}", e)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ version = "1.4.0"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
futures = "0.1"
|
futures = "0.1"
|
||||||
rpassword = "0.3.0"
|
rpassword = "0.3.0"
|
||||||
bigint = "3.0"
|
bigint = "4.0"
|
||||||
parity-rpc = { path = "../rpc" }
|
parity-rpc = { path = "../rpc" }
|
||||||
parity-rpc-client = { path = "../rpc_client" }
|
parity-rpc-client = { path = "../rpc_client" }
|
||||||
ethcore-util = { path = "../util" }
|
ethcore-util = { path = "../util" }
|
||||||
|
@ -8,7 +8,7 @@ version = "0.1.3"
|
|||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bigint = "3.0"
|
bigint = "4.0"
|
||||||
rustc-hex = "1.0"
|
rustc-hex = "1.0"
|
||||||
rand = "0.3.12"
|
rand = "0.3.12"
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
#![feature(test)]
|
#![feature(test)]
|
||||||
|
|
||||||
extern crate test;
|
extern crate test;
|
||||||
extern crate bigint;
|
extern crate ethcore_bigint as bigint;
|
||||||
extern crate rlp;
|
extern crate rlp;
|
||||||
|
|
||||||
use test::Bencher;
|
use test::Bencher;
|
||||||
|
15
util/rlp_derive/Cargo.toml
Normal file
15
util/rlp_derive/Cargo.toml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
[package]
|
||||||
|
name = "rlp_derive"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["debris <marek.kotewicz@gmail.com>"]
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "rlp_derive"
|
||||||
|
proc-macro = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
syn = "0.11.11"
|
||||||
|
quote = "0.3.15"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
rlp = { path = "../rlp" }
|
139
util/rlp_derive/src/de.rs
Normal file
139
util/rlp_derive/src/de.rs
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
use {syn, quote};
|
||||||
|
|
||||||
|
struct ParseQuotes {
|
||||||
|
single: quote::Tokens,
|
||||||
|
list: quote::Tokens,
|
||||||
|
takes_index: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn decodable_parse_quotes() -> ParseQuotes {
|
||||||
|
ParseQuotes {
|
||||||
|
single: quote! { rlp.val_at },
|
||||||
|
list: quote! { rlp.list_at },
|
||||||
|
takes_index: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn decodable_wrapper_parse_quotes() -> ParseQuotes {
|
||||||
|
ParseQuotes {
|
||||||
|
single: quote! { rlp.as_val },
|
||||||
|
list: quote! { rlp.as_list },
|
||||||
|
takes_index: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn impl_decodable(ast: &syn::DeriveInput) -> quote::Tokens {
|
||||||
|
let body = match ast.body {
|
||||||
|
syn::Body::Struct(ref s) => s,
|
||||||
|
_ => panic!("#[derive(RlpDecodable)] is only defined for structs."),
|
||||||
|
};
|
||||||
|
|
||||||
|
let stmts: Vec<_> = match *body {
|
||||||
|
syn::VariantData::Struct(ref fields) | syn::VariantData::Tuple(ref fields) =>
|
||||||
|
fields.iter().enumerate().map(decodable_field_map).collect(),
|
||||||
|
syn::VariantData::Unit => panic!("#[derive(RlpDecodable)] is not defined for Unit structs."),
|
||||||
|
};
|
||||||
|
|
||||||
|
let name = &ast.ident;
|
||||||
|
|
||||||
|
let dummy_const = syn::Ident::new(format!("_IMPL_RLP_DECODABLE_FOR_{}", name));
|
||||||
|
let impl_block = quote! {
|
||||||
|
impl rlp::Decodable for #name {
|
||||||
|
fn decode(rlp: &rlp::UntrustedRlp) -> Result<Self, rlp::DecoderError> {
|
||||||
|
let result = #name {
|
||||||
|
#(#stmts)*
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||||
|
const #dummy_const: () = {
|
||||||
|
extern crate rlp;
|
||||||
|
#impl_block
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn impl_decodable_wrapper(ast: &syn::DeriveInput) -> quote::Tokens {
|
||||||
|
let body = match ast.body {
|
||||||
|
syn::Body::Struct(ref s) => s,
|
||||||
|
_ => panic!("#[derive(RlpDecodableWrapper)] is only defined for structs."),
|
||||||
|
};
|
||||||
|
|
||||||
|
let stmt = match *body {
|
||||||
|
syn::VariantData::Struct(ref fields) | syn::VariantData::Tuple(ref fields) => {
|
||||||
|
if fields.len() == 1 {
|
||||||
|
let field = fields.first().expect("fields.len() == 1; qed");
|
||||||
|
decodable_field(0, field, decodable_wrapper_parse_quotes())
|
||||||
|
} else {
|
||||||
|
panic!("#[derive(RlpDecodableWrapper)] is only defined for structs with one field.")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
syn::VariantData::Unit => panic!("#[derive(RlpDecodableWrapper)] is not defined for Unit structs."),
|
||||||
|
};
|
||||||
|
|
||||||
|
let name = &ast.ident;
|
||||||
|
|
||||||
|
let dummy_const = syn::Ident::new(format!("_IMPL_RLP_DECODABLE_FOR_{}", name));
|
||||||
|
let impl_block = quote! {
|
||||||
|
impl rlp::Decodable for #name {
|
||||||
|
fn decode(rlp: &rlp::UntrustedRlp) -> Result<Self, rlp::DecoderError> {
|
||||||
|
let result = #name {
|
||||||
|
#stmt
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||||
|
const #dummy_const: () = {
|
||||||
|
extern crate rlp;
|
||||||
|
#impl_block
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn decodable_field_map(tuple: (usize, &syn::Field)) -> quote::Tokens {
|
||||||
|
decodable_field(tuple.0, tuple.1, decodable_parse_quotes())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn decodable_field(index: usize, field: &syn::Field, quotes: ParseQuotes) -> quote::Tokens {
|
||||||
|
let ident = match field.ident {
|
||||||
|
Some(ref ident) => ident.to_string(),
|
||||||
|
None => index.to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let id = syn::Ident::new(ident);
|
||||||
|
let index = syn::Ident::new(index.to_string());
|
||||||
|
|
||||||
|
let single = quotes.single;
|
||||||
|
let list = quotes.list;
|
||||||
|
|
||||||
|
match field.ty {
|
||||||
|
syn::Ty::Path(_, ref path) => {
|
||||||
|
let ident = &path.segments.first().expect("there must be at least 1 segment").ident;
|
||||||
|
if &ident.to_string() == "Vec" {
|
||||||
|
if quotes.takes_index {
|
||||||
|
quote! { #id: #list(#index)?, }
|
||||||
|
} else {
|
||||||
|
quote! { #id: #list()?, }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if quotes.takes_index {
|
||||||
|
quote! { #id: #single(#index)?, }
|
||||||
|
} else {
|
||||||
|
quote! { #id: #single()?, }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => panic!("rlp_derive not supported"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
110
util/rlp_derive/src/en.rs
Normal file
110
util/rlp_derive/src/en.rs
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
use {syn, quote};
|
||||||
|
|
||||||
|
pub fn impl_encodable(ast: &syn::DeriveInput) -> quote::Tokens {
|
||||||
|
let body = match ast.body {
|
||||||
|
syn::Body::Struct(ref s) => s,
|
||||||
|
_ => panic!("#[derive(RlpEncodable)] is only defined for structs."),
|
||||||
|
};
|
||||||
|
|
||||||
|
let stmts: Vec<_> = match *body {
|
||||||
|
syn::VariantData::Struct(ref fields) | syn::VariantData::Tuple(ref fields) =>
|
||||||
|
fields.iter().enumerate().map(encodable_field_map).collect(),
|
||||||
|
syn::VariantData::Unit => panic!("#[derive(RlpEncodable)] is not defined for Unit structs."),
|
||||||
|
};
|
||||||
|
|
||||||
|
let name = &ast.ident;
|
||||||
|
|
||||||
|
let stmts_len = syn::Ident::new(stmts.len().to_string());
|
||||||
|
let dummy_const = syn::Ident::new(format!("_IMPL_RLP_ENCODABLE_FOR_{}", name));
|
||||||
|
let impl_block = quote! {
|
||||||
|
impl rlp::Encodable for #name {
|
||||||
|
fn rlp_append(&self, stream: &mut rlp::RlpStream) {
|
||||||
|
stream.begin_list(#stmts_len);
|
||||||
|
#(#stmts)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||||
|
const #dummy_const: () = {
|
||||||
|
extern crate rlp;
|
||||||
|
#impl_block
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn impl_encodable_wrapper(ast: &syn::DeriveInput) -> quote::Tokens {
|
||||||
|
let body = match ast.body {
|
||||||
|
syn::Body::Struct(ref s) => s,
|
||||||
|
_ => panic!("#[derive(RlpEncodableWrapper)] is only defined for structs."),
|
||||||
|
};
|
||||||
|
|
||||||
|
let stmt = match *body {
|
||||||
|
syn::VariantData::Struct(ref fields) | syn::VariantData::Tuple(ref fields) => {
|
||||||
|
if fields.len() == 1 {
|
||||||
|
let field = fields.first().expect("fields.len() == 1; qed");
|
||||||
|
encodable_field(0, field)
|
||||||
|
} else {
|
||||||
|
panic!("#[derive(RlpEncodableWrapper)] is only defined for structs with one field.")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
syn::VariantData::Unit => panic!("#[derive(RlpEncodableWrapper)] is not defined for Unit structs."),
|
||||||
|
};
|
||||||
|
|
||||||
|
let name = &ast.ident;
|
||||||
|
|
||||||
|
let dummy_const = syn::Ident::new(format!("_IMPL_RLP_ENCODABLE_FOR_{}", name));
|
||||||
|
let impl_block = quote! {
|
||||||
|
impl rlp::Encodable for #name {
|
||||||
|
fn rlp_append(&self, stream: &mut rlp::RlpStream) {
|
||||||
|
#stmt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||||
|
const #dummy_const: () = {
|
||||||
|
extern crate rlp;
|
||||||
|
#impl_block
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn encodable_field_map(tuple: (usize, &syn::Field)) -> quote::Tokens {
|
||||||
|
encodable_field(tuple.0, tuple.1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn encodable_field(index: usize, field: &syn::Field) -> quote::Tokens {
|
||||||
|
let ident = match field.ident {
|
||||||
|
Some(ref ident) => ident.to_string(),
|
||||||
|
None => index.to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let id = syn::Ident::new(format!("self.{}", ident));
|
||||||
|
|
||||||
|
match field.ty {
|
||||||
|
syn::Ty::Path(_, ref path) => {
|
||||||
|
let top_segment = path.segments.first().expect("there must be at least 1 segment");
|
||||||
|
let ident = &top_segment.ident;
|
||||||
|
if &ident.to_string() == "Vec" {
|
||||||
|
let inner_ident = match top_segment.parameters {
|
||||||
|
syn::PathParameters::AngleBracketed(ref angle) => {
|
||||||
|
let ty = angle.types.first().expect("Vec has only one angle bracketed type; qed");
|
||||||
|
match *ty {
|
||||||
|
syn::Ty::Path(_, ref path) => &path.segments.first().expect("there must be at least 1 segment").ident,
|
||||||
|
_ => panic!("rlp_derive not supported"),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => unreachable!("Vec has only one angle bracketed type; qed"),
|
||||||
|
};
|
||||||
|
quote! { stream.append_list::<#inner_ident, _>(&#id); }
|
||||||
|
} else {
|
||||||
|
quote! { stream.append(&#id); }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => panic!("rlp_derive not supported"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
43
util/rlp_derive/src/lib.rs
Normal file
43
util/rlp_derive/src/lib.rs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
extern crate proc_macro;
|
||||||
|
extern crate syn;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate quote;
|
||||||
|
|
||||||
|
mod en;
|
||||||
|
mod de;
|
||||||
|
|
||||||
|
use proc_macro::TokenStream;
|
||||||
|
use en::{impl_encodable, impl_encodable_wrapper};
|
||||||
|
use de::{impl_decodable, impl_decodable_wrapper};
|
||||||
|
|
||||||
|
#[proc_macro_derive(RlpEncodable)]
|
||||||
|
pub fn encodable(input: TokenStream) -> TokenStream {
|
||||||
|
let s = input.to_string();
|
||||||
|
let ast = syn::parse_derive_input(&s).unwrap();
|
||||||
|
let gen = impl_encodable(&ast);
|
||||||
|
gen.parse().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro_derive(RlpEncodableWrapper)]
|
||||||
|
pub fn encodable_wrapper(input: TokenStream) -> TokenStream {
|
||||||
|
let s = input.to_string();
|
||||||
|
let ast = syn::parse_derive_input(&s).unwrap();
|
||||||
|
let gen = impl_encodable_wrapper(&ast);
|
||||||
|
gen.parse().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro_derive(RlpDecodable)]
|
||||||
|
pub fn decodable(input: TokenStream) -> TokenStream {
|
||||||
|
let s = input.to_string();
|
||||||
|
let ast = syn::parse_derive_input(&s).unwrap();
|
||||||
|
let gen = impl_decodable(&ast);
|
||||||
|
gen.parse().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro_derive(RlpDecodableWrapper)]
|
||||||
|
pub fn decodable_wrapper(input: TokenStream) -> TokenStream {
|
||||||
|
let s = input.to_string();
|
||||||
|
let ast = syn::parse_derive_input(&s).unwrap();
|
||||||
|
let gen = impl_decodable_wrapper(&ast);
|
||||||
|
gen.parse().unwrap()
|
||||||
|
}
|
44
util/rlp_derive/tests/rlp.rs
Normal file
44
util/rlp_derive/tests/rlp.rs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
extern crate rlp;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate rlp_derive;
|
||||||
|
|
||||||
|
use rlp::{encode, decode};
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, RlpEncodable, RlpDecodable)]
|
||||||
|
struct Foo {
|
||||||
|
a: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, RlpEncodableWrapper, RlpDecodableWrapper)]
|
||||||
|
struct FooWrapper {
|
||||||
|
a: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_encode_foo() {
|
||||||
|
let foo = Foo {
|
||||||
|
a: "cat".into(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let expected = vec![0xc4, 0x83, b'c', b'a', b't'];
|
||||||
|
let out = encode(&foo).into_vec();
|
||||||
|
assert_eq!(out, expected);
|
||||||
|
|
||||||
|
let decoded = decode(&expected);
|
||||||
|
assert_eq!(foo, decoded);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_encode_foo_wrapper() {
|
||||||
|
let foo = FooWrapper {
|
||||||
|
a: "cat".into(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let expected = vec![0x83, b'c', b'a', b't'];
|
||||||
|
let out = encode(&foo).into_vec();
|
||||||
|
assert_eq!(out, expected);
|
||||||
|
|
||||||
|
let decoded = decode(&expected);
|
||||||
|
assert_eq!(foo, decoded);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user