Skip to content

Commit

Permalink
Merge with master
Browse files Browse the repository at this point in the history
  • Loading branch information
xgreenx committed Mar 15, 2023
1 parent 6912d21 commit 02dd5e9
Show file tree
Hide file tree
Showing 16 changed files with 100 additions and 155 deletions.
23 changes: 11 additions & 12 deletions fuel-asm/src/panic_reason.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,13 @@ pub enum PanicReason {
/// The jump instruction cannot move backwards in predicate verification.
IllegalJump = 0x1f,
/// The contract ID is already deployed and can't be overwritten.
ContractIdAlreadyDeployed = 0x22,
ContractIdAlreadyDeployed = 0x20,
/// The loaded contract mismatch expectations.
ContractMismatch = 0x23,
ContractMismatch = 0x21,
/// No more nested calls are allowed.
NestedCallLimitReached = 0x24,
NestedCallLimitReached = 0x22,
/// The byte can't be mapped to any known `PanicReason`.
UnknownPanicReason = 0x25,
UnknownPanicReason = 0x23,
}

impl fmt::Display for PanicReason {
Expand Down Expand Up @@ -137,11 +137,9 @@ impl From<u8> for PanicReason {
0x1d => ExpectedOutputVariable,
0x1e => ExpectedParentInternalContext,
0x1f => IllegalJump,
0x20 => NonZeroMessageOutputRecipient,
0x21 => ZeroedMessageOutputRecipient,
0x22 => ContractIdAlreadyDeployed,
0x23 => ContractMismatch,
0x24 => NestedCallLimitReached,
0x20 => ContractIdAlreadyDeployed,
0x21 => ContractMismatch,
0x22 => NestedCallLimitReached,
_ => UnknownPanicReason,
}
}
Expand All @@ -168,15 +166,16 @@ mod tests {

#[test]
fn test_u8_panic_reason_round_trip() {
for i in 0..0x25 {
const LAST_PANIC_REASON: u8 = 0x23;
for i in 0..LAST_PANIC_REASON {
let reason = PanicReason::from(i);
let i2 = reason as u8;
assert_eq!(i, i2);
}
for i in 0x25..=255 {
for i in LAST_PANIC_REASON..=255 {
let reason = PanicReason::from(i);
let i2 = reason as u8;
assert_eq!(0x25, i2);
assert_eq!(LAST_PANIC_REASON, i2);
}
}
}
7 changes: 5 additions & 2 deletions fuel-tx/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use crate::TxPointer;

use crate::input::coin::{CoinPredicate, CoinSigned};
use crate::input::contract::Contract;
use crate::input::message::MessagePredicate;
use crate::input::message::MetadataPredicate;
use input::*;

#[cfg(feature = "std")]
Expand Down Expand Up @@ -214,7 +214,10 @@ pub trait Executable: field::Inputs + field::Outputs + field::Witnesses {
.filter_map(|input| match input {
Input::CoinPredicate(CoinPredicate { asset_id, .. })
| Input::CoinSigned(CoinSigned { asset_id, .. }) => Some(asset_id),
Input::MetadataPredicate(_) | Input::MetadataSigned(_) => Some(&AssetId::BASE),
Input::DepositCoinSigned(_)
| Input::DepositCoinPredicate(_)
| Input::MetadataPredicate(_)
| Input::MetadataSigned(_) => Some(&AssetId::BASE),
_ => None,
})
.collect_vec()
Expand Down
9 changes: 7 additions & 2 deletions fuel-tx/src/transaction/id.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{field, Input, Transaction};
use crate::input::coin::CoinSigned;
use crate::input::message::MetadataSigned;
use crate::input::message::{DepositCoinSigned, MetadataSigned};
use crate::{field, Input, Transaction};
use fuel_crypto::{Message, PublicKey, SecretKey, Signature};
use fuel_types::Bytes32;

Expand Down Expand Up @@ -53,6 +53,11 @@ where
Input::CoinSigned(CoinSigned {
owner, witness_index, ..
})
| Input::DepositCoinSigned(DepositCoinSigned {
recipient: owner,
witness_index,
..
})
| Input::MetadataSigned(MetadataSigned {
recipient: owner,
witness_index,
Expand Down
16 changes: 9 additions & 7 deletions fuel-tx/src/transaction/types/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,10 +266,10 @@ impl Input {
Self::CoinSigned(CoinSigned { utxo_id, .. })
| Self::CoinPredicate(CoinPredicate { utxo_id, .. })
| Self::Contract(Contract { utxo_id, .. }) => Some(utxo_id),
Self::DepositCoinSigned { .. } => None,
Self::DepositCoinPredicate { .. } => None,
Self::MetadataSigned { .. } => None,
Self::MetadataPredicate { .. } => None,
Self::DepositCoinSigned(_) => None,
Self::DepositCoinPredicate(_) => None,
Self::MetadataSigned(_) => None,
Self::MetadataPredicate(_) => None,
}
}

Expand Down Expand Up @@ -630,9 +630,11 @@ impl io::Read for Input {
let _ = contract.read(&mut full_buf[WORD_SIZE..])?;
}

bytes::store_number(ident_buf, InputRepr::Message as Word);
Self::DepositCoinSigned(message) => {
bytes::store_number(ident_buf, InputRepr::Message as Word);
let _ = message.read(&mut full_buf[WORD_SIZE..])?;
}

Self::DepositCoinPredicate(message) => {
bytes::store_number(ident_buf, InputRepr::Message as Word);
let _ = message.read(&mut full_buf[WORD_SIZE..])?;
Expand Down Expand Up @@ -687,8 +689,8 @@ impl io::Write for Input {
}

InputRepr::Message => {
let mut message = MessageFull::default();
let n = WORD_SIZE + MessageFull::write(&mut message, &full_buf[WORD_SIZE..])?;
let mut message = FullMessage::default();
let n = WORD_SIZE + FullMessage::write(&mut message, &full_buf[WORD_SIZE..])?;

*self = match (message.data.is_empty(), message.predicate.is_empty()) {
(true, true) => Self::DepositCoinSigned(message.into_coin_signed()),
Expand Down
7 changes: 3 additions & 4 deletions fuel-tx/src/transaction/types/input/coin.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use crate::transaction::types::input::consts::INPUT_COIN_FIXED_SIZE;
use crate::input::sizes::CoinSizes;
use crate::transaction::types::input::AsField;
use crate::{TxPointer, UtxoId};
use fuel_types::bytes::Deserializable;
use fuel_types::bytes::{SizedBytes, WORD_SIZE};
use fuel_types::{bytes, Address, AssetId, Word};
use fuel_types::bytes::{Deserializable, SizedBytes};
use fuel_types::{bytes, Address, AssetId, MemLayout, MemLocType, Word};

pub type CoinFull = Coin<Full>;
pub type CoinSigned = Coin<Signed>;
Expand Down
5 changes: 2 additions & 3 deletions fuel-tx/src/transaction/types/input/contract.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use crate::transaction::types::input::consts::INPUT_CONTRACT_SIZE;
use crate::input::sizes::ContractSizes;
use crate::{TxPointer, UtxoId};
use fuel_types::bytes::{Deserializable, SizedBytes, WORD_SIZE};
use fuel_types::bytes::{Deserializable, SizedBytes};
use fuel_types::{bytes, Bytes32, ContractId, MemLayout, MemLocType, Word};
use crate::input::sizes::ContractSizes;

/// It is a full representation of the contract input from the specification:
/// https://github.com/FuelLabs/fuel-specs/blob/master/src/protocol/tx_format/input.md#inputcontract.
Expand Down
18 changes: 12 additions & 6 deletions fuel-tx/src/transaction/types/input/message.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::transaction::types::input::consts::INPUT_MESSAGE_FIXED_SIZE;
use crate::input::sizes::MessageSizes;
use crate::transaction::types::input::AsField;
use fuel_types::bytes::{SizedBytes, WORD_SIZE};
use fuel_types::{bytes, Address, MessageId, Word};
use fuel_types::bytes::SizedBytes;
use fuel_types::{bytes, Address, MemLayout, MemLocType, MessageId, Word};

pub type FullMessage = Message<specifications::Full>;
pub type MetadataSigned = Message<specifications::Metadata<specifications::Signed>>;
Expand Down Expand Up @@ -219,11 +219,11 @@ where
bytes::store_number_at(buf, S::layout(S::LAYOUT.witness_index), witness_index);

let data_size = if let Some(data) = data.as_field() {
data.as_field()
data.len()
} else {
0
};
bytes::store_number_at(buf, S::layout(S::LAYOUT.data_len), data_size);
bytes::store_number_at(buf, S::layout(S::LAYOUT.data_len), data_size as Word);

let predicate_len = if let Some(predicate) = predicate.as_field() {
predicate.len()
Expand All @@ -239,7 +239,13 @@ where
};
bytes::store_number_at(buf, S::layout(S::LAYOUT.predicate_data_len), predicate_data_len as Word);

let (_, buf) = bytes::store_raw_bytes(full_buf.get_mut(LEN..).ok_or(bytes::eof())?, data.as_slice())?;
let buf = full_buf.get_mut(LEN..).ok_or(bytes::eof())?;
let buf = if let Some(data) = data.as_field() {
let (_, buf) = bytes::store_raw_bytes(buf, data.as_slice())?;
buf
} else {
buf
};

let buf = if let Some(predicate) = predicate.as_field() {
let (_, buf) = bytes::store_raw_bytes(buf, predicate.as_slice())?;
Expand Down
2 changes: 1 addition & 1 deletion fuel-tx/src/transaction/types/input/ser_de_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use fuel_types::MemLayout;
#[test]
fn test_input_serialization() {
const DATA_SIZE: usize = 16;
let mut input = Input::message_predicate(
let mut input = Input::metadata_predicate(
MessageId::from([1u8; 32]),
Address::from([2u8; 32]),
Address::from([3u8; 32]),
Expand Down
9 changes: 0 additions & 9 deletions fuel-tx/tests/offset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,15 +257,6 @@ fn outputs_assert<Tx: Outputs>(tx: &Tx, bytes: &[u8], cases: &mut TestedFields)

assert_eq!(contract_id, contract_id_p);
}

if let Some(recipient) = o.recipient() {
cases.output_recipient = true;

let ofs = output_ofs + o.repr().recipient_offset().expect("output have recipient");
let recipient_p = Address::from_bytes_ref_checked(&bytes[ofs..ofs + Address::LEN]).unwrap();

assert_eq!(recipient, recipient_p);
}
});
}

Expand Down
2 changes: 1 addition & 1 deletion fuel-tx/tests/valid_cases/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ fn input_coin_message_signature() {
.iter()
.enumerate()
.try_for_each(|(index, input)| match input {
Input::CoinSigned { .. } | Input::MetadataSigned { .. } => {
Input::CoinSigned(_) | Input::DepositCoinSigned(_) | Input::MetadataSigned(_) => {
input.check(index, &txhash, outputs, witnesses, &Default::default())
}
_ => Ok(()),
Expand Down
9 changes: 9 additions & 0 deletions fuel-types/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ key!(Bytes4, 4);
key!(Bytes8, 8);
key!(Bytes20, 20);
key!(Bytes32, 32);
key!(Nonce, 32);
key!(MessageId, 32);
key!(Salt, 32);

Expand All @@ -314,3 +315,11 @@ impl AssetId {
/// The base native asset of the Fuel protocol.
pub const BASE: AssetId = AssetId::zeroed();
}

impl From<u64> for Nonce {
fn from(value: u64) -> Self {
let mut default = [0u8; 32];
default[..8].copy_from_slice(&value.to_be_bytes()[..]);
default.into()
}
}
43 changes: 13 additions & 30 deletions fuel-vm/src/interpreter/blockchain.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,27 @@
use super::contract::{balance, contract_size};
use super::gas::{dependent_gas_charge, ProfileGas};
use super::internal::{
absolute_output_mem_range, append_receipt, base_asset_balance_sub, current_contract, inc_pc, internal_contract,
internal_contract_bounds, set_message_output, tx_id, AppendReceipt,
append_receipt, base_asset_balance_sub, current_contract, inc_pc, internal_contract, internal_contract_bounds,
tx_id, AppendReceipt,
};
use super::memory::{try_mem_write, try_zeroize, OwnershipRegisters};
use super::{ExecutableTransaction, Interpreter, MemoryRange, RuntimeBalances};
use crate::arith::{add_usize, checked_add_usize, checked_add_word, checked_sub_word};
use crate::call::CallFrame;
use crate::constraints::{reg_key::*, CheckedMemConstLen, CheckedMemRange, CheckedMemValue};
use crate::context::Context;
use crate::error::{Bug, BugId, BugVariant, RuntimeError};
use crate::gas::DependentCost;
use crate::interpreter::PanicContext;
use crate::prelude::Profiler;
use crate::storage::{ContractsAssets, ContractsAssetsStorage, ContractsRawCode, InterpreterStorage};
use crate::{arith, consts::*};

use fuel_asm::PanicReason;
use fuel_storage::{StorageInspect, StorageSize};
use fuel_tx::{Output, Receipt};
use fuel_types::bytes::{self, Deserializable};
use fuel_tx::Receipt;
use fuel_types::bytes;
use fuel_types::{Address, AssetId, Bytes32, ContractId, RegisterId, Word};

use crate::arith::{add_usize, checked_add_usize, checked_add_word, checked_sub_word};
use crate::interpreter::PanicContext;
use std::borrow::Borrow;
use std::ops::Range;

Expand Down Expand Up @@ -667,6 +666,11 @@ pub(crate) fn timestamp(
inc_pc(pc)
}

// TODO: Register b is the address of the begin of the data and register c
// is the end of the data(Based on the specification).
// The user doesn't specify the output index for message.
// We need to use the index of the receipt to calculate the `Nonce`.
// Add unit tests for a new usage.
struct MessageOutputCtx<'vm, Tx> {
max_message_data_length: u64,
memory: &'vm mut [u8; MEM_SIZE],
Expand All @@ -681,6 +685,7 @@ struct MessageOutputCtx<'vm, Tx> {
/// B
call_abi_len: Word,
/// C
#[allow(dead_code)]
message_output_idx: Word,
/// D
amount_coins_to_send: Word,
Expand All @@ -703,19 +708,6 @@ impl<Tx> MessageOutputCtx<'_, Tx> {

let recipient = recipient_address.try_from(self.memory)?;

if recipient == Address::zeroed() {
return Err(PanicReason::ZeroedMessageOutputRecipient.into());
}

let output = absolute_output_mem_range(self.tx, self.tx_offset, self.message_output_idx as usize, None)?
.ok_or(PanicReason::OutputNotFound)?;
let output = Output::from_bytes(output.read(self.memory))?;

// amount isn't checked because we are allowed to send zero balances with a message
if !matches!(output, Output::Message { recipient, .. } if recipient == Address::zeroed()) {
return Err(PanicReason::NonZeroMessageOutputRecipient.into());
}

// validations passed, perform the mutations

base_asset_balance_sub(self.balances, self.memory, self.amount_coins_to_send)?;
Expand All @@ -725,24 +717,15 @@ impl<Tx> MessageOutputCtx<'_, Tx> {
let call_abi = call_abi.read(self.memory).to_vec();
let sender = Address::from_bytes_ref(sender.read(self.memory));

let message = Output::message(recipient, self.amount_coins_to_send);
let receipt = Receipt::message_out_from_tx_output(
txid,
self.message_output_idx,
self.receipts.len() as Word,
*sender,
recipient,
self.amount_coins_to_send,
call_abi,
);

set_message_output(
self.tx,
self.memory,
self.tx_offset,
self.message_output_idx as usize,
message,
)?;

append_receipt(
AppendReceipt {
receipts: self.receipts,
Expand Down
Loading

0 comments on commit 02dd5e9

Please sign in to comment.