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.
 | ||||
| 	///
 | ||||
| 	/// JSON must be of the form `{ "name": "identity", "linear": {"base": 10, "word": 20} }`.
 | ||||
| @ -55,12 +61,6 @@ impl Builtin { | ||||
| 		} | ||||
| 		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]) { | ||||
|  | ||||
| @ -36,15 +36,17 @@ impl EnvInfo { | ||||
| 			gas_used: x!(0), | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	pub fn from_json(json: &Json) -> EnvInfo { | ||||
| 		let current_number = u64_from_json(&json["currentNumber"]); | ||||
| impl FromJson for EnvInfo { | ||||
| 	fn from_json(json: &Json) -> EnvInfo { | ||||
| 		let current_number: u64 = xjson!(&json["currentNumber"]); | ||||
| 		EnvInfo { | ||||
| 			number: current_number, | ||||
| 			author: address_from_json(&json["currentCoinbase"]), | ||||
| 			author: xjson!(&json["currentCoinbase"]), | ||||
| 			difficulty: xjson!(&json["currentDifficulty"]), | ||||
| 			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(), | ||||
| 			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.
 | ||||
| 	pub fn 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)] | ||||
| mod tests { | ||||
| 	use util::*; | ||||
|  | ||||
| @ -8,13 +8,21 @@ impl PodState { | ||||
| 	/// Contruct a new object from the `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.
 | ||||
| 	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)| { | ||||
| 			let balance = acc.find("balance").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 code = acc.find("code").map(&bytes_from_json); | ||||
| 			let storage = acc.find("storage").map(&BTreeMap::from_json); | ||||
| 			let code = acc.find("code").map(&Bytes::from_json); | ||||
| 			if balance.is_some() || nonce.is_some() || storage.is_some() || code.is_some() { | ||||
| 				state.insert(address_from_hex(address), PodAccount{ | ||||
| 					balance: balance.unwrap_or(U256::zero()), | ||||
| @ -26,12 +34,6 @@ impl PodState { | ||||
| 			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 { | ||||
|  | ||||
| @ -148,9 +148,11 @@ impl Spec { | ||||
| 		ret.append_raw(&empty_list, 1); | ||||
| 		ret.out() | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl FromJson for Spec { | ||||
| 	/// 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?)
 | ||||
| 		// move it to proper data structure
 | ||||
| 		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())), | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl Spec { | ||||
| 	/// Ensure that the given state DB has the trie nodes in for the genesis state.
 | ||||
| 	pub fn ensure_db_good(&self, db: &mut HashDB) { | ||||
| 		if !db.contains(&self.state_root()) { | ||||
| @ -229,8 +233,7 @@ impl Spec { | ||||
| 
 | ||||
| 	/// Create a new Spec from a JSON string.
 | ||||
| 	pub fn from_json_str(s: &str) -> Spec { | ||||
| 		let json = Json::from_str(s).expect("Json is invalid"); | ||||
| 		Self::from_json(json) | ||||
| 		Self::from_json(&Json::from_str(s).expect("Json is invalid")) | ||||
| 	} | ||||
| 
 | ||||
| 	/// 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() { | ||||
| 			let address = Address::from(addr.as_ref()); | ||||
| 			let balance = xjson!(&s["balance"]); | ||||
| 			let code = bytes_from_json(&s["code"]); | ||||
| 			let code = xjson!(&s["code"]); | ||||
| 			let _nonce: U256 = xjson!(&s["nonce"]); | ||||
| 
 | ||||
| 			state.new_contract(&address); | ||||
| 			state.add_balance(&address, &balance); | ||||
| 			state.init_code(&address, code); | ||||
| 
 | ||||
| 			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); | ||||
| 			} | ||||
| 			BTreeMap::from_json(&s["storage"]).into_iter().foreach(|(k, v)| state.set_storage(&address, k, v)); | ||||
| 		}); | ||||
| 
 | ||||
| 		let mut info = EnvInfo::new(); | ||||
| 
 | ||||
| 		test.find("env").map(|env| { | ||||
| 			info.author = address_from_json(&env["currentCoinbase"]); | ||||
| 			info.author = xjson!(&env["currentCoinbase"]); | ||||
| 			info.difficulty = xjson!(&env["currentDifficulty"]); | ||||
| 			info.gas_limit = xjson!(&env["currentGasLimit"]); | ||||
| 			info.number = xjson!(&env["currentNumber"]); | ||||
| @ -199,11 +194,11 @@ fn do_json_test(json_data: &[u8]) -> Vec<String> { | ||||
| 		// params
 | ||||
| 		let mut params = ActionParams::new(); | ||||
| 		test.find("exec").map(|exec| { | ||||
| 			params.address = address_from_json(&exec["address"]); | ||||
| 			params.sender = address_from_json(&exec["caller"]); | ||||
| 			params.origin = address_from_json(&exec["origin"]); | ||||
| 			params.code = bytes_from_json(&exec["code"]); | ||||
| 			params.data = bytes_from_json(&exec["data"]); | ||||
| 			params.address = xjson!(&exec["address"]); | ||||
| 			params.sender = xjson!(&exec["caller"]); | ||||
| 			params.origin = xjson!(&exec["origin"]); | ||||
| 			params.code = xjson!(&exec["code"]); | ||||
| 			params.data = xjson!(&exec["data"]); | ||||
| 			params.gas = xjson!(&exec["gas"]); | ||||
| 			params.gas_price = xjson!(&exec["gasPrice"]); | ||||
| 			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"]));
 | ||||
| 				fail_unless(!out_of_gas, "expected to run out of gas."); | ||||
| 				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() { | ||||
| 					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.nonce(&address) == xjson!(&s["nonce"]), "nonce 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"); | ||||
| 					} | ||||
| 					BTreeMap::from_json(&s["storage"]).iter().foreach(|(k, v)| fail_unless(&state.storage_at(&address, &k) == v, "storage is incorrect")); | ||||
| 				}); | ||||
| 
 | ||||
| 				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() { | ||||
| 					let is = &callcreates[i]; | ||||
| 					let expected = &cc[i]; | ||||
| 					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.data == Bytes::from_json(&expected["data"]), "callcreates data is incorrect"); | ||||
| 					fail_unless(is.destination == xjson!(&expected["destination"]), "callcreates destination 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.
 | ||||
|  | ||||
| @ -16,8 +16,8 @@ fn do_json_test(json_data: &[u8]) -> Vec<String> { | ||||
| 
 | ||||
| 		let t = Transaction::from_json(&test["transaction"]); | ||||
| 		let env = EnvInfo::from_json(&test["env"]); | ||||
| 		let _out = bytes_from_json(&test["out"]); | ||||
| 		let post_state_root = h256_from_json(&test["postStateRoot"]); | ||||
| 		let _out = Bytes::from_json(&test["out"]); | ||||
| 		let post_state_root = xjson!(&test["postStateRoot"]); | ||||
| 		let pre = PodState::from_json(&test["pre"]); | ||||
| 		let post = PodState::from_json(&test["post"]); | ||||
| 		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(|s| BlockNumber::from_str(s).ok()) | ||||
| 			.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)); | ||||
| 		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")) { | ||||
| 			let t = res.unwrap(); | ||||
| 			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_price == xjson!(&tx["gasPrice"])); | ||||
| 			fail_unless(t.nonce == xjson!(&tx["nonce"])); | ||||
| 			fail_unless(t.value == xjson!(&tx["value"])); | ||||
| 			if let Action::Call(ref to) = t.action { | ||||
| 				*ot.borrow_mut() = t.clone(); | ||||
| 				fail_unless(to == &address_from_json(&tx["to"])); | ||||
| 				fail_unless(to == &xjson!(&tx["to"])); | ||||
| 			} else { | ||||
| 				*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.
 | ||||
| 	pub fn nonce(&self) -> &U256 { &self.nonce } | ||||
| 	/// 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 { | ||||
| 	fn rlp_append(&self, s: &mut RlpStream) { self.rlp_append_opt(s, Seal::With) } | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user