pub type Test = super::tester::GenericTester<String, State>;
use std::collections::BTreeMap;
use serde::Deserialize;
use crate::{
bytes::Bytes,
hash::{Address, H256},
maybe::MaybeEmpty,
uint::Uint,
spec::{ForkSpec, State as AccountState},
transaction::Transaction,
vm::Env
};
#[derive(Debug, PartialEq, Deserialize)]
pub struct State {
pub env: Env,
#[serde(rename = "pre")]
pub pre_state: AccountState,
#[serde(rename = "post")]
pub post_states: BTreeMap<ForkSpec, Vec<PostStateResult>>,
pub transaction: MultiTransaction,
}
#[derive(Debug, PartialEq, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct MultiTransaction {
pub data: Vec<Bytes>,
pub gas_limit: Vec<Uint>,
pub gas_price: Uint,
pub nonce: Uint,
#[serde(rename = "secretKey")]
pub secret: Option<H256>,
pub to: MaybeEmpty<Address>,
pub value: Vec<Uint>,
}
impl MultiTransaction {
pub fn select(&self, indexes: &PostStateIndexes) -> Transaction {
Transaction {
data: self.data[indexes.data as usize].clone(),
gas_limit: self.gas_limit[indexes.gas as usize],
gas_price: self.gas_price,
nonce: self.nonce,
to: self.to.clone(),
value: self.value[indexes.value as usize],
r: Default::default(),
s: Default::default(),
v: Default::default(),
secret: self.secret.clone(),
}
}
}
#[derive(Debug, PartialEq, Deserialize)]
pub struct PostStateIndexes {
pub data: u64,
pub gas: u64,
pub value: u64,
}
#[derive(Debug, PartialEq, Deserialize)]
pub struct PostStateResult {
pub hash: H256,
pub indexes: PostStateIndexes,
}
#[cfg(test)]
mod tests {
use serde_json;
use super::{MultiTransaction, State};
#[test]
fn multi_transaction_deserialization() {
let s = r#"{
"data": [ "" ],
"gasLimit": [ "0x2dc6c0", "0x222222" ],
"gasPrice": "0x01",
"nonce": "0x00",
"secretKey": "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to": "1000000000000000000000000000000000000000",
"value": [ "0x00", "0x01", "0x02" ]
}"#;
let _deserialized: MultiTransaction = serde_json::from_str(s).unwrap();
}
#[test]
fn state_deserialization() {
let s = r#"{
"env": {
"currentCoinbase": "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty": "0x0100",
"currentGasLimit": "0x01c9c380",
"currentNumber": "0x00",
"currentTimestamp": "0x01",
"previousHash": "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"post": {
"EIP150": [
{
"hash": "3e6dacc1575c6a8c76422255eca03529bbf4c0dda75dfc110b22d6dc4152396f",
"indexes": { "data": 0, "gas": 0, "value": 0 }
},
{
"hash": "99a450d8ce5b987a71346d8a0a1203711f770745c7ef326912e46761f14cd764",
"indexes": { "data": 0, "gas": 0, "value": 1 }
}
],
"EIP158": [
{
"hash": "3e6dacc1575c6a8c76422255eca03529bbf4c0dda75dfc110b22d6dc4152396f",
"indexes": { "data": 0, "gas": 0, "value": 0 }
},
{
"hash": "99a450d8ce5b987a71346d8a0a1203711f770745c7ef326912e46761f14cd764",
"indexes": { "data": 0, "gas": 0, "value": 1 }
}
]
},
"pre": {
"1000000000000000000000000000000000000000": {
"balance": "0x0de0b6b3a7640000",
"code": "0x6040600060406000600173100000000000000000000000000000000000000162055730f1600055",
"nonce": "0x00",
"storage": {
}
},
"1000000000000000000000000000000000000001": {
"balance": "0x0de0b6b3a7640000",
"code": "0x604060006040600060027310000000000000000000000000000000000000026203d090f1600155",
"nonce": "0x00",
"storage": {
}
},
"1000000000000000000000000000000000000002": {
"balance": "0x00",
"code": "0x600160025533600455346007553060e6553260e8553660ec553860ee553a60f055",
"nonce": "0x00",
"storage": {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
"balance": "0x0de0b6b3a7640000",
"code": "0x",
"nonce": "0x00",
"storage": {
}
}
},
"transaction": {
"data": [ "" ],
"gasLimit": [ "285000", "100000", "6000" ],
"gasPrice": "0x01",
"nonce": "0x00",
"secretKey": "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to": "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value": [ "10", "0" ]
}
}"#;
let _deserialized: State = serde_json::from_str(s).unwrap();
}
}