From 728883f45e44472c8e9e017f12f9c4a62e9ee7da Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 11 Jan 2016 19:40:02 +0100 Subject: [PATCH 01/10] Remove unneeded panic. --- src/executive.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/executive.rs b/src/executive.rs index 07af3b71b..6ea0be1cc 100644 --- a/src/executive.rs +++ b/src/executive.rs @@ -559,8 +559,5 @@ mod tests { let _res = ex.call(¶ms, &mut substate, &mut []); println!("res: {:?}", _res); } - - assert!(false); - } } From 845ac87f88111f97d176a886628f2886a7f12826 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 11 Jan 2016 20:36:29 +0100 Subject: [PATCH 02/10] Transaction includes signature. --- src/basic_types.rs | 5 +++++ src/header.rs | 5 ----- src/transaction.rs | 40 +++++++++++++++++++++++++++++++--------- 3 files changed, 36 insertions(+), 14 deletions(-) diff --git a/src/basic_types.rs b/src/basic_types.rs index 2c18c59d2..2466d8813 100644 --- a/src/basic_types.rs +++ b/src/basic_types.rs @@ -5,3 +5,8 @@ pub type LogBloom = H2048; /// Constant 2048-bit datum for 0. Often used as a default. pub static ZERO_LOGBLOOM: LogBloom = H2048([0x00; 256]); + +pub enum Seal { + With, + Without, +} diff --git a/src/header.rs b/src/header.rs index 41230b2ce..7a01797a6 100644 --- a/src/header.rs +++ b/src/header.rs @@ -34,11 +34,6 @@ pub struct Header { pub hash: RefCell>, } -pub enum Seal { - With, - Without, -} - impl Header { /// Create a new, default-valued, header. pub fn new() -> Header { diff --git a/src/transaction.rs b/src/transaction.rs index 3c3301dd9..fcaa39b59 100644 --- a/src/transaction.rs +++ b/src/transaction.rs @@ -1,4 +1,5 @@ use util::*; +use basic_types::*; pub enum Action { Create, @@ -14,13 +15,14 @@ pub struct Transaction { pub action: Action, pub value: U256, pub data: Bytes, + pub signature: Signature, hash: RefCell>, //TODO: make this private } -impl RlpStandard for Transaction { - fn rlp_append(&self, s: &mut RlpStream) { - s.append_list(6); +impl Transaction { + pub fn rlp_append_opt(&self, s: &mut RlpStream, with_seal: Seal) { + s.append_list(6 + match with_seal { Seal::With => 3, _ => 0 }); s.append(&self.nonce); s.append(&self.gas_price); s.append(&self.gas); @@ -30,7 +32,27 @@ impl RlpStandard for Transaction { }; s.append(&self.value); s.append(&self.data); + match with_seal { + Seal::With => { + s.append(&(self.signature.as_slice()[64] as u16)); + s.append(&&self.signature.as_slice()[0..32]); + s.append(&&self.signature.as_slice()[32..64]); + }, + _ => {} + } } + + pub fn rlp_bytes_opt(&self, with_seal: Seal) -> Bytes { + let mut s = RlpStream::new(); + self.rlp_append_opt(&mut s, with_seal); + s.out() + } + + pub fn rlp_sha3_opt(&self, with_seal: Seal) -> H256 { self.rlp_bytes_opt(with_seal).sha3() } +} + +impl RlpStandard for Transaction { + fn rlp_append(&self, s: &mut RlpStream) { self.rlp_append_opt(s, Seal::With) } } impl Transaction { @@ -55,7 +77,9 @@ impl Transaction { pub fn action(&self) -> &Action { &self.action } /// Returns transaction sender. - pub fn sender(&self) -> Address { Address::new() } + pub fn sender(&self) -> Address { + Address::new() + } } impl Decodable for Action { @@ -72,17 +96,15 @@ impl Decodable for Action { impl Decodable for Transaction { fn decode(decoder: &D) -> Result where D: Decoder { let d = try!(decoder.as_list()); - - let transaction = Transaction { + Ok(Transaction { nonce: try!(Decodable::decode(&d[0])), gas_price: try!(Decodable::decode(&d[1])), gas: try!(Decodable::decode(&d[2])), action: try!(Decodable::decode(&d[3])), value: try!(Decodable::decode(&d[4])), data: try!(Decodable::decode(&d[5])), + signature: Signature::from_rsv(&try!(Decodable::decode(&d[6])), &try!(Decodable::decode(&d[7])), try!(u16::decode(&d[8])) as u8), hash: RefCell::new(None) - }; - - Ok(transaction) + }) } } From 7239acc451baaf5bd16e3814738dfeacdb3134e1 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 11 Jan 2016 20:47:19 +0100 Subject: [PATCH 03/10] Transaction address decoding. --- src/error.rs | 6 ++++++ src/executive.rs | 16 ++++++++-------- src/state.rs | 2 +- src/transaction.rs | 8 +++++--- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/error.rs b/src/error.rs index 4b5b1b6f1..2c4e79813 100644 --- a/src/error.rs +++ b/src/error.rs @@ -97,6 +97,12 @@ impl From for Error { } } +impl From for Error { + fn from(err: CryptoError) -> Error { + Error::Util(UtilError::Crypto(err)) + } +} + // TODO: uncomment below once https://github.com/rust-lang/rust/issues/27336 sorted. /*#![feature(concat_idents)] macro_rules! assimilate { diff --git a/src/executive.rs b/src/executive.rs index 6ea0be1cc..06a405c1d 100644 --- a/src/executive.rs +++ b/src/executive.rs @@ -94,24 +94,24 @@ impl<'a> Executive<'a> { } /// This funtion should be used to execute transaction. - pub fn transact(&mut self, t: &Transaction) -> ExecutionResult { + pub fn transact(&mut self, t: &Transaction) -> Result { // TODO: validate transaction signature ?/ sender - let sender = t.sender(); + let sender = try!(t.sender()); let nonce = self.state.nonce(&sender); // validate transaction nonce if t.nonce != nonce { - return Err(ExecutionError::InvalidNonce { expected: nonce, is: t.nonce }); + return Err(From::from(ExecutionError::InvalidNonce { expected: nonce, is: t.nonce })); } // validate if transaction fits into given block if self.info.gas_used + t.gas > self.info.gas_limit { - return Err(ExecutionError::BlockGasLimitReached { + return Err(From::from(ExecutionError::BlockGasLimitReached { gas_limit: self.info.gas_limit, gas_used: self.info.gas_used, gas: t.gas - }); + })); } // TODO: we might need bigints here, or at least check overflows. @@ -121,7 +121,7 @@ impl<'a> Executive<'a> { // avoid unaffordable transactions if balance < total_cost { - return Err(ExecutionError::NotEnoughCash { required: total_cost, is: balance }); + return Err(From::from(ExecutionError::NotEnoughCash { required: total_cost, is: balance })); } // NOTE: there can be no invalid transactions from this point. @@ -160,7 +160,7 @@ impl<'a> Executive<'a> { }; // finalize here! - self.finalize(t, substate, backup, res) + Ok(try!(self.finalize(t, substate, backup, res))) } /// Calls contract function with given contract params. @@ -232,7 +232,7 @@ impl<'a> Executive<'a> { // real ammount to refund let refund = cmp::min(sstore_refunds + suicide_refunds, (t.gas - gas_left) / U256::from(2)) + gas_left; let refund_value = refund * t.gas_price; - self.state.add_balance(&t.sender(), &refund_value); + self.state.add_balance(&t.sender().unwrap(), &refund_value); // fees earned by author let fees = (t.gas - refund) * t.gas_price; diff --git a/src/state.rs b/src/state.rs index cdd861b33..42813ca76 100644 --- a/src/state.rs +++ b/src/state.rs @@ -2,7 +2,7 @@ use common::*; use engine::Engine; use executive::Executive; -pub type ApplyResult = Result; +pub type ApplyResult = Result; /// Representation of the entire state of all accounts in the system. pub struct State { diff --git a/src/transaction.rs b/src/transaction.rs index fcaa39b59..4f2ad5014 100644 --- a/src/transaction.rs +++ b/src/transaction.rs @@ -1,5 +1,6 @@ use util::*; use basic_types::*; +use error::Error; pub enum Action { Create, @@ -48,7 +49,7 @@ impl Transaction { s.out() } - pub fn rlp_sha3_opt(&self, with_seal: Seal) -> H256 { self.rlp_bytes_opt(with_seal).sha3() } + pub fn rlp_sha3_opt(&self, with_seal: Seal) -> H256 { self.rlp_bytes_opt(with_seal).sha3() } } impl RlpStandard for Transaction { @@ -77,8 +78,9 @@ impl Transaction { pub fn action(&self) -> &Action { &self.action } /// Returns transaction sender. - pub fn sender(&self) -> Address { - Address::new() + pub fn sender(&self) -> Result { + let p = try!(ec::recover(&self.signature, &self.rlp_sha3_opt(Seal::Without))); + Ok(From::from(p.sha3())) } } From b9e2d7dabc645f9a1508f2e5676b50fc3c298d28 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 11 Jan 2016 21:57:22 +0100 Subject: [PATCH 04/10] Transaction test and a fix. --- src/transaction.rs | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/src/transaction.rs b/src/transaction.rs index 4f2ad5014..f7a414eab 100644 --- a/src/transaction.rs +++ b/src/transaction.rs @@ -16,7 +16,11 @@ pub struct Transaction { pub action: Action, pub value: U256, pub data: Bytes, - pub signature: Signature, + + // signature + pub v: u8, + pub r: H256, + pub s: H256, hash: RefCell>, //TODO: make this private } @@ -34,11 +38,7 @@ impl Transaction { s.append(&self.value); s.append(&self.data); match with_seal { - Seal::With => { - s.append(&(self.signature.as_slice()[64] as u16)); - s.append(&&self.signature.as_slice()[0..32]); - s.append(&&self.signature.as_slice()[32..64]); - }, + Seal::With => { s.append(&(self.v as u16)).append(&self.r).append(&self.s); }, _ => {} } } @@ -77,11 +77,14 @@ impl Transaction { /// Returns transaction type. pub fn action(&self) -> &Action { &self.action } + /// Construct a signature object from the sig. + pub fn signature(&self) -> Signature { Signature::from_rsv(&self.r, &self.s, self.v - 27) } + + /// The message hash of the transaction. + pub fn message_hash(&self) -> H256 { self.rlp_sha3_opt(Seal::Without) } + /// Returns transaction sender. - pub fn sender(&self) -> Result { - let p = try!(ec::recover(&self.signature, &self.rlp_sha3_opt(Seal::Without))); - Ok(From::from(p.sha3())) - } + pub fn sender(&self) -> Result { Ok(From::from(try!(ec::recover(&self.signature(), &self.message_hash())).sha3())) } } impl Decodable for Action { @@ -105,8 +108,24 @@ impl Decodable for Transaction { action: try!(Decodable::decode(&d[3])), value: try!(Decodable::decode(&d[4])), data: try!(Decodable::decode(&d[5])), - signature: Signature::from_rsv(&try!(Decodable::decode(&d[6])), &try!(Decodable::decode(&d[7])), try!(u16::decode(&d[8])) as u8), + v: try!(u16::decode(&d[6])) as u8, + r: try!(Decodable::decode(&d[7])), + s: try!(Decodable::decode(&d[8])), hash: RefCell::new(None) }) } } + +#[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")); +} \ No newline at end of file From 735202fac02bd7d9f8b9e7a33dad02891317e1ad Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 11 Jan 2016 22:00:25 +0100 Subject: [PATCH 05/10] Minor API reduction. --- src/transaction.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/transaction.rs b/src/transaction.rs index f7a414eab..aff97f226 100644 --- a/src/transaction.rs +++ b/src/transaction.rs @@ -26,6 +26,7 @@ pub struct Transaction { } impl Transaction { + /// Append object into RLP stream, optionally with or without the signature. pub fn rlp_append_opt(&self, s: &mut RlpStream, with_seal: Seal) { s.append_list(6 + match with_seal { Seal::With => 3, _ => 0 }); s.append(&self.nonce); @@ -43,13 +44,12 @@ impl Transaction { } } + /// Get the RLP serialisation of the object, optionally with or without the signature. pub fn rlp_bytes_opt(&self, with_seal: Seal) -> Bytes { let mut s = RlpStream::new(); self.rlp_append_opt(&mut s, with_seal); s.out() } - - pub fn rlp_sha3_opt(&self, with_seal: Seal) -> H256 { self.rlp_bytes_opt(with_seal).sha3() } } impl RlpStandard for Transaction { @@ -81,7 +81,7 @@ impl Transaction { pub fn signature(&self) -> Signature { Signature::from_rsv(&self.r, &self.s, self.v - 27) } /// The message hash of the transaction. - pub fn message_hash(&self) -> H256 { self.rlp_sha3_opt(Seal::Without) } + pub fn message_hash(&self) -> H256 { self.rlp_bytes_opt(Seal::Without).sha3() } /// Returns transaction sender. pub fn sender(&self) -> Result { Ok(From::from(try!(ec::recover(&self.signature(), &self.message_hash())).sha3())) } From 5765fb1069f87adc87ced2d3e819c9cc2a4d1b05 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 12 Jan 2016 01:30:30 +0100 Subject: [PATCH 06/10] Transaction tests passing. --- res/ttTransactionTest.json | 531 +++++++++++++++++++++++++++++++++++++ src/transaction.rs | 102 ++++++- 2 files changed, 630 insertions(+), 3 deletions(-) create mode 100644 res/ttTransactionTest.json diff --git a/res/ttTransactionTest.json b/res/ttTransactionTest.json new file mode 100644 index 000000000..c868d11d0 --- /dev/null +++ b/res/ttTransactionTest.json @@ -0,0 +1,531 @@ +{ + "AddressLessThan20" : { + "blocknumber" : "0", + "rlp" : "0xf8528001825208870b9331677e6ebf0a801ca098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" + }, + "AddressLessThan20Prefixed0" : { + "blocknumber" : "0", + "rlp" : "0xf85f800182520894000000000000000000000000000b9331677e6ebf0a801ca098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3", + "sender" : "31bb58672e8bf7684108feeacf424ab62b873824", + "transaction" : { + "data" : "", + "gasLimit" : "0x5208", + "gasPrice" : "0x01", + "nonce" : "0x00", + "r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", + "s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3", + "to" : "0x000000000000000000000000000b9331677e6ebf", + "v" : "0x1c", + "value" : "0x0a" + } + }, + "AddressMoreThan20" : { + "blocknumber" : "0", + "rlp" : "0xf860800182520895b94f5374fce5edbc8e2a8697c15331677e6ebf0b1c0a801ca098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" + }, + "AddressMoreThan20PrefixedBy0" : { + "blocknumber" : "0", + "rlp" : "0xf867367b8252089c0000000000000000095e7baea6a6c7c4c2dfeb977efac326af552d870b121ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" + }, + "DataTestEnoughGAS" : { + "blocknumber" : "0", + "rlp" : "0xf86d80018259d894095e7baea6a6c7c4c2dfeb977efac326af552d870a8e0358ac39584bc98a7c979f984b031ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "sender" : "ce26839c9bd0e87e38897bb97fca8b340fd12a53", + "transaction" : { + "data" : "0x0358ac39584bc98a7c979f984b03", + "gasLimit" : "0x59d8", + "gasPrice" : "0x01", + "nonce" : "0x00", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "v" : "0x1b", + "value" : "0x0a" + } + }, + "DataTestFirstZeroBytes" : { + "blocknumber" : "0", + "rlp" : "0xf87c80018261a894095e7baea6a6c7c4c2dfeb977efac326af552d870a9d00000000000000000000000000010000000000000000000000000000001ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "sender" : "8131688854fe0dca411aa19572a01fe3e3e4fa74", + "transaction" : { + "data" : "0x000000000000000000000000001000000000000000000000000000000", + "gasLimit" : "0x61a8", + "gasPrice" : "0x01", + "nonce" : "0x00", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "v" : "0x1b", + "value" : "0x0a" + } + }, + "DataTestLastZeroBytes" : { + "blocknumber" : "0", + "rlp" : "0xf87c80018261a894095e7baea6a6c7c4c2dfeb977efac326af552d870a9d00100000000000000000000000000000000000000000000000000000001ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "sender" : "ead53a9560ea38feb0bc2cad8ef65e5d8f990fc1", + "transaction" : { + "data" : "0x010000000000000000000000000000000000000000000000000000000", + "gasLimit" : "0x61a8", + "gasPrice" : "0x01", + "nonce" : "0x00", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "v" : "0x1b", + "value" : "0x0a" + } + }, + "DataTestNotEnoughGAS" : { + "blocknumber" : "0", + "rlp" : "0xf86d800182521c94095e7baea6a6c7c4c2dfeb977efac326af552d870a8e0358ac39584bc98a7c979f984b031ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" + }, + "DataTestZeroBytes" : { + "blocknumber" : "0", + "rlp" : "0xf87c80018261a894095e7baea6a6c7c4c2dfeb977efac326af552d870a9d00000000000000000000000000000000000000000000000000000000001ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "sender" : "b7ab01c0f092d30aeed17e23adb7aa5a9b2ee077", + "transaction" : { + "data" : "0x000000000000000000000000000000000000000000000000000000000", + "gasLimit" : "0x61a8", + "gasPrice" : "0x01", + "nonce" : "0x00", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "v" : "0x1b", + "value" : "0x0a" + } + }, + "EmptyTransaction" : { + "blocknumber" : "0", + "rlp" : "0xf85d80808094095e7baea6a6c7c4c2dfeb977efac326af552d8780801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" + }, + "NotEnoughGasLimit" : { + "blocknumber" : "0", + "rlp" : "0xf85f0301824e2094b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a801ca098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" + }, + "RSsecp256k1" : { + "blocknumber" : "0", + "rlp" : "0xf85f030182520894b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a801ca0fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141a0fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141" + }, + "RightVRSTest" : { + "blocknumber" : "0", + "rlp" : "0xf85f030182520894b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a801ca098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3", + "sender" : "fa7f04899691becd07dd3081d0a2f3ee7640af52", + "transaction" : { + "data" : "0x", + "gasLimit" : "0x5208", + "gasPrice" : "0x01", + "nonce" : "0x03", + "r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", + "s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3", + "to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "v" : "0x1c", + "value" : "0x0a" + } + }, + "SenderTest" : { + "blocknumber" : "0", + "rlp" : "0xf85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "sender" : "0f65fe9276bc9a24ae7083ae28e2660ef72df99e", + "senderExpect" : "sender 0f65fe9276bc9a24ae7083ae28e2660ef72df99e", + "transaction" : { + "data" : "", + "gasLimit" : "0x5208", + "gasPrice" : "0x01", + "nonce" : "0x00", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "v" : "0x1b", + "value" : "0x0a" + } + }, + "TransactionWithGasLimitOverflow" : { + "blocknumber" : "0", + "rlp" : "0xf87e807ba101000000000000000000000000000000000000000000000000000000000000000094095e7baea6a6c7c4c2dfeb977efac326af552d870b801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" + }, + "TransactionWithGasLimitxPriceOverflow" : { + "blocknumber" : "0", + "rlp" : "0xf8858088016345785d8a0000a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff94095e7baea6a6c7c4c2dfeb977efac326af552d8780801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "sender" : "700764607c82cf3e9cf4ecbd49185f8914f1a361", + "transaction" : { + "data" : "", + "gasLimit" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "gasPrice" : "0x016345785d8a0000", + "nonce" : "0x00", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "v" : "0x1b", + "value" : "0x00" + } + }, + "TransactionWithGasPriceOverflow" : { + "blocknumber" : "0", + "rlp" : "0xf88080a101000000000000000000000000000000000000000000000000000000000000000082520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" + }, + "TransactionWithHighValueOverflow" : { + "blocknumber" : "0", + "rlp" : "0xf880800182520894095e7baea6a6c7c4c2dfeb977efac326af552d87a1010000000000000000000000000000000000000000000000000000000000000000801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" + }, + "TransactionWithHihghGas" : { + "blocknumber" : "0", + "rlp" : "0xf87d8001a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff94095e7baea6a6c7c4c2dfeb977efac326af552d8780801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "sender" : "9e92c26895f279d68ad7b57b803dc522717d5572", + "transaction" : { + "data" : "", + "gasLimit" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "gasPrice" : "0x01", + "nonce" : "0x00", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "v" : "0x1b", + "value" : "0x00" + } + }, + "TransactionWithHihghGasPrice" : { + "blocknumber" : "0", + "rlp" : "0xf87f80a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82520894095e7baea6a6c7c4c2dfeb977efac326af552d8780801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "sender" : "b10eac078276dc8dbf1753715396d480156236f8", + "transaction" : { + "data" : "", + "gasLimit" : "0x5208", + "gasPrice" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "nonce" : "0x00", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "v" : "0x1b", + "value" : "0x00" + } + }, + "TransactionWithHihghNonce256" : { + "blocknumber" : "0", + "rlp" : "0xf87fa0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0182520894095e7baea6a6c7c4c2dfeb977efac326af552d8780801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "sender" : "9b96002788562fefd5ac08d5af877fa738272dc7", + "transaction" : { + "data" : "", + "gasLimit" : "0x5208", + "gasPrice" : "0x01", + "nonce" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "v" : "0x1b", + "value" : "0x00" + } + }, + "TransactionWithHihghNonce32" : { + "blocknumber" : "0", + "rlp" : "0xf8648501000000000182520894095e7baea6a6c7c4c2dfeb977efac326af552d8780801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "sender" : "e86dc346fd8debf719486ff2f9c4c629fe58fc46", + "transaction" : { + "data" : "", + "gasLimit" : "0x5208", + "gasPrice" : "0x01", + "nonce" : "0x0100000000", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "v" : "0x1b", + "value" : "0x00" + } + }, + "TransactionWithHihghValue" : { + "blocknumber" : "0", + "rlp" : "0xf87f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d87a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "sender" : "396bd0363e26195eeacfedbe54c44f16fbe470b6", + "transaction" : { + "data" : "", + "gasLimit" : "0x5208", + "gasPrice" : "0x01", + "nonce" : "0x00", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "v" : "0x1b", + "value" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + } + }, + "TransactionWithNonceOverflow" : { + "blocknumber" : "0", + "rlp" : "0xf880a10100000000000000000000000000000000000000000000000000000000000000000182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" + }, + "TransactionWithRSvalue0" : { + "blocknumber" : "0", + "rlp" : "0xdf800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801b8080" + }, + "TransactionWithRSvalue1" : { + "blocknumber" : "0", + "rlp" : "0xdf800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801b0101", + "sender" : "98c188f183d4e93ff2bffadd145f39b4a792ed85", + "transaction" : { + "data" : "", + "gasLimit" : "0x5208", + "gasPrice" : "0x01", + "nonce" : "0x00", + "r" : "0x01", + "s" : "0x01", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "v" : "0x1b", + "value" : "0x0b" + } + }, + "TransactionWithRvalue0" : { + "blocknumber" : "0", + "rlp" : "0xf83f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801b80a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" + }, + "TransactionWithRvalue1" : { + "blocknumber" : "0", + "rlp" : "0xf83f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801b01a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "sender" : "421ba7ba39c1c2ddb98308deca3af1dd9e461740", + "transaction" : { + "data" : "", + "gasLimit" : "0x5208", + "gasPrice" : "0x01", + "nonce" : "0x00", + "r" : "0x01", + "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "v" : "0x1b", + "value" : "0x0b" + } + }, + "TransactionWithRvalueHigh" : { + "blocknumber" : "0", + "rlp" : "0xf85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801ba0fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140a08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" + }, + "TransactionWithRvalueOverflow" : { + "blocknumber" : "0", + "rlp" : "0xf861800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801ba2fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641410000a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" + }, + "TransactionWithRvaluePrefixed00" : { + "blocknumber" : "0", + "rlp" : "0xf850800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801b910ebaaedce6af48a03bbfd25e8cd0364141a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "sender" : "0dd0dcb6502a463fa90ecaa59ca29a5e6571deef", + "transaction" : { + "data" : "", + "gasLimit" : "0x5208", + "gasPrice" : "0x01", + "nonce" : "0x00", + "r" : "0xebaaedce6af48a03bbfd25e8cd0364141", + "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "v" : "0x1b", + "value" : "0x0b" + } + }, + "TransactionWithRvalueTooHigh" : { + "blocknumber" : "0", + "rlp" : "0xf85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801ba0fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" + }, + "TransactionWithSvalue0" : { + "blocknumber" : "0", + "rlp" : "0xf83f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a3664935380" + }, + "TransactionWithSvalue1" : { + "blocknumber" : "0", + "rlp" : "0xf83f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a3664935301", + "sender" : "e115cf6bb5656786569dd273705242ca72d84bc0", + "transaction" : { + "data" : "", + "gasLimit" : "0x5208", + "gasPrice" : "0x01", + "nonce" : "0x00", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0x01", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "v" : "0x1b", + "value" : "0x0b" + } + }, + "TransactionWithSvalueEqual_c_secp256k1n_x05" : { + "blocknumber" : "0", + "rlp" : "0xf85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a07fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0", + "sender" : "b284109d8e781949638d995c19f8feba0268191c", + "transaction" : { + "data" : "", + "gasLimit" : "0x5208", + "gasPrice" : "0x01", + "nonce" : "0x00", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "v" : "0x1b", + "value" : "0x0b" + } + }, + "TransactionWithSvalueHigh" : { + "blocknumber" : "0", + "rlp" : "0xf85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", + "sender" : "474869ba435affa1f45aaada48520880921c0887", + "transaction" : { + "data" : "", + "gasLimit" : "0x5208", + "gasPrice" : "0x01", + "nonce" : "0x00", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "v" : "0x1b", + "value" : "0x0b" + } + }, + "TransactionWithSvalueLargerThan_c_secp256k1n_x05" : { + "blocknumber" : "0", + "rlp" : "0xf85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a07fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a1", + "sender" : "5ced92a94a7bfd7853b12d33ee59dd10ae94eb86", + "transaction" : { + "data" : "", + "gasLimit" : "0x5208", + "gasPrice" : "0x01", + "nonce" : "0x00", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a1", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "v" : "0x1b", + "value" : "0x0b" + } + }, + "TransactionWithSvalueLessThan_c_secp256k1n_x05" : { + "blocknumber" : "0", + "rlp" : "0xf85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a07fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b2090", + "sender" : "33e931e187e9cb5b6f8560755519d54560dd63e8", + "transaction" : { + "data" : "", + "gasLimit" : "0x5208", + "gasPrice" : "0x01", + "nonce" : "0x00", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b2090", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "v" : "0x1b", + "value" : "0x0b" + } + }, + "TransactionWithSvalueOverflow" : { + "blocknumber" : "0", + "rlp" : "0xf861800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a2fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f0000" + }, + "TransactionWithSvaluePrefixed00" : { + "blocknumber" : "0", + "rlp" : "0xf851800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801ba098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a920ef0b28ad43601b4ab949f53faa07bd2c804", + "sender" : "a825d77f343f31619c991cd7db5aaa6adbe9452e", + "transaction" : { + "data" : "", + "gasLimit" : "0x5208", + "gasPrice" : "0x01", + "nonce" : "0x00", + "r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", + "s" : "0xef0b28ad43601b4ab949f53faa07bd2c804", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "v" : "0x1b", + "value" : "0x0b" + } + }, + "TransactionWithSvalueTooHigh" : { + "blocknumber" : "0", + "rlp" : "0xf85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141" + }, + "TransactionWithTooFewRLPElements" : { + "blocknumber" : "0", + "rlp" : "0xf85b800194095e7baea6a6c7c4c2dfeb977efac326af552d87801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" + }, + "TransactionWithTooManyRLPElements" : { + "blocknumber" : "0", + "rlp" : "0xf865800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804851de98d0edd" + }, + "V_overflow32bit" : { + "blocknumber" : "0", + "rlp" : "0xf866030182520894b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a82554485010000001ba098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" + }, + "V_overflow32bitSigned" : { + "blocknumber" : "0", + "rlp" : "0xf865030182520894b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a825544847fffffffa098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" + }, + "V_overflow64bitPlus27" : { + "blocknumber" : "0", + "rlp" : "0xf86a03018255f094b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a8255448901000000000000001ba098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" + }, + "V_overflow64bitPlus28" : { + "blocknumber" : "0", + "rlp" : "0xf86a03018255f094b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a8255448901000000000000001ca098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" + }, + "V_overflow64bitSigned" : { + "blocknumber" : "0", + "rlp" : "0xf869030182520894b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a82554488ffffffffffffff1ca098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" + }, + "WrongVRSTestIncorrectSize" : { + "blocknumber" : "0", + "rlp" : "0xf863800182520894b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a801ca298ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a02c3a28887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a302c3" + }, + "WrongVRSTestVEqual26" : { + "blocknumber" : "0", + "rlp" : "0xf85f800182520894b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a801aa098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" + }, + "WrongVRSTestVEqual29" : { + "blocknumber" : "0", + "rlp" : "0xf85f800182520894b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a801da098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" + }, + "WrongVRSTestVEqual31" : { + "blocknumber" : "0", + "rlp" : "0xf85f800182520894b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a801fa098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" + }, + "WrongVRSTestVOverflow" : { + "blocknumber" : "0", + "rlp" : "0xf861800182520894b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a80820136a098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" + }, + "dataTx_bcValidBlockTest" : { + "blocknumber" : "0", + "rlp" : "0xf901fb803282c3508080b901ae60056013565b6101918061001d6000396000f35b3360008190555056006001600060e060020a6000350480630a874df61461003a57806341c0e1b514610058578063a02b161e14610066578063dbbdf0831461007757005b610045600435610149565b80600160a060020a031660005260206000f35b610060610161565b60006000f35b6100716004356100d4565b60006000f35b61008560043560243561008b565b60006000f35b600054600160a060020a031632600160a060020a031614156100ac576100b1565b6100d0565b8060018360005260205260406000208190555081600060005260206000a15b5050565b600054600160a060020a031633600160a060020a031614158015610118575033600160a060020a0316600182600052602052604060002054600160a060020a031614155b61012157610126565b610146565b600060018260005260205260406000208190555080600060005260206000a15b50565b60006001826000526020526040600020549050919050565b600054600160a060020a031633600160a060020a0316146101815761018f565b600054600160a060020a0316ff5b561ca0c5689ed1ad124753d54576dfb4b571465a41900a1dff4058d8adf16f752013d0a0e221cbd70ec28c94a3b55ec771bcbc70778d6ee0b51ca7ea9514594c861b1884", + "sender" : "a94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "transaction" : { + "data" : "0x60056013565b6101918061001d6000396000f35b3360008190555056006001600060e060020a6000350480630a874df61461003a57806341c0e1b514610058578063a02b161e14610066578063dbbdf0831461007757005b610045600435610149565b80600160a060020a031660005260206000f35b610060610161565b60006000f35b6100716004356100d4565b60006000f35b61008560043560243561008b565b60006000f35b600054600160a060020a031632600160a060020a031614156100ac576100b1565b6100d0565b8060018360005260205260406000208190555081600060005260206000a15b5050565b600054600160a060020a031633600160a060020a031614158015610118575033600160a060020a0316600182600052602052604060002054600160a060020a031614155b61012157610126565b610146565b600060018260005260205260406000208190555080600060005260206000a15b50565b60006001826000526020526040600020549050919050565b600054600160a060020a031633600160a060020a0316146101815761018f565b600054600160a060020a0316ff5b56", + "gasLimit" : "0xc350", + "gasPrice" : "0x32", + "nonce" : "0x00", + "r" : "0xc5689ed1ad124753d54576dfb4b571465a41900a1dff4058d8adf16f752013d0", + "s" : "0xe221cbd70ec28c94a3b55ec771bcbc70778d6ee0b51ca7ea9514594c861b1884", + "to" : "", + "v" : "0x1c", + "value" : "0x00" + } + }, + "invalidSignature" : { + "blocknumber" : "0", + "rlp" : "0xf8638080830f424094095e7baea6a6c7c4c2dfeb977efac326af552d87830186a0801ba0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0badf00d70ec28c94a3b55ec771bcbc70778d6ee0b51ca7ea9514594c861b1884" + }, + "libsecp256k1test" : { + "blocknumber" : "0", + "rlp" : "0xd1808609184e72a00082f3888080801b2c04", + "sender" : "170ad78f26da62f591fa3fe3d54c30016167cbbf", + "transaction" : { + "data" : "0x", + "gasLimit" : "0xf388", + "gasPrice" : "0x09184e72a000", + "nonce" : "0x00", + "r" : "0x2c", + "s" : "0x04", + "to" : "", + "v" : "0x1b", + "value" : "0x00" + } + }, + "unpadedRValue" : { + "blocknumber" : "0", + "rlp" : "0xf8880d8609184e72a00082f710947c47ef93268a311f4cad0c750724299e9b72c26880a4379607f500000000000000000000000000000000000000000000000000000000000000051c9f6ab6dda9f4df56ea45583af36660329147f1753f3724ea5eb9ed83e812ca77a0495701e230667832c8999e884e366a61028633ecf951e8cd66d119f381ae5718", + "sender" : "c1584838993ee7a9581cba0bced81785e8bb581d", + "transaction" : { + "data" : "0x379607f50000000000000000000000000000000000000000000000000000000000000005", + "gasLimit" : "0xf710", + "gasPrice" : "0x09184e72a000", + "nonce" : "0x0d", + "r" : "0x006ab6dda9f4df56ea45583af36660329147f1753f3724ea5eb9ed83e812ca77", + "s" : "0x495701e230667832c8999e884e366a61028633ecf951e8cd66d119f381ae5718", + "to" : "7c47ef93268a311f4cad0c750724299e9b72c268", + "v" : "0x1c", + "value" : "0x00" + } + } +} \ No newline at end of file diff --git a/src/transaction.rs b/src/transaction.rs index aff97f226..4d93fc6b3 100644 --- a/src/transaction.rs +++ b/src/transaction.rs @@ -1,6 +1,7 @@ use util::*; use basic_types::*; use error::Error; +use evm::Schedule; pub enum Action { Create, @@ -19,8 +20,8 @@ pub struct Transaction { // signature pub v: u8, - pub r: H256, - pub s: H256, + pub r: U256, + pub s: U256, hash: RefCell>, //TODO: make this private } @@ -77,14 +78,31 @@ impl Transaction { /// Returns transaction type. pub fn action(&self) -> &Action { &self.action } + /// 0 is `v` is 27, 1 if 28, and 4 otherwise. + pub fn standard_v(&self) -> u8 { match self.v { 27 => 0, 28 => 1, _ => 4 } } + /// Construct a signature object from the sig. - pub fn signature(&self) -> Signature { Signature::from_rsv(&self.r, &self.s, self.v - 27) } + pub fn signature(&self) -> Signature { Signature::from_rsv(&From::from(&self.r), &From::from(&self.s), self.standard_v()) } /// The message hash of the transaction. pub fn message_hash(&self) -> H256 { self.rlp_bytes_opt(Seal::Without).sha3() } /// Returns transaction sender. pub fn sender(&self) -> Result { Ok(From::from(try!(ec::recover(&self.signature(), &self.message_hash())).sha3())) } + + /// Get the transaction cost in gas for the given params. + pub fn gas_required_for(is_create: bool, data: &[u8], schedule: &Schedule, gas: &U256) -> U256 { + // CRITICAL TODO XXX FIX NEED BIGINT!!!!! + data.iter().fold( + U256::from(if is_create {schedule.tx_create_gas} else {schedule.tx_gas}) + *gas, + |g, b| g + U256::from(match *b { 0 => schedule.tx_data_zero_gas, _ => schedule.tx_data_non_zero_gas}) + ) + } + + /// Get the transaction cost in gas for this transaction + pub fn gas_required(&self, schedule: &Schedule, gas: &U256) -> U256 { + Self::gas_required_for(match self.action{Action::Create=>true, Action::Call(_)=>false}, &self.data, schedule, gas) + } } impl Decodable for Action { @@ -101,6 +119,9 @@ impl Decodable for Action { impl Decodable for Transaction { fn decode(decoder: &D) -> Result where D: Decoder { let d = try!(decoder.as_list()); + if d.len() != 9 { + return Err(DecoderError::RlpIncorrectListLen); + } Ok(Transaction { nonce: try!(Decodable::decode(&d[0])), gas_price: try!(Decodable::decode(&d[1])), @@ -128,4 +149,79 @@ fn sender_test() { } 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..] + } else { + s + } +} + +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() + } else { + FromHex::from_hex(clean(s)).unwrap() + } +} + +pub fn address_from_json(json: &Json) -> Address { + let s = json.as_string().unwrap(); + if s.len() % 2 == 1 { + address_from_hex(&("0".to_string() + &(clean(s).to_string()))[..]) + } else { + address_from_hex(clean(s)) + } +} + +pub fn u256_from_json(json: &Json) -> U256 { + let s = json.as_string().unwrap(); + if s.len() >= 2 && &s[0..2] == "0x" { + // hex + U256::from_str(&s[2..]).unwrap() + } + else { + // dec + U256::from_dec_str(s).unwrap() + } +} + +#[test] +fn json_tests() { + 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 _ = BlockNumber::from_str(test["blocknumber"].as_string().unwrap()).unwrap(); + let rlp = bytes_from_json(&test["rlp"]); + let r: Result = UntrustedRlp::new(&rlp).as_val(); + if let Ok(t) = r { + if t.sender().is_ok() && t.gas >= t.gas_required(&schedule, &U256::zero()) { + if let (Some(&Json::Object(ref tx)), Some(&Json::String(ref expect_sender))) = (test.find("transaction"), test.find("sender")) { + assert_eq!(t.sender().unwrap(), address_from_hex(clean(expect_sender))); + assert_eq!(t.data, bytes_from_json(&tx["data"])); + assert_eq!(t.gas, u256_from_json(&tx["gasLimit"])); + assert_eq!(t.gas_price, u256_from_json(&tx["gasPrice"])); + assert_eq!(t.nonce, u256_from_json(&tx["nonce"])); + assert_eq!(t.value, u256_from_json(&tx["value"])); + if let Action::Call(ref to) = t.action { + assert_eq!(to, &address_from_json(&tx["to"])); + } else { + assert_eq!(bytes_from_json(&tx["to"]).len(), 0); + } + } + else { failed.push(name.to_string()); } + } + else if test.find("transaction").is_some() { failed.push(name.to_string()); } + } + else if test.find("transaction").is_some() { failed.push(name.to_string()); } + } + for f in failed.iter() { + println!("FAILED: {:?}", f); + } + assert!(failed.len() == 0); } \ No newline at end of file From 8970ef572e7ac6a0a959298943887167fa5f16c4 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 12 Jan 2016 01:41:47 +0100 Subject: [PATCH 07/10] Slightly cleaner test code. --- src/transaction.rs | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/transaction.rs b/src/transaction.rs index 4d93fc6b3..082a0977f 100644 --- a/src/transaction.rs +++ b/src/transaction.rs @@ -196,29 +196,31 @@ fn json_tests() { 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 r: Result = UntrustedRlp::new(&rlp).as_val(); if let Ok(t) = r { if t.sender().is_ok() && t.gas >= t.gas_required(&schedule, &U256::zero()) { if let (Some(&Json::Object(ref tx)), Some(&Json::String(ref expect_sender))) = (test.find("transaction"), test.find("sender")) { - assert_eq!(t.sender().unwrap(), address_from_hex(clean(expect_sender))); - assert_eq!(t.data, bytes_from_json(&tx["data"])); - assert_eq!(t.gas, u256_from_json(&tx["gasLimit"])); - assert_eq!(t.gas_price, u256_from_json(&tx["gasPrice"])); - assert_eq!(t.nonce, u256_from_json(&tx["nonce"])); - assert_eq!(t.value, u256_from_json(&tx["value"])); + 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 { - assert_eq!(to, &address_from_json(&tx["to"])); + fail_unless(to == &address_from_json(&tx["to"])); } else { - assert_eq!(bytes_from_json(&tx["to"]).len(), 0); + fail_unless(bytes_from_json(&tx["to"]).len() == 0); } } - else { failed.push(name.to_string()); } + else { fail_unless(false) } } - else if test.find("transaction").is_some() { failed.push(name.to_string()); } + else { fail_unless(test.find("transaction").is_none()) } } - else if test.find("transaction").is_some() { failed.push(name.to_string()); } + else { fail_unless(test.find("transaction").is_none()) } } for f in failed.iter() { println!("FAILED: {:?}", f); From df3db60ec080b4780ca2f5fcfe39518060d0c444 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 12 Jan 2016 11:44:16 +0100 Subject: [PATCH 08/10] Nicer transaction validation API. Nicer OutOfBounds API in general. --- src/block.rs | 4 +-- src/error.rs | 22 +++++++++++++++-- src/ethereum/ethash.rs | 6 ++--- src/transaction.rs | 55 +++++++++++++++++++++++------------------- src/verification.rs | 14 +++++------ 5 files changed, 62 insertions(+), 39 deletions(-) diff --git a/src/block.rs b/src/block.rs index b683ab159..ce125b8df 100644 --- a/src/block.rs +++ b/src/block.rs @@ -129,7 +129,7 @@ impl<'x, 'y> OpenBlock<'x, 'y> { /// Alter the extra_data for the block. pub fn set_extra_data(&mut self, extra_data: Bytes) -> Result<(), BlockError> { if extra_data.len() > self.engine.maximum_extra_data_size() { - Err(BlockError::ExtraDataOutOfBounds(OutOfBounds{min: 0, max: self.engine.maximum_extra_data_size(), found: extra_data.len()})) + Err(BlockError::ExtraDataOutOfBounds(OutOfBounds{min: None, max: Some(self.engine.maximum_extra_data_size()), found: extra_data.len()})) } else { self.block.header.set_extra_data(extra_data); Ok(()) @@ -142,7 +142,7 @@ impl<'x, 'y> OpenBlock<'x, 'y> { /// that the header itself is actually valid. pub fn push_uncle(&mut self, valid_uncle_header: Header) -> Result<(), BlockError> { if self.block.uncles.len() >= self.engine.maximum_uncle_count() { - return Err(BlockError::TooManyUncles(OutOfBounds{min: 0, max: self.engine.maximum_uncle_count(), found: self.block.uncles.len()})); + return Err(BlockError::TooManyUncles(OutOfBounds{min: None, max: Some(self.engine.maximum_uncle_count()), found: self.block.uncles.len()})); } // TODO: check number // TODO: check not a direct ancestor (use last_hashes for that) diff --git a/src/error.rs b/src/error.rs index 2c4e79813..85349c25c 100644 --- a/src/error.rs +++ b/src/error.rs @@ -11,8 +11,8 @@ pub struct Mismatch { #[derive(Debug)] pub struct OutOfBounds { - pub min: T, - pub max: T, + pub min: Option, + pub max: Option, pub found: T, } @@ -33,6 +33,11 @@ pub enum ExecutionError { Internal } +#[derive(Debug)] +pub enum TransactionError { + InvalidGasLimit(OutOfBounds), +} + #[derive(Debug)] pub enum BlockError { TooManyUncles(OutOfBounds), @@ -83,6 +88,13 @@ pub enum Error { Block(BlockError), UnknownEngineName(String), Execution(ExecutionError), + Transaction(TransactionError), +} + +impl From for Error { + fn from(err: TransactionError) -> Error { + Error::Transaction(err) + } } impl From for Error { @@ -103,6 +115,12 @@ impl From for Error { } } +impl From for Error { + fn from(err: DecoderError) -> Error { + Error::Util(UtilError::Decoder(err)) + } +} + // TODO: uncomment below once https://github.com/rust-lang/rust/issues/27336 sorted. /*#![feature(concat_idents)] macro_rules! assimilate { diff --git a/src/ethereum/ethash.rs b/src/ethereum/ethash.rs index d3a64d723..f3c4ad170 100644 --- a/src/ethereum/ethash.rs +++ b/src/ethereum/ethash.rs @@ -53,11 +53,11 @@ impl Engine for Ethash { } let min_gas_limit = decode(self.spec().engine_params.get("minGasLimit").unwrap()); if header.gas_limit < min_gas_limit { - return Err(From::from(BlockError::InvalidGasLimit(OutOfBounds { min: min_gas_limit, max: From::from(0), found: header.gas_limit }))); + return Err(From::from(BlockError::InvalidGasLimit(OutOfBounds { min: Some(min_gas_limit), max: None, found: header.gas_limit }))); } let maximum_extra_data_size = self.maximum_extra_data_size(); if header.number != 0 && header.extra_data.len() > maximum_extra_data_size { - return Err(From::from(BlockError::ExtraDataOutOfBounds(OutOfBounds { min: 0, max: maximum_extra_data_size, found: header.extra_data.len() }))); + return Err(From::from(BlockError::ExtraDataOutOfBounds(OutOfBounds { min: None, max: Some(maximum_extra_data_size), found: header.extra_data.len() }))); } // TODO: Verify seal (quick) Ok(()) @@ -78,7 +78,7 @@ impl Engine for Ethash { let min_gas = parent.gas_limit - parent.gas_limit / gas_limit_divisor; let max_gas = parent.gas_limit + parent.gas_limit / gas_limit_divisor; if header.gas_limit <= min_gas || header.gas_limit >= max_gas { - return Err(From::from(BlockError::InvalidGasLimit(OutOfBounds { min: min_gas, max: max_gas, found: header.gas_limit }))); + return Err(From::from(BlockError::InvalidGasLimit(OutOfBounds { min: Some(min_gas), max: Some(max_gas), found: header.gas_limit }))); } Ok(()) } diff --git a/src/transaction.rs b/src/transaction.rs index 082a0977f..43bd2f1d9 100644 --- a/src/transaction.rs +++ b/src/transaction.rs @@ -1,6 +1,6 @@ use util::*; use basic_types::*; -use error::Error; +use error::*; use evm::Schedule; pub enum Action { @@ -91,17 +91,27 @@ impl Transaction { pub fn sender(&self) -> Result { Ok(From::from(try!(ec::recover(&self.signature(), &self.message_hash())).sha3())) } /// Get the transaction cost in gas for the given params. - pub fn gas_required_for(is_create: bool, data: &[u8], schedule: &Schedule, gas: &U256) -> U256 { + pub fn gas_required_for(is_create: bool, data: &[u8], schedule: &Schedule) -> U256 { // CRITICAL TODO XXX FIX NEED BIGINT!!!!! data.iter().fold( - U256::from(if is_create {schedule.tx_create_gas} else {schedule.tx_gas}) + *gas, + U256::from(if is_create {schedule.tx_create_gas} else {schedule.tx_gas}), |g, b| g + U256::from(match *b { 0 => schedule.tx_data_zero_gas, _ => schedule.tx_data_non_zero_gas}) ) } - /// Get the transaction cost in gas for this transaction - pub fn gas_required(&self, schedule: &Schedule, gas: &U256) -> U256 { - Self::gas_required_for(match self.action{Action::Create=>true, Action::Call(_)=>false}, &self.data, schedule, gas) + /// Get the transaction cost in gas for this transaction. + pub fn gas_required(&self, schedule: &Schedule) -> U256 { + Self::gas_required_for(match self.action{Action::Create=>true, Action::Call(_)=>false}, &self.data, schedule) + } + + /// Do basic validation, checking for valid signature and minimum gas, + pub fn validate(self, schedule: &Schedule) -> Result { + try!(self.sender()); + if self.gas < self.gas_required(&schedule) { + Err(From::from(TransactionError::InvalidGasLimit(OutOfBounds{min: Some(self.gas_required(&schedule)), max: None, found: self.gas}))) + } else { + Ok(self) + } } } @@ -200,27 +210,22 @@ fn json_tests() { 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 r: Result = UntrustedRlp::new(&rlp).as_val(); - if let Ok(t) = r { - if t.sender().is_ok() && t.gas >= t.gas_required(&schedule, &U256::zero()) { - if let (Some(&Json::Object(ref tx)), Some(&Json::String(ref expect_sender))) = (test.find("transaction"), test.find("sender")) { - 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); - } - } - else { fail_unless(false) } + 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); } - else { fail_unless(test.find("transaction").is_none()) } } - else { fail_unless(test.find("transaction").is_none()) } } for f in failed.iter() { println!("FAILED: {:?}", f); diff --git a/src/verification.rs b/src/verification.rs index be885162a..1f7125e6f 100644 --- a/src/verification.rs +++ b/src/verification.rs @@ -47,7 +47,7 @@ pub fn verify_block_final(bytes: &[u8], engine: &Engine, bc: &BlockChain) -> Res let num_uncles = Rlp::new(bytes).at(2).item_count(); if num_uncles != 0 { if num_uncles > engine.maximum_uncle_count() { - return Err(From::from(BlockError::TooManyUncles(OutOfBounds { min: 0, max: engine.maximum_uncle_count(), found: num_uncles }))); + return Err(From::from(BlockError::TooManyUncles(OutOfBounds { min: None, max: Some(engine.maximum_uncle_count()), found: num_uncles }))); } let mut excluded = HashSet::new(); @@ -83,10 +83,10 @@ pub fn verify_block_final(bytes: &[u8], engine: &Engine, bc: &BlockChain) -> Res let depth = if header.number > uncle.number { header.number - uncle.number } else { 0 }; if depth > 6 { - return Err(From::from(BlockError::UncleTooOld(OutOfBounds { min: header.number - depth, max: header.number - 1, found: uncle.number }))); + return Err(From::from(BlockError::UncleTooOld(OutOfBounds { min: Some(header.number - depth), max: Some(header.number - 1), found: uncle.number }))); } else if depth < 1 { - return Err(From::from(BlockError::UncleIsBrother(OutOfBounds { min: header.number - depth, max: header.number - 1, found: uncle.number }))); + return Err(From::from(BlockError::UncleIsBrother(OutOfBounds { min: Some(header.number - depth), max: Some(header.number - 1), found: uncle.number }))); } // cB @@ -115,10 +115,10 @@ pub fn verify_block_final(bytes: &[u8], engine: &Engine, bc: &BlockChain) -> Res /// Check basic header parameters. fn verify_header(header: &Header) -> Result<(), Error> { if header.number > From::from(BlockNumber::max_value()) { - return Err(From::from(BlockError::InvalidNumber(OutOfBounds { max: From::from(BlockNumber::max_value()), min: 0, found: header.number }))) + return Err(From::from(BlockError::InvalidNumber(OutOfBounds { max: Some(From::from(BlockNumber::max_value())), min: None, found: header.number }))) } if header.gas_used > header.gas_limit { - return Err(From::from(BlockError::TooMuchGasUsed(OutOfBounds { max: header.gas_limit, min: From::from(0), found: header.gas_used }))); + return Err(From::from(BlockError::TooMuchGasUsed(OutOfBounds { max: Some(header.gas_limit), min: None, found: header.gas_used }))); } Ok(()) } @@ -129,10 +129,10 @@ fn verify_parent(header: &Header, parent: &Header) -> Result<(), Error> { return Err(From::from(BlockError::InvalidParentHash(Mismatch { expected: parent.hash(), found: header.parent_hash.clone() }))) } if header.timestamp <= parent.timestamp { - return Err(From::from(BlockError::InvalidTimestamp(OutOfBounds { max: u64::max_value(), min: parent.timestamp + 1, found: header.timestamp }))) + return Err(From::from(BlockError::InvalidTimestamp(OutOfBounds { max: None, min: Some(parent.timestamp + 1), found: header.timestamp }))) } if header.number <= parent.number { - return Err(From::from(BlockError::InvalidNumber(OutOfBounds { max: BlockNumber::max_value(), min: parent.number + 1, found: header.number }))); + return Err(From::from(BlockError::InvalidNumber(OutOfBounds { max: None, min: Some(parent.number + 1), found: header.number }))); } Ok(()) } From 7634d60a9779d9e3ccc4639190d1a37b288a6413 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 12 Jan 2016 12:22:18 +0100 Subject: [PATCH 09/10] Add tests module, add two more transaction tests. --- .gitmodules | 3 + .../res => res/ethereum}/frontier.json | 0 .../res => res/ethereum}/frontier_test.json | 0 .../res => res/ethereum}/homestead_test.json | 0 .../ethereum/res => res/ethereum}/morden.json | 0 .../res => res/ethereum}/olympic.json | 0 res/ethereum/tests | 1 + res/ttTransactionTest.json | 531 ------------------ src/ethereum/mod.rs | 10 +- src/transaction.rs | 108 ++-- 10 files changed, 73 insertions(+), 580 deletions(-) create mode 100644 .gitmodules rename {src/ethereum/res => res/ethereum}/frontier.json (100%) rename {src/ethereum/res => res/ethereum}/frontier_test.json (100%) rename {src/ethereum/res => res/ethereum}/homestead_test.json (100%) rename {src/ethereum/res => res/ethereum}/morden.json (100%) rename {src/ethereum/res => res/ethereum}/olympic.json (100%) create mode 160000 res/ethereum/tests delete mode 100644 res/ttTransactionTest.json diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000..84843f000 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "res/ethereum/tests"] + path = res/ethereum/tests + url = git@github.com:ethereum/tests diff --git a/src/ethereum/res/frontier.json b/res/ethereum/frontier.json similarity index 100% rename from src/ethereum/res/frontier.json rename to res/ethereum/frontier.json diff --git a/src/ethereum/res/frontier_test.json b/res/ethereum/frontier_test.json similarity index 100% rename from src/ethereum/res/frontier_test.json rename to res/ethereum/frontier_test.json diff --git a/src/ethereum/res/homestead_test.json b/res/ethereum/homestead_test.json similarity index 100% rename from src/ethereum/res/homestead_test.json rename to res/ethereum/homestead_test.json diff --git a/src/ethereum/res/morden.json b/res/ethereum/morden.json similarity index 100% rename from src/ethereum/res/morden.json rename to res/ethereum/morden.json diff --git a/src/ethereum/res/olympic.json b/res/ethereum/olympic.json similarity index 100% rename from src/ethereum/res/olympic.json rename to res/ethereum/olympic.json diff --git a/res/ethereum/tests b/res/ethereum/tests new file mode 160000 index 000000000..dc86e6359 --- /dev/null +++ b/res/ethereum/tests @@ -0,0 +1 @@ +Subproject commit dc86e6359675440aea59ddb48648a01c799925d8 diff --git a/res/ttTransactionTest.json b/res/ttTransactionTest.json deleted file mode 100644 index c868d11d0..000000000 --- a/res/ttTransactionTest.json +++ /dev/null @@ -1,531 +0,0 @@ -{ - "AddressLessThan20" : { - "blocknumber" : "0", - "rlp" : "0xf8528001825208870b9331677e6ebf0a801ca098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" - }, - "AddressLessThan20Prefixed0" : { - "blocknumber" : "0", - "rlp" : "0xf85f800182520894000000000000000000000000000b9331677e6ebf0a801ca098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3", - "sender" : "31bb58672e8bf7684108feeacf424ab62b873824", - "transaction" : { - "data" : "", - "gasLimit" : "0x5208", - "gasPrice" : "0x01", - "nonce" : "0x00", - "r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", - "s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3", - "to" : "0x000000000000000000000000000b9331677e6ebf", - "v" : "0x1c", - "value" : "0x0a" - } - }, - "AddressMoreThan20" : { - "blocknumber" : "0", - "rlp" : "0xf860800182520895b94f5374fce5edbc8e2a8697c15331677e6ebf0b1c0a801ca098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" - }, - "AddressMoreThan20PrefixedBy0" : { - "blocknumber" : "0", - "rlp" : "0xf867367b8252089c0000000000000000095e7baea6a6c7c4c2dfeb977efac326af552d870b121ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" - }, - "DataTestEnoughGAS" : { - "blocknumber" : "0", - "rlp" : "0xf86d80018259d894095e7baea6a6c7c4c2dfeb977efac326af552d870a8e0358ac39584bc98a7c979f984b031ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", - "sender" : "ce26839c9bd0e87e38897bb97fca8b340fd12a53", - "transaction" : { - "data" : "0x0358ac39584bc98a7c979f984b03", - "gasLimit" : "0x59d8", - "gasPrice" : "0x01", - "nonce" : "0x00", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "0x1b", - "value" : "0x0a" - } - }, - "DataTestFirstZeroBytes" : { - "blocknumber" : "0", - "rlp" : "0xf87c80018261a894095e7baea6a6c7c4c2dfeb977efac326af552d870a9d00000000000000000000000000010000000000000000000000000000001ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", - "sender" : "8131688854fe0dca411aa19572a01fe3e3e4fa74", - "transaction" : { - "data" : "0x000000000000000000000000001000000000000000000000000000000", - "gasLimit" : "0x61a8", - "gasPrice" : "0x01", - "nonce" : "0x00", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "0x1b", - "value" : "0x0a" - } - }, - "DataTestLastZeroBytes" : { - "blocknumber" : "0", - "rlp" : "0xf87c80018261a894095e7baea6a6c7c4c2dfeb977efac326af552d870a9d00100000000000000000000000000000000000000000000000000000001ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", - "sender" : "ead53a9560ea38feb0bc2cad8ef65e5d8f990fc1", - "transaction" : { - "data" : "0x010000000000000000000000000000000000000000000000000000000", - "gasLimit" : "0x61a8", - "gasPrice" : "0x01", - "nonce" : "0x00", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "0x1b", - "value" : "0x0a" - } - }, - "DataTestNotEnoughGAS" : { - "blocknumber" : "0", - "rlp" : "0xf86d800182521c94095e7baea6a6c7c4c2dfeb977efac326af552d870a8e0358ac39584bc98a7c979f984b031ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" - }, - "DataTestZeroBytes" : { - "blocknumber" : "0", - "rlp" : "0xf87c80018261a894095e7baea6a6c7c4c2dfeb977efac326af552d870a9d00000000000000000000000000000000000000000000000000000000001ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", - "sender" : "b7ab01c0f092d30aeed17e23adb7aa5a9b2ee077", - "transaction" : { - "data" : "0x000000000000000000000000000000000000000000000000000000000", - "gasLimit" : "0x61a8", - "gasPrice" : "0x01", - "nonce" : "0x00", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "0x1b", - "value" : "0x0a" - } - }, - "EmptyTransaction" : { - "blocknumber" : "0", - "rlp" : "0xf85d80808094095e7baea6a6c7c4c2dfeb977efac326af552d8780801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" - }, - "NotEnoughGasLimit" : { - "blocknumber" : "0", - "rlp" : "0xf85f0301824e2094b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a801ca098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" - }, - "RSsecp256k1" : { - "blocknumber" : "0", - "rlp" : "0xf85f030182520894b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a801ca0fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141a0fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141" - }, - "RightVRSTest" : { - "blocknumber" : "0", - "rlp" : "0xf85f030182520894b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a801ca098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3", - "sender" : "fa7f04899691becd07dd3081d0a2f3ee7640af52", - "transaction" : { - "data" : "0x", - "gasLimit" : "0x5208", - "gasPrice" : "0x01", - "nonce" : "0x03", - "r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", - "s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3", - "to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "v" : "0x1c", - "value" : "0x0a" - } - }, - "SenderTest" : { - "blocknumber" : "0", - "rlp" : "0xf85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", - "sender" : "0f65fe9276bc9a24ae7083ae28e2660ef72df99e", - "senderExpect" : "sender 0f65fe9276bc9a24ae7083ae28e2660ef72df99e", - "transaction" : { - "data" : "", - "gasLimit" : "0x5208", - "gasPrice" : "0x01", - "nonce" : "0x00", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "0x1b", - "value" : "0x0a" - } - }, - "TransactionWithGasLimitOverflow" : { - "blocknumber" : "0", - "rlp" : "0xf87e807ba101000000000000000000000000000000000000000000000000000000000000000094095e7baea6a6c7c4c2dfeb977efac326af552d870b801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" - }, - "TransactionWithGasLimitxPriceOverflow" : { - "blocknumber" : "0", - "rlp" : "0xf8858088016345785d8a0000a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff94095e7baea6a6c7c4c2dfeb977efac326af552d8780801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", - "sender" : "700764607c82cf3e9cf4ecbd49185f8914f1a361", - "transaction" : { - "data" : "", - "gasLimit" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "gasPrice" : "0x016345785d8a0000", - "nonce" : "0x00", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "0x1b", - "value" : "0x00" - } - }, - "TransactionWithGasPriceOverflow" : { - "blocknumber" : "0", - "rlp" : "0xf88080a101000000000000000000000000000000000000000000000000000000000000000082520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" - }, - "TransactionWithHighValueOverflow" : { - "blocknumber" : "0", - "rlp" : "0xf880800182520894095e7baea6a6c7c4c2dfeb977efac326af552d87a1010000000000000000000000000000000000000000000000000000000000000000801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" - }, - "TransactionWithHihghGas" : { - "blocknumber" : "0", - "rlp" : "0xf87d8001a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff94095e7baea6a6c7c4c2dfeb977efac326af552d8780801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", - "sender" : "9e92c26895f279d68ad7b57b803dc522717d5572", - "transaction" : { - "data" : "", - "gasLimit" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "gasPrice" : "0x01", - "nonce" : "0x00", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "0x1b", - "value" : "0x00" - } - }, - "TransactionWithHihghGasPrice" : { - "blocknumber" : "0", - "rlp" : "0xf87f80a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82520894095e7baea6a6c7c4c2dfeb977efac326af552d8780801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", - "sender" : "b10eac078276dc8dbf1753715396d480156236f8", - "transaction" : { - "data" : "", - "gasLimit" : "0x5208", - "gasPrice" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "nonce" : "0x00", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "0x1b", - "value" : "0x00" - } - }, - "TransactionWithHihghNonce256" : { - "blocknumber" : "0", - "rlp" : "0xf87fa0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0182520894095e7baea6a6c7c4c2dfeb977efac326af552d8780801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", - "sender" : "9b96002788562fefd5ac08d5af877fa738272dc7", - "transaction" : { - "data" : "", - "gasLimit" : "0x5208", - "gasPrice" : "0x01", - "nonce" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "0x1b", - "value" : "0x00" - } - }, - "TransactionWithHihghNonce32" : { - "blocknumber" : "0", - "rlp" : "0xf8648501000000000182520894095e7baea6a6c7c4c2dfeb977efac326af552d8780801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", - "sender" : "e86dc346fd8debf719486ff2f9c4c629fe58fc46", - "transaction" : { - "data" : "", - "gasLimit" : "0x5208", - "gasPrice" : "0x01", - "nonce" : "0x0100000000", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "0x1b", - "value" : "0x00" - } - }, - "TransactionWithHihghValue" : { - "blocknumber" : "0", - "rlp" : "0xf87f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d87a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", - "sender" : "396bd0363e26195eeacfedbe54c44f16fbe470b6", - "transaction" : { - "data" : "", - "gasLimit" : "0x5208", - "gasPrice" : "0x01", - "nonce" : "0x00", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "0x1b", - "value" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - } - }, - "TransactionWithNonceOverflow" : { - "blocknumber" : "0", - "rlp" : "0xf880a10100000000000000000000000000000000000000000000000000000000000000000182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" - }, - "TransactionWithRSvalue0" : { - "blocknumber" : "0", - "rlp" : "0xdf800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801b8080" - }, - "TransactionWithRSvalue1" : { - "blocknumber" : "0", - "rlp" : "0xdf800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801b0101", - "sender" : "98c188f183d4e93ff2bffadd145f39b4a792ed85", - "transaction" : { - "data" : "", - "gasLimit" : "0x5208", - "gasPrice" : "0x01", - "nonce" : "0x00", - "r" : "0x01", - "s" : "0x01", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "0x1b", - "value" : "0x0b" - } - }, - "TransactionWithRvalue0" : { - "blocknumber" : "0", - "rlp" : "0xf83f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801b80a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" - }, - "TransactionWithRvalue1" : { - "blocknumber" : "0", - "rlp" : "0xf83f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801b01a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", - "sender" : "421ba7ba39c1c2ddb98308deca3af1dd9e461740", - "transaction" : { - "data" : "", - "gasLimit" : "0x5208", - "gasPrice" : "0x01", - "nonce" : "0x00", - "r" : "0x01", - "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "0x1b", - "value" : "0x0b" - } - }, - "TransactionWithRvalueHigh" : { - "blocknumber" : "0", - "rlp" : "0xf85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801ba0fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140a08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" - }, - "TransactionWithRvalueOverflow" : { - "blocknumber" : "0", - "rlp" : "0xf861800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801ba2fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641410000a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" - }, - "TransactionWithRvaluePrefixed00" : { - "blocknumber" : "0", - "rlp" : "0xf850800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801b910ebaaedce6af48a03bbfd25e8cd0364141a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", - "sender" : "0dd0dcb6502a463fa90ecaa59ca29a5e6571deef", - "transaction" : { - "data" : "", - "gasLimit" : "0x5208", - "gasPrice" : "0x01", - "nonce" : "0x00", - "r" : "0xebaaedce6af48a03bbfd25e8cd0364141", - "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "0x1b", - "value" : "0x0b" - } - }, - "TransactionWithRvalueTooHigh" : { - "blocknumber" : "0", - "rlp" : "0xf85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801ba0fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" - }, - "TransactionWithSvalue0" : { - "blocknumber" : "0", - "rlp" : "0xf83f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a3664935380" - }, - "TransactionWithSvalue1" : { - "blocknumber" : "0", - "rlp" : "0xf83f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a3664935301", - "sender" : "e115cf6bb5656786569dd273705242ca72d84bc0", - "transaction" : { - "data" : "", - "gasLimit" : "0x5208", - "gasPrice" : "0x01", - "nonce" : "0x00", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0x01", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "0x1b", - "value" : "0x0b" - } - }, - "TransactionWithSvalueEqual_c_secp256k1n_x05" : { - "blocknumber" : "0", - "rlp" : "0xf85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a07fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0", - "sender" : "b284109d8e781949638d995c19f8feba0268191c", - "transaction" : { - "data" : "", - "gasLimit" : "0x5208", - "gasPrice" : "0x01", - "nonce" : "0x00", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "0x1b", - "value" : "0x0b" - } - }, - "TransactionWithSvalueHigh" : { - "blocknumber" : "0", - "rlp" : "0xf85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", - "sender" : "474869ba435affa1f45aaada48520880921c0887", - "transaction" : { - "data" : "", - "gasLimit" : "0x5208", - "gasPrice" : "0x01", - "nonce" : "0x00", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "0x1b", - "value" : "0x0b" - } - }, - "TransactionWithSvalueLargerThan_c_secp256k1n_x05" : { - "blocknumber" : "0", - "rlp" : "0xf85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a07fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a1", - "sender" : "5ced92a94a7bfd7853b12d33ee59dd10ae94eb86", - "transaction" : { - "data" : "", - "gasLimit" : "0x5208", - "gasPrice" : "0x01", - "nonce" : "0x00", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a1", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "0x1b", - "value" : "0x0b" - } - }, - "TransactionWithSvalueLessThan_c_secp256k1n_x05" : { - "blocknumber" : "0", - "rlp" : "0xf85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a07fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b2090", - "sender" : "33e931e187e9cb5b6f8560755519d54560dd63e8", - "transaction" : { - "data" : "", - "gasLimit" : "0x5208", - "gasPrice" : "0x01", - "nonce" : "0x00", - "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", - "s" : "0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b2090", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "0x1b", - "value" : "0x0b" - } - }, - "TransactionWithSvalueOverflow" : { - "blocknumber" : "0", - "rlp" : "0xf861800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a2fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f0000" - }, - "TransactionWithSvaluePrefixed00" : { - "blocknumber" : "0", - "rlp" : "0xf851800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801ba098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a920ef0b28ad43601b4ab949f53faa07bd2c804", - "sender" : "a825d77f343f31619c991cd7db5aaa6adbe9452e", - "transaction" : { - "data" : "", - "gasLimit" : "0x5208", - "gasPrice" : "0x01", - "nonce" : "0x00", - "r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", - "s" : "0xef0b28ad43601b4ab949f53faa07bd2c804", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "0x1b", - "value" : "0x0b" - } - }, - "TransactionWithSvalueTooHigh" : { - "blocknumber" : "0", - "rlp" : "0xf85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141" - }, - "TransactionWithTooFewRLPElements" : { - "blocknumber" : "0", - "rlp" : "0xf85b800194095e7baea6a6c7c4c2dfeb977efac326af552d87801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" - }, - "TransactionWithTooManyRLPElements" : { - "blocknumber" : "0", - "rlp" : "0xf865800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804851de98d0edd" - }, - "V_overflow32bit" : { - "blocknumber" : "0", - "rlp" : "0xf866030182520894b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a82554485010000001ba098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" - }, - "V_overflow32bitSigned" : { - "blocknumber" : "0", - "rlp" : "0xf865030182520894b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a825544847fffffffa098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" - }, - "V_overflow64bitPlus27" : { - "blocknumber" : "0", - "rlp" : "0xf86a03018255f094b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a8255448901000000000000001ba098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" - }, - "V_overflow64bitPlus28" : { - "blocknumber" : "0", - "rlp" : "0xf86a03018255f094b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a8255448901000000000000001ca098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" - }, - "V_overflow64bitSigned" : { - "blocknumber" : "0", - "rlp" : "0xf869030182520894b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a82554488ffffffffffffff1ca098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" - }, - "WrongVRSTestIncorrectSize" : { - "blocknumber" : "0", - "rlp" : "0xf863800182520894b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a801ca298ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a02c3a28887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a302c3" - }, - "WrongVRSTestVEqual26" : { - "blocknumber" : "0", - "rlp" : "0xf85f800182520894b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a801aa098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" - }, - "WrongVRSTestVEqual29" : { - "blocknumber" : "0", - "rlp" : "0xf85f800182520894b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a801da098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" - }, - "WrongVRSTestVEqual31" : { - "blocknumber" : "0", - "rlp" : "0xf85f800182520894b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a801fa098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" - }, - "WrongVRSTestVOverflow" : { - "blocknumber" : "0", - "rlp" : "0xf861800182520894b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a80820136a098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" - }, - "dataTx_bcValidBlockTest" : { - "blocknumber" : "0", - "rlp" : "0xf901fb803282c3508080b901ae60056013565b6101918061001d6000396000f35b3360008190555056006001600060e060020a6000350480630a874df61461003a57806341c0e1b514610058578063a02b161e14610066578063dbbdf0831461007757005b610045600435610149565b80600160a060020a031660005260206000f35b610060610161565b60006000f35b6100716004356100d4565b60006000f35b61008560043560243561008b565b60006000f35b600054600160a060020a031632600160a060020a031614156100ac576100b1565b6100d0565b8060018360005260205260406000208190555081600060005260206000a15b5050565b600054600160a060020a031633600160a060020a031614158015610118575033600160a060020a0316600182600052602052604060002054600160a060020a031614155b61012157610126565b610146565b600060018260005260205260406000208190555080600060005260206000a15b50565b60006001826000526020526040600020549050919050565b600054600160a060020a031633600160a060020a0316146101815761018f565b600054600160a060020a0316ff5b561ca0c5689ed1ad124753d54576dfb4b571465a41900a1dff4058d8adf16f752013d0a0e221cbd70ec28c94a3b55ec771bcbc70778d6ee0b51ca7ea9514594c861b1884", - "sender" : "a94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "transaction" : { - "data" : "0x60056013565b6101918061001d6000396000f35b3360008190555056006001600060e060020a6000350480630a874df61461003a57806341c0e1b514610058578063a02b161e14610066578063dbbdf0831461007757005b610045600435610149565b80600160a060020a031660005260206000f35b610060610161565b60006000f35b6100716004356100d4565b60006000f35b61008560043560243561008b565b60006000f35b600054600160a060020a031632600160a060020a031614156100ac576100b1565b6100d0565b8060018360005260205260406000208190555081600060005260206000a15b5050565b600054600160a060020a031633600160a060020a031614158015610118575033600160a060020a0316600182600052602052604060002054600160a060020a031614155b61012157610126565b610146565b600060018260005260205260406000208190555080600060005260206000a15b50565b60006001826000526020526040600020549050919050565b600054600160a060020a031633600160a060020a0316146101815761018f565b600054600160a060020a0316ff5b56", - "gasLimit" : "0xc350", - "gasPrice" : "0x32", - "nonce" : "0x00", - "r" : "0xc5689ed1ad124753d54576dfb4b571465a41900a1dff4058d8adf16f752013d0", - "s" : "0xe221cbd70ec28c94a3b55ec771bcbc70778d6ee0b51ca7ea9514594c861b1884", - "to" : "", - "v" : "0x1c", - "value" : "0x00" - } - }, - "invalidSignature" : { - "blocknumber" : "0", - "rlp" : "0xf8638080830f424094095e7baea6a6c7c4c2dfeb977efac326af552d87830186a0801ba0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0badf00d70ec28c94a3b55ec771bcbc70778d6ee0b51ca7ea9514594c861b1884" - }, - "libsecp256k1test" : { - "blocknumber" : "0", - "rlp" : "0xd1808609184e72a00082f3888080801b2c04", - "sender" : "170ad78f26da62f591fa3fe3d54c30016167cbbf", - "transaction" : { - "data" : "0x", - "gasLimit" : "0xf388", - "gasPrice" : "0x09184e72a000", - "nonce" : "0x00", - "r" : "0x2c", - "s" : "0x04", - "to" : "", - "v" : "0x1b", - "value" : "0x00" - } - }, - "unpadedRValue" : { - "blocknumber" : "0", - "rlp" : "0xf8880d8609184e72a00082f710947c47ef93268a311f4cad0c750724299e9b72c26880a4379607f500000000000000000000000000000000000000000000000000000000000000051c9f6ab6dda9f4df56ea45583af36660329147f1753f3724ea5eb9ed83e812ca77a0495701e230667832c8999e884e366a61028633ecf951e8cd66d119f381ae5718", - "sender" : "c1584838993ee7a9581cba0bced81785e8bb581d", - "transaction" : { - "data" : "0x379607f50000000000000000000000000000000000000000000000000000000000000005", - "gasLimit" : "0xf710", - "gasPrice" : "0x09184e72a000", - "nonce" : "0x0d", - "r" : "0x006ab6dda9f4df56ea45583af36660329147f1753f3724ea5eb9ed83e812ca77", - "s" : "0x495701e230667832c8999e884e366a61028633ecf951e8cd66d119f381ae5718", - "to" : "7c47ef93268a311f4cad0c750724299e9b72c268", - "v" : "0x1c", - "value" : "0x00" - } - } -} \ No newline at end of file diff --git a/src/ethereum/mod.rs b/src/ethereum/mod.rs index b3efe4a3d..832afa2ec 100644 --- a/src/ethereum/mod.rs +++ b/src/ethereum/mod.rs @@ -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 { diff --git a/src/transaction.rs b/src/transaction.rs index 43bd2f1d9..64f5b5806 100644 --- a/src/transaction.rs +++ b/src/transaction.rs @@ -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 { + 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} } \ No newline at end of file From c6ec6e4aef61c9ab410c251257ac74b8343e31f6 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 12 Jan 2016 12:34:14 +0100 Subject: [PATCH 10/10] State::exists, docs and tests. --- src/state.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/state.rs b/src/state.rs index 42813ca76..e02da4ecb 100644 --- a/src/state.rs +++ b/src/state.rs @@ -76,6 +76,11 @@ impl State { self.cache.borrow_mut().insert(account.clone(), None); } + /// Determine whether an account exists. + pub fn exists(&self, a: &Address) -> bool { + self.cache.borrow().get(&a).unwrap_or(&None).is_some() || SecTrieDB::new(&self.db, &self.root).contains(&a) + } + /// Get the balance of account `a`. pub fn balance(&self, a: &Address) -> U256 { self.get(a, false).as_ref().map(|account| account.balance().clone()).unwrap_or(U256::from(0u8)) @@ -287,9 +292,12 @@ fn get_from_database() { fn remove() { let a = Address::zero(); let mut s = State::new_temp(); + assert_eq!(s.exists(&a), false); s.inc_nonce(&a); + assert_eq!(s.exists(&a), true); assert_eq!(s.nonce(&a), U256::from(1u64)); s.kill_account(&a); + assert_eq!(s.exists(&a), false); assert_eq!(s.nonce(&a), U256::from(0u64)); } @@ -300,20 +308,24 @@ fn remove_from_database() { let mut s = State::new_temp(); s.inc_nonce(&a); s.commit(); + assert_eq!(s.exists(&a), true); assert_eq!(s.nonce(&a), U256::from(1u64)); s.drop() }; let (r, db) = { let mut s = State::from_existing(db, r, U256::from(0u8)); + assert_eq!(s.exists(&a), true); assert_eq!(s.nonce(&a), U256::from(1u64)); s.kill_account(&a); s.commit(); + assert_eq!(s.exists(&a), false); assert_eq!(s.nonce(&a), U256::from(0u64)); s.drop() }; let s = State::from_existing(db, r, U256::from(0u8)); + assert_eq!(s.exists(&a), false); assert_eq!(s.nonce(&a), U256::from(0u64)); }