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

Add support for Transaction::Upload, Transaction::Upgrade, and Transaction::Blob #6500

Merged
merged 18 commits into from
Sep 11, 2024
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
20 changes: 16 additions & 4 deletions sway-lib-std/src/inputs.sw
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,10 @@ use ::tx::{
tx_type,
};
use core::ops::Eq;

const GTF_INPUT_TYPE = 0x200;
use ::revert::revert;

// GTF Opcode const selectors
//
pub const GTF_INPUT_TYPE = 0x200;
// pub const GTF_INPUT_COIN_TX_ID = 0x201;
// pub const GTF_INPUT_COIN_OUTPUT_INDEX = 0x202;
pub const GTF_INPUT_COIN_OWNER = 0x203;
Expand All @@ -33,7 +32,7 @@ pub const GTF_INPUT_COIN_PREDICATE_LENGTH = 0x209;
pub const GTF_INPUT_COIN_PREDICATE_DATA_LENGTH = 0x20A;
pub const GTF_INPUT_COIN_PREDICATE = 0x20B;
pub const GTF_INPUT_COIN_PREDICATE_DATA = 0x20C;

// pub const GTF_INPUT_COIN_PREDICATE_GAS_USED = 0x20D;
// pub const GTF_INPUT_CONTRACT_CONTRACT_ID = 0x225;
pub const GTF_INPUT_MESSAGE_SENDER = 0x240;
pub const GTF_INPUT_MESSAGE_RECIPIENT = 0x241;
Expand All @@ -46,6 +45,7 @@ pub const GTF_INPUT_MESSAGE_PREDICATE_DATA_LENGTH = 0x247;
pub const GTF_INPUT_MESSAGE_DATA = 0x248;
pub const GTF_INPUT_MESSAGE_PREDICATE = 0x249;
pub const GTF_INPUT_MESSAGE_PREDICATE_DATA = 0x24A;
// pub const GTF_INPUT_MESSAGE_PREDICATE_GAS_USED = 0x24B;

/// The input type for a transaction.
pub enum Input {
Expand Down Expand Up @@ -113,6 +113,10 @@ pub fn input_type(index: u64) -> Option<Input> {
///
/// * [u16] - The number of inputs in the transaction.
///
/// # Reverts
///
/// * When the input type is unrecognized. This should never happen.
///
/// # Examples
///
/// ```sway
Expand All @@ -127,6 +131,10 @@ pub fn input_count() -> u16 {
match tx_type() {
Transaction::Script => __gtf::<u16>(0, GTF_SCRIPT_INPUTS_COUNT),
Transaction::Create => __gtf::<u16>(0, GTF_CREATE_INPUTS_COUNT),
Transaction::Upgrade => __gtf::<u16>(0, GTF_SCRIPT_INPUTS_COUNT),
Transaction::Upload => __gtf::<u16>(0, GTF_SCRIPT_INPUTS_COUNT),
Transaction::Blob => __gtf::<u16>(0, GTF_SCRIPT_INPUTS_COUNT),
_ => revert(0),
bitzoic marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand Down Expand Up @@ -158,6 +166,10 @@ fn input_pointer(index: u64) -> Option<raw_ptr> {
match tx_type() {
Transaction::Script => Some(__gtf::<raw_ptr>(index, GTF_SCRIPT_INPUT_AT_INDEX)),
Transaction::Create => Some(__gtf::<raw_ptr>(index, GTF_CREATE_INPUT_AT_INDEX)),
Transaction::Upgrade => Some(__gtf::<raw_ptr>(index, GTF_SCRIPT_INPUT_AT_INDEX)),
Transaction::Upload => Some(__gtf::<raw_ptr>(index, GTF_SCRIPT_INPUT_AT_INDEX)),
Transaction::Blob => Some(__gtf::<raw_ptr>(index, GTF_SCRIPT_INPUT_AT_INDEX)),
_ => None,
}
}

Expand Down
8 changes: 8 additions & 0 deletions sway-lib-std/src/outputs.sw
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ fn output_pointer(index: u64) -> Option<raw_ptr> {
match tx_type() {
Transaction::Script => Some(__gtf::<raw_ptr>(index, GTF_SCRIPT_OUTPUT_AT_INDEX)),
Transaction::Create => Some(__gtf::<raw_ptr>(index, GTF_CREATE_OUTPUT_AT_INDEX)),
Transaction::Upgrade => Some(__gtf::<raw_ptr>(index, GTF_SCRIPT_OUTPUT_AT_INDEX)),
Transaction::Upload => Some(__gtf::<raw_ptr>(index, GTF_SCRIPT_OUTPUT_AT_INDEX)),
Transaction::Blob => Some(__gtf::<raw_ptr>(index, GTF_SCRIPT_OUTPUT_AT_INDEX)),
_ => None,
}
}

Expand Down Expand Up @@ -139,6 +143,10 @@ pub fn output_count() -> u16 {
match tx_type() {
Transaction::Script => __gtf::<u16>(0, GTF_SCRIPT_OUTPUTS_COUNT),
Transaction::Create => __gtf::<u16>(0, GTF_CREATE_OUTPUTS_COUNT),
Transaction::Upgrade => __gtf::<u16>(0, GTF_SCRIPT_OUTPUTS_COUNT),
Transaction::Upload => __gtf::<u16>(0, GTF_SCRIPT_OUTPUTS_COUNT),
Transaction::Blob => __gtf::<u16>(0, GTF_SCRIPT_OUTPUTS_COUNT),
_ => revert(0),
}
}

Expand Down
92 changes: 83 additions & 9 deletions sway-lib-std/src/tx.sw
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ library;

use ::revert::revert;
use ::option::Option::{self, *};
use ::alloc::alloc_bytes;

// GTF Opcode const selectors
//
Expand All @@ -18,6 +19,7 @@ pub const GTF_SCRIPT_SCRIPT_DATA = 0x00A;
pub const GTF_SCRIPT_INPUT_AT_INDEX = 0x00B;
pub const GTF_SCRIPT_OUTPUT_AT_INDEX = 0x00C;
pub const GTF_SCRIPT_WITNESS_AT_INDEX = 0x00D;

pub const GTF_TX_LENGTH = 0x00E;

// pub const GTF_CREATE_BYTECODE_WITNESS_INDEX = 0x101;
Expand Down Expand Up @@ -46,10 +48,35 @@ pub enum Transaction {
Script: (),
/// A contract deployment transaction.
Create: (),
/// The transaction is created by the block producer and is not signed.
///
/// # Additional Information
///
/// NOTE: This should never be valid in execution but it provided for congruency to the FuelVM specs.
Mint: (),
/// The Upgrade transaction allows upgrading either consensus parameters or state transition function used by the network to produce future blocks.
Upgrade: (),
///The Upload transaction allows the huge bytecode to be divided into subsections and uploaded slowly to the chain.
Upload: (),
/// The Blob inserts a simple binary blob in the chain. It's raw immutable data that can be cheaply loaded by the VM and used as instructions or just data.
Blob: (),
}

impl core::ops::Eq for Transaction {
fn eq(self, other: Self) -> bool {
match (self, other) {
(Transaction::Script, Transaction::Script) => true,
(Transaction::Create, Transaction::Create) => true,
(Transaction::Mint, Transaction::Mint) => true,
(Transaction::Upgrade, Transaction::Upgrade) => true,
(Transaction::Upload, Transaction::Upload) => true,
(Transaction::Blob, Transaction::Blob) => true,
_ => false,
}
}
}

/// Get the type of the current transaction.
/// Either `Transaction::Script` or `Transaction::Create`.
///
/// # Returns
///
Expand All @@ -73,13 +100,28 @@ pub enum Transaction {
/// Transaction::Create => {
/// log("Contract deployment transaction");
/// },
/// Transaction::Mint => {
/// log("This should never happen");
/// },
/// Transaction::Upgrade => {
/// log("Upgrade transaction");
/// },
/// Transaction::Upload => {
/// log("Upload transaction");
/// },
/// Transaction::Blob => {
/// log("Blob transaction");
/// },
/// }
/// }
/// ```
pub fn tx_type() -> Transaction {
match __gtf::<u8>(0, GTF_TYPE) {
0u8 => Transaction::Script,
1u8 => Transaction::Create,
3u8 => Transaction::Upgrade,
4u8 => Transaction::Upload,
5u8 => Transaction::Blob,
_ => revert(0),
}
}
Expand Down Expand Up @@ -233,7 +275,7 @@ pub fn tx_max_fee() -> Option<u64> {
pub fn tx_script_length() -> Option<u64> {
match tx_type() {
Transaction::Script => Some(__gtf::<u64>(0, GTF_SCRIPT_SCRIPT_LENGTH)),
Transaction::Create => None,
_ => None,
}
}

Expand All @@ -256,7 +298,7 @@ pub fn tx_script_length() -> Option<u64> {
pub fn tx_script_data_length() -> Option<u64> {
match tx_type() {
Transaction::Script => Some(__gtf::<u64>(0, GTF_SCRIPT_SCRIPT_DATA_LENGTH)),
Transaction::Create => None,
_ => None,
}
}

Expand All @@ -266,6 +308,10 @@ pub fn tx_script_data_length() -> Option<u64> {
///
/// * [u64] - The witnesses count for the transaction.
///
/// # Reverts
///
/// * When the transaction type is unrecognized. This should never happen.
///
/// # Examples
///
/// ```sway
Expand All @@ -280,6 +326,10 @@ pub fn tx_witnesses_count() -> u64 {
match tx_type() {
Transaction::Script => __gtf::<u64>(0, GTF_SCRIPT_WITNESSES_COUNT),
Transaction::Create => __gtf::<u64>(0, GTF_CREATE_WITNESSES_COUNT),
Transaction::Upgrade => __gtf::<u64>(0, GTF_SCRIPT_WITNESSES_COUNT),
Transaction::Upload => __gtf::<u64>(0, GTF_SCRIPT_WITNESSES_COUNT),
Transaction::Blob => __gtf::<u64>(0, GTF_SCRIPT_WITNESSES_COUNT),
_ => revert(0),
}
}

Expand Down Expand Up @@ -311,6 +361,10 @@ fn tx_witness_pointer(index: u64) -> Option<raw_ptr> {
match tx_type() {
Transaction::Script => Some(__gtf::<raw_ptr>(index, GTF_SCRIPT_WITNESS_AT_INDEX)),
Transaction::Create => Some(__gtf::<raw_ptr>(index, GTF_CREATE_WITNESS_AT_INDEX)),
Transaction::Upgrade => Some(__gtf::<raw_ptr>(index, GTF_SCRIPT_WITNESS_AT_INDEX)),
Transaction::Upload => Some(__gtf::<raw_ptr>(index, GTF_SCRIPT_WITNESS_AT_INDEX)),
Transaction::Blob => Some(__gtf::<raw_ptr>(index, GTF_SCRIPT_WITNESS_AT_INDEX)),
_ => None,
}
}

Expand Down Expand Up @@ -344,6 +398,11 @@ pub fn tx_witness_data_length(index: u64) -> Option<u64> {

/// Get the witness data at `index`.
///
/// # Additional Information
///
/// **Unsafe. Assumes the type is correct.**
/// This function does not support ownership types(Vec, Bytes, String, etc).
///
/// # Arguments
///
/// * `index` - The index of the witness to get the data for.
Expand All @@ -367,10 +426,26 @@ pub fn tx_witness_data<T>(index: u64) -> Option<T> {
return None
}

if __size_of::<T>() == 1 {
Some(__gtf::<raw_ptr>(index, GTF_WITNESS_DATA).add::<u8>(7).read::<T>())
let length = match tx_witness_data_length(index) {
Some(len) => len,
None => return None,
};

if __is_reference_type::<T>() {
let witness_data_ptr = __gtf::<raw_ptr>(index, GTF_WITNESS_DATA);
let new_ptr = alloc_bytes(length);
witness_data_ptr.copy_bytes_to(new_ptr, length);

Some(asm(ptr: new_ptr) {
ptr: T
})
} else {
Some(__gtf::<raw_ptr>(index, GTF_WITNESS_DATA).read::<T>())
// u8 is the only value type that is less than 8 bytes and should be handled separately
if __size_of::<T>() == 1 {
Some(__gtf::<raw_ptr>(index, GTF_WITNESS_DATA).add::<u8>(7).read::<T>())
} else {
Some(__gtf::<raw_ptr>(index, GTF_WITNESS_DATA).read::<T>())
}
}
}

Expand Down Expand Up @@ -424,8 +499,8 @@ fn tx_script_data_start_pointer() -> Option<raw_ptr> {
///
/// # Additional Information
///
/// **Unsafe.**
/// **Assumes the type is correct.**
/// **Unsafe. Assumes the type is correct.**
/// This function does not support ownership types(Vec, Bytes, String, etc).
///
/// # Returns
///
Expand Down Expand Up @@ -480,7 +555,6 @@ pub fn tx_script_bytecode<T>() -> Option<T> {
}

/// Get the hash of the script bytecode.
/// Reverts if not a transaction-script.
///
/// # Returns
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use test_fuel_coin_abi::*;
#[cfg(experimental_new_encoding = false)]
const FUEL_COIN_CONTRACT_ID = 0xec2277ebe007ade87e3d797c3b1e070dcd542d5ef8f038b471f262ef9cebc87c;
#[cfg(experimental_new_encoding = true)]
const FUEL_COIN_CONTRACT_ID = 0xf8c7b4d09f9964ab4c437ac7f5cbd6dbad7e1f218fce452c5807aac3c67afa6f;
const FUEL_COIN_CONTRACT_ID = 0xf2fecff29038dab2ef571397ea5507359265c9154608e7de36ccbea20ed5c8aa;

#[cfg(experimental_new_encoding = false)]
const BALANCE_CONTRACT_ID = 0xf6cd545152ac83225e8e7df2efb5c6fa6e37bc9b9e977b5ea8103d28668925df;
Expand Down
1 change: 1 addition & 0 deletions test/src/in_language_tests/Forc.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ members = [
"test_programs/revert_inline_tests",
"test_programs/storage_key_inline_tests",
"test_programs/string_inline_tests",
"test_programs/tx_inline_tests",
"test_programs/u128_inline_tests",
"test_programs/vec_inline_tests",
"test_programs/array_conversions_b256_inline_tests",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[project]
authors = ["Fuel Labs <[email protected]>"]
entry = "main.sw"
license = "Apache-2.0"
name = "tx_inline_tests"

[dependencies]
std = { path = "../../../../../sway-lib-std" }
Loading
Loading