Skip to content
This repository has been archived by the owner on Jan 4, 2023. It is now read-only.

Commit

Permalink
Add Message Input/Output & receipt
Browse files Browse the repository at this point in the history
Include message input and output with their respective validation rules.

This commit will introduce a stateful property to the transaction
validation. A valid transaction might not be validated anymore in
post-execution since its outputs might be mutated at runtime in the VM.

Related issue: FuelLabs/fuel-specs#318
  • Loading branch information
vlopes11 committed Jun 24, 2022
1 parent 51ff66d commit 66624ea
Show file tree
Hide file tree
Showing 20 changed files with 1,052 additions and 341 deletions.
21 changes: 20 additions & 1 deletion src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ impl<'a> TransactionBuilder<'a> {
#[cfg(feature = "std")]
pub fn add_unsigned_coin_input(
&mut self,
utxo_id: crate::UtxoId,
secret: &'a SecretKey,
utxo_id: crate::UtxoId,
amount: Word,
asset_id: fuel_types::AssetId,
maturity: Word,
Expand All @@ -99,6 +99,25 @@ impl<'a> TransactionBuilder<'a> {
self
}

#[cfg(feature = "std")]
pub fn add_unsigned_message_input(
&mut self,
secret: &'a SecretKey,
sender: fuel_types::Address,
recipient: fuel_types::Address,
nonce: Word,
amount: Word,
data: Vec<u8>,
) -> &mut Self {
let pk = secret.public_key();

self.sign_keys.push(secret);
self.tx
.add_unsigned_message_input(sender, recipient, nonce, &pk, amount, data);

self
}

pub fn inputs(&self) -> &[Input] {
self.tx.inputs()
}
Expand Down
130 changes: 126 additions & 4 deletions src/receipt.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use fuel_asm::InstructionResult;
use fuel_types::bytes::{padded_len_usize, SizedBytes, WORD_SIZE};
use fuel_types::{Address, AssetId, Bytes32, ContractId, Word};
use fuel_types::bytes::{self, padded_len_usize, SizedBytes, WORD_SIZE};
use fuel_types::{Address, AssetId, Bytes32, ContractId, MessageId, Word};

use alloc::vec::Vec;

Expand Down Expand Up @@ -104,6 +104,17 @@ pub enum Receipt {
result: ScriptExecutionResult,
gas_used: Word,
},

MessageOut {
message_id: MessageId,
sender: Address,
recipient: Address,
amount: Word,
nonce: Bytes32,
len: Word,
digest: Bytes32,
data: Vec<u8>,
},
}

impl Receipt {
Expand Down Expand Up @@ -136,7 +147,20 @@ impl Receipt {
Self::Return { id, val, pc, is }
}

pub const fn return_data(
pub fn return_data(
id: ContractId,
ptr: Word,
digest: Bytes32,
data: Vec<u8>,
pc: Word,
is: Word,
) -> Self {
let len = bytes::padded_len(&data) as Word;

Self::return_data_with_len(id, ptr, len, digest, data, pc, is)
}

pub const fn return_data_with_len(
id: ContractId,
ptr: Word,
len: Word,
Expand Down Expand Up @@ -184,7 +208,22 @@ impl Receipt {
}
}

pub const fn log_data(
pub fn log_data(
id: ContractId,
ra: Word,
rb: Word,
ptr: Word,
digest: Bytes32,
data: Vec<u8>,
pc: Word,
is: Word,
) -> Self {
let len = bytes::padded_len(&data) as Word;

Self::log_data_with_len(id, ra, rb, ptr, len, digest, data, pc, is)
}

pub const fn log_data_with_len(
id: ContractId,
ra: Word,
rb: Word,
Expand Down Expand Up @@ -248,6 +287,44 @@ impl Receipt {
Self::ScriptResult { result, gas_used }
}

pub fn message_out(
message_id: MessageId,
sender: Address,
recipient: Address,
amount: Word,
nonce: Bytes32,
digest: Bytes32,
data: Vec<u8>,
) -> Self {
let len = bytes::padded_len(&data) as Word;

Self::message_out_with_len(
message_id, sender, recipient, amount, nonce, len, digest, data,
)
}

pub const fn message_out_with_len(
message_id: MessageId,
sender: Address,
recipient: Address,
amount: Word,
nonce: Bytes32,
len: Word,
digest: Bytes32,
data: Vec<u8>,
) -> Self {
Self::MessageOut {
message_id,
sender,
recipient,
amount,
nonce,
len,
digest,
data,
}
}

pub const fn id(&self) -> Option<&ContractId> {
match self {
Self::Call { id, .. } => Some(id),
Expand All @@ -260,6 +337,7 @@ impl Receipt {
Self::Transfer { id, .. } => Some(id),
Self::TransferOut { id, .. } => Some(id),
Self::ScriptResult { .. } => None,
Self::MessageOut { .. } => None,
}
}

Expand All @@ -275,6 +353,7 @@ impl Receipt {
Self::Transfer { pc, .. } => Some(*pc),
Self::TransferOut { pc, .. } => Some(*pc),
Self::ScriptResult { .. } => None,
Self::MessageOut { .. } => None,
}
}

Expand All @@ -290,6 +369,7 @@ impl Receipt {
Self::Transfer { is, .. } => Some(*is),
Self::TransferOut { is, .. } => Some(*is),
Self::ScriptResult { .. } => None,
Self::MessageOut { .. } => None,
}
}

Expand All @@ -313,6 +393,7 @@ impl Receipt {
Self::Call { amount, .. } => Some(*amount),
Self::Transfer { amount, .. } => Some(*amount),
Self::TransferOut { amount, .. } => Some(*amount),
Self::MessageOut { amount, .. } => Some(*amount),
_ => None,
}
}
Expand Down Expand Up @@ -366,6 +447,7 @@ impl Receipt {
match self {
Self::ReturnData { len, .. } => Some(*len),
Self::LogData { len, .. } => Some(*len),
Self::MessageOut { len, .. } => Some(*len),
_ => None,
}
}
Expand All @@ -382,6 +464,7 @@ impl Receipt {
match self {
Self::ReturnData { digest, .. } => Some(digest),
Self::LogData { digest, .. } => Some(digest),
Self::MessageOut { digest, .. } => Some(digest),
_ => None,
}
}
Expand All @@ -390,6 +473,7 @@ impl Receipt {
match self {
Self::ReturnData { data, .. } => Some(data),
Self::LogData { data, .. } => Some(data),
Self::MessageOut { data, .. } => Some(data),
_ => None,
}
}
Expand Down Expand Up @@ -446,6 +530,34 @@ impl Receipt {
}
}

pub const fn message_id(&self) -> Option<&MessageId> {
match self {
Self::MessageOut { message_id, .. } => Some(message_id),
_ => None,
}
}

pub const fn sender(&self) -> Option<&Address> {
match self {
Self::MessageOut { sender, .. } => Some(sender),
_ => None,
}
}

pub const fn recipient(&self) -> Option<&Address> {
match self {
Self::MessageOut { recipient, .. } => Some(recipient),
_ => None,
}
}

pub const fn nonce(&self) -> Option<&Bytes32> {
match self {
Self::MessageOut { nonce, .. } => Some(nonce),
_ => None,
}
}

fn variant_len_without_data(variant: ReceiptRepr) -> usize {
ContractId::LEN // id
+ WORD_SIZE // pc
Expand Down Expand Up @@ -502,6 +614,16 @@ impl Receipt {
WORD_SIZE // status
+ WORD_SIZE // gas_used
}

ReceiptRepr::MessageOut => {
MessageId::LEN // message_id
+ Address::LEN // sender
+ Address::LEN // recipient
+ WORD_SIZE // amount
+ Bytes32::LEN // nonce
+ WORD_SIZE // len
+ Bytes32::LEN // digest
}
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/receipt/receipt_repr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub enum ReceiptRepr {
Transfer = 0x07,
TransferOut = 0x08,
ScriptResult = 0x09,
MessageOut = 0x0A,
}

impl From<&Receipt> for ReceiptRepr {
Expand All @@ -27,6 +28,7 @@ impl From<&Receipt> for ReceiptRepr {
Receipt::Transfer { .. } => Self::Transfer,
Receipt::TransferOut { .. } => Self::TransferOut,
Receipt::ScriptResult { .. } => Self::ScriptResult,
Receipt::MessageOut { .. } => Self::MessageOut,
}
}
}
Loading

0 comments on commit 66624ea

Please sign in to comment.