multiversx_chain_vm/host/execution/
exec_create.rs1use crate::{
2 blockchain::state::BlockchainStateRef,
3 host::context::{BlockchainUpdate, TxCache, TxContext, TxInput, TxResult},
4 host::runtime::{RuntimeInstanceCallLambda, RuntimeRef},
5 types::{VMAddress, VMCodeMetadata},
6};
7
8pub fn commit_deploy<F>(
10 tx_input: TxInput,
11 contract_path: &[u8],
12 code_metadata: VMCodeMetadata,
13 state: &mut BlockchainStateRef,
14 runtime: &RuntimeRef,
15 f: F,
16) -> (VMAddress, TxResult)
17where
18 F: RuntimeInstanceCallLambda,
19{
20 state.increase_account_nonce(&tx_input.from);
23 state.subtract_tx_gas(&tx_input.from, tx_input.gas_limit, tx_input.gas_price);
24
25 let tx_cache = TxCache::new(state.get_arc());
26
27 let (mut tx_result, new_address, blockchain_updates) = execute_deploy(
28 tx_input.clone(),
29 contract_path.to_vec(),
30 code_metadata,
31 tx_cache,
32 runtime,
33 f,
34 );
35
36 if tx_result.result_status.is_success() {
37 blockchain_updates.apply(state);
38 }
39
40 tx_result.append_internal_vm_errors_event_log(&tx_input);
42
43 (new_address, tx_result)
44}
45
46pub fn execute_deploy<F>(
48 mut tx_input: TxInput,
49 contract_path: Vec<u8>,
50 code_metadata: VMCodeMetadata,
51 tx_cache: TxCache,
52 runtime: &RuntimeRef,
53 f: F,
54) -> (TxResult, VMAddress, BlockchainUpdate)
55where
56 F: RuntimeInstanceCallLambda,
57{
58 let new_address = tx_cache.get_new_address(&tx_input.from);
59 tx_input.to = new_address.clone();
60 let tx_context = TxContext::new(runtime.clone(), tx_input, tx_cache);
61 let tx_input_ref = tx_context.input_ref();
62
63 if let Err(err) = tx_context
64 .tx_cache
65 .subtract_egld_balance(&tx_input_ref.from, &tx_input_ref.egld_value)
66 {
67 return (
68 TxResult::from_panic_obj(&err),
69 VMAddress::zero(),
70 BlockchainUpdate::empty(),
71 );
72 }
73 tx_context.create_new_contract(
74 &new_address,
75 contract_path,
76 code_metadata,
77 tx_input_ref.from.clone(),
78 );
79 tx_context
80 .tx_cache
81 .increase_egld_balance(&new_address, &tx_input_ref.egld_value);
82
83 let tx_context = runtime.execute(tx_context, f);
84
85 let (tx_result, blockchain_updates) = tx_context.into_results();
86 (tx_result, new_address, blockchain_updates)
87}