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

no_std support for fuel-tx and fuel-vm #582

Merged
merged 49 commits into from
Sep 22, 2023
Merged
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
9df7764
WIP
Dentosal Sep 1, 2023
b5c74f4
WIP: use k256 crate for no_std compliant cryptography
Dentosal Sep 1, 2023
2812411
Merge branch 'master' into dento/nostd_crypto
Dentosal Sep 1, 2023
6b7f326
Re-add secp256k1 crate support, add backend selection
Dentosal Sep 5, 2023
4eda0ee
Fix clippy issues with features on/off
Dentosal Sep 7, 2023
f1c6df6
Merge branch 'master' into dento/nostd_crypto
Dentosal Sep 7, 2023
dcd67d9
Fmt toml files
Dentosal Sep 7, 2023
f9465cb
Cleanup for CI
Dentosal Sep 7, 2023
637368b
Add changelog entry
Dentosal Sep 7, 2023
b68c1c5
Doc-tests cleanup
Dentosal Sep 7, 2023
1640c4e
Rename secp module to secp256
Dentosal Sep 7, 2023
73bd6c1
Fix warnings with no_std target
Dentosal Sep 7, 2023
94ad309
Run checks for no_std fuel-crypto
Dentosal Sep 7, 2023
24cad19
WIP
Dentosal Sep 7, 2023
14b19c3
Merge branch 'master' into dento/nostd
Dentosal Sep 11, 2023
4537fbd
WIP
Dentosal Sep 13, 2023
926643c
WIP: before attempting to un-indirect error types
Dentosal Sep 13, 2023
c0f193d
Error type rework
Dentosal Sep 13, 2023
3838725
Change deps from last commit to be no_std
Dentosal Sep 13, 2023
2511ad9
Make cargo check work under --target x86_64-unknown-none --features a…
Dentosal Sep 13, 2023
3f69a40
Toml fmt
Dentosal Sep 13, 2023
a2ee758
Move more stuff out of #[cfg(feature = "std")]
Dentosal Sep 13, 2023
3d255a9
Cleanup fuel-asm cfgs
Dentosal Sep 13, 2023
b45cbdf
Add changelog
Dentosal Sep 13, 2023
7475926
Move some fuel-asm gates from std to alloc feature
Dentosal Sep 13, 2023
6a7129c
Clippy fixes
Dentosal Sep 13, 2023
438f9db
Add missing no_std/alloc imports for fuel-vm tests (WIP)
Dentosal Sep 13, 2023
52bab5d
Finalize test import fixes
Dentosal Sep 13, 2023
e7e9805
Merge branch 'master' into dento/nostd
Dentosal Sep 15, 2023
329efcd
Temporarily disable fuel-crypto self-dev-dep
Dentosal Sep 15, 2023
a4a3cae
Some cfg-related import fixes
Dentosal Sep 15, 2023
7dc6f6f
Fix changelog
Dentosal Sep 15, 2023
c56d7fa
Re-apply fuel-crypto self-dev-dep
Dentosal Sep 15, 2023
17a650d
Compatibility fixes for fuel-core
Dentosal Sep 16, 2023
aaf7ac4
Feature-gate fuel-vm tests behind alloc
Dentosal Sep 16, 2023
b417a64
Add riscv32imac-unknown-none-elf to cargo make matrix targets
Dentosal Sep 18, 2023
6d9229e
Remove unneeded alloc feature gating
Dentosal Sep 20, 2023
90d0050
Use alloc feature with tests
Dentosal Sep 20, 2023
be98b79
Remove a useless import
Dentosal Sep 20, 2023
1001bec
Use qualified path instead of an import
Dentosal Sep 20, 2023
d398c76
bugfix: StorageRead<ContractsRawCode> of MemoryStorage returned incor…
Dentosal Sep 20, 2023
20b5b5c
Update fuel-asm/src/encoding_tests.rs
Dentosal Sep 20, 2023
3ec9c1c
WIP: adding fully generic storage error (likely not)
Dentosal Sep 20, 2023
412c55f
more wip
Dentosal Sep 20, 2023
9ea67a8
WIP: tests passing again
Dentosal Sep 20, 2023
a7f6382
Cleanup: clippy
Dentosal Sep 20, 2023
618a6bd
Merge branch 'master' into dento/nostd
Dentosal Sep 21, 2023
4433b49
Minor moments after review
xgreenx Sep 21, 2023
94d1050
Change two match'es to map_err's
Dentosal Sep 21, 2023
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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ jobs:
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ env.RUST_VERSION }}
targets: "thumbv6m-none-eabi,wasm32-unknown-unknown"
targets: "thumbv6m-none-eabi,riscv32imac-unknown-none-elf,wasm32-unknown-unknown"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious - did you chose the IMAC extensions for any particular reason, or is that just a safe default?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's closes to the internal target used by risc-zero

components: "clippy"
- name: Install Cargo Make
uses: davidB/rust-cargo-make@v1
Expand Down
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

#### Breaking

- [#578](https://github.com/FuelLabs/fuel-vm/pull/578): Support `no_std` environments for `fuel-crypto`, falling back to a pure-Rust crypto implementation.
- [#582](https://github.com/FuelLabs/fuel-vm/pull/582): Make `fuel-vm` and `fuel-tx` crates compatible with `no_std` + `alloc`. This includes reworking all error handling that used `std::io::Error`, replacing some `std::collection::{HashMap, HashSet}` with `hashbrown::{HashMap, HashSet}` and many changes to feature-gating of APIs.

## [Version 0.37.0]

#### Breaking
Expand All @@ -16,7 +21,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
These opcodes charged inadequately low costs in comparison to the amount of work.
This change should make all transactions that used these opcodes much more expensive than before.
- [#533](https://github.com/FuelLabs/fuel-vm/pull/533): Use custom serialization for fuel-types to allow no_std compilation.
- [#578](https://github.com/FuelLabs/fuel-vm/pull/578): Support `no_std` environments for `fuel-crypto`, falling back to a pure-Rust crypto implementation.

## [Version 0.36.1]

Expand Down
3 changes: 2 additions & 1 deletion fuel-asm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ rstest = "0.16"
[features]
default = ["std"]
typescript = ["wasm-bindgen", "wee_alloc"]
std = ["serde?/default", "fuel-types/std"]
std = ["alloc", "serde?/default", "fuel-types/std"]
alloc = ["fuel-asm/alloc"]
serde = ["dep:serde"]

# docs.rs-specific configuration
Expand Down
1 change: 1 addition & 0 deletions fuel-asm/src/encoding_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use fuel_asm as _;
use strum::IntoEnumIterator;

#[test]
#[cfg(tests)]
fn opcode() {
// values picked to test edge cases
let r = RegId::new_checked(0x2d).unwrap();
Expand Down
13 changes: 8 additions & 5 deletions fuel-asm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@
#![deny(unsafe_code)]
#![deny(unused_crate_dependencies)]

#[cfg(feature = "alloc")]
extern crate alloc;

#[cfg(feature = "wee_alloc")]
use wee_alloc as _;

#[cfg(all(no_std, feature = "wee_alloc"))]
// Use `wee_alloc` as the global allocator.
#[cfg(all(no_std, feature = "wee_alloc"))]
#[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;

Expand Down Expand Up @@ -877,15 +880,15 @@ where

// Collect instructions into bytes or halfwords

#[cfg(feature = "std")]
impl core::iter::FromIterator<Instruction> for Vec<u8> {
#[cfg(feature = "alloc")]
impl core::iter::FromIterator<Instruction> for alloc::vec::Vec<u8> {
fn from_iter<I: IntoIterator<Item = Instruction>>(iter: I) -> Self {
iter.into_iter().flat_map(Instruction::to_bytes).collect()
}
}

#[cfg(feature = "std")]
impl core::iter::FromIterator<Instruction> for Vec<u32> {
#[cfg(feature = "alloc")]
impl core::iter::FromIterator<Instruction> for alloc::vec::Vec<u32> {
fn from_iter<I: IntoIterator<Item = Instruction>>(iter: I) -> Self {
iter.into_iter().map(u32::from).collect()
}
Expand Down
16 changes: 0 additions & 16 deletions fuel-asm/src/panic_reason.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,22 +120,6 @@ impl fmt::Display for PanicReason {
}
}

#[cfg(feature = "std")]
impl std::error::Error for PanicReason {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
None
}
}

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

io::Error::new(io::ErrorKind::Other, reason)
}
}

impl From<core::array::TryFromSliceError> for PanicReason {
fn from(_: core::array::TryFromSliceError) -> Self {
Self::MemoryOverflow
Expand Down
2 changes: 1 addition & 1 deletion fuel-crypto/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
#![deny(unsafe_code)]
#![deny(unused_crate_dependencies)]

#[cfg(test)]
// Satisfy unused_crate_dependencies lint for self-dependency enabling test features
#[cfg(test)]
use fuel_crypto as _;

/// Required export for using mnemonic keygen on [`SecretKey::new_from_mnemonic`]
Expand Down
1 change: 1 addition & 0 deletions fuel-crypto/src/secp256/backend/r1/p256.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ pub fn sign_prehashed(

/// Convert the public key point to its uncompressed non-prefixed representation,
/// i.e. 32 bytes of x coordinate and 32 bytes of y coordinate.
#[cfg(feature = "test-helpers")]
bvrooman marked this conversation as resolved.
Show resolved Hide resolved
pub fn encode_pubkey(key: VerifyingKey) -> [u8; 64] {
let point = key.to_encoded_point(false);
let mut result = [0u8; 64];
Expand Down
2 changes: 1 addition & 1 deletion fuel-merkle/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ thiserror = "1.0"

[features]
default = ["std"]
std = ["dep:thiserror", "digest/default", "hex/default", "sha2/default"]
std = ["dep:thiserror", "fuel-storage/std", "digest/default", "hex/default", "sha2/default"]
test-helpers = []

[[test]]
Expand Down
2 changes: 1 addition & 1 deletion fuel-merkle/benches/smt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ fn sparse_merkle_tree(c: &mut Criterion) {

let rng = &mut StdRng::seed_from_u64(8586);
let gen = || Some((MerkleTreeKey::new(random_bytes32(rng)), random_bytes32(rng)));
let data = std::iter::from_fn(gen).take(50_000).collect::<Vec<_>>();
let data = core::iter::from_fn(gen).take(50_000).collect::<Vec<_>>();

let expected_root = baseline_root(data.clone().into_iter());
let root = subject_root(data.clone().into_iter());
Expand Down
23 changes: 12 additions & 11 deletions fuel-merkle/src/binary/merkle_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@ use crate::{

use alloc::vec::Vec;
use core::marker::PhantomData;
use fuel_storage::StorageError;

#[derive(Debug, Clone)]
#[derive(Debug)]
#[cfg_attr(feature = "std", derive(thiserror::Error))]
pub enum MerkleTreeError<StorageError> {
bvrooman marked this conversation as resolved.
Show resolved Hide resolved
pub enum MerkleTreeError {
#[cfg_attr(feature = "std", error("proof index {0} is not valid"))]
InvalidProofIndex(u64),

Expand All @@ -40,8 +41,8 @@ pub enum MerkleTreeError<StorageError> {
StorageError(StorageError),
}

impl<StorageError> From<StorageError> for MerkleTreeError<StorageError> {
fn from(err: StorageError) -> MerkleTreeError<StorageError> {
impl From<StorageError> for MerkleTreeError {
fn from(err: StorageError) -> MerkleTreeError {
MerkleTreeError::StorageError(err)
}
}
Expand Down Expand Up @@ -130,10 +131,10 @@ impl<TableType, StorageType> MerkleTree<TableType, StorageType> {
}
}

impl<TableType, StorageType, StorageError> MerkleTree<TableType, StorageType>
impl<TableType, StorageType> MerkleTree<TableType, StorageType>
where
TableType: Mappable<Key = u64, Value = Primitive, OwnedValue = Primitive>,
StorageType: StorageInspect<TableType, Error = StorageError>,
StorageType: StorageInspect<TableType>,
{
pub fn new(storage: StorageType) -> Self {
Self {
Expand All @@ -147,7 +148,7 @@ where
pub fn load(
storage: StorageType,
leaves_count: u64,
) -> Result<Self, MerkleTreeError<StorageError>> {
) -> Result<Self, MerkleTreeError> {
let mut tree = Self {
storage,
head: None,
Expand All @@ -163,7 +164,7 @@ where
pub fn prove(
&self,
proof_index: u64,
) -> Result<(Bytes32, ProofSet), MerkleTreeError<StorageError>> {
) -> Result<(Bytes32, ProofSet), MerkleTreeError> {
if proof_index + 1 > self.leaves_count {
return Err(MerkleTreeError::InvalidProofIndex(proof_index))
}
Expand Down Expand Up @@ -291,7 +292,7 @@ where
///
/// By excluding the root position `07`, we have established the set of
/// side positions `03`, `09`, and `12`, matching our set of MMR peaks.
fn build(&mut self) -> Result<(), MerkleTreeError<StorageError>> {
fn build(&mut self) -> Result<(), MerkleTreeError> {
let mut current_head = None;
let peaks = &self.peak_positions();
for peak in peaks.iter() {
Expand All @@ -312,10 +313,10 @@ where
}
}

impl<TableType, StorageType, StorageError> MerkleTree<TableType, StorageType>
impl<TableType, StorageType> MerkleTree<TableType, StorageType>
where
TableType: Mappable<Key = u64, Value = Primitive, OwnedValue = Primitive>,
StorageType: StorageMutate<TableType, Error = StorageError>,
StorageType: StorageMutate<TableType>,
{
pub fn push(&mut self, data: &[u8]) -> Result<(), StorageError> {
let node = Node::create_leaf(self.leaves_count, data);
Expand Down
13 changes: 7 additions & 6 deletions fuel-merkle/src/common/node.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use crate::common::{
Bytes32,
Bytes8,
use crate::{
common::{
Bytes32,
Bytes8,
},
sparse::StorageNodeError,
};

use alloc::string::String;
Expand Down Expand Up @@ -29,14 +32,12 @@ pub trait Node {
}

pub trait ParentNode: Sized + Node {
type Error;

fn left_child(&self) -> ChildResult<Self>;
fn right_child(&self) -> ChildResult<Self>;
}

#[allow(type_alias_bounds)]
pub type ChildResult<T: ParentNode> = Result<T, ChildError<T::Key, T::Error>>;
pub type ChildResult<T: ParentNode> = Result<T, ChildError<T::Key, StorageNodeError>>;

#[derive(Debug, Clone)]
#[cfg_attr(feature = "std", derive(thiserror::Error))]
Expand Down
3 changes: 0 additions & 3 deletions fuel-merkle/src/common/path_iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,6 @@ mod test {
Bytes8,
};
use alloc::vec::Vec;
use core::convert::Infallible;

#[derive(Debug, Clone, PartialEq)]
struct TestNode {
Expand Down Expand Up @@ -273,8 +272,6 @@ mod test {
}

impl ParentNode for TestNode {
type Error = Infallible;

fn left_child(&self) -> ChildResult<Self> {
Ok(TestNode::child(self, -1))
}
Expand Down
3 changes: 0 additions & 3 deletions fuel-merkle/src/common/position.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use crate::common::{
Bytes8,
PositionPath,
};
use core::convert::Infallible;

/// # Position
///
Expand Down Expand Up @@ -273,8 +272,6 @@ impl Node for Position {
}

impl ParentNode for Position {
type Error = Infallible;

fn left_child(&self) -> ChildResult<Self> {
Ok(Position::left_child(*self))
}
Expand Down
14 changes: 8 additions & 6 deletions fuel-merkle/src/common/storage_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::{
};

use alloc::borrow::Cow;
use fuel_storage::StorageError;
use hashbrown::HashMap;

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -44,15 +45,16 @@ where
Type::Key: Eq + core::hash::Hash,
Type::OwnedKey: Eq + core::hash::Hash + core::borrow::Borrow<Type::Key>,
{
type Error = core::convert::Infallible;

fn get(&self, key: &Type::Key) -> Result<Option<Cow<Type::OwnedValue>>, Self::Error> {
fn get(
&self,
key: &Type::Key,
) -> Result<Option<Cow<Type::OwnedValue>>, StorageError> {
let result = self.map.get(key);
let value = result.map(Cow::Borrowed);
Ok(value)
}

fn contains_key(&self, key: &Type::Key) -> Result<bool, Self::Error> {
fn contains_key(&self, key: &Type::Key) -> Result<bool, StorageError> {
Dentosal marked this conversation as resolved.
Show resolved Hide resolved
let contains = self.map.contains_key(key);
Ok(contains)
}
Expand All @@ -68,7 +70,7 @@ where
&mut self,
key: &Type::Key,
value: &Type::Value,
) -> Result<Option<Type::OwnedValue>, Self::Error> {
) -> Result<Option<Type::OwnedValue>, StorageError> {
let previous = self.map.remove(key);

self.map
Expand All @@ -79,7 +81,7 @@ where
fn remove(
&mut self,
key: &Type::Key,
) -> Result<Option<Type::OwnedValue>, Self::Error> {
) -> Result<Option<Type::OwnedValue>, StorageError> {
let value = self.map.remove(key);
Ok(value)
}
Expand Down
3 changes: 2 additions & 1 deletion fuel-merkle/src/sparse/branch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::{
};
use fuel_storage::{
Mappable,
StorageError,
StorageMutate,
};

Expand All @@ -33,7 +34,7 @@ pub(crate) fn merge_branches<Storage, Table>(
storage: &mut Storage,
mut left_branch: Branch,
mut right_branch: Branch,
) -> Result<Branch, Storage::Error>
) -> Result<Branch, StorageError>
where
Storage: StorageMutate<Table>,
Table: Mappable<Key = Bytes32, Value = Primitive, OwnedValue = Primitive>,
Expand Down
Loading