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

PanicReason rework #477

Merged
merged 5 commits into from
Jun 13, 2023
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
9 changes: 6 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ Description of the upcoming release here.

### Changed

#### Breaking

- [#477](https://github.com/FuelLabs/fuel-vm/pull/477): The `PanicReason::UnknownPanicReason` is `0x00`.
The `PanicReason` now implements `From<u8>` instead of `TryFrom<u8>` and can't return an error anymore.

- [#478](https://github.com/FuelLabs/fuel-vm/pull/478): The `memcopy` method is updated
and returns `MemoryWriteOverlap` instead of `MemoryOverflow`.

Expand All @@ -29,12 +34,9 @@ Description of the upcoming release here.
leaves by setting the leaf key to the hash of an existing leaf or node. This is
done by removing the insertion of the leaf using the leaf key.


- [#484](https://github.com/FuelLabs/fuel-vm/pull/484): Fixed bug with not-working `CreateMetadata`.


- [#484](https://github.com/FuelLabs/fuel-vm/pull/484): Fixed bug with not-working `CreateMetadata`.

#### Breaking

- [#473](https://github.com/FuelLabs/fuel-vm/pull/473): CFS and CFSI were not validating
Expand All @@ -51,6 +53,7 @@ Description of the upcoming release here.

- [#478](https://github.com/FuelLabs/fuel-vm/pull/478): The `CheckedMemRange` is replaced by the `MemoryRange`.


## [Version 0.33.0]

The release contains a lot of breaking changes.
Expand Down
38 changes: 1 addition & 37 deletions fuel-asm/src/encoding_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,43 +69,7 @@ fn opcode() {
fn panic_reason_description() {
let imm24 = 0xbfffff;

let reasons = vec![
PanicReason::Revert,
PanicReason::OutOfGas,
PanicReason::TransactionValidity,
PanicReason::MemoryOverflow,
PanicReason::ArithmeticOverflow,
PanicReason::ContractNotFound,
PanicReason::MemoryOwnership,
PanicReason::NotEnoughBalance,
PanicReason::ExpectedInternalContext,
PanicReason::AssetIdNotFound,
PanicReason::InputNotFound,
PanicReason::OutputNotFound,
PanicReason::WitnessNotFound,
PanicReason::TransactionMaturity,
PanicReason::InvalidMetadataIdentifier,
PanicReason::MalformedCallStructure,
PanicReason::ReservedRegisterNotWritable,
PanicReason::ErrorFlag,
PanicReason::InvalidImmediateValue,
PanicReason::ExpectedCoinInput,
PanicReason::MaxMemoryAccess,
PanicReason::MemoryWriteOverlap,
PanicReason::ContractNotInInputs,
PanicReason::InternalBalanceOverflow,
PanicReason::ContractMaxSize,
PanicReason::ExpectedUnallocatedStack,
PanicReason::MaxStaticContractsReached,
PanicReason::TransferAmountCannotBeZero,
PanicReason::ExpectedOutputVariable,
PanicReason::ExpectedParentInternalContext,
PanicReason::IllegalJump,
PanicReason::ArithmeticError,
PanicReason::ContractInstructionNotAllowed,
];

for r in reasons {
for r in PanicReason::iter() {
let b = r as u8;
let r_p = PanicReason::try_from(b).expect("Should get panic reason");
let w = Word::from(r as u8);
Expand Down
11 changes: 4 additions & 7 deletions fuel-asm/src/panic_instruction.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use crate::panic_reason::InvalidPanicReason;
use crate::{Instruction, PanicReason, RawInstruction, Word};

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
Expand Down Expand Up @@ -39,15 +38,13 @@ impl From<PanicInstruction> for Word {
}
}

impl TryFrom<Word> for PanicInstruction {
type Error = InvalidPanicReason;

fn try_from(val: Word) -> Result<Self, Self::Error> {
impl From<Word> for PanicInstruction {
fn from(val: Word) -> Self {
// Safe to cast as we've shifted the 8 MSB.
let reason_u8 = (val >> REASON_OFFSET) as u8;
// Cast to truncate in order to remove the `reason` bits.
let instruction = (val >> INSTR_OFFSET) as u32;
let reason = PanicReason::try_from(reason_u8)?;
Ok(Self { reason, instruction })
let reason = PanicReason::from(reason_u8);
Self { reason, instruction }
}
}
57 changes: 15 additions & 42 deletions fuel-asm/src/panic_reason.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
use core::{convert, fmt};
use core::fmt;

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, strum::EnumIter)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[repr(u8)]
#[non_exhaustive]
/// Panic reason representation for the interpreter.
pub enum PanicReason {
/// The byte can't be mapped to any known `PanicReason`.
UnknownPanicReason = 0x00,
/// Found `RVRT` instruction.
Revert = 0x01,
/// Execution ran out of gas.
Expand Down Expand Up @@ -82,8 +84,6 @@ pub enum PanicReason {
ArithmeticError = 0x23,
/// The contract instruction is not allowed in predicates.
ContractInstructionNotAllowed = 0x24,
/// The byte can't be mapped to any known `PanicReason`.
UnknownPanicReason = 0x25,
}

impl fmt::Display for PanicReason {
Expand All @@ -99,28 +99,11 @@ impl std::error::Error for PanicReason {
}
}

// TODO: Remove this - `Infallible` has nothing to do with `PanicReason`.
impl From<convert::Infallible> for PanicReason {
fn from(_i: convert::Infallible) -> Self {
unreachable!()
}
}

/// Failed to parse a `u8` as a valid panic reason.
#[derive(Debug, Eq, PartialEq)]
pub struct InvalidPanicReason;

impl TryFrom<u8> for PanicReason {
type Error = InvalidPanicReason;

impl From<u8> for PanicReason {
/// Converts the `u8` into a `PanicReason`.
fn try_from(b: u8) -> Result<Self, Self::Error> {
if b == 0 {
return Err(InvalidPanicReason);
}

fn from(b: u8) -> Self {
use PanicReason::*;
let reason = match b {
match b {
0x01 => Revert,
0x02 => OutOfGas,
0x03 => TransactionValidity,
Expand Down Expand Up @@ -158,18 +141,7 @@ impl TryFrom<u8> for PanicReason {
0x23 => ArithmeticError,
0x24 => ContractInstructionNotAllowed,
_ => UnknownPanicReason,
};

Ok(reason)
}
}

#[cfg(feature = "std")]
impl From<InvalidPanicReason> for std::io::Error {
fn from(_: InvalidPanicReason) -> Self {
use std::io;

io::Error::new(io::ErrorKind::InvalidInput, "Panic reason can't be zero")
}
}
}

Expand All @@ -191,20 +163,21 @@ impl From<core::array::TryFromSliceError> for PanicReason {
#[cfg(test)]
mod tests {
use super::*;
use strum::IntoEnumIterator;

#[test]
fn test_u8_panic_reason_round_trip() {
const LAST_PANIC_REASON: u8 = PanicReason::UnknownPanicReason as u8;
let reason = PanicReason::try_from(0);
assert!(reason.is_err());
let last_known_panic_reason: u8 = PanicReason::iter().last().unwrap() as u8 + 1;
let reason = PanicReason::from(0);
assert_eq!(reason, PanicReason::UnknownPanicReason);

for i in 1..LAST_PANIC_REASON {
for i in 1..last_known_panic_reason {
let reason = PanicReason::try_from(i).unwrap();
let i2 = reason as u8;
assert_eq!(i, i2);
}
for i in LAST_PANIC_REASON..=255 {
let reason = PanicReason::try_from(i).unwrap();
for i in last_known_panic_reason..=255 {
let reason = PanicReason::from(i);
let i2 = reason as u8;
assert_eq!(PanicReason::UnknownPanicReason as u8, i2);
}
Expand Down
2 changes: 1 addition & 1 deletion fuel-tx/src/receipt/receipt_std.rs
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ impl io::Write for Receipt {

let id = id.into();

*self = Self::panic(id, PanicInstruction::try_from(reason)?, pc, is);
*self = Self::panic(id, PanicInstruction::from(reason), pc, is);
}

ReceiptRepr::Revert => {
Expand Down
Loading