No flags found
Use flags to group coverage reports by test type, project and/or folders.
Then setup custom commit statuses and notifications for each flag.
e.g., #unittest #integration
#production #enterprise
#frontend #backend
d9c17b6
... +2 ...
e646ddd
Use flags to group coverage reports by test type, project and/or folders.
Then setup custom commit statuses and notifications for each flag.
e.g., #unittest #integration
#production #enterprise
#frontend #backend
73 | 73 | /// Configuration for execution of ink! constructor. |
|
74 | 74 | #[derive(Debug, Copy, Clone)] |
|
75 | 75 | pub struct ExecuteConstructorConfig { |
|
76 | + | /// Yields `true` if the ink! constructor accepts payment. |
|
77 | + | pub payable: bool, |
|
76 | 78 | /// Yields `true` if the dynamic storage allocator has been enabled. |
|
77 | 79 | /// |
|
78 | 80 | /// # Note |
93 | 95 | f: F, |
|
94 | 96 | ) -> Result<(), DispatchError> |
|
95 | 97 | where |
|
96 | - | Contract: SpreadLayout + ContractRootKey, |
|
98 | + | Contract: SpreadLayout + ContractRootKey + ContractEnv, |
|
97 | 99 | F: FnOnce() -> R, |
|
98 | 100 | <private::Seal<R> as ConstructorReturnType<Contract>>::ReturnValue: scale::Encode, |
|
99 | 101 | private::Seal<R>: ConstructorReturnType<Contract>, |
|
100 | 102 | { |
|
103 | + | if !config.payable { |
|
104 | + | deny_payment::<<Contract as ContractEnv>::Env>()?; |
|
105 | + | } |
|
101 | 106 | if config.dynamic_storage_alloc { |
|
102 | 107 | alloc::initialize(ContractPhase::Deploy); |
|
103 | 108 | } |
280 | 285 | #[derive(Debug, Copy, Clone)] |
|
281 | 286 | pub struct ExecuteMessageConfig { |
|
282 | 287 | /// Yields `true` if the ink! message accepts payment. |
|
283 | - | /// |
|
284 | - | /// # Note |
|
285 | - | /// |
|
286 | - | /// If no ink! message within the same ink! smart contract |
|
287 | - | /// is payable then this flag will be `true` since the check |
|
288 | - | /// then is moved before the message dispatch as an optimization. |
|
289 | 288 | pub payable: bool, |
|
290 | 289 | /// Yields `true` if the ink! message might mutate contract storage. |
|
291 | 290 | /// |
67 | 67 | pub struct Constructor { |
|
68 | 68 | /// The underlying Rust method item. |
|
69 | 69 | pub(super) item: syn::ImplItemMethod, |
|
70 | + | /// If the ink! constructor can receive funds. |
|
71 | + | is_payable: bool, |
|
70 | 72 | /// An optional user provided selector. |
|
71 | 73 | /// |
|
72 | 74 | /// # Note |
158 | 160 | &ir::AttributeArgKind::Constructor, |
|
159 | 161 | |arg| { |
|
160 | 162 | match arg.kind() { |
|
161 | - | ir::AttributeArg::Constructor | ir::AttributeArg::Selector(_) => { |
|
162 | - | Ok(()) |
|
163 | - | } |
|
164 | - | ir::AttributeArg::Payable => { |
|
165 | - | Err(Some(format_err!( |
|
166 | - | arg.span(), |
|
167 | - | "constructors are implicitly payable" |
|
168 | - | ))) |
|
169 | - | } |
|
163 | + | ir::AttributeArg::Constructor |
|
164 | + | | ir::AttributeArg::Payable |
|
165 | + | | ir::AttributeArg::Selector(_) => Ok(()), |
|
170 | 166 | _ => Err(None), |
|
171 | 167 | } |
|
172 | 168 | }, |
182 | 178 | Self::ensure_valid_return_type(&method_item)?; |
|
183 | 179 | Self::ensure_no_self_receiver(&method_item)?; |
|
184 | 180 | let (ink_attrs, other_attrs) = Self::sanitize_attributes(&method_item)?; |
|
181 | + | let is_payable = ink_attrs.is_payable(); |
|
185 | 182 | let selector = ink_attrs.selector(); |
|
186 | 183 | Ok(Constructor { |
|
187 | 184 | selector, |
|
185 | + | is_payable, |
|
188 | 186 | item: syn::ImplItemMethod { |
|
189 | 187 | attrs: other_attrs, |
|
190 | 188 | ..method_item |
217 | 215 | } |
|
218 | 216 | ||
219 | 217 | fn is_payable(&self) -> bool { |
|
220 | - | true |
|
218 | + | self.is_payable |
|
221 | 219 | } |
|
222 | 220 | ||
223 | 221 | fn visibility(&self) -> Visibility { |
302 | 300 | } |
|
303 | 301 | } |
|
304 | 302 | ||
303 | + | #[test] |
|
304 | + | fn is_payable_works() { |
|
305 | + | let test_inputs: Vec<(bool, syn::ImplItemMethod)> = vec![ |
|
306 | + | // Not payable. |
|
307 | + | ( |
|
308 | + | false, |
|
309 | + | syn::parse_quote! { |
|
310 | + | #[ink(constructor)] |
|
311 | + | fn my_constructor() -> Self {} |
|
312 | + | }, |
|
313 | + | ), |
|
314 | + | // Normalized ink! attribute. |
|
315 | + | ( |
|
316 | + | true, |
|
317 | + | syn::parse_quote! { |
|
318 | + | #[ink(constructor, payable)] |
|
319 | + | pub fn my_constructor() -> Self {} |
|
320 | + | }, |
|
321 | + | ), |
|
322 | + | // Different ink! attributes. |
|
323 | + | ( |
|
324 | + | true, |
|
325 | + | syn::parse_quote! { |
|
326 | + | #[ink(constructor)] |
|
327 | + | #[ink(payable)] |
|
328 | + | pub fn my_constructor() -> Self {} |
|
329 | + | }, |
|
330 | + | ), |
|
331 | + | // Another ink! attribute, separate and normalized attribute. |
|
332 | + | ( |
|
333 | + | true, |
|
334 | + | syn::parse_quote! { |
|
335 | + | #[ink(constructor)] |
|
336 | + | #[ink(selector = 0xDEADBEEF, payable)] |
|
337 | + | pub fn my_constructor() -> Self {} |
|
338 | + | }, |
|
339 | + | ), |
|
340 | + | ]; |
|
341 | + | for (expect_payable, item_method) in test_inputs { |
|
342 | + | let is_payable = <ir::Constructor as TryFrom<_>>::try_from(item_method) |
|
343 | + | .unwrap() |
|
344 | + | .is_payable(); |
|
345 | + | assert_eq!(is_payable, expect_payable); |
|
346 | + | } |
|
347 | + | } |
|
348 | + | ||
305 | 349 | #[test] |
|
306 | 350 | fn visibility_works() { |
|
307 | 351 | let test_inputs: Vec<(bool, syn::ImplItemMethod)> = vec![ |
577 | 621 | #[ink(event)] |
|
578 | 622 | fn my_constructor() -> Self {} |
|
579 | 623 | }, |
|
580 | - | // constructor + payable |
|
581 | - | syn::parse_quote! { |
|
582 | - | #[ink(constructor)] |
|
583 | - | #[ink(payable)] |
|
584 | - | fn my_constructor() -> Self {} |
|
585 | - | }, |
|
586 | 624 | ]; |
|
587 | 625 | for item_method in item_methods { |
|
588 | 626 | assert_try_from_fails( |
386 | 386 | output: &mut [u8; 33], |
|
387 | 387 | ) -> Result { |
|
388 | 388 | use secp256k1::{ |
|
389 | - | recovery::{ |
|
389 | + | ecdsa::{ |
|
390 | 390 | RecoverableSignature, |
|
391 | 391 | RecoveryId, |
|
392 | 392 | }, |
415 | 415 | }); |
|
416 | 416 | ||
417 | 417 | let secp = Secp256k1::new(); |
|
418 | - | let pub_key = secp.recover(&message, &signature); |
|
418 | + | let pub_key = secp.recover_ecdsa(&message, &signature); |
|
419 | 419 | match pub_key { |
|
420 | 420 | Ok(pub_key) => { |
|
421 | 421 | *output = pub_key.serialize(); |
1 | + | use ink_lang as ink; |
|
2 | + | ||
3 | + | #[ink::contract] |
|
4 | + | mod contract { |
|
5 | + | #[ink(storage)] |
|
6 | + | pub struct Contract {} |
|
7 | + | ||
8 | + | impl Contract { |
|
9 | + | #[ink(constructor, selector = 0)] |
|
10 | + | pub fn constructor() -> Self { |
|
11 | + | Self {} |
|
12 | + | } |
|
13 | + | ||
14 | + | #[ink(message)] |
|
15 | + | pub fn message(&self) {} |
|
16 | + | } |
|
17 | + | } |
|
18 | + | ||
19 | + | use contract::Contract; |
|
20 | + | ||
21 | + | fn main() { |
|
22 | + | assert!(!<Contract as ::ink_lang::reflect::DispatchableConstructorInfo<0>>::PAYABLE); |
|
23 | + | } |
252 | 252 | output: &mut [u8; 33], |
|
253 | 253 | ) -> Result<()> { |
|
254 | 254 | use secp256k1::{ |
|
255 | - | recovery::{ |
|
255 | + | ecdsa::{ |
|
256 | 256 | RecoverableSignature, |
|
257 | 257 | RecoveryId, |
|
258 | 258 | }, |
279 | 279 | }); |
|
280 | 280 | ||
281 | 281 | let secp = Secp256k1::new(); |
|
282 | - | let pub_key = secp.recover(&message, &signature); |
|
282 | + | let pub_key = secp.recover_ecdsa(&message, &signature); |
|
283 | 283 | match pub_key { |
|
284 | 284 | Ok(pub_key) => { |
|
285 | 285 | *output = pub_key.serialize(); |
Learn more Showing 5 files with coverage changes found.
crates/lang/ir/src/ir/attrs.rs
crates/lang/tests/ui/contract/pass/constructor-non-payable-multiple.rs
crates/lang/tests/ui/contract/pass/constructor-non-payable.rs
crates/lang/tests/ui/contract/pass/constructor-payable.rs
crates/lang/tests/ui/contract/pass/constructor-payable-multiple.rs
Files | Coverage |
---|---|
call | 28.33% |
engine | 68.02% |
api.rs | 36.36% |
arithmetic.rs | 100.00% |
backend.rs | 80.65% |
chain_extension.rs | 0.00% |
topics.rs | 100.00% |
types.rs | 22.22% |
Folder Totals (8 files) | 58.64% |
Project Totals (252 files) | 78.83% |
e646ddd
67ad398
9ce2509
d9c17b6