From e3fa730dc78cdec410232ccb31d81edd370793be Mon Sep 17 00:00:00 2001 From: debris Date: Tue, 12 Jan 2016 18:31:47 +0100 Subject: [PATCH 1/2] executive tests in progress --- src/executive.rs | 80 +++++++++++++++++++++++++++++++++++++++++++--- src/transaction.rs | 15 +++++++++ 2 files changed, 90 insertions(+), 5 deletions(-) diff --git a/src/executive.rs b/src/executive.rs index 4e829cdd5..0fdb46335 100644 --- a/src/executive.rs +++ b/src/executive.rs @@ -55,7 +55,6 @@ pub struct Executed { pub cumulative_gas_used: U256, /// Vector of logs generated by transaction. pub logs: Vec, - /// Execution ended running out of gas. pub out_of_gas: bool, /// Addresses of contracts created during execution of transaction. @@ -102,8 +101,6 @@ impl<'a> Executive<'a> { /// This funtion should be used to execute transaction. pub fn transact(&mut self, t: &Transaction) -> Result { - // TODO: validate transaction signature ?/ sender - let sender = try!(t.sender()); let nonce = self.state.nonce(&sender); @@ -244,9 +241,10 @@ impl<'a> Executive<'a> { self.state.add_balance(&t.sender().unwrap(), &refund_value); // fees earned by author - let fees = (t.gas - refund) * t.gas_price; + let fees = t.gas - refund; + let fees_value = fees * t.gas_price; let author = &self.info.author; - self.state.add_balance(author, &fees); + self.state.add_balance(author, &fees_value); // perform suicides for address in substate.suicides.iter() { @@ -742,4 +740,76 @@ mod tests { assert_eq!(state.storage_at(&address, &H256::from(&U256::zero())), H256::from(&U256::from(1))); assert_eq!(state.storage_at(&address, &H256::from(&U256::one())), H256::from(&U256::from(1))); } + + #[test] + fn test_transact_simple() { + let mut t = Transaction::new(U256::zero(), U256::zero(), U256::from(100_000), Action::Create, U256::from(17), "3331600055".from_hex().unwrap()); + t.r = U256::from_str("98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a").unwrap(); + t.s = U256::from_str("8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3").unwrap(); + t.v = 0x1c; + let sender = t.sender().unwrap(); + + let mut state = State::new_temp(); + state.add_balance(&sender, &U256::from(17)); + let mut info = EnvInfo::new(); + info.gas_limit = U256::from(100_000); + let engine = TestEngine::new(0); + + let executed = { + let mut ex = Executive::new(&mut state, &info, &engine); + ex.transact(&t).unwrap() + }; + + assert_eq!(executed.gas, U256::from(100_000)); + assert_eq!(executed.gas_used, U256::from(5025)); + assert_eq!(executed.refunded, U256::from(94_975)); + assert_eq!(executed.cumulative_gas_used, U256::from(5025)); + assert_eq!(executed.logs.len(), 0); + assert_eq!(executed.out_of_gas, false); + assert_eq!(executed.contracts_created.len(), 0); + } + + #[test] + fn test_transact_invalid_sender() { + let mut t = Transaction::new(U256::zero(), U256::zero(), U256::from(100_000), Action::Create, U256::from(17), "3331600055".from_hex().unwrap()); + t.r = U256::from_str("98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a").unwrap(); + t.s = U256::from_str("8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3").unwrap(); + t.v = 0x1d; + + let mut state = State::new_temp(); + let info = EnvInfo::new(); + let engine = TestEngine::new(0); + + let res = { + let mut ex = Executive::new(&mut state, &info, &engine); + ex.transact(&t) + }; + + match res { + Err(Error::Util(UtilError::Crypto(CryptoError::InvalidSignature))) => (), + _ => assert!(false, "expected signature error") + } + } + + #[test] + fn test_transact_invalid_nonce() { + let mut t = Transaction::new(U256::one(), U256::zero(), U256::from(100_000), Action::Create, U256::from(17), "3331600055".from_hex().unwrap()); + t.r = U256::from_str("98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a").unwrap(); + t.s = U256::from_str("8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3").unwrap(); + t.v = 0x1c; + + let mut state = State::new_temp(); + let info = EnvInfo::new(); + let engine = TestEngine::new(0); + + let res = { + let mut ex = Executive::new(&mut state, &info, &engine); + ex.transact(&t) + }; + + match res { + Err(Error::Execution(ExecutionError::InvalidNonce { expected, is })) if expected == U256::zero() && is == U256::one() => (), + _ => assert!(false, "expected signature error") + } + } } diff --git a/src/transaction.rs b/src/transaction.rs index 661c1355f..df7da7da2 100644 --- a/src/transaction.rs +++ b/src/transaction.rs @@ -27,6 +27,21 @@ pub struct Transaction { } impl Transaction { + pub fn new(nonce: U256, gas_price: U256, gas: U256, action: Action, value: U256, data: Bytes) -> Transaction { + Transaction { + nonce: nonce, + gas_price: gas_price, + gas: gas, + action: action, + value: value, + data: data, + v: 0, + r: U256::zero(), + s: U256::zero(), + hash: RefCell::new(None) + } + } + /// 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 }); From 09662ace501a65f3600f8544b1b1bd7aa8b91db8 Mon Sep 17 00:00:00 2001 From: debris Date: Tue, 12 Jan 2016 19:43:26 +0100 Subject: [PATCH 2/2] executive transact tests --- src/executive.rs | 81 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 71 insertions(+), 10 deletions(-) diff --git a/src/executive.rs b/src/executive.rs index 344b57e27..9f04293a0 100644 --- a/src/executive.rs +++ b/src/executive.rs @@ -747,9 +747,10 @@ mod tests { let keypair = KeyPair::create().unwrap(); t.sign(&keypair.secret()); let sender = t.sender().unwrap(); + let contract = contract_address(&sender, &U256::zero()); let mut state = State::new_temp(); - state.add_balance(&sender, &U256::from(17)); + state.add_balance(&sender, &U256::from(18)); let mut info = EnvInfo::new(); info.gas_limit = U256::from(100_000); let engine = TestEngine::new(0); @@ -760,20 +761,25 @@ mod tests { }; assert_eq!(executed.gas, U256::from(100_000)); - assert_eq!(executed.gas_used, U256::from(5025)); - assert_eq!(executed.refunded, U256::from(94_975)); - assert_eq!(executed.cumulative_gas_used, U256::from(5025)); + assert_eq!(executed.gas_used, U256::from(20_025)); + assert_eq!(executed.refunded, U256::from(79_975)); + assert_eq!(executed.cumulative_gas_used, U256::from(20_025)); assert_eq!(executed.logs.len(), 0); assert_eq!(executed.out_of_gas, false); assert_eq!(executed.contracts_created.len(), 0); + assert_eq!(state.balance(&sender), U256::from(1)); + assert_eq!(state.balance(&contract), U256::from(17)); + assert_eq!(state.nonce(&sender), U256::from(1)); + assert_eq!(state.storage_at(&contract, &H256::new()), H256::from(&U256::from(1))); } #[test] fn test_transact_invalid_sender() { - let mut t = Transaction::new_create(U256::from(17), "3331600055".from_hex().unwrap(), U256::from(100_000), U256::zero(), U256::zero()); + let t = Transaction::new_create(U256::from(17), "3331600055".from_hex().unwrap(), U256::from(100_000), U256::zero(), U256::zero()); let mut state = State::new_temp(); - let info = EnvInfo::new(); + let mut info = EnvInfo::new(); + info.gas_limit = U256::from(100_000); let engine = TestEngine::new(0); let res = { @@ -783,7 +789,7 @@ mod tests { match res { Err(Error::Util(UtilError::Crypto(CryptoError::InvalidSignature))) => (), - _ => assert!(false, "expected signature error") + _ => assert!(false, "Expected invalid signature error.") } } @@ -792,9 +798,12 @@ mod tests { let mut t = Transaction::new_create(U256::from(17), "3331600055".from_hex().unwrap(), U256::from(100_000), U256::zero(), U256::one()); let keypair = KeyPair::create().unwrap(); t.sign(&keypair.secret()); + let sender = t.sender().unwrap(); let mut state = State::new_temp(); - let info = EnvInfo::new(); + state.add_balance(&sender, &U256::from(17)); + let mut info = EnvInfo::new(); + info.gas_limit = U256::from(100_000); let engine = TestEngine::new(0); let res = { @@ -803,8 +812,60 @@ mod tests { }; match res { - Err(Error::Execution(ExecutionError::InvalidNonce { expected, is })) if expected == U256::zero() && is == U256::one() => (), - _ => assert!(false, "expected signature error") + Err(Error::Execution(ExecutionError::InvalidNonce { expected, is })) + if expected == U256::zero() && is == U256::one() => (), + _ => assert!(false, "Expected invalid nonce error.") + } + } + + #[test] + fn test_transact_gas_limit_reached() { + let mut t = Transaction::new_create(U256::from(17), "3331600055".from_hex().unwrap(), U256::from(80_001), U256::zero(), U256::zero()); + let keypair = KeyPair::create().unwrap(); + t.sign(&keypair.secret()); + let sender = t.sender().unwrap(); + + let mut state = State::new_temp(); + state.add_balance(&sender, &U256::from(17)); + let mut info = EnvInfo::new(); + info.gas_used = U256::from(20_000); + info.gas_limit = U256::from(100_000); + let engine = TestEngine::new(0); + + let res = { + let mut ex = Executive::new(&mut state, &info, &engine); + ex.transact(&t) + }; + + match res { + Err(Error::Execution(ExecutionError::BlockGasLimitReached { gas_limit, gas_used, gas })) + if gas_limit == U256::from(100_000) && gas_used == U256::from(20_000) && gas == U256::from(80_001) => (), + _ => assert!(false, "Expected block gas limit error.") + } + } + + #[test] + fn test_not_enough_cash() { + let mut t = Transaction::new_create(U256::from(18), "3331600055".from_hex().unwrap(), U256::from(100_000), U256::one(), U256::zero()); + let keypair = KeyPair::create().unwrap(); + t.sign(&keypair.secret()); + let sender = t.sender().unwrap(); + + let mut state = State::new_temp(); + state.add_balance(&sender, &U256::from(100_017)); + let mut info = EnvInfo::new(); + info.gas_limit = U256::from(100_000); + let engine = TestEngine::new(0); + + let res = { + let mut ex = Executive::new(&mut state, &info, &engine); + ex.transact(&t) + }; + + match res { + Err(Error::Execution(ExecutionError::NotEnoughCash { required , is })) + if required == U512::zero() && is == U512::one() => (), + _ => assert!(false, "Expected not enough cash error.") } } }