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 a feature that propose u32 tx_pointer in fuel-tx and fuel-vm #899

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

### Added

- [899](https://github.com/FuelLabs/fuel-vm/pull/899): Add a feature that propose `u32` `tx_pointer` instead of `u16` in `fuel-tx` and `fuel-vm`.

### Fixed
- [889](https://github.com/FuelLabs/fuel-vm/pull/889): Debugger breakpoint caused receipts to be produced incorrectly.

Expand Down
1 change: 1 addition & 0 deletions fuel-tx/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ random = ["fuel-crypto/random", "fuel-types/random", "rand"]
std = ["alloc", "fuel-asm/std", "fuel-crypto/std", "fuel-merkle/std", "fuel-types/std", "itertools/default", "rand?/default", "serde/default", "hex/std"]
alloc = ["hashbrown", "fuel-types/alloc", "itertools/use_alloc", "fuel-merkle", "strum", "strum_macros", "bitflags", "postcard", "educe", "derive_more", "fuel-asm/serde", "fuel-types/serde"]
da-compression = ["fuel-compression"]
u32-tx-pointer = []

[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(fuzzing)'] }
3 changes: 2 additions & 1 deletion fuel-tx/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,8 @@ impl TransactionBuilder<Blob> {
impl TransactionBuilder<Mint> {
pub fn mint(
block_height: BlockHeight,
tx_index: u16,
#[cfg(feature = "u32-tx-pointer")] tx_index: u32,
#[cfg(not(feature = "u32-tx-pointer"))] tx_index: u16,
input_contract: input::contract::Contract,
output_contract: output::contract::Contract,
mint_amount: Word,
Expand Down
81 changes: 80 additions & 1 deletion fuel-tx/src/tx_pointer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,20 @@ pub struct TxPointer {
/// Block height
block_height: BlockHeight,
/// Transaction index
#[cfg(feature = "u32-tx-pointer")]
tx_index: u32,
#[cfg(not(feature = "u32-tx-pointer"))]
tx_index: u16,
}

impl TxPointer {
pub const LEN: usize = 2 * WORD_SIZE;

pub const fn new(block_height: BlockHeight, tx_index: u16) -> Self {
pub const fn new(
block_height: BlockHeight,
#[cfg(feature = "u32-tx-pointer")] tx_index: u32,
#[cfg(not(feature = "u32-tx-pointer"))] tx_index: u16,
) -> Self {
Self {
block_height,
tx_index,
Expand All @@ -52,6 +59,12 @@ impl TxPointer {
self.block_height
}

#[cfg(feature = "u32-tx-pointer")]
pub const fn tx_index(&self) -> u32 {
self.tx_index
}

#[cfg(not(feature = "u32-tx-pointer"))]
pub const fn tx_index(&self) -> u16 {
self.tx_index
}
Expand All @@ -70,12 +83,28 @@ impl fmt::Display for TxPointer {
}
}

#[cfg(feature = "u32-tx-pointer")]
impl fmt::LowerHex for TxPointer {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:08x}{:08x}", self.block_height, self.tx_index)
}
}

#[cfg(not(feature = "u32-tx-pointer"))]
impl fmt::LowerHex for TxPointer {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:08x}{:04x}", self.block_height, self.tx_index)
}
}

#[cfg(feature = "u32-tx-pointer")]
impl fmt::UpperHex for TxPointer {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:08X}{:08X}", self.block_height, self.tx_index)
}
}

#[cfg(not(feature = "u32-tx-pointer"))]
impl fmt::UpperHex for TxPointer {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:08X}{:04X}", self.block_height, self.tx_index)
Expand All @@ -85,6 +114,26 @@ impl fmt::UpperHex for TxPointer {
impl str::FromStr for TxPointer {
type Err = &'static str;

#[cfg(feature = "u32-tx-pointer")]
/// TxPointer is encoded as 16 hex characters:
/// - 8 characters for block height
/// - 8 characters for tx index
fn from_str(s: &str) -> Result<Self, Self::Err> {
const ERR: &str = "Invalid encoded byte in TxPointer";

if s.len() != 16 || !s.is_char_boundary(8) {
return Err(ERR)
}

let (block_height, tx_index) = s.split_at(8);

let block_height = u32::from_str_radix(block_height, 16).map_err(|_| ERR)?;
let tx_index = u32::from_str_radix(tx_index, 16).map_err(|_| ERR)?;

Ok(Self::new(block_height.into(), tx_index))
}

#[cfg(not(feature = "u32-tx-pointer"))]
/// TxPointer is encoded as 12 hex characters:
/// - 8 characters for block height
/// - 4 characters for tx index
Expand Down Expand Up @@ -144,6 +193,7 @@ pub mod typescript {
}
}

#[cfg(not(feature = "u32-tx-pointer"))]
#[test]
fn fmt_encode_decode() {
use core::str::FromStr;
Expand Down Expand Up @@ -172,6 +222,35 @@ fn fmt_encode_decode() {
}
}

#[cfg(feature = "u32-tx-pointer")]
#[test]
fn fmt_encode_decode_u32() {
use core::str::FromStr;

let cases = vec![(83473, 3829)];

for (block_height, tx_index) in cases {
let tx_pointer = TxPointer::new(block_height.into(), tx_index);

let lower = format!("{tx_pointer:x}");
let upper = format!("{tx_pointer:X}");

assert_eq!(lower, format!("{block_height:08x}{tx_index:08x}"));
assert_eq!(upper, format!("{block_height:08X}{tx_index:08X}"));

let x = TxPointer::from_str(&lower).expect("failed to decode from str");
assert_eq!(tx_pointer, x);

let x = TxPointer::from_str(&upper).expect("failed to decode from str");
assert_eq!(tx_pointer, x);

let bytes = tx_pointer.clone().to_bytes();
let tx_pointer_p = TxPointer::from_bytes(&bytes).expect("failed to deserialize");

assert_eq!(tx_pointer, tx_pointer_p);
}
}

/// See https://github.com/FuelLabs/fuel-vm/issues/521
#[test]
fn decode_bug() {
Expand Down
1 change: 1 addition & 0 deletions fuel-vm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ test-helpers = [
"tai64",
"fuel-crypto/test-helpers",
]
u32-tx-pointer = ["fuel-tx/u32-tx-pointer"]

[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(fuzzing)'] }
31 changes: 28 additions & 3 deletions fuel-vm/src/tests/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,16 @@ fn malleable_fields_do_not_affect_validity_of_create() {
match tx.inputs_mut()[0] {
Input::CoinPredicate(CoinPredicate {
ref mut tx_pointer, ..
}) => *tx_pointer = TxPointer::from_str("123456780001").unwrap(),
}) => {
#[cfg(not(feature = "u32-tx-pointer"))]
{
*tx_pointer = TxPointer::from_str("123456780001").unwrap()
}
#[cfg(feature = "u32-tx-pointer")]
{
*tx_pointer = TxPointer::from_str("1234567800000001").unwrap()
}
}
_ => unreachable!(),
};

Expand Down Expand Up @@ -318,7 +327,16 @@ fn malleable_fields_do_not_affect_validity_of_script() {
match tx.inputs_mut()[0] {
Input::CoinPredicate(CoinPredicate {
ref mut tx_pointer, ..
}) => *tx_pointer = TxPointer::from_str("123456780001").unwrap(),
}) => {
#[cfg(not(feature = "u32-tx-pointer"))]
{
*tx_pointer = TxPointer::from_str("123456780001").unwrap()
}
#[cfg(feature = "u32-tx-pointer")]
{
*tx_pointer = TxPointer::from_str("1234567800000001").unwrap()
}
}
_ => unreachable!(),
};

Expand All @@ -333,7 +351,14 @@ fn malleable_fields_do_not_affect_validity_of_script() {
*utxo_id = UtxoId::new([1; 32].into(), 0);
*balance_root = [2; 32].into();
*state_root = [3; 32].into();
*tx_pointer = TxPointer::from_str("123456780001").unwrap();
#[cfg(not(feature = "u32-tx-pointer"))]
{
*tx_pointer = TxPointer::from_str("123456780001").unwrap();
}
#[cfg(feature = "u32-tx-pointer")]
{
*tx_pointer = TxPointer::from_str("1234567800000001").unwrap();
}
}
_ => unreachable!(),
};
Expand Down
Loading