From b69d8a87403c6118a4a665ff3af15f078f46ad53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20Leegwater=20Sim=C3=B5es?= Date: Mon, 18 Mar 2024 11:25:28 +0100 Subject: [PATCH 1/2] piecrust: allow feeder calls to set the gas limit Resolves #344 --- piecrust/CHANGELOG.md | 6 ++++++ piecrust/src/session.rs | 11 ++++++----- piecrust/tests/feeder.rs | 4 +++- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/piecrust/CHANGELOG.md b/piecrust/CHANGELOG.md index 97e3a9bb..18a2d38f 100644 --- a/piecrust/CHANGELOG.md +++ b/piecrust/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed + +- Change `Session::feeder_call` and `Session::feeder_call_raw` to allow for the + caller to specify the gas limit [#344] + ## [0.17.0] - 2024-02-28 ### Added @@ -379,6 +384,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 +[#344]: https://github.com/dusk-network/piecrust/issues/344 [#336]: https://github.com/dusk-network/piecrust/issues/336 [#325]: https://github.com/dusk-network/piecrust/issues/325 [#324]: https://github.com/dusk-network/piecrust/issues/324 diff --git a/piecrust/src/session.rs b/piecrust/src/session.rs index cb605740..71e9f1a2 100644 --- a/piecrust/src/session.rs +++ b/piecrust/src/session.rs @@ -465,14 +465,14 @@ impl Session { /// Feeder calls are used to have the contract be able to report larger /// amounts of data to the host via the channel included in this call. /// - /// These calls are always performed with the maximum amount of gas, since - /// the contracts may spend quite a large amount in an effort to report - /// data. + /// These calls should be performed with a large amount of gas, since the + /// contracts may spend quite a large amount in an effort to report data. pub fn feeder_call( &mut self, contract: ContractId, fn_name: &str, fn_arg: &A, + gas_limit: u64, feeder: mpsc::Sender>, ) -> Result, Error> where @@ -483,7 +483,7 @@ impl Session { + for<'b> CheckBytes>, { self.inner.feeder = Some(feeder); - let r = self.call(contract, fn_name, fn_arg, u64::MAX); + let r = self.call(contract, fn_name, fn_arg, gas_limit); self.inner.feeder = None; r } @@ -500,10 +500,11 @@ impl Session { contract: ContractId, fn_name: &str, fn_arg: V, + gas_limit: u64, feeder: mpsc::Sender>, ) -> Result>, Error> { self.inner.feeder = Some(feeder); - let r = self.call_raw(contract, fn_name, fn_arg, u64::MAX); + let r = self.call_raw(contract, fn_name, fn_arg, gas_limit); self.inner.feeder = None; r } diff --git a/piecrust/tests/feeder.rs b/piecrust/tests/feeder.rs index cfe0eca1..9c0e1686 100644 --- a/piecrust/tests/feeder.rs +++ b/piecrust/tests/feeder.rs @@ -24,10 +24,12 @@ fn feed() -> Result<(), Error> { )?; const FEED_NUM: u32 = 10; + const GAS_LIMIT: u64 = 1_000_000; let (sender, receiver) = mpsc::channel(); - session.feeder_call::<_, ()>(id, "feed_num", &FEED_NUM, sender)?; + session + .feeder_call::<_, ()>(id, "feed_num", &FEED_NUM, GAS_LIMIT, sender)?; let numbers = receiver .into_iter() From d3f0364cb01d23a4886c6337fceaca85e6d4fbcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20Leegwater=20Sim=C3=B5es?= Date: Tue, 19 Mar 2024 11:41:51 +0100 Subject: [PATCH 2/2] piecrust: add out-of-gas tests for feeder calls --- piecrust/tests/feeder.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/piecrust/tests/feeder.rs b/piecrust/tests/feeder.rs index 9c0e1686..a9bd7dee 100644 --- a/piecrust/tests/feeder.rs +++ b/piecrust/tests/feeder.rs @@ -71,3 +71,29 @@ fn feed_errors_when_normal_call() -> Result<(), Error> { Ok(()) } + +#[test] +fn feed_out_of_gas() -> Result<(), Error> { + let vm = VM::ephemeral()?; + + let mut session = vm.session(SessionData::builder())?; + + let id = session.deploy( + contract_bytecode!("feeder"), + ContractData::builder().owner(OWNER), + LIMIT, + )?; + + const FEED_NUM: u32 = 100; + const GAS_LIMIT: u64 = 1_000; + + let (sender, _receiver) = mpsc::channel(); + + let err = session + .feeder_call::<_, ()>(id, "feed_num", &FEED_NUM, GAS_LIMIT, sender) + .expect_err("Call should error when out of gas"); + + assert!(matches!(err, Error::OutOfGas)); + + Ok(()) +}