pallet_revive/test_utils/
builder.rs1use super::{deposit_limit, GAS_LIMIT};
19use crate::{
20 address::AddressMapper, AccountIdOf, BalanceOf, BumpNonce, Code, Config, ContractResult,
21 DepositLimit, ExecReturnValue, InstantiateReturnValue, OriginFor, Pallet, Weight, U256,
22};
23use alloc::{vec, vec::Vec};
24use frame_support::pallet_prelude::DispatchResultWithPostInfo;
25use paste::paste;
26use sp_core::H160;
27
28macro_rules! builder {
30 (
32 $method:ident($($field:ident: $type:ty,)*) -> $result:ty;
33 $($extra:item)*
34 ) => {
35 paste!{
36 builder!([< $method:camel Builder >], $method($($field: $type,)* ) -> $result; $($extra)*);
37 }
38 };
39 (
41 $name:ident,
42 $method:ident($($field:ident: $type:ty,)*) -> $result:ty;
43 $($extra:item)*
44 ) => {
45 #[doc = concat!("A builder to construct a ", stringify!($method), " call")]
46 pub struct $name<T: Config> {
47 $($field: $type,)*
48 }
49
50 #[allow(dead_code)]
51 impl<T: Config> $name<T>
52 where
53 BalanceOf<T>: Into<sp_core::U256> + TryFrom<sp_core::U256>,
54 crate::MomentOf<T>: Into<sp_core::U256>,
55 T::Hash: frame_support::traits::IsType<sp_core::H256>,
56 {
57 $(
58 #[doc = concat!("Set the ", stringify!($field))]
59 pub fn $field(mut self, value: $type) -> Self {
60 self.$field = value;
61 self
62 }
63 )*
64
65 #[doc = concat!("Build the ", stringify!($method), " call")]
66 pub fn build(self) -> $result {
67 Pallet::<T>::$method(
68 $(self.$field,)*
69 )
70 }
71
72 $($extra)*
73 }
74 }
75}
76
77pub struct Contract<T: Config> {
78 pub account_id: AccountIdOf<T>,
79 pub addr: H160,
80}
81
82builder!(
83 instantiate_with_code(
84 origin: OriginFor<T>,
85 value: BalanceOf<T>,
86 gas_limit: Weight,
87 storage_deposit_limit: BalanceOf<T>,
88 code: Vec<u8>,
89 data: Vec<u8>,
90 salt: Option<[u8; 32]>,
91 ) -> DispatchResultWithPostInfo;
92
93 pub fn instantiate_with_code(origin: OriginFor<T>, code: Vec<u8>) -> Self {
95 Self {
96 origin,
97 value: 0u32.into(),
98 gas_limit: GAS_LIMIT,
99 storage_deposit_limit: deposit_limit::<T>(),
100 code,
101 data: vec![],
102 salt: Some([0; 32]),
103 }
104 }
105);
106
107builder!(
108 instantiate(
109 origin: OriginFor<T>,
110 value: BalanceOf<T>,
111 gas_limit: Weight,
112 storage_deposit_limit: BalanceOf<T>,
113 code_hash: sp_core::H256,
114 data: Vec<u8>,
115 salt: Option<[u8; 32]>,
116 ) -> DispatchResultWithPostInfo;
117
118 pub fn instantiate(origin: OriginFor<T>, code_hash: sp_core::H256) -> Self {
120 Self {
121 origin,
122 value: 0u32.into(),
123 gas_limit: GAS_LIMIT,
124 storage_deposit_limit: deposit_limit::<T>(),
125 code_hash,
126 data: vec![],
127 salt: Some([0; 32]),
128 }
129 }
130);
131
132builder!(
133 bare_instantiate(
134 origin: OriginFor<T>,
135 evm_value: U256,
136 gas_limit: Weight,
137 storage_deposit_limit: DepositLimit<BalanceOf<T>>,
138 code: Code,
139 data: Vec<u8>,
140 salt: Option<[u8; 32]>,
141 bump_nonce: BumpNonce,
142 ) -> ContractResult<InstantiateReturnValue, BalanceOf<T>>;
143
144 pub fn native_value(mut self, value: BalanceOf<T>) -> Self {
146 self.evm_value = Pallet::<T>::convert_native_to_evm(value);
147 self
148 }
149
150 pub fn build_and_unwrap_result(self) -> InstantiateReturnValue {
152 self.build().result.unwrap()
153 }
154
155 pub fn build_and_unwrap_contract(self) -> Contract<T> {
157 let result = self.build().result.unwrap();
158 assert!(!result.result.did_revert(), "instantiation did revert");
159
160 let addr = result.addr;
161 let account_id = T::AddressMapper::to_account_id(&addr);
162 Contract{ account_id, addr }
163 }
164
165 pub fn bare_instantiate(origin: OriginFor<T>, code: Code) -> Self {
167 Self {
168 origin,
169 evm_value: Default::default(),
170 gas_limit: GAS_LIMIT,
171 storage_deposit_limit: DepositLimit::Balance(deposit_limit::<T>()),
172 code,
173 data: vec![],
174 salt: Some([0; 32]),
175 bump_nonce: BumpNonce::Yes,
176 }
177 }
178);
179
180builder!(
181 call(
182 origin: OriginFor<T>,
183 dest: H160,
184 value: BalanceOf<T>,
185 gas_limit: Weight,
186 storage_deposit_limit: BalanceOf<T>,
187 data: Vec<u8>,
188 ) -> DispatchResultWithPostInfo;
189
190 pub fn call(origin: OriginFor<T>, dest: H160) -> Self {
192 CallBuilder {
193 origin,
194 dest,
195 value: 0u32.into(),
196 gas_limit: GAS_LIMIT,
197 storage_deposit_limit: deposit_limit::<T>(),
198 data: vec![],
199 }
200 }
201);
202
203builder!(
204 bare_call(
205 origin: OriginFor<T>,
206 dest: H160,
207 evm_value: U256,
208 gas_limit: Weight,
209 storage_deposit_limit: DepositLimit<BalanceOf<T>>,
210 data: Vec<u8>,
211 ) -> ContractResult<ExecReturnValue, BalanceOf<T>>;
212
213 pub fn native_value(mut self, value: BalanceOf<T>) -> Self {
215 self.evm_value = Pallet::<T>::convert_native_to_evm(value);
216 self
217 }
218
219 pub fn build_and_unwrap_result(self) -> ExecReturnValue {
221 self.build().result.unwrap()
222 }
223
224 pub fn bare_call(origin: OriginFor<T>, dest: H160) -> Self {
226 Self {
227 origin,
228 dest,
229 evm_value: Default::default(),
230 gas_limit: GAS_LIMIT,
231 storage_deposit_limit: DepositLimit::Balance(deposit_limit::<T>()),
232 data: vec![],
233 }
234 }
235);
236
237builder!(
238 eth_call(
239 origin: OriginFor<T>,
240 dest: H160,
241 value: U256,
242 gas_limit: Weight,
243 storage_deposit_limit: BalanceOf<T>,
244 data: Vec<u8>,
245 ) -> DispatchResultWithPostInfo;
246
247 pub fn eth_call(origin: OriginFor<T>, dest: H160) -> Self {
249 Self {
250 origin,
251 dest,
252 value: 0u32.into(),
253 gas_limit: GAS_LIMIT,
254 storage_deposit_limit: deposit_limit::<T>(),
255 data: vec![],
256 }
257 }
258);