commit
2c804645c1
136
src/executive.rs
136
src/executive.rs
@ -55,7 +55,6 @@ pub struct Executed {
|
|||||||
pub cumulative_gas_used: U256,
|
pub cumulative_gas_used: U256,
|
||||||
/// Vector of logs generated by transaction.
|
/// Vector of logs generated by transaction.
|
||||||
pub logs: Vec<LogEntry>,
|
pub logs: Vec<LogEntry>,
|
||||||
|
|
||||||
/// Execution ended running out of gas.
|
/// Execution ended running out of gas.
|
||||||
pub out_of_gas: bool,
|
pub out_of_gas: bool,
|
||||||
/// Addresses of contracts created during execution of transaction.
|
/// Addresses of contracts created during execution of transaction.
|
||||||
@ -102,8 +101,6 @@ impl<'a> Executive<'a> {
|
|||||||
|
|
||||||
/// This funtion should be used to execute transaction.
|
/// This funtion should be used to execute transaction.
|
||||||
pub fn transact(&mut self, t: &Transaction) -> Result<Executed, Error> {
|
pub fn transact(&mut self, t: &Transaction) -> Result<Executed, Error> {
|
||||||
// TODO: validate transaction signature ?/ sender
|
|
||||||
|
|
||||||
let sender = try!(t.sender());
|
let sender = try!(t.sender());
|
||||||
let nonce = self.state.nonce(&sender);
|
let nonce = self.state.nonce(&sender);
|
||||||
|
|
||||||
@ -244,9 +241,10 @@ impl<'a> Executive<'a> {
|
|||||||
self.state.add_balance(&t.sender().unwrap(), &refund_value);
|
self.state.add_balance(&t.sender().unwrap(), &refund_value);
|
||||||
|
|
||||||
// fees earned by author
|
// 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;
|
let author = &self.info.author;
|
||||||
self.state.add_balance(author, &fees);
|
self.state.add_balance(author, &fees_value);
|
||||||
|
|
||||||
// perform suicides
|
// perform suicides
|
||||||
for address in substate.suicides.iter() {
|
for address in substate.suicides.iter() {
|
||||||
@ -742,4 +740,132 @@ 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::zero())), H256::from(&U256::from(1)));
|
||||||
assert_eq!(state.storage_at(&address, &H256::from(&U256::one())), 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_create(U256::from(17), "3331600055".from_hex().unwrap(), U256::from(100_000), U256::zero(), U256::zero());
|
||||||
|
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(18));
|
||||||
|
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(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 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 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::Util(UtilError::Crypto(CryptoError::InvalidSignature))) => (),
|
||||||
|
_ => assert!(false, "Expected invalid signature error.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_transact_invalid_nonce() {
|
||||||
|
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();
|
||||||
|
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 = {
|
||||||
|
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 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.")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user