Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a separate error for nonexistent contract input #868

Merged
merged 5 commits into from
Dec 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

### Breaking
- [863](https://github.com/FuelLabs/fuel-vm/pull/863): Changed StorageRead::read to load a serialized value starting from a offset. The function returns an optional value equal to the number of bytes read when defined, or none if the offset specified in input is outside the boundaries of the serialized value read.
- [868](https://github.com/FuelLabs/fuel-vm/pull/868): Fixed error message when having a nonexistent contract in inputs. Instead of saying "contract was in inputs, but doesn't exist", the message was just "contract not in inputs". Now there's a separate error for that.

## [Version 0.58.2]

Expand Down
3 changes: 2 additions & 1 deletion fuel-asm/src/panic_reason.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,8 @@ enum_from! {
UnsupportedOperationType = 0x3a,
/// Read alt_bn_128 curve point is invalid.
InvalidEllipticCurvePoint = 0x3b,

/// Given input contract does not exist.
InputContractDoesNotExist = 0x3c,
}
}

Expand Down
64 changes: 51 additions & 13 deletions fuel-vm/src/interpreter/executors/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ use fuel_tx::{
Input,
Receipt,
ScriptExecutionResult,
Transaction,
Upgrade,
UpgradeMetadata,
UpgradePurpose,
Expand Down Expand Up @@ -845,12 +846,59 @@ where
}

pub(crate) fn run(&mut self) -> Result<ProgramState, InterpreterError<S::DataError>> {
for input in self.transaction().inputs() {
if let Input::Contract(contract) = input {
if !self.check_contract_exists(&contract.contract_id)? {
return Err(InterpreterError::Panic(
PanicReason::InputContractDoesNotExist,
));
}
}
}

// TODO: Remove `Create`, `Upgrade`, and `Upload` from here
// https://github.com/FuelLabs/fuel-vm/issues/251
let gas_costs = self.gas_costs().clone();
let fee_params = *self.fee_params();
let base_asset_id = *self.base_asset_id();
let gas_price = self.gas_price();

#[cfg(debug_assertions)]
// The `match` statement exists to ensure that all variants of `Transaction`
// are handled below. If a new variant is added, the compiler will
// emit an error.
{
let mint: Transaction = Transaction::mint(
Default::default(),
Default::default(),
Default::default(),
Default::default(),
Default::default(),
Default::default(),
)
.into();
match mint {
Transaction::Create(_) => {
// Handled in the `self.tx.as_create_mut()` branch.
}
Transaction::Upgrade(_) => {
// Handled in the `self.tx.as_upgrade_mut()` branch.
}
Transaction::Upload(_) => {
// Handled in the `self.tx.as_upload_mut()` branch.
}
Transaction::Blob(_) => {
// Handled in the `self.tx.as_blob_mut()` branch.
}
Transaction::Script(_) => {
// Handled in the `else` branch.
}
Transaction::Mint(_) => {
// The `Mint` transaction doesn't implement `ExecutableTransaction`.
}
};
}

let state = if let Some(create) = self.tx.as_create_mut() {
Self::deploy_inner(
create,
Expand Down Expand Up @@ -896,25 +944,15 @@ where
)?;
ProgramState::Return(1)
} else {
if self.transaction().inputs().iter().any(|input| {
if let Input::Contract(contract) = input {
!self
.check_contract_exists(&contract.contract_id)
.unwrap_or(false)
} else {
false
}
}) {
return Err(InterpreterError::Panic(PanicReason::ContractNotInInputs));
}

let gas_limit;
let is_empty_script;
if let Some(script) = self.transaction().as_script() {
gas_limit = *script.script_gas_limit();
is_empty_script = script.script().is_empty();
} else {
unreachable!("Only `Create` and `Script` transactions can be executed inside of the VM")
unreachable!(
"Only `Script` transactions can be executed inside of the VM"
)
}

// TODO set tree balance
Expand Down
Loading