Merge pull request #86 from gavofyork/gav

Add tests module, add two more transaction tests.
This commit is contained in:
Arkadiy Paronyan
2016-01-12 12:26:36 +01:00
10 changed files with 73 additions and 580 deletions

View File

@@ -12,19 +12,19 @@ pub use self::denominations::*;
use super::spec::*;
/// Create a new Olympic chain spec.
pub fn new_olympic() -> Spec { Spec::from_json_utf8(include_bytes!("res/olympic.json")) }
pub fn new_olympic() -> Spec { Spec::from_json_utf8(include_bytes!("../../res/ethereum/olympic.json")) }
/// Create a new Frontier mainnet chain spec.
pub fn new_frontier() -> Spec { Spec::from_json_utf8(include_bytes!("res/frontier.json")) }
pub fn new_frontier() -> Spec { Spec::from_json_utf8(include_bytes!("../../res/ethereum/frontier.json")) }
/// Create a new Frontier chain spec as though it never changes to Homestead.
pub fn new_frontier_test() -> Spec { Spec::from_json_utf8(include_bytes!("res/frontier_test.json")) }
pub fn new_frontier_test() -> Spec { Spec::from_json_utf8(include_bytes!("../../res/ethereum/frontier_test.json")) }
/// Create a new Homestead chain spec as though it never changed from Frontier.
pub fn new_homestead_test() -> Spec { Spec::from_json_utf8(include_bytes!("res/homestead_test.json")) }
pub fn new_homestead_test() -> Spec { Spec::from_json_utf8(include_bytes!("../../res/ethereum/homestead_test.json")) }
/// Create a new Morden chain spec.
pub fn new_morden() -> Spec { Spec::from_json_utf8(include_bytes!("res/morden.json")) }
pub fn new_morden() -> Spec { Spec::from_json_utf8(include_bytes!("../../res/ethereum/morden.json")) }
#[cfg(test)]
mod tests {

File diff suppressed because it is too large Load Diff

View File

@@ -1,33 +0,0 @@
{
"engineName": "Ethash",
"params": {
"accountStartNonce": "0x00",
"frontierCompatibilityModeLimit": "0xffffffffffffffff",
"maximumExtraDataSize": "0x20",
"tieBreakingGas": false,
"minGasLimit": "0x1388",
"gasLimitBoundDivisor": "0x0400",
"minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"networkID" : "0x1"
},
"genesis": {
"nonce": "0x0000000000000042",
"difficulty": "0x400000000",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"author": "0x0000000000000000000000000000000000000000",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa",
"gasLimit": "0x1388"
},
"accounts": {
"0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } },
"0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "linear": { "base": 60, "word": 12 } } },
"0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } },
"0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "linear": { "base": 15, "word": 3 } } }
}
}

View File

@@ -1,33 +0,0 @@
{
"engineName": "Ethash",
"params": {
"accountStartNonce": "0x00",
"frontierCompatibilityModeLimit": "0xffffffff",
"maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388",
"tieBreakingGas": false,
"gasLimitBoundDivisor": "0x0400",
"minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"networkID" : "0x1"
},
"genesis": {
"nonce": "0x0000000000000042",
"difficulty": "0x400000000",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"author": "0x0000000000000000000000000000000000000000",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa",
"gasLimit": "0x1388"
},
"accounts": {
"0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } },
"0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "linear": { "base": 60, "word": 12 } } },
"0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } },
"0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "linear": { "base": 15, "word": 3 } } }
}
}

View File

@@ -1,34 +0,0 @@
{
"engineName": "Ethash",
"params": {
"accountStartNonce": "0x0100000",
"frontierCompatibilityModeLimit": "0xfffa2990",
"maximumExtraDataSize": "0x20",
"tieBreakingGas": false,
"minGasLimit": "0x1388",
"gasLimitBoundDivisor": "0x0400",
"minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar": "",
"networkID" : "0x2"
},
"genesis": {
"nonce": "0x00006d6f7264656e",
"difficulty": "0x20000",
"mixHash": "0x00000000000000000000000000000000000000647572616c65787365646c6578",
"author": "0x0000000000000000000000000000000000000000",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x",
"gasLimit": "0x2fefd8"
},
"accounts": {
"0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } },
"0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "linear": { "base": 60, "word": 12 } } },
"0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } },
"0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "linear": { "base": 15, "word": 3 } } },
"102e61f5d8f9bc71d0ad4a084df4e65e05ce0e1c": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" }
}
}

View File

@@ -1,41 +0,0 @@
{
"engineName": "Ethash",
"params": {
"accountStartNonce": "0x00",
"frontierCompatibilityModeLimit": "0xffffffff",
"maximumExtraDataSize": "0x0400",
"tieBreakingGas": false,
"minGasLimit": "125000",
"gasLimitBoundDivisor": "0x0400",
"minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800",
"durationLimit": "0x08",
"blockReward": "0x14D1120D7B160000",
"registrar": "5e70c0bbcd5636e0f9f9316e9f8633feb64d4050",
"networkID" : "0x0"
},
"genesis": {
"nonce": "0x000000000000002a",
"difficulty": "0x20000",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"author": "0x0000000000000000000000000000000000000000",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x",
"gasLimit": "0x2fefd8"
},
"accounts": {
"0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } },
"0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "linear": { "base": 60, "word": 12 } } },
"0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } },
"0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "linear": { "base": 15, "word": 3 } } },
"dbdbdb2cbd23b783741e8d7fcf51e459b497e4a6": { "balance": "1606938044258990275541962092341162602522202993782792835301376" },
"e6716f9544a56c530d868e4bfbacb172315bdead": { "balance": "1606938044258990275541962092341162602522202993782792835301376" },
"b9c015918bdaba24b4ff057a92a3873d6eb201be": { "balance": "1606938044258990275541962092341162602522202993782792835301376" },
"1a26338f0d905e295fccb71fa9ea849ffa12aaf4": { "balance": "1606938044258990275541962092341162602522202993782792835301376" },
"2ef47100e0787b915105fd5e3f4ff6752079d5cb": { "balance": "1606938044258990275541962092341162602522202993782792835301376" },
"cd2a3d9f938e13cd947ec05abc7fe734df8dd826": { "balance": "1606938044258990275541962092341162602522202993782792835301376" },
"6c386a4b26f73c802f34673f7248bb118f97424a": { "balance": "1606938044258990275541962092341162602522202993782792835301376" },
"e4157b34ea9615cfbde6b4fda419828124b70c78": { "balance": "1606938044258990275541962092341162602522202993782792835301376" }
}
}

View File

@@ -147,20 +147,6 @@ impl Decodable for Transaction {
}
}
#[test]
fn sender_test() {
let t: Transaction = decode(&FromHex::from_hex("f85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804").unwrap());
assert_eq!(t.data, b"");
assert_eq!(t.gas, U256::from(0x5208u64));
assert_eq!(t.gas_price, U256::from(0x01u64));
assert_eq!(t.nonce, U256::from(0x00u64));
if let Action::Call(ref to) = t.action {
assert_eq!(*to, address_from_hex("095e7baea6a6c7c4c2dfeb977efac326af552d87"));
} else { panic!(); }
assert_eq!(t.value, U256::from(0x0au64));
assert_eq!(t.sender().unwrap(), address_from_hex("0f65fe9276bc9a24ae7083ae28e2660ef72df99e"));
}
pub fn clean(s: &str) -> &str {
if s.len() >= 2 && &s[0..2] == "0x" {
&s[2..]
@@ -172,9 +158,9 @@ pub fn clean(s: &str) -> &str {
pub fn bytes_from_json(json: &Json) -> Bytes {
let s = json.as_string().unwrap();
if s.len() % 2 == 1 {
FromHex::from_hex(&("0".to_string() + &(clean(s).to_string()))[..]).unwrap()
FromHex::from_hex(&("0".to_string() + &(clean(s).to_string()))[..]).unwrap_or(vec![])
} else {
FromHex::from_hex(clean(s)).unwrap()
FromHex::from_hex(clean(s)).unwrap_or(vec![])
}
}
@@ -199,36 +185,70 @@ pub fn u256_from_json(json: &Json) -> U256 {
}
}
#[test]
fn json_tests() {
#[cfg(test)]
mod tests {
use util::*;
use evm::Schedule;
use header::BlockNumber;
let json = Json::from_str(::std::str::from_utf8(include_bytes!("../res/ttTransactionTest.json")).unwrap()).expect("Json is invalid");
let mut failed = Vec::new();
let schedule = Schedule::new_frontier();
for (name, test) in json.as_object().unwrap() {
let mut fail = false;
let mut fail_unless = |cond: bool| if !cond && fail { failed.push(name.to_string()); fail = true };
let _ = BlockNumber::from_str(test["blocknumber"].as_string().unwrap()).unwrap();
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));
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.gas == u256_from_json(&tx["gasLimit"]));
fail_unless(t.gas_price == u256_from_json(&tx["gasPrice"]));
fail_unless(t.nonce == u256_from_json(&tx["nonce"]));
fail_unless(t.value == u256_from_json(&tx["value"]));
if let Action::Call(ref to) = t.action {
fail_unless(to == &address_from_json(&tx["to"]));
} else {
fail_unless(bytes_from_json(&tx["to"]).len() == 0);
use super::*;
#[test]
fn sender_test() {
let t: Transaction = decode(&FromHex::from_hex("f85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804").unwrap());
assert_eq!(t.data, b"");
assert_eq!(t.gas, U256::from(0x5208u64));
assert_eq!(t.gas_price, U256::from(0x01u64));
assert_eq!(t.nonce, U256::from(0x00u64));
if let Action::Call(ref to) = t.action {
assert_eq!(*to, address_from_hex("095e7baea6a6c7c4c2dfeb977efac326af552d87"));
} else { panic!(); }
assert_eq!(t.value, U256::from(0x0au64));
assert_eq!(t.sender().unwrap(), address_from_hex("0f65fe9276bc9a24ae7083ae28e2660ef72df99e"));
}
fn do_json_test(json_data: &[u8]) -> Vec<String> {
let json = Json::from_str(::std::str::from_utf8(json_data).unwrap()).expect("Json is invalid");
let mut failed = Vec::new();
let schedule = Schedule::new_frontier();
for (name, test) in json.as_object().unwrap() {
let mut fail = false;
let mut fail_unless = |cond: bool| if !cond && fail { failed.push(name.to_string()); fail = true };
let _ = BlockNumber::from_str(test["blocknumber"].as_string().unwrap()).unwrap();
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));
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.gas == u256_from_json(&tx["gasLimit"]));
fail_unless(t.gas_price == u256_from_json(&tx["gasPrice"]));
fail_unless(t.nonce == u256_from_json(&tx["nonce"]));
fail_unless(t.value == u256_from_json(&tx["value"]));
if let Action::Call(ref to) = t.action {
fail_unless(to == &address_from_json(&tx["to"]));
} else {
fail_unless(bytes_from_json(&tx["to"]).len() == 0);
}
}
}
for f in failed.iter() {
println!("FAILED: {:?}", f);
}
failed
}
macro_rules! declare_test {
($test_set_name: ident/$name: ident) => {
#[test]
#[allow(non_snake_case)]
fn $name() {
assert!(do_json_test(include_bytes!(concat!("../res/ethereum/tests/", stringify!($test_set_name), "/", stringify!($name), ".json"))).len() == 0);
}
}
}
for f in failed.iter() {
println!("FAILED: {:?}", f);
}
assert!(failed.len() == 0);
declare_test!{TransactionTests/ttTransactionTest}
declare_test!{TransactionTests/tt10mbDataField}
declare_test!{TransactionTests/ttWrongRLPTransaction}
}