From c181fdfa6ccc4364c8d7c8843565b61c78a9940e Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Tue, 13 Jun 2017 11:30:16 +0800 Subject: [PATCH] Problem: account_state might be mutated multiple times In `into_context`, MessageCall needs both `require(caller)` and `require_code(address)`, but it might have already returned before requiring the later. --- sputnikvm/src/vm/transaction.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/sputnikvm/src/vm/transaction.rs b/sputnikvm/src/vm/transaction.rs index 2bde2d05..eb58b381 100644 --- a/sputnikvm/src/vm/transaction.rs +++ b/sputnikvm/src/vm/transaction.rs @@ -77,22 +77,27 @@ impl Transaction { Transaction::MessageCall { address, caller, gas_price, gas_limit, value, data } => { + account_state.require(caller)?; + account_state.require_code(address)?; + if !is_code { - let nonce = account_state.nonce(caller)?; + let nonce = account_state.nonce(caller).unwrap(); account_state.set_nonce(caller, nonce + M256::from(1u64)).unwrap(); } Ok(Context { address, caller, data, gas_price, value, gas_limit: gas_limit - upfront, - code: account_state.code(address)?.into(), + code: account_state.code(address).unwrap().into(), origin: origin.unwrap_or(caller), }) }, Transaction::ContractCreation { caller, gas_price, gas_limit, value, init, } => { - let nonce = account_state.nonce(caller)?; + account_state.require(caller)?; + + let nonce = account_state.nonce(caller).unwrap(); account_state.set_nonce(caller, nonce + M256::from(1u64)).unwrap(); let mut rlp = RlpStream::new_list(2);