Skip to content

Commit 0dc4c06

Browse files
author
Eduardo Leegwater Simões
committed
piecrust: use empty constructor arguments by default
Previously we were erroring out when providing no arguments for a constructor that takes no argument. This is undesirable since downstream does not necessarily know that the contract they deploy has a constructor. A contract that is provided an argument that it doesn't expect will still error at deploy time, during execution of the constructor. Resolves #316
1 parent 56ae082 commit 0dc4c06

File tree

3 files changed

+17
-24
lines changed

3 files changed

+17
-24
lines changed

piecrust/CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Changed
1111

12+
- Use empty constructor arguments by default [#316]
1213
- Upgrade `dusk-wasmtime` to version `18`
1314

1415
## [0.16.0] - 2024-02-14
@@ -366,6 +367,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
366367
<!-- ISSUES -->
367368
[#325]: https://github.com/dusk-network/piecrust/issues/325
368369
[#324]: https://github.com/dusk-network/piecrust/issues/324
370+
[#316]: https://github.com/dusk-network/piecrust/issues/316
369371
[#301]: https://github.com/dusk-network/piecrust/issues/313
370372
[#301]: https://github.com/dusk-network/piecrust/issues/301
371373
[#296]: https://github.com/dusk-network/piecrust/issues/296

piecrust/src/session.rs

+7-16
Original file line numberDiff line numberDiff line change
@@ -289,22 +289,13 @@ impl Session {
289289
let instance =
290290
self.instance(&contract_id).expect("instance should exist");
291291

292-
let has_init = instance.is_function_exported(INIT_METHOD);
293-
if has_init && arg.is_none() {
294-
return Err(InitalizationError(
295-
"Contract has constructor but no argument was provided"
296-
.into(),
297-
));
298-
}
299-
300-
if let Some(arg) = arg {
301-
if !has_init {
302-
return Err(InitalizationError(
303-
"Argument was provided but contract has no constructor"
304-
.into(),
305-
));
306-
}
307-
292+
if instance.is_function_exported(INIT_METHOD) {
293+
// If no argument was provided, we call the constructor anyway,
294+
// but with an empty argument. The alternative is to panic, but
295+
// that assumes that the caller of `deploy` knows that the
296+
// contract has a constructor in the first place, which might
297+
// not be the case, such as when ingesting untrusted bytecode.
298+
let arg = arg.unwrap_or_default();
308299
self.call_inner(contract_id, INIT_METHOD, arg, gas_limit)?;
309300
}
310301

piecrust/tests/constructor.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -73,20 +73,20 @@ fn constructor() -> Result<(), Error> {
7373
}
7474

7575
#[test]
76-
fn missing_init() -> Result<(), Error> {
76+
fn empty_constructor_argument() -> Result<(), Error> {
7777
let vm = VM::ephemeral()?;
7878

7979
let mut session = vm.session(SessionData::builder())?;
8080

81-
let result = session.deploy(
82-
contract_bytecode!("counter"),
83-
ContractData::builder(OWNER).constructor_arg(&0xabu8),
81+
let id = session.deploy(
82+
contract_bytecode!("empty_constructor"),
83+
ContractData::builder(OWNER),
8484
LIMIT,
85-
);
85+
)?;
8686

87-
assert!(
88-
result.is_err(),
89-
"deploy with data when the 'init' method is not exported should fail with an error"
87+
assert_eq!(
88+
session.call::<_, u8>(id, "read_value", &(), LIMIT)?.data,
89+
0x10
9090
);
9191

9292
Ok(())

0 commit comments

Comments
 (0)