Skip to content

Commit

Permalink
feat!: add support for experimental encoding in logs (#1259)
Browse files Browse the repository at this point in the history
closes: #1247,
#1151,
#901,
#898

This PR adds support for sway's experimental encoding in logs. The new
encoder is enabled with the `experimental` rustflag.

To run the tests, first build the forc projects with: 
`forc build --path packages/fuels --experimental-new-encoding` then run
the tests with:
 `RUSTFLAGS='--cfg experimental' cargo test --test logs`
 
 What was done:
 - added `ExperimentalBoundedDecoder`
 - updated how `RawSlice` was  encoded and decoded
 - added tests for the new encoding
 - add new CI step that runs tests with the new `experimental` flag
 
 BREAKING CHANGE:
 - change `RawSlice` encoding and decoding
  • Loading branch information
hal3e authored Jan 29, 2024
1 parent 7caf8af commit 1221632
Show file tree
Hide file tree
Showing 21 changed files with 738 additions and 81 deletions.
34 changes: 32 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ jobs:
# TODO: To be removed once https://github.com/FuelLabs/fuels-rs/issues/881 is unblocked.
- name: Build Sway test projects w type paths
run: forc build --terse --json-abi-with-callpaths
run: forc build --terse --error-on-warnings --json-abi-with-callpaths
working-directory: packages/fuels

- uses: actions/upload-artifact@v2
Expand All @@ -97,6 +97,25 @@ jobs:
!packages/fuels/tests/**/Forc.lock
!packages/fuels/tests/.gitignore
# TODO: To be removed once experimental encoding is the default
- name: Build Sway test projects w experimental logs
run: forc build --terse --error-on-warnings --json-abi-with-callpaths --experimental-new-encoding
working-directory: packages/fuels

- uses: actions/upload-artifact@v2
with:
retention-days: 2
name: sway-examples-w-experimental-logs
# cache only the sway build artifacts, skip all src files
path: |
packages/fuels/tests
!packages/fuels/tests/*.rs
!packages/fuels/tests/**/*.rs
!packages/fuels/tests/**/*.sw
!packages/fuels/tests/**/Forc.toml
!packages/fuels/tests/**/Forc.lock
!packages/fuels/tests/.gitignore
get-workspace-members:
runs-on: ubuntu-latest
outputs:
Expand Down Expand Up @@ -182,6 +201,11 @@ jobs:
args:
- command: check_doc_unresolved_links
args:
# TODO: To be removed once experimental encoding is the default
- command: test_experimental_logs
args:
download_sway_artifacts: sway-examples-w-experimental-logs
install_fuel_core: true
steps:
- name: Checkout repository
uses: actions/checkout@v3
Expand Down Expand Up @@ -218,8 +242,9 @@ jobs:
name: ${{ matrix.download_sway_artifacts }}
path: packages/fuels/tests/

# TODO: `test_experimental_logs` to be removed once experimental encoding is the default.
- name: Install nextest
if: ${{ matrix.cargo_command == 'nextest' }}
if: ${{ matrix.cargo_command == 'nextest' || matrix.command == 'test_experimental_logs' }}
uses: taiki-e/install-action@nextest

- name: Install cargo-machete
Expand Down Expand Up @@ -257,6 +282,11 @@ jobs:
run: |
! cargo doc --document-private-items |& grep -A 6 "warning: unresolved link to"
# TODO: To be removed once experimental encoding is the default.
- name: Test experimental logs
if: ${{ matrix.command == 'test_experimental_logs' }}
run: RUSTFLAGS='--cfg experimental' cargo nextest run --test logs

publish:
needs:
- cargo-verifications
Expand Down
19 changes: 19 additions & 0 deletions packages/fuels-core/src/codec/abi_decoder.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
mod bounded_decoder;
#[cfg(experimental)]
mod experimental_bounded_decoder;

use crate::{
codec::abi_decoder::bounded_decoder::BoundedDecoder,
types::{errors::Result, param_types::ParamType, Token},
};

#[cfg(experimental)]
use crate::codec::abi_decoder::experimental_bounded_decoder::ExperimentalBoundedDecoder;

#[derive(Debug, Clone, Copy)]
pub struct DecoderConfig {
/// Entering a struct, array, tuple, enum or vector increases the depth. Decoding will fail if
Expand Down Expand Up @@ -77,6 +82,20 @@ impl ABIDecoder {
pub fn decode_multiple(&self, param_types: &[ParamType], bytes: &[u8]) -> Result<Vec<Token>> {
BoundedDecoder::new(self.config).decode_multiple(param_types, bytes)
}

#[cfg(experimental)]
pub fn experimental_decode(&self, param_type: &ParamType, bytes: &[u8]) -> Result<Token> {
ExperimentalBoundedDecoder::new(self.config).decode(param_type, bytes)
}

#[cfg(experimental)]
pub fn experimental_decode_multiple(
&self,
param_types: &[ParamType],
bytes: &[u8],
) -> Result<Vec<Token>> {
ExperimentalBoundedDecoder::new(self.config).decode_multiple(param_types, bytes)
}
}

#[cfg(test)]
Expand Down
23 changes: 5 additions & 18 deletions packages/fuels-core/src/codec/abi_decoder/bounded_decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use crate::{
checked_round_up_to_word_alignment,
codec::DecoderConfig,
constants::WORD_SIZE,
traits::Tokenizable,
types::{
enum_variants::EnumVariants,
errors::{error, Result},
Expand Down Expand Up @@ -36,7 +35,7 @@ impl BoundedDecoder {
}
}

pub fn decode(&mut self, param_type: &ParamType, bytes: &[u8]) -> Result<Token> {
pub(crate) fn decode(&mut self, param_type: &ParamType, bytes: &[u8]) -> Result<Token> {
param_type.validate_is_decodable(self.config.max_depth)?;
match param_type {
// Unit, U8 and Bool are returned as u64 from receipt "Return"
Expand Down Expand Up @@ -94,7 +93,7 @@ impl BoundedDecoder {
ParamType::U256 => Self::decode_u256(bytes),
ParamType::Bool => Self::decode_bool(bytes),
ParamType::B256 => Self::decode_b256(bytes),
ParamType::RawSlice => self.decode_raw_slice(bytes),
ParamType::RawSlice => Self::decode_raw_slice(bytes),
ParamType::StringSlice => Self::decode_string_slice(bytes),
ParamType::StringArray(len) => Self::decode_string_array(bytes, *len),
ParamType::Array(ref t, length) => {
Expand Down Expand Up @@ -215,22 +214,10 @@ impl BoundedDecoder {
})
}

fn decode_raw_slice(&mut self, bytes: &[u8]) -> Result<Decoded> {
let raw_slice_element = ParamType::U64;
let num_of_elements =
ParamType::calculate_num_of_elements(&raw_slice_element, bytes.len())?;
let param_type = ParamType::U64;
let (tokens, bytes_read) =
self.decode_params(std::iter::repeat(&param_type).take(num_of_elements), bytes)?;
let elements = tokens
.into_iter()
.map(u64::from_token)
.collect::<Result<Vec<u64>>>()
.map_err(|e| error!(InvalidData, "{e}"))?;

fn decode_raw_slice(bytes: &[u8]) -> Result<Decoded> {
Ok(Decoded {
token: Token::RawSlice(elements),
bytes_read,
token: Token::RawSlice(bytes.to_vec()),
bytes_read: bytes.len(),
})
}

Expand Down
Loading

0 comments on commit 1221632

Please sign in to comment.