Change over to new FromJson API.
This commit is contained in:
parent
d3091b95c3
commit
6eea05d255
@ -39,6 +39,12 @@ impl Builtin {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Simple forwarder for cost.
|
||||||
|
pub fn cost(&self, s: usize) -> U256 { (*self.cost)(s) }
|
||||||
|
|
||||||
|
/// Simple forwarder for execute.
|
||||||
|
pub fn execute(&self, input: &[u8], output: &mut[u8]) { (*self.execute)(input, output); }
|
||||||
|
|
||||||
/// Create a builtin from JSON.
|
/// Create a builtin from JSON.
|
||||||
///
|
///
|
||||||
/// JSON must be of the form `{ "name": "identity", "linear": {"base": 10, "word": 20} }`.
|
/// JSON must be of the form `{ "name": "identity", "linear": {"base": 10, "word": 20} }`.
|
||||||
@ -55,12 +61,6 @@ impl Builtin {
|
|||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Simple forwarder for cost.
|
|
||||||
pub fn cost(&self, s: usize) -> U256 { (*self.cost)(s) }
|
|
||||||
|
|
||||||
/// Simple forwarder for execute.
|
|
||||||
pub fn execute(&self, input: &[u8], output: &mut[u8]) { (*self.execute)(input, output); }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn copy_to(src: &[u8], dest: &mut[u8]) {
|
pub fn copy_to(src: &[u8], dest: &mut[u8]) {
|
||||||
|
@ -36,15 +36,17 @@ impl EnvInfo {
|
|||||||
gas_used: x!(0),
|
gas_used: x!(0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn from_json(json: &Json) -> EnvInfo {
|
impl FromJson for EnvInfo {
|
||||||
let current_number = u64_from_json(&json["currentNumber"]);
|
fn from_json(json: &Json) -> EnvInfo {
|
||||||
|
let current_number: u64 = xjson!(&json["currentNumber"]);
|
||||||
EnvInfo {
|
EnvInfo {
|
||||||
number: current_number,
|
number: current_number,
|
||||||
author: address_from_json(&json["currentCoinbase"]),
|
author: xjson!(&json["currentCoinbase"]),
|
||||||
difficulty: xjson!(&json["currentDifficulty"]),
|
difficulty: xjson!(&json["currentDifficulty"]),
|
||||||
gas_limit: xjson!(&json["currentGasLimit"]),
|
gas_limit: xjson!(&json["currentGasLimit"]),
|
||||||
timestamp: u64_from_json(&json["currentTimestamp"]),
|
timestamp: xjson!(&json["currentTimestamp"]),
|
||||||
last_hashes: (1..257).map(|i| format!("{}", current_number - i).as_bytes().sha3()).collect(),
|
last_hashes: (1..257).map(|i| format!("{}", current_number - i).as_bytes().sha3()).collect(),
|
||||||
gas_used: x!(0),
|
gas_used: x!(0),
|
||||||
}
|
}
|
||||||
|
@ -28,16 +28,6 @@ impl LogEntry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert given JSON object to a LogEntry.
|
|
||||||
pub fn from_json(json: &Json) -> LogEntry {
|
|
||||||
// TODO: check bloom.
|
|
||||||
LogEntry {
|
|
||||||
address: address_from_json(&json["address"]),
|
|
||||||
topics: vec_h256_from_json(&json["topics"]),
|
|
||||||
data: bytes_from_json(&json["data"]),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns reference to address.
|
/// Returns reference to address.
|
||||||
pub fn address(&self) -> &Address {
|
pub fn address(&self) -> &Address {
|
||||||
&self.address
|
&self.address
|
||||||
@ -59,6 +49,18 @@ impl LogEntry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FromJson for LogEntry {
|
||||||
|
/// Convert given JSON object to a LogEntry.
|
||||||
|
fn from_json(json: &Json) -> LogEntry {
|
||||||
|
// TODO: check bloom.
|
||||||
|
LogEntry {
|
||||||
|
address: xjson!(&json["address"]),
|
||||||
|
topics: xjson!(&json["topics"]),
|
||||||
|
data: xjson!(&json["data"]),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use util::*;
|
use util::*;
|
||||||
|
@ -8,13 +8,21 @@ impl PodState {
|
|||||||
/// Contruct a new object from the `m`.
|
/// Contruct a new object from the `m`.
|
||||||
pub fn new(m: BTreeMap<Address, PodAccount>) -> PodState { PodState(m) }
|
pub fn new(m: BTreeMap<Address, PodAccount>) -> PodState { PodState(m) }
|
||||||
|
|
||||||
|
/// Get the underlying map.
|
||||||
|
pub fn get(&self) -> &BTreeMap<Address, PodAccount> { &self.0 }
|
||||||
|
|
||||||
|
/// Drain object to get the underlying map.
|
||||||
|
pub fn drain(self) -> BTreeMap<Address, PodAccount> { self.0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromJson for PodState {
|
||||||
/// Translate the JSON object into a hash map of account information ready for insertion into State.
|
/// Translate the JSON object into a hash map of account information ready for insertion into State.
|
||||||
pub fn from_json(json: &Json) -> PodState {
|
fn from_json(json: &Json) -> PodState {
|
||||||
PodState(json.as_object().unwrap().iter().fold(BTreeMap::new(), |mut state, (address, acc)| {
|
PodState(json.as_object().unwrap().iter().fold(BTreeMap::new(), |mut state, (address, acc)| {
|
||||||
let balance = acc.find("balance").map(&U256::from_json);
|
let balance = acc.find("balance").map(&U256::from_json);
|
||||||
let nonce = acc.find("nonce").map(&U256::from_json);
|
let nonce = acc.find("nonce").map(&U256::from_json);
|
||||||
let storage = acc.find("storage").map(&map_h256_h256_from_json);;
|
let storage = acc.find("storage").map(&BTreeMap::from_json);
|
||||||
let code = acc.find("code").map(&bytes_from_json);
|
let code = acc.find("code").map(&Bytes::from_json);
|
||||||
if balance.is_some() || nonce.is_some() || storage.is_some() || code.is_some() {
|
if balance.is_some() || nonce.is_some() || storage.is_some() || code.is_some() {
|
||||||
state.insert(address_from_hex(address), PodAccount{
|
state.insert(address_from_hex(address), PodAccount{
|
||||||
balance: balance.unwrap_or(U256::zero()),
|
balance: balance.unwrap_or(U256::zero()),
|
||||||
@ -26,12 +34,6 @@ impl PodState {
|
|||||||
state
|
state
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the underlying map.
|
|
||||||
pub fn get(&self) -> &BTreeMap<Address, PodAccount> { &self.0 }
|
|
||||||
|
|
||||||
/// Drain object to get the underlying map.
|
|
||||||
pub fn drain(self) -> BTreeMap<Address, PodAccount> { self.0 }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for PodState {
|
impl fmt::Display for PodState {
|
||||||
|
@ -148,9 +148,11 @@ impl Spec {
|
|||||||
ret.append_raw(&empty_list, 1);
|
ret.append_raw(&empty_list, 1);
|
||||||
ret.out()
|
ret.out()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromJson for Spec {
|
||||||
/// Loads a chain-specification from a json data structure
|
/// Loads a chain-specification from a json data structure
|
||||||
pub fn from_json(json: Json) -> Spec {
|
fn from_json(json: &Json) -> Spec {
|
||||||
// once we commit ourselves to some json parsing library (serde?)
|
// once we commit ourselves to some json parsing library (serde?)
|
||||||
// move it to proper data structure
|
// move it to proper data structure
|
||||||
let mut state = HashMap::new();
|
let mut state = HashMap::new();
|
||||||
@ -210,7 +212,9 @@ impl Spec {
|
|||||||
state_root_memo: RwLock::new(genesis.find("stateRoot").and_then(|_| genesis["stateRoot"].as_string()).map(|s| H256::from_str(&s[2..]).unwrap())),
|
state_root_memo: RwLock::new(genesis.find("stateRoot").and_then(|_| genesis["stateRoot"].as_string()).map(|s| H256::from_str(&s[2..]).unwrap())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Spec {
|
||||||
/// Ensure that the given state DB has the trie nodes in for the genesis state.
|
/// Ensure that the given state DB has the trie nodes in for the genesis state.
|
||||||
pub fn ensure_db_good(&self, db: &mut HashDB) {
|
pub fn ensure_db_good(&self, db: &mut HashDB) {
|
||||||
if !db.contains(&self.state_root()) {
|
if !db.contains(&self.state_root()) {
|
||||||
@ -229,8 +233,7 @@ impl Spec {
|
|||||||
|
|
||||||
/// Create a new Spec from a JSON string.
|
/// Create a new Spec from a JSON string.
|
||||||
pub fn from_json_str(s: &str) -> Spec {
|
pub fn from_json_str(s: &str) -> Spec {
|
||||||
let json = Json::from_str(s).expect("Json is invalid");
|
Self::from_json(&Json::from_str(s).expect("Json is invalid"))
|
||||||
Self::from_json(json)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new Spec which conforms to the Morden chain except that it's a NullEngine consensus.
|
/// Create a new Spec which conforms to the Morden chain except that it's a NullEngine consensus.
|
||||||
|
@ -170,24 +170,19 @@ fn do_json_test(json_data: &[u8]) -> Vec<String> {
|
|||||||
test.find("pre").map(|pre| for (addr, s) in pre.as_object().unwrap() {
|
test.find("pre").map(|pre| for (addr, s) in pre.as_object().unwrap() {
|
||||||
let address = Address::from(addr.as_ref());
|
let address = Address::from(addr.as_ref());
|
||||||
let balance = xjson!(&s["balance"]);
|
let balance = xjson!(&s["balance"]);
|
||||||
let code = bytes_from_json(&s["code"]);
|
let code = xjson!(&s["code"]);
|
||||||
let _nonce: U256 = xjson!(&s["nonce"]);
|
let _nonce: U256 = xjson!(&s["nonce"]);
|
||||||
|
|
||||||
state.new_contract(&address);
|
state.new_contract(&address);
|
||||||
state.add_balance(&address, &balance);
|
state.add_balance(&address, &balance);
|
||||||
state.init_code(&address, code);
|
state.init_code(&address, code);
|
||||||
|
BTreeMap::from_json(&s["storage"]).into_iter().foreach(|(k, v)| state.set_storage(&address, k, v));
|
||||||
for (k, v) in s["storage"].as_object().unwrap() {
|
|
||||||
let key = H256::from(&u256_from_str(k));
|
|
||||||
let val = H256::from(&U256::from_json(v));
|
|
||||||
state.set_storage(&address, key, val);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut info = EnvInfo::new();
|
let mut info = EnvInfo::new();
|
||||||
|
|
||||||
test.find("env").map(|env| {
|
test.find("env").map(|env| {
|
||||||
info.author = address_from_json(&env["currentCoinbase"]);
|
info.author = xjson!(&env["currentCoinbase"]);
|
||||||
info.difficulty = xjson!(&env["currentDifficulty"]);
|
info.difficulty = xjson!(&env["currentDifficulty"]);
|
||||||
info.gas_limit = xjson!(&env["currentGasLimit"]);
|
info.gas_limit = xjson!(&env["currentGasLimit"]);
|
||||||
info.number = xjson!(&env["currentNumber"]);
|
info.number = xjson!(&env["currentNumber"]);
|
||||||
@ -199,11 +194,11 @@ fn do_json_test(json_data: &[u8]) -> Vec<String> {
|
|||||||
// params
|
// params
|
||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::new();
|
||||||
test.find("exec").map(|exec| {
|
test.find("exec").map(|exec| {
|
||||||
params.address = address_from_json(&exec["address"]);
|
params.address = xjson!(&exec["address"]);
|
||||||
params.sender = address_from_json(&exec["caller"]);
|
params.sender = xjson!(&exec["caller"]);
|
||||||
params.origin = address_from_json(&exec["origin"]);
|
params.origin = xjson!(&exec["origin"]);
|
||||||
params.code = bytes_from_json(&exec["code"]);
|
params.code = xjson!(&exec["code"]);
|
||||||
params.data = bytes_from_json(&exec["data"]);
|
params.data = xjson!(&exec["data"]);
|
||||||
params.gas = xjson!(&exec["gas"]);
|
params.gas = xjson!(&exec["gas"]);
|
||||||
params.gas_price = xjson!(&exec["gasPrice"]);
|
params.gas_price = xjson!(&exec["gasPrice"]);
|
||||||
params.value = xjson!(&exec["value"]);
|
params.value = xjson!(&exec["value"]);
|
||||||
@ -231,23 +226,16 @@ fn do_json_test(json_data: &[u8]) -> Vec<String> {
|
|||||||
//println!("name: {}, gas_left : {:?}, expected: {:?}", name, gas_left, U256::from(&test["gas"]));
|
//println!("name: {}, gas_left : {:?}, expected: {:?}", name, gas_left, U256::from(&test["gas"]));
|
||||||
fail_unless(!out_of_gas, "expected to run out of gas.");
|
fail_unless(!out_of_gas, "expected to run out of gas.");
|
||||||
fail_unless(gas_left == xjson!(&test["gas"]), "gas_left is incorrect");
|
fail_unless(gas_left == xjson!(&test["gas"]), "gas_left is incorrect");
|
||||||
fail_unless(output == bytes_from_json(&test["out"]), "output is incorrect");
|
fail_unless(output == Bytes::from_json(&test["out"]), "output is incorrect");
|
||||||
|
|
||||||
|
|
||||||
test.find("post").map(|pre| for (addr, s) in pre.as_object().unwrap() {
|
test.find("post").map(|pre| for (addr, s) in pre.as_object().unwrap() {
|
||||||
let address = Address::from(addr.as_ref());
|
let address = Address::from(addr.as_ref());
|
||||||
//let balance = U256::from(&s["balance"]);
|
|
||||||
|
|
||||||
fail_unless(state.code(&address).unwrap_or(vec![]) == bytes_from_json(&s["code"]), "code is incorrect");
|
fail_unless(state.code(&address).unwrap_or(vec![]) == Bytes::from_json(&s["code"]), "code is incorrect");
|
||||||
fail_unless(state.balance(&address) == xjson!(&s["balance"]), "balance is incorrect");
|
fail_unless(state.balance(&address) == xjson!(&s["balance"]), "balance is incorrect");
|
||||||
fail_unless(state.nonce(&address) == xjson!(&s["nonce"]), "nonce is incorrect");
|
fail_unless(state.nonce(&address) == xjson!(&s["nonce"]), "nonce is incorrect");
|
||||||
|
BTreeMap::from_json(&s["storage"]).iter().foreach(|(k, v)| fail_unless(&state.storage_at(&address, &k) == v, "storage is incorrect"));
|
||||||
for (k, v) in s["storage"].as_object().unwrap() {
|
|
||||||
let key = H256::from(&u256_from_str(k));
|
|
||||||
let val = H256::from(&U256::from_json(v));
|
|
||||||
|
|
||||||
fail_unless(state.storage_at(&address, &key) == val, "storage is incorrect");
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let cc = test["callcreates"].as_array().unwrap();
|
let cc = test["callcreates"].as_array().unwrap();
|
||||||
@ -255,8 +243,8 @@ fn do_json_test(json_data: &[u8]) -> Vec<String> {
|
|||||||
for i in 0..cc.len() {
|
for i in 0..cc.len() {
|
||||||
let is = &callcreates[i];
|
let is = &callcreates[i];
|
||||||
let expected = &cc[i];
|
let expected = &cc[i];
|
||||||
fail_unless(is.data == bytes_from_json(&expected["data"]), "callcreates data is incorrect");
|
fail_unless(is.data == Bytes::from_json(&expected["data"]), "callcreates data is incorrect");
|
||||||
fail_unless(is.destination == address_from_json(&expected["destination"]), "callcreates destination is incorrect");
|
fail_unless(is.destination == xjson!(&expected["destination"]), "callcreates destination is incorrect");
|
||||||
fail_unless(is.value == xjson!(&expected["value"]), "callcreates value is incorrect");
|
fail_unless(is.value == xjson!(&expected["value"]), "callcreates value is incorrect");
|
||||||
|
|
||||||
// TODO: call_gas is calculated in externalities and is not exposed to TestExt.
|
// TODO: call_gas is calculated in externalities and is not exposed to TestExt.
|
||||||
|
@ -16,8 +16,8 @@ fn do_json_test(json_data: &[u8]) -> Vec<String> {
|
|||||||
|
|
||||||
let t = Transaction::from_json(&test["transaction"]);
|
let t = Transaction::from_json(&test["transaction"]);
|
||||||
let env = EnvInfo::from_json(&test["env"]);
|
let env = EnvInfo::from_json(&test["env"]);
|
||||||
let _out = bytes_from_json(&test["out"]);
|
let _out = Bytes::from_json(&test["out"]);
|
||||||
let post_state_root = h256_from_json(&test["postStateRoot"]);
|
let post_state_root = xjson!(&test["postStateRoot"]);
|
||||||
let pre = PodState::from_json(&test["pre"]);
|
let pre = PodState::from_json(&test["pre"]);
|
||||||
let post = PodState::from_json(&test["post"]);
|
let post = PodState::from_json(&test["post"]);
|
||||||
let logs: Vec<_> = test["logs"].as_array().unwrap().iter().map(&LogEntry::from_json).collect();
|
let logs: Vec<_> = test["logs"].as_array().unwrap().iter().map(&LogEntry::from_json).collect();
|
||||||
|
@ -14,23 +14,23 @@ fn do_json_test(json_data: &[u8]) -> Vec<String> {
|
|||||||
.and_then(|j| j.as_string())
|
.and_then(|j| j.as_string())
|
||||||
.and_then(|s| BlockNumber::from_str(s).ok())
|
.and_then(|s| BlockNumber::from_str(s).ok())
|
||||||
.unwrap_or(0) { x if x < 900000 => &old_schedule, _ => &new_schedule };
|
.unwrap_or(0) { x if x < 900000 => &old_schedule, _ => &new_schedule };
|
||||||
let rlp = bytes_from_json(&test["rlp"]);
|
let rlp = Bytes::from_json(&test["rlp"]);
|
||||||
let res = UntrustedRlp::new(&rlp).as_val().map_err(|e| From::from(e)).and_then(|t: Transaction| t.validate(schedule, schedule.have_delegate_call));
|
let res = UntrustedRlp::new(&rlp).as_val().map_err(|e| From::from(e)).and_then(|t: Transaction| t.validate(schedule, schedule.have_delegate_call));
|
||||||
fail_unless(test.find("transaction").is_none() == res.is_err());
|
fail_unless(test.find("transaction").is_none() == res.is_err());
|
||||||
if let (Some(&Json::Object(ref tx)), Some(&Json::String(ref expect_sender))) = (test.find("transaction"), test.find("sender")) {
|
if let (Some(&Json::Object(ref tx)), Some(&Json::String(ref expect_sender))) = (test.find("transaction"), test.find("sender")) {
|
||||||
let t = res.unwrap();
|
let t = res.unwrap();
|
||||||
fail_unless(t.sender().unwrap() == address_from_hex(clean(expect_sender)));
|
fail_unless(t.sender().unwrap() == address_from_hex(clean(expect_sender)));
|
||||||
fail_unless(t.data == bytes_from_json(&tx["data"]));
|
fail_unless(t.data == Bytes::from_json(&tx["data"]));
|
||||||
fail_unless(t.gas == xjson!(&tx["gasLimit"]));
|
fail_unless(t.gas == xjson!(&tx["gasLimit"]));
|
||||||
fail_unless(t.gas_price == xjson!(&tx["gasPrice"]));
|
fail_unless(t.gas_price == xjson!(&tx["gasPrice"]));
|
||||||
fail_unless(t.nonce == xjson!(&tx["nonce"]));
|
fail_unless(t.nonce == xjson!(&tx["nonce"]));
|
||||||
fail_unless(t.value == xjson!(&tx["value"]));
|
fail_unless(t.value == xjson!(&tx["value"]));
|
||||||
if let Action::Call(ref to) = t.action {
|
if let Action::Call(ref to) = t.action {
|
||||||
*ot.borrow_mut() = t.clone();
|
*ot.borrow_mut() = t.clone();
|
||||||
fail_unless(to == &address_from_json(&tx["to"]));
|
fail_unless(to == &xjson!(&tx["to"]));
|
||||||
} else {
|
} else {
|
||||||
*ot.borrow_mut() = t.clone();
|
*ot.borrow_mut() = t.clone();
|
||||||
fail_unless(bytes_from_json(&tx["to"]).len() == 0);
|
fail_unless(Bytes::from_json(&tx["to"]).len() == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,32 +79,6 @@ impl Transaction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_json(json: &Json) -> Transaction {
|
|
||||||
let mut r = Transaction {
|
|
||||||
nonce: xjson!(&json["nonce"]),
|
|
||||||
gas_price: xjson!(&json["gasPrice"]),
|
|
||||||
gas: xjson!(&json["gasLimit"]),
|
|
||||||
action: match bytes_from_json(&json["to"]) {
|
|
||||||
ref x if x.len() == 0 => Action::Create,
|
|
||||||
ref x => Action::Call(Address::from_slice(x)),
|
|
||||||
},
|
|
||||||
value: xjson!(&json["value"]),
|
|
||||||
data: bytes_from_json(&json["data"]),
|
|
||||||
v: match json.find("v") { Some(ref j) => u8_from_json(j), None => 0 },
|
|
||||||
r: match json.find("r") { Some(j) => xjson!(j), None => x!(0) },
|
|
||||||
s: match json.find("s") { Some(j) => xjson!(j), None => x!(0) },
|
|
||||||
hash: RefCell::new(None),
|
|
||||||
sender: match json.find("sender") {
|
|
||||||
Some(&Json::String(ref sender)) => RefCell::new(Some(address_from_hex(clean(sender)))),
|
|
||||||
_ => RefCell::new(None),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
if let Some(&Json::String(ref secret_key)) = json.find("secretKey") {
|
|
||||||
r.sign(&h256_from_hex(clean(secret_key)));
|
|
||||||
}
|
|
||||||
r
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the nonce of the transaction.
|
/// Get the nonce of the transaction.
|
||||||
pub fn nonce(&self) -> &U256 { &self.nonce }
|
pub fn nonce(&self) -> &U256 { &self.nonce }
|
||||||
/// Get the gas price of the transaction.
|
/// Get the gas price of the transaction.
|
||||||
@ -144,6 +118,34 @@ impl Transaction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FromJson for Transaction {
|
||||||
|
fn from_json(json: &Json) -> Transaction {
|
||||||
|
let mut r = Transaction {
|
||||||
|
nonce: xjson!(&json["nonce"]),
|
||||||
|
gas_price: xjson!(&json["gasPrice"]),
|
||||||
|
gas: xjson!(&json["gasLimit"]),
|
||||||
|
action: match Bytes::from_json(&json["to"]) {
|
||||||
|
ref x if x.len() == 0 => Action::Create,
|
||||||
|
ref x => Action::Call(Address::from_slice(x)),
|
||||||
|
},
|
||||||
|
value: xjson!(&json["value"]),
|
||||||
|
data: xjson!(&json["data"]),
|
||||||
|
v: match json.find("v") { Some(ref j) => u16::from_json(j) as u8, None => 0 },
|
||||||
|
r: match json.find("r") { Some(j) => xjson!(j), None => x!(0) },
|
||||||
|
s: match json.find("s") { Some(j) => xjson!(j), None => x!(0) },
|
||||||
|
hash: RefCell::new(None),
|
||||||
|
sender: match json.find("sender") {
|
||||||
|
Some(&Json::String(ref sender)) => RefCell::new(Some(address_from_hex(clean(sender)))),
|
||||||
|
_ => RefCell::new(None),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
if let Some(&Json::String(ref secret_key)) = json.find("secretKey") {
|
||||||
|
r.sign(&h256_from_hex(clean(secret_key)));
|
||||||
|
}
|
||||||
|
r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl RlpStandard for Transaction {
|
impl RlpStandard for Transaction {
|
||||||
fn rlp_append(&self, s: &mut RlpStream) { self.rlp_append_opt(s, Seal::With) }
|
fn rlp_append(&self, s: &mut RlpStream) { self.rlp_append_opt(s, Seal::With) }
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user