casper_executor_wasm/
install.rs

1use std::sync::Arc;
2
3use bytes::Bytes;
4use casper_executor_wasm_common::error::CallError;
5use casper_executor_wasm_interface::{executor::ExecuteError, GasUsage};
6use casper_storage::{global_state::error::Error as GlobalStateError, AddressGenerator};
7use casper_types::{
8    account::AccountHash, execution::Effects, BlockHash, BlockTime, Digest, TransactionHash,
9};
10use parking_lot::RwLock;
11use thiserror::Error;
12
13// NOTE: One struct that represents both InstallContractRequest and ExecuteRequest.
14
15/// Store contract request.
16pub struct InstallContractRequest {
17    /// Initiator's address.
18    pub(crate) initiator: AccountHash,
19    /// Gas limit.
20    pub(crate) gas_limit: u64,
21    /// Wasm bytes of the contract to be stored.
22    pub(crate) wasm_bytes: Bytes,
23    /// Constructor entry point name.
24    pub(crate) entry_point: Option<String>,
25    /// Input data for the constructor.
26    pub(crate) input: Option<Bytes>,
27    /// Attached tokens value that to be transferred into the constructor.
28    pub(crate) transferred_value: u64,
29    /// Transaction hash.
30    pub(crate) transaction_hash: TransactionHash,
31    /// Address generator.
32    pub(crate) address_generator: Arc<RwLock<AddressGenerator>>,
33    /// Chain name.
34    pub(crate) chain_name: Arc<str>,
35    /// Block time.
36    pub(crate) block_time: BlockTime,
37    /// State hash.
38    pub(crate) state_hash: Digest,
39    /// Parent block hash.
40    pub(crate) parent_block_hash: BlockHash,
41    /// Block height.
42    pub(crate) block_height: u64,
43    /// Seed used for smart contract hash computation.
44    pub(crate) seed: Option<[u8; 32]>,
45}
46
47#[derive(Default)]
48pub struct InstallContractRequestBuilder {
49    initiator: Option<AccountHash>,
50    gas_limit: Option<u64>,
51    wasm_bytes: Option<Bytes>,
52    entry_point: Option<String>,
53    input: Option<Bytes>,
54    transferred_value: Option<u64>,
55    transaction_hash: Option<TransactionHash>,
56    address_generator: Option<Arc<RwLock<AddressGenerator>>>,
57    chain_name: Option<Arc<str>>,
58    block_time: Option<BlockTime>,
59    state_hash: Option<Digest>,
60    parent_block_hash: Option<BlockHash>,
61    block_height: Option<u64>,
62    seed: Option<[u8; 32]>,
63}
64
65impl InstallContractRequestBuilder {
66    pub fn with_initiator(mut self, initiator: AccountHash) -> Self {
67        self.initiator = Some(initiator);
68        self
69    }
70
71    pub fn with_gas_limit(mut self, gas_limit: u64) -> Self {
72        self.gas_limit = Some(gas_limit);
73        self
74    }
75
76    pub fn with_wasm_bytes(mut self, wasm_bytes: Bytes) -> Self {
77        self.wasm_bytes = Some(wasm_bytes);
78        self
79    }
80
81    pub fn with_entry_point(mut self, entry_point: String) -> Self {
82        self.entry_point = Some(entry_point);
83        self
84    }
85
86    pub fn with_input(mut self, input: Bytes) -> Self {
87        self.input = Some(input);
88        self
89    }
90
91    pub fn with_transferred_value(mut self, transferred_value: u64) -> Self {
92        self.transferred_value = Some(transferred_value);
93        self
94    }
95
96    pub fn with_address_generator(mut self, address_generator: AddressGenerator) -> Self {
97        self.address_generator = Some(Arc::new(RwLock::new(address_generator)));
98        self
99    }
100
101    pub fn with_shared_address_generator(
102        mut self,
103        address_generator: Arc<RwLock<AddressGenerator>>,
104    ) -> Self {
105        self.address_generator = Some(address_generator);
106        self
107    }
108
109    pub fn with_transaction_hash(mut self, transaction_hash: TransactionHash) -> Self {
110        self.transaction_hash = Some(transaction_hash);
111        self
112    }
113
114    pub fn with_chain_name<T: Into<Arc<str>>>(mut self, chain_name: T) -> Self {
115        self.chain_name = Some(chain_name.into());
116        self
117    }
118
119    pub fn with_block_time(mut self, block_time: BlockTime) -> Self {
120        self.block_time = Some(block_time);
121        self
122    }
123
124    pub fn with_seed(mut self, seed: [u8; 32]) -> Self {
125        self.seed = Some(seed);
126        self
127    }
128
129    pub fn with_state_hash(mut self, state_hash: Digest) -> Self {
130        self.state_hash = Some(state_hash);
131        self
132    }
133
134    pub fn with_parent_block_hash(mut self, parent_block_hash: BlockHash) -> Self {
135        self.parent_block_hash = Some(parent_block_hash);
136        self
137    }
138
139    pub fn with_block_height(mut self, block_height: u64) -> Self {
140        self.block_height = Some(block_height);
141        self
142    }
143
144    pub fn build(self) -> Result<InstallContractRequest, &'static str> {
145        let initiator = self.initiator.ok_or("Initiator not set")?;
146        let gas_limit = self.gas_limit.ok_or("Gas limit not set")?;
147        let wasm_bytes = self.wasm_bytes.ok_or("Wasm bytes not set")?;
148        let entry_point = self.entry_point;
149        let input = self.input;
150        let transferred_value = self.transferred_value.ok_or("Value not set")?;
151        let address_generator = self.address_generator.ok_or("Address generator not set")?;
152        let transaction_hash = self.transaction_hash.ok_or("Transaction hash not set")?;
153        let chain_name = self.chain_name.ok_or("Chain name not set")?;
154        let block_time = self.block_time.ok_or("Block time not set")?;
155        let seed = self.seed;
156        let state_hash = self.state_hash.ok_or("State hash not set")?;
157        let parent_block_hash = self.parent_block_hash.ok_or("Parent block hash not set")?;
158        let block_height = self.block_height.ok_or("Block height not set")?;
159        Ok(InstallContractRequest {
160            initiator,
161            gas_limit,
162            wasm_bytes,
163            entry_point,
164            input,
165            transferred_value,
166            address_generator,
167            transaction_hash,
168            chain_name,
169            block_time,
170            seed,
171            state_hash,
172            parent_block_hash,
173            block_height,
174        })
175    }
176}
177
178/// Result of executing a Wasm contract.
179#[derive(Debug)]
180pub struct InstallContractResult {
181    /// Smart contract address.
182    pub(crate) smart_contract_addr: [u8; 32],
183    /// Gas usage.
184    pub(crate) gas_usage: GasUsage,
185    /// Effects produced by the execution.
186    pub(crate) effects: Effects,
187    /// Post state hash after installation.
188    pub(crate) post_state_hash: Digest,
189}
190impl InstallContractResult {
191    pub fn effects(&self) -> &Effects {
192        &self.effects
193    }
194
195    pub fn gas_usage(&self) -> &GasUsage {
196        &self.gas_usage
197    }
198
199    pub fn post_state_hash(&self) -> Digest {
200        self.post_state_hash
201    }
202
203    pub fn smart_contract_addr(&self) -> &[u8; 32] {
204        &self.smart_contract_addr
205    }
206}
207
208#[derive(Debug, Error)]
209pub enum InstallContractError {
210    #[error("system contract error: {0}")]
211    SystemContract(CallError),
212
213    #[error("execute: {0}")]
214    Execute(ExecuteError),
215
216    #[error("Global state error: {0}")]
217    GlobalState(#[from] GlobalStateError),
218
219    #[error("constructor error: {host_error}")]
220    Constructor { host_error: CallError },
221}