Skip to content

Commit

Permalink
./Make the fuel-tx WASM compatible with serde feature enabled (#542)
Browse files Browse the repository at this point in the history
  • Loading branch information
xgreenx committed Aug 3, 2023
1 parent 30cd02b commit f17a8c2
Show file tree
Hide file tree
Showing 23 changed files with 157 additions and 103 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ jobs:
args: --target thumbv6m-none-eabi -p fuel-asm -p fuel-storage -p fuel-merkle --no-default-features
- command: check
args: --target wasm32-unknown-unknown -p fuel-crypto --no-default-features
- command: check
args: --target wasm32-unknown-unknown -p fuel-tx --features serde --no-default-features
- command: check
args: --target wasm32-unknown-unknown -p fuel-types --features serde --no-default-features
- command: rustc
args: --target wasm32-unknown-unknown -p fuel-types --features typescript --crate-type=cdylib
- command: rustc
Expand Down
4 changes: 4 additions & 0 deletions ci_checks.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ cargo check --all-targets --no-default-features &&
cargo check --all-targets --all-features &&
cargo check --target thumbv6m-none-eabi -p fuel-asm -p fuel-storage -p fuel-merkle --no-default-features &&
cargo check --target wasm32-unknown-unknown -p fuel-crypto --no-default-features &&
cargo check --target wasm32-unknown-unknown -p fuel-types --features serde --no-default-features &&
cargo check --target wasm32-unknown-unknown -p fuel-tx --features serde --no-default-features &&
cargo rustc --target wasm32-unknown-unknown -p fuel-types --features typescript --crate-type=cdylib &&
cargo rustc --target wasm32-unknown-unknown -p fuel-asm --features typescript --crate-type=cdylib &&
cargo make check &&
cargo test --all-targets --all-features &&
cargo test --all-targets --no-default-features &&
Expand Down
2 changes: 1 addition & 1 deletion fuel-asm/src/encoding_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ fn opcode() {

for opcode_int in 0..64 {
let Ok(op) = Opcode::try_from(opcode_int) else {
continue;
continue
};

instructions.push(op.test_construct(r, r, r, r, imm12));
Expand Down
4 changes: 2 additions & 2 deletions fuel-crypto/src/ed25519.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ pub fn verify(
message: &Message,
) -> Result<(), Error> {
let Ok(signature) = Signature::from_bytes(&**signature) else {
return Err(Error::InvalidSignature);
return Err(Error::InvalidSignature)
};

let Ok(pub_key) = ed25519_dalek::PublicKey::from_bytes(&**pub_key) else {
return Err(Error::InvalidPublicKey);
return Err(Error::InvalidPublicKey)
};

if pub_key.verify_strict(&**message, &signature).is_ok() {
Expand Down
10 changes: 6 additions & 4 deletions fuel-tx/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,10 @@ use fuel_types::{
Word,
};

use alloc::vec::Vec;
use std::collections::HashMap;
use alloc::{
collections::BTreeMap,
vec::Vec,
};

pub trait BuildableAloc
where
Expand Down Expand Up @@ -126,7 +128,7 @@ pub struct TransactionBuilder<Tx> {
// We take the key by reference so this lib won't have the responsibility to properly
// zeroize the keys
// Maps signing keys -> witness indexes
sign_keys: HashMap<SecretKey, u8>,
sign_keys: BTreeMap<SecretKey, u8>,
}

impl TransactionBuilder<Script> {
Expand Down Expand Up @@ -199,7 +201,7 @@ impl<Tx> TransactionBuilder<Tx> {
fn with_tx(tx: Tx) -> Self {
let should_prepare_script = false;
let should_prepare_predicate = false;
let sign_keys = HashMap::new();
let sign_keys = BTreeMap::new();

Self {
tx,
Expand Down
7 changes: 3 additions & 4 deletions fuel-tx/src/receipt/receipt_repr.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::receipt::Receipt;
use fuel_types::Word;

macro_rules! enum_from {
(
Expand All @@ -21,12 +20,12 @@ macro_rules! enum_from {
}

#[cfg(feature = "std")]
impl TryFrom<Word> for $name {
impl TryFrom<fuel_types::Word> for $name {
type Error = std::io::Error;

fn try_from(x: Word) -> Result<Self, Self::Error> {
fn try_from(x: fuel_types::Word) -> Result<Self, Self::Error> {
match x {
$(x if x == $name::$vname as Word => Ok($name::$vname),)*
$(x if x == $name::$vname as fuel_types::Word => Ok($name::$vname),)*
_ => Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
"The provided identifier is invalid!",
Expand Down
18 changes: 10 additions & 8 deletions fuel-tx/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use fuel_types::{
AssetId,
BlockHeight,
Bytes32,
ChainId,
Nonce,
Salt,
Word,
Expand Down Expand Up @@ -58,19 +57,22 @@ pub use validity::{

use crate::TxPointer;

use crate::input::coin::{
CoinPredicate,
CoinSigned,
};
use input::*;

#[cfg(feature = "std")]
use crate::input::{
coin::{
CoinPredicate,
CoinSigned,
},
contract::Contract,
message::{
MessageCoinPredicate,
MessageDataPredicate,
},
};
use input::*;

#[cfg(feature = "std")]
pub use fuel_types::ChainId;
#[cfg(feature = "std")]
pub use id::{
Signable,
Expand Down Expand Up @@ -474,7 +476,7 @@ pub mod field {
};

use alloc::vec::Vec;
use std::ops::{
use core::ops::{
Deref,
DerefMut,
};
Expand Down
15 changes: 5 additions & 10 deletions fuel-tx/src/transaction/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,7 @@ mod storage;
mod utxo_id;
mod witness;

use crate::TxId;
pub use create::Create;
use fuel_crypto::Hasher;
use fuel_types::{
bytes::SerializableVec,
ChainId,
};
pub use mint::Mint;
pub use output::{
Output,
Expand All @@ -24,11 +18,12 @@ pub use storage::StorageSlot;
pub use utxo_id::UtxoId;
pub use witness::Witness;

pub fn compute_transaction_id<T: SerializableVec + Clone>(
chain_id: &ChainId,
#[cfg(feature = "std")]
pub fn compute_transaction_id<T: fuel_types::bytes::SerializableVec + Clone>(
chain_id: &fuel_types::ChainId,
tx: &mut T,
) -> TxId {
let mut hasher = Hasher::default();
) -> crate::TxId {
let mut hasher = fuel_crypto::Hasher::default();
// chain ID
hasher.input(chain_id.to_be_bytes());
// transaction bytes
Expand Down
58 changes: 38 additions & 20 deletions fuel-tx/src/transaction/types/create.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::{
transaction::{
compute_transaction_id,
field::{
BytecodeLength,
BytecodeWitnessIndex,
Expand All @@ -13,7 +12,6 @@ use crate::{
StorageSlots,
Witnesses,
},
metadata::CommonMetadata,
validity::{
check_common_part,
FormatValidityChecks,
Expand All @@ -26,7 +24,6 @@ use crate::{
Input,
Output,
StorageSlot,
TxId,
Witness,
};
use derivative::Derivative;
Expand All @@ -40,17 +37,19 @@ use fuel_types::{
AssetId,
BlockHeight,
Bytes32,
ChainId,
ContractId,
MemLayout,
MemLocType,
Salt,
Word,
};

#[cfg(feature = "alloc")]
use alloc::vec::Vec;
use core::cmp::max;
#[cfg(feature = "std")]
use fuel_types::{
ChainId,
MemLayout,
MemLocType,
};
#[cfg(feature = "std")]
use std::collections::HashMap;
#[cfg(feature = "std")]
Expand All @@ -75,9 +74,12 @@ pub struct CreateMetadata {
pub witnesses_offset_at: Vec<usize>,
}

#[cfg(feature = "std")]
impl CreateMetadata {
/// Computes the `Metadata` for the `tx` transaction.
pub fn compute(tx: &Create, chain_id: &ChainId) -> Result<Self, CheckError> {
use crate::transaction::metadata::CommonMetadata;

let CommonMetadata {
id,
inputs_offset,
Expand Down Expand Up @@ -154,7 +156,7 @@ impl Create {

#[cfg(feature = "std")]
impl crate::UniqueIdentifier for Create {
fn id(&self, chain_id: &ChainId) -> TxId {
fn id(&self, chain_id: &ChainId) -> crate::TxId {
if let Some(id) = self.cached_id() {
return id
}
Expand All @@ -169,10 +171,10 @@ impl crate::UniqueIdentifier for Create {
.for_each(Output::prepare_sign);
clone.witnesses_mut().clear();

compute_transaction_id(chain_id, &mut clone)
crate::transaction::compute_transaction_id(chain_id, &mut clone)
}

fn cached_id(&self) -> Option<TxId> {
fn cached_id(&self) -> Option<crate::TxId> {
self.metadata.as_ref().map(|m| m.id)
}
}
Expand Down Expand Up @@ -215,8 +217,10 @@ impl FormatValidityChecks for Create {

// There will be at most len(witnesses) - 1 signatures to cache, as one of the
// witnesses will be bytecode
let mut recovery_cache =
Some(HashMap::with_capacity(max(self.witnesses().len() - 1, 1)));
let mut recovery_cache = Some(HashMap::with_capacity(core::cmp::max(
self.witnesses().len() - 1,
1,
)));

self.inputs()
.iter()
Expand Down Expand Up @@ -293,14 +297,28 @@ impl FormatValidityChecks for Create {
self.metadata.is_some(),
"`check_without_signatures` is called without cached metadata"
);
let (state_root_calculated, contract_id_calculated) = if let Some(metadata) =
&self.metadata
{
(metadata.state_root, metadata.contract_id)
} else {
let metadata = CreateMetadata::compute(self, &consensus_params.chain_id())?;
(metadata.state_root, metadata.contract_id)
};
let (state_root_calculated, contract_id_calculated) =
if let Some(metadata) = &self.metadata {
(metadata.state_root, metadata.contract_id)
} else {
#[cfg(feature = "std")]
{
let metadata =
CreateMetadata::compute(self, &consensus_params.chain_id())?;
(metadata.state_root, metadata.contract_id)
}

#[cfg(not(feature = "std"))]
{
let salt = self.salt();
let storage_slots = self.storage_slots();
let contract = Contract::try_from(self)?;
let contract_root = contract.root();
let state_root = Contract::initial_state_root(storage_slots.iter());
let contract_id = contract.id(salt, &contract_root, &state_root);
(state_root, contract_id)
}
};

let mut contract_created = false;
self.outputs
Expand Down
7 changes: 5 additions & 2 deletions fuel-tx/src/transaction/types/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ use crate::{
TxPointer,
UtxoId,
};
use alloc::vec::Vec;
use alloc::{
string::ToString,
vec::Vec,
};
use coin::*;
use consts::*;
use contract::*;
Expand Down Expand Up @@ -157,7 +160,7 @@ impl Default for Input {
}
}

impl bytes::SizedBytes for Input {
impl SizedBytes for Input {
fn serialized_size(&self) -> usize {
match self {
Self::CoinSigned(coin) => WORD_SIZE + coin.serialized_size(),
Expand Down
13 changes: 7 additions & 6 deletions fuel-tx/src/transaction/types/input/coin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,20 @@ use crate::{
TxPointer,
UtxoId,
};
use alloc::vec::Vec;
use derivative::Derivative;
use fuel_types::{
bytes,
bytes::{
Deserializable,
SizedBytes,
},
Address,
AssetId,
BlockHeight,
MemLayout,
MemLocType,
Word,
};

#[cfg(feature = "std")]
use fuel_types::MemLocType;

pub type CoinFull = Coin<Full>;
pub type CoinSigned = Coin<Signed>;
pub type CoinPredicate = Coin<Predicate>;
Expand Down Expand Up @@ -136,7 +135,7 @@ where
}
}

impl<Specification> SizedBytes for Coin<Specification>
impl<Specification> bytes::SizedBytes for Coin<Specification>
where
Specification: CoinSpecification,
{
Expand Down Expand Up @@ -164,6 +163,7 @@ where
Specification: CoinSpecification,
{
fn read(&mut self, full_buf: &mut [u8]) -> std::io::Result<usize> {
use fuel_types::bytes::SizedBytes;
let serialized_size = self.serialized_size();
if full_buf.len() < serialized_size {
return Err(bytes::eof())
Expand Down Expand Up @@ -274,6 +274,7 @@ where
Specification: CoinSpecification,
{
fn write(&mut self, full_buf: &[u8]) -> std::io::Result<usize> {
use fuel_types::bytes::Deserializable;
type S = CoinSizes;
const LEN: usize = CoinSizes::LEN;
let buf: &[_; LEN] = full_buf
Expand Down
Loading

0 comments on commit f17a8c2

Please sign in to comment.