cita_vm/
executive.rs

1use std::cell::RefCell;
2use std::sync::Arc;
3
4use cita_trie::DB;
5use ethereum_types::{Address, H256, U256};
6use evm::InterpreterParams;
7use hashbrown::{HashMap, HashSet};
8use log::debug;
9use rlp::RlpStream;
10
11use crate::common;
12use crate::err;
13use crate::evm;
14use crate::native;
15use crate::state::{State, StateObjectInfo};
16use hasher::Hasher;
17
18/// BlockDataProvider provides functions to get block's hash from chain.
19///
20/// Block data(only hash) are required to cita-vm from externalize database.
21pub trait BlockDataProvider: Send + Sync {
22    /// Function get_block_hash returns the block_hash of the specific block.
23    fn get_block_hash(&self, number: &U256) -> H256;
24}
25
26/// BlockDataProviderMock is a mock for BlockDataProvider. We could use it in
27/// tests or demos.
28#[derive(Default)]
29pub struct BlockDataProviderMock {
30    data: HashMap<U256, H256>,
31}
32
33impl BlockDataProviderMock {
34    /// Set blockhash for a specific block.
35    pub fn set(&mut self, number: U256, hash: H256) {
36        self.data.insert(number, hash);
37    }
38}
39
40/// Impl.
41impl BlockDataProvider for BlockDataProviderMock {
42    fn get_block_hash(&self, number: &U256) -> H256 {
43        *self.data.get(number).unwrap_or(&H256::zero())
44    }
45}
46
47/// Store storages shared datas.
48#[derive(Clone, Default, Debug)]
49pub struct Store {
50    refund: HashMap<Address, u64>,                 // For record refunds
51    origin: HashMap<Address, HashMap<H256, H256>>, // For record origin value
52    selfdestruct: HashSet<Address>,                // For self destruct
53    // Field inused used for garbage collection.
54    //
55    // Test:
56    //   ./tests/jsondata/GeneralStateTests/stSStoreTest/sstore_combinations_initial0.json
57    //   ./tests/jsondata/GeneralStateTests/stSStoreTest/sstore_combinations_initial1.json
58    //   ./tests/jsondata/GeneralStateTests/stSStoreTest/sstore_combinations_initial2.json
59    inused: HashSet<Address>,
60    evm_context: evm::Context,
61    evm_cfg: evm::InterpreterConf,
62}
63
64impl Store {
65    /// Merge with sub store.
66    pub fn merge(&mut self, other: Arc<RefCell<Self>>) {
67        self.refund = other.borrow().refund.clone();
68        self.origin = other.borrow().origin.clone();
69        self.selfdestruct = other.borrow().selfdestruct.clone();
70        self.inused = other.borrow().inused.clone();
71    }
72
73    /// When a account has been read or write, record a log
74    /// to prove that it has dose.
75    pub fn used(&mut self, address: Address) {
76        if address == Address::zero() {
77            return;
78        }
79        self.inused.insert(address);
80    }
81}
82
83/// An implemention for evm::DataProvider
84pub struct DataProvider<B> {
85    block_provider: Arc<dyn BlockDataProvider>,
86    state_provider: Arc<RefCell<State<B>>>,
87    store: Arc<RefCell<Store>>,
88}
89
90impl<B: DB> DataProvider<B> {
91    /// Create a new instance. It's obvious.
92    pub fn new(b: Arc<dyn BlockDataProvider>, s: Arc<RefCell<State<B>>>, store: Arc<RefCell<Store>>) -> Self {
93        DataProvider {
94            block_provider: b,
95            state_provider: s,
96            store,
97        }
98    }
99}
100
101/// Returns new address created from address and nonce.
102pub fn create_address_from_address_and_nonce(address: &Address, nonce: &U256) -> Address {
103    let mut stream = RlpStream::new_list(2);
104    stream.append(address);
105    stream.append(nonce);
106    Address::from(H256::from_slice(common::hash::summary(stream.as_raw()).as_slice()))
107}
108
109/// Returns new address created from sender salt and code hash.
110/// See: EIP 1014.
111pub fn create_address_from_salt_and_code_hash(address: &Address, salt: H256, code: Vec<u8>) -> Address {
112    let code_hash = &common::hash::summary(&code[..])[..];
113    let mut buffer = [0u8; 1 + 20 + 32 + 32];
114    buffer[0] = 0xff;
115    buffer[1..=20].copy_from_slice(&address[..]);
116    buffer[(1 + 20)..(1 + 20 + 32)].copy_from_slice(&salt[..]);
117    buffer[(1 + 20 + 32)..].copy_from_slice(code_hash);
118    Address::from(H256::from_slice(common::hash::summary(&buffer).as_slice()))
119}
120
121/// A selector for func create_address_from_address_and_nonce() and
122/// create_address_from_salt_and_code_hash()
123pub enum CreateKind {
124    FromAddressAndNonce, // use create_address_from_address_and_nonce
125    FromSaltAndCodeHash, // use create_address_from_salt_and_code_hash
126}
127
128/// Returns the default interpreter configs for Constantinople.
129pub fn get_interpreter_conf() -> evm::InterpreterConf {
130    evm::InterpreterConf {
131        eip1283: false,
132        ..Default::default()
133    }
134}
135
136/// If a contract creation is attempted, due to either a creation transaction
137/// or the CREATE (or future CREATE2) opcode, and the destination address
138/// already has either nonzero nonce, or nonempty code, then the creation
139/// throws immediately, with exactly the same behavior as would arise if the
140/// first byte in the init code were an invalid opcode. This applies
141/// retroactively starting from genesis.
142///
143/// See: EIP 684
144pub fn can_create<B: DB + 'static>(
145    state_provider: Arc<RefCell<State<B>>>,
146    address: &Address,
147) -> Result<bool, err::Error> {
148    let a = state_provider.borrow_mut().nonce(address)?;
149    let b = state_provider.borrow_mut().code(address)?;
150    Ok(a.is_zero() && b.is_empty())
151}
152
153// There are two payment: fixed value for transcation and mutable value
154// for input data. If is_create, another G_CREATE gas required.
155//
156// gas_prepare = 21000 + (68 or 4 per byte) + (32000 if tx.to == 0)
157pub fn get_gas_prepare(request: &InterpreterParams) -> u64 {
158    let mut gas_prepare: u64 = 0;
159    gas_prepare += G_TRANSACTION;
160    if request.is_create {
161        gas_prepare += G_CREATE
162    }
163    for i in &request.input {
164        if i == &0u8 {
165            gas_prepare += G_TX_DATA_ZERO
166        } else {
167            gas_prepare += G_TX_DATA_NON_ZERO
168        }
169    }
170    gas_prepare
171}
172
173/// Function get_refund returns the real ammount to refund for a transaction.
174pub fn get_refund(store: Arc<RefCell<Store>>, request: &InterpreterParams, gas_left: u64) -> u64 {
175    let refunds_bound = match store.borrow().refund.get(&request.origin) {
176        Some(&data) => data,
177        None => 0u64,
178    };
179    // Get real ammount to refund
180    std::cmp::min(refunds_bound, (request.gas_limit - gas_left) >> 1)
181}
182
183/// Liquidtion for a transaction.
184pub fn clear<B: DB + 'static>(
185    state_provider: Arc<RefCell<State<B>>>,
186    store: Arc<RefCell<Store>>,
187    request: &InterpreterParams,
188    gas_left: u64,
189    refund: u64,
190) -> Result<(), err::Error> {
191    state_provider
192        .borrow_mut()
193        .add_balance(&request.sender, request.gas_price * (gas_left + refund))?;
194    state_provider.borrow_mut().add_balance(
195        &store.borrow().evm_context.coinbase,
196        request.gas_price * (request.gas_limit - gas_left - refund),
197    )?;
198    Ok(())
199}
200
201/// Mutable configs in cita-vm's execution.
202#[derive(Clone, Debug)]
203pub struct Config {
204    pub block_gas_limit: u64, // gas limit for a block.
205    pub check_nonce: bool,
206    pub check_balance: bool,
207}
208
209impl Default for Config {
210    fn default() -> Self {
211        Config {
212            block_gas_limit: 8_000_000,
213            check_nonce: false,
214            check_balance: true,
215        }
216    }
217}
218
219/// Function call_pure enters into the specific contract with no check or checkpoints.
220fn call_pure<B: DB + 'static>(
221    block_provider: Arc<dyn BlockDataProvider>,
222    state_provider: Arc<RefCell<State<B>>>,
223    store: Arc<RefCell<Store>>,
224    request: &InterpreterParams,
225) -> Result<evm::InterpreterResult, err::Error> {
226    let evm_context = store.borrow().evm_context.clone();
227    let evm_cfg = store.borrow().evm_cfg.clone();
228    let evm_params = request.clone();
229    let evm_data_provider = DataProvider::new(block_provider.clone(), state_provider.clone(), store);
230    // Transfer value
231    if !request.disable_transfer_value {
232        state_provider
233            .borrow_mut()
234            .transfer_balance(&request.sender, &request.receiver, request.value)?;
235    }
236
237    // Execute pre-compiled contracts.
238    if native::contains(&request.contract.code_address) {
239        let c = native::get(request.contract.code_address);
240        let gas = c.required_gas(&request.input);
241        if request.gas_limit < gas {
242            return Err(err::Error::Evm(evm::Error::OutOfGas));
243        }
244        let r = c.run(&request.input);
245        match r {
246            Ok(ok) => {
247                return Ok(evm::InterpreterResult::Normal(ok, request.gas_limit - gas, vec![]));
248            }
249            Err(e) => return Err(e),
250        }
251    }
252    // Run
253    let mut evm_it = evm::Interpreter::new(evm_context, evm_cfg, Box::new(evm_data_provider), evm_params);
254    Ok(evm_it.run()?)
255}
256
257/// Function call enters into the specific contract.
258fn call<B: DB + 'static>(
259    block_provider: Arc<dyn BlockDataProvider>,
260    state_provider: Arc<RefCell<State<B>>>,
261    store: Arc<RefCell<Store>>,
262    request: &InterpreterParams,
263) -> Result<evm::InterpreterResult, err::Error> {
264    // Here not need check twice,becauce prepay is subed ,but need think call_static
265    /*if !request.disable_transfer_value && state_provider.borrow_mut().balance(&request.sender)? < request.value {
266        return Err(err::Error::NotEnoughBalance);
267    }*/
268    // Run
269    state_provider.borrow_mut().checkpoint();
270    let store_son = Arc::new(RefCell::new(store.borrow_mut().clone()));
271    let r = call_pure(
272        block_provider.clone(),
273        state_provider.clone(),
274        store_son.clone(),
275        request,
276    );
277    debug!("call result={:?}", r);
278    match r {
279        Ok(evm::InterpreterResult::Normal(output, gas_left, logs)) => {
280            state_provider.borrow_mut().discard_checkpoint();
281            store.borrow_mut().merge(store_son);
282            Ok(evm::InterpreterResult::Normal(output, gas_left, logs))
283        }
284        Ok(evm::InterpreterResult::Revert(output, gas_left)) => {
285            state_provider.borrow_mut().revert_checkpoint();
286            Ok(evm::InterpreterResult::Revert(output, gas_left))
287        }
288        Err(e) => {
289            state_provider.borrow_mut().revert_checkpoint();
290            Err(e)
291        }
292        _ => unimplemented!(),
293    }
294}
295
296/// Function create creates a new contract.
297fn create<B: DB + 'static>(
298    block_provider: Arc<dyn BlockDataProvider>,
299    state_provider: Arc<RefCell<State<B>>>,
300    store: Arc<RefCell<Store>>,
301    request: &InterpreterParams,
302    create_kind: CreateKind,
303) -> Result<evm::InterpreterResult, err::Error> {
304    debug!("create request={:?}", request);
305    let address = match create_kind {
306        CreateKind::FromAddressAndNonce => {
307            // Generate new address created from address, nonce
308            create_address_from_address_and_nonce(&request.sender, &request.nonce)
309        }
310        CreateKind::FromSaltAndCodeHash => {
311            // Generate new address created from sender salt and code hash
312            create_address_from_salt_and_code_hash(&request.sender, request.extra, request.input.clone())
313        }
314    };
315    debug!("create address={:?}", address);
316    // Ensure there's no existing contract already at the designated address
317    if !can_create(state_provider.clone(), &address)? {
318        return Err(err::Error::ContractAlreadyExist);
319    }
320    // Make a checkpoint here
321    state_provider.borrow_mut().checkpoint();
322    // Create a new contract
323    let balance = state_provider.borrow_mut().balance(&address)?;
324    state_provider.borrow_mut().new_contract(
325        &address,
326        balance,
327        // The init nonce for a new contract is one, see above documents.
328        U256::zero(),
329        // The init code should be none. Consider a situation: ContractA will create
330        // ContractB with address 0x1ff...fff, but ContractB's init code contains some
331        // op like "get code hash from 0x1ff..fff or get code size form 0x1ff...fff",
332        // The right result should be "summary(none)" and "0".
333        vec![],
334    );
335    let mut reqchan = request.clone();
336    reqchan.address = address;
337    reqchan.receiver = address;
338    reqchan.is_create = false;
339    reqchan.input = vec![];
340    reqchan.contract = evm::Contract {
341        code_address: address,
342        code_data: request.input.clone(),
343    };
344    let r = call(block_provider.clone(), state_provider.clone(), store, &reqchan);
345    match r {
346        Ok(evm::InterpreterResult::Normal(output, gas_left, logs)) => {
347            // Ensure code size
348            if output.len() as u64 > MAX_CREATE_CODE_SIZE {
349                state_provider.borrow_mut().revert_checkpoint();
350                return Err(err::Error::ExccedMaxCodeSize);
351            }
352            // Pay every byte returnd from CREATE
353            let gas_code_deposit: u64 = G_CODE_DEPOSIT * output.len() as u64;
354            if gas_left < gas_code_deposit {
355                state_provider.borrow_mut().revert_checkpoint();
356                return Err(err::Error::Evm(evm::Error::OutOfGas));
357            }
358            let gas_left = gas_left - gas_code_deposit;
359            state_provider.borrow_mut().set_code(&address, output.clone())?;
360            state_provider.borrow_mut().discard_checkpoint();
361            let r = Ok(evm::InterpreterResult::Create(output, gas_left, logs, address));
362            debug!("create result={:?}", r);
363            debug!("create gas_left={:?}", gas_left);
364            r
365        }
366        Ok(evm::InterpreterResult::Revert(output, gas_left)) => {
367            state_provider.borrow_mut().revert_checkpoint();
368            let r = Ok(evm::InterpreterResult::Revert(output, gas_left));
369            debug!("create gas_left={:?}", gas_left);
370            debug!("create result={:?}", r);
371            r
372        }
373        Err(e) => {
374            debug!("create err={:?}", e);
375            state_provider.borrow_mut().revert_checkpoint();
376            Err(e)
377        }
378        _ => unimplemented!(),
379    }
380}
381
382const G_TX_DATA_ZERO: u64 = 0; //4; // Paid for every zero byte of data or code for a transaction
383const G_TX_DATA_NON_ZERO: u64 = 0; //68; // Paid for every non-zero byte of data or code for a transaction
384const G_TRANSACTION: u64 = 21000; // Paid for every transaction
385const G_CREATE: u64 = 32000; // Paid for contract create
386const G_CODE_DEPOSIT: u64 = 200; // Paid per byte for a CREATE operation to succeed in placing code into state.
387const MAX_CREATE_CODE_SIZE: u64 = std::u64::MAX; // See: https://github.com/ethereum/EIPs/issues/659
388
389/// Transaction struct.
390#[derive(Clone, Debug)]
391pub struct Transaction {
392    pub from: Address,
393    pub to: Option<Address>, // Some for call and None for create.
394    pub value: U256,
395    pub nonce: U256,
396    pub gas_limit: u64,
397    pub gas_price: U256,
398    pub input: Vec<u8>,
399}
400
401/// Reinterpret tx to interpreter params.
402fn reinterpret_tx<B: DB + 'static>(tx: Transaction, state_provider: Arc<RefCell<State<B>>>) -> InterpreterParams {
403    let mut request = InterpreterParams {
404        origin: tx.from,
405        sender: tx.from,
406        ..Default::default()
407    };
408    match tx.to {
409        Some(data) => {
410            request.receiver = data;
411            request.address = data;
412            request.contract = evm::Contract {
413                code_address: data,
414                code_data: state_provider.borrow_mut().code(&data).unwrap_or_default(),
415            };
416        }
417        None => {
418            request.is_create = true;
419        }
420    }
421    request.gas_price = tx.gas_price;
422    request.gas_limit = tx.gas_limit;
423    request.value = tx.value;
424    request.input = tx.input;
425    request.nonce = tx.nonce;
426    request
427}
428
429/// Execute the transaction from transaction pool
430pub fn exec<B: DB + 'static>(
431    block_provider: Arc<dyn BlockDataProvider>,
432    state_provider: Arc<RefCell<State<B>>>,
433    evm_context: evm::Context,
434    config: Config,
435    tx: Transaction,
436) -> Result<evm::InterpreterResult, err::Error> {
437    let request = &mut reinterpret_tx(tx, state_provider.clone());
438    // Ensure gas < block_gas_limit
439
440    /* TODO : this judgement need be reconsider
441     fi config.block_gas_limit > G_TRANSACTION && request.gas_limit > config.block_gas_limit {
442        return Err(err::Error::ExccedMaxBlockGasLimit);
443    }
444    */
445
446    if config.check_nonce {
447        // Ensure nonce
448        if request.nonce + 1 != state_provider.borrow_mut().nonce(&request.sender)? {
449            return Err(err::Error::InvalidNonce);
450        }
451    } else {
452        request.nonce = state_provider.borrow_mut().nonce(&request.sender)?;
453    }
454    // Ensure gas
455    let gas_prepare = get_gas_prepare(request);
456    if request.gas_limit < gas_prepare {
457        return Err(err::Error::NotEnoughBaseGas);
458    }
459
460    // Ensure value
461    if config.check_balance {
462        let gas_prepay = request.gas_price * request.gas_limit;
463        if state_provider.borrow_mut().balance(&request.sender)? < gas_prepay + request.value {
464            return Err(err::Error::NotEnoughBalance);
465        }
466        // Pay intrinsic gas
467        state_provider.borrow_mut().sub_balance(&request.sender, gas_prepay)?;
468    }
469
470    // Increament the nonce for the next transaction
471    // Comment for inc_nonce out of this exec
472    // state_provider.borrow_mut().inc_nonce(&request.sender)?;
473
474    // Init the store for the transaction
475    let store = Store {
476        evm_cfg: get_interpreter_conf(),
477        evm_context,
478        ..Default::default()
479    };
480    //store.used(request.receiver);
481    let store = Arc::new(RefCell::new(store));
482    // Create a sub request
483    let mut reqchan = request.clone();
484    reqchan.gas_limit = request.gas_limit - gas_prepare;
485    if !config.check_balance {
486        reqchan.disable_transfer_value = true;
487    }
488    let r = if request.is_create {
489        create(
490            block_provider.clone(),
491            state_provider.clone(),
492            store.clone(),
493            &reqchan,
494            CreateKind::FromAddressAndNonce,
495        )
496    } else {
497        call(block_provider.clone(), state_provider.clone(), store.clone(), &reqchan)
498    };
499    // Finalize
500    match r {
501        Ok(evm::InterpreterResult::Normal(output, gas_left, logs)) => {
502            if config.check_balance {
503                let refund = get_refund(store.clone(), request, gas_left);
504                clear(state_provider.clone(), store.clone(), request, gas_left, refund)?;
505            }
506            // Handle self destruct: Kill it.
507            // Note: must after ends of the transaction.
508            for e in store.borrow_mut().selfdestruct.drain() {
509                state_provider.borrow_mut().kill_contract(&e)
510            }
511            state_provider.borrow_mut().kill_garbage(&store.borrow().inused.clone());
512            Ok(evm::InterpreterResult::Normal(output, gas_left, logs))
513        }
514        Ok(evm::InterpreterResult::Revert(output, gas_left)) => {
515            if config.check_balance {
516                clear(state_provider.clone(), store.clone(), request, gas_left, 0)?;
517            }
518            state_provider.borrow_mut().kill_garbage(&store.borrow().inused.clone());
519            Ok(evm::InterpreterResult::Revert(output, gas_left))
520        }
521        Ok(evm::InterpreterResult::Create(output, gas_left, logs, addr)) => {
522            if config.check_balance {
523                let refund = get_refund(store.clone(), request, gas_left);
524                clear(state_provider.clone(), store.clone(), request, gas_left, refund)?;
525            }
526            for e in store.borrow_mut().selfdestruct.drain() {
527                state_provider.borrow_mut().kill_contract(&e)
528            }
529            state_provider.borrow_mut().kill_garbage(&store.borrow().inused.clone());
530            Ok(evm::InterpreterResult::Create(output, gas_left, logs, addr))
531        }
532        Err(e) => {
533            // When error, coinbase eats all gas as it's price, yummy.
534            if config.check_balance {
535                clear(state_provider.clone(), store.clone(), request, 0, 0)?;
536            }
537            state_provider.borrow_mut().kill_garbage(&store.borrow().inused.clone());
538            Err(e)
539        }
540    }
541}
542
543/// Handle the call request in read only mode.
544/// Note:
545///   1) tx.to shouldn't be none
546///   2) tx.nonce is just omited
547///   3) tx.value must be 0. This is due to solidity's check.
548///
549/// This function is similar with `exec`, but all check & checkpoints are removed.
550#[allow(unused_variables)]
551pub fn exec_static<B: DB + 'static>(
552    block_provider: Arc<dyn BlockDataProvider>,
553    state_provider: Arc<RefCell<State<B>>>,
554    evm_context: evm::Context,
555    config: Config,
556    tx: Transaction,
557) -> Result<evm::InterpreterResult, err::Error> {
558    if tx.to.is_none() {
559        return Err(err::Error::CreateInStaticCall);
560    }
561    let mut request = reinterpret_tx(tx, state_provider.clone());
562    request.read_only = true;
563    request.disable_transfer_value = true;
564    let store = Store {
565        evm_cfg: get_interpreter_conf(),
566        evm_context,
567        ..Default::default()
568    };
569    let store = Arc::new(RefCell::new(store));
570    call_pure(block_provider.clone(), state_provider, store, &request)
571}
572
573pub struct Executive<B> {
574    pub block_provider: Arc<dyn BlockDataProvider>,
575    pub state_provider: Arc<RefCell<State<B>>>,
576    pub config: Config,
577}
578
579impl<B: DB + 'static> Executive<B> {
580    pub fn new(block_provider: Arc<dyn BlockDataProvider>, state_provider: State<B>, config: Config) -> Self {
581        Self {
582            block_provider,
583            state_provider: Arc::new(RefCell::new(state_provider)),
584            config,
585        }
586    }
587
588    pub fn exec(&self, evm_context: evm::Context, tx: Transaction) -> Result<evm::InterpreterResult, err::Error> {
589        exec(
590            self.block_provider.clone(),
591            self.state_provider.clone(),
592            evm_context,
593            self.config.clone(),
594            tx,
595        )
596
597        // Bellow is saved for jsondata test
598        /*let coinbase = evm_context.coinbase;
599        let exec_result = exec(
600            self.block_provider.clone(),
601            self.state_provider.clone(),
602            evm_context,
603            self.config.clone(),
604            tx.clone(),
605        );
606        match exec_result {
607            Err(err::Error::ExccedMaxBlockGasLimit)
608            | Err(err::Error::NotEnoughBaseGas)
609            | Err(err::Error::InvalidNonce)
610            | Err(err::Error::NotEnoughBalance) => {
611                let balance = tx.gas_price * G_TRANSACTION;
612                let account_balance = self.state_provider.borrow_mut().balance(&tx.from)?;
613                let real = {
614                    if balance > account_balance {
615                        account_balance
616                    } else {
617                        balance
618                    }
619                };
620                self.state_provider.borrow_mut().sub_balance(&tx.from, real)?;
621                self.state_provider.borrow_mut().add_balance(&coinbase, real)?;
622                self.state_provider.borrow_mut().inc_nonce(&tx.from)?;
623            }
624            Err(err::Error::Evm(_)) => {}
625            Err(_) => {}
626            Ok(_) => {}
627        }
628        exec_result
629        */
630    }
631
632    pub fn exec_static(
633        block_provider: Arc<dyn BlockDataProvider>,
634        state_provider: State<B>,
635        evm_context: evm::Context,
636        config: Config,
637        tx: Transaction,
638    ) -> Result<evm::InterpreterResult, err::Error> {
639        exec_static(
640            block_provider,
641            Arc::new(RefCell::new(state_provider)),
642            evm_context,
643            config,
644            tx,
645        )
646    }
647
648    pub fn commit(&self) -> Result<H256, err::Error> {
649        self.state_provider.borrow_mut().commit()?;
650        Ok(self.state_provider.borrow_mut().root)
651    }
652}
653
654impl<B: DB + 'static> evm::DataProvider for DataProvider<B> {
655    fn get_balance(&self, address: &Address) -> U256 {
656        self.state_provider
657            .borrow_mut()
658            .balance(address)
659            .unwrap_or_else(|_| U256::zero())
660    }
661
662    fn add_refund(&mut self, address: &Address, n: u64) {
663        self.store
664            .borrow_mut()
665            .refund
666            .entry(*address)
667            .and_modify(|v| *v += n)
668            .or_insert(n);
669    }
670
671    fn sub_refund(&mut self, address: &Address, n: u64) {
672        debug!("ext.sub_refund {:?} {}", address, n);
673        self.store
674            .borrow_mut()
675            .refund
676            .entry(*address)
677            .and_modify(|v| *v -= n)
678            .or_insert(n);
679    }
680
681    fn get_refund(&self, address: &Address) -> u64 {
682        self.store.borrow_mut().refund.get(address).map_or(0, |v| *v)
683    }
684
685    fn get_code_size(&self, address: &Address) -> u64 {
686        self.state_provider.borrow_mut().code_size(address).unwrap_or(0) as u64
687    }
688
689    fn get_code(&self, address: &Address) -> Vec<u8> {
690        self.state_provider
691            .borrow_mut()
692            .code(address)
693            .unwrap_or_else(|_| vec![])
694    }
695
696    fn get_code_hash(&self, address: &Address) -> H256 {
697        self.state_provider
698            .borrow_mut()
699            .code_hash(address)
700            .unwrap_or_else(|_| H256::zero())
701    }
702
703    fn get_block_hash(&self, number: &U256) -> H256 {
704        self.block_provider.get_block_hash(number)
705    }
706
707    fn get_storage(&self, address: &Address, key: &H256) -> H256 {
708        self.state_provider
709            .borrow_mut()
710            .get_storage(address, key)
711            .unwrap_or_else(|_| H256::zero())
712    }
713
714    fn set_storage(&mut self, address: &Address, key: H256, value: H256) {
715        let a = self.get_storage(address, &key);
716        self.store
717            .borrow_mut()
718            .origin
719            .entry(*address)
720            .or_default()
721            .entry(key)
722            .or_insert(a);
723        if let Err(e) = self.state_provider.borrow_mut().set_storage(address, key, value) {
724            panic!("{}", e);
725        }
726    }
727
728    fn get_storage_origin(&self, address: &Address, key: &H256) -> H256 {
729        //self.store.borrow_mut().used(address.clone());
730        match self.store.borrow_mut().origin.get(address) {
731            Some(account) => match account.get(key) {
732                Some(val) => *val,
733                None => self.get_storage(address, key),
734            },
735            None => self.get_storage(address, key),
736        }
737    }
738
739    fn set_storage_origin(&mut self, _address: &Address, _key: H256, _value: H256) {
740        unimplemented!()
741    }
742
743    fn selfdestruct(&mut self, address: &Address, refund_to: &Address) -> bool {
744        if self.store.borrow_mut().selfdestruct.contains(address) {
745            return false;
746        }
747        //self.store.borrow_mut().used(refund_to.clone());
748        self.store.borrow_mut().selfdestruct.insert(*address);
749        let b = self.get_balance(address);
750
751        if address != refund_to {
752            self.state_provider
753                .borrow_mut()
754                .transfer_balance(address, refund_to, b)
755                .unwrap();
756        } else {
757            // Must ensure that the balance of address which is suicide is zero.
758            self.state_provider.borrow_mut().sub_balance(address, b).unwrap();
759        }
760        true
761    }
762
763    fn sha3(&self, data: &[u8]) -> H256 {
764        H256::from_slice(hasher::HasherKeccak::new().digest(data).as_slice())
765    }
766
767    fn is_empty(&self, address: &Address) -> bool {
768        self.state_provider.borrow_mut().is_empty(address).unwrap_or(false)
769    }
770
771    fn exist(&self, address: &Address) -> bool {
772        self.state_provider.borrow_mut().exist(address).unwrap_or(false)
773    }
774
775    fn call(&self, opcode: evm::OpCode, params: evm::InterpreterParams) -> Result<evm::InterpreterResult, evm::Error> {
776        match opcode {
777            evm::OpCode::CALL | evm::OpCode::CALLCODE | evm::OpCode::DELEGATECALL | evm::OpCode::STATICCALL => {
778                //self.store.borrow_mut().used(params.address);
779                let r = call(
780                    self.block_provider.clone(),
781                    self.state_provider.clone(),
782                    self.store.clone(),
783                    &params,
784                );
785                r.or(Err(evm::Error::CallError))
786            }
787            evm::OpCode::CREATE | evm::OpCode::CREATE2 => {
788                let mut request = params;
789                request.nonce = self
790                    .state_provider
791                    .borrow_mut()
792                    .nonce(&request.sender)
793                    .or(Err(evm::Error::CallError))?;
794                // Must inc nonce for sender
795                // See: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-161.md
796                self.state_provider
797                    .borrow_mut()
798                    .inc_nonce(&request.sender)
799                    .or(Err(evm::Error::CallError))?;
800                let r = match opcode {
801                    evm::OpCode::CREATE => create(
802                        self.block_provider.clone(),
803                        self.state_provider.clone(),
804                        self.store.clone(),
805                        &request,
806                        CreateKind::FromAddressAndNonce,
807                    ),
808                    evm::OpCode::CREATE2 => create(
809                        self.block_provider.clone(),
810                        self.state_provider.clone(),
811                        self.store.clone(),
812                        &request,
813                        CreateKind::FromSaltAndCodeHash,
814                    ),
815                    _ => unimplemented!(),
816                }
817                .or(Err(evm::Error::CallError));
818                debug!("ext.create.result = {:?}", r);
819                r
820            }
821            _ => unimplemented!(),
822        }
823    }
824}