From 20b8ff062eddd5794d34dca95b482408d797d5b2 Mon Sep 17 00:00:00 2001 From: Vaivaswatha N Date: Mon, 6 May 2024 09:50:45 +0530 Subject: [PATCH] Fixes to accessing the data section during bytecode gen (#5927) ## Description This PR fixes a bunch of issues we had in generating access to the data section. It also fixes #5876. Reverts #5918. --------- Co-authored-by: Joshua Batty --- forc-pkg/src/manifest/build_profile.rs | 5 + forc-pkg/src/pkg.rs | 8 +- forc-pkg/tests/sections/Forc.toml | 1 + forc-plugins/forc-client/src/op/deploy.rs | 1 + forc-plugins/forc-client/src/op/run/mod.rs | 1 + forc/src/cli/commands/test.rs | 1 + forc/src/cli/shared.rs | 3 + forc/src/ops/forc_build.rs | 1 + forc/src/ops/forc_contract_id.rs | 1 + forc/src/ops/forc_predicate_root.rs | 1 + sway-core/src/asm_generation/finalized_asm.rs | 118 +++++++----- .../fuel/abstract_instruction_set.rs | 20 +- .../src/asm_generation/fuel/data_section.rs | 4 +- .../src/asm_generation/programs/allocated.rs | 2 +- sway-core/src/asm_lang/allocated_ops.rs | 28 ++- sway-core/src/build_config.rs | 9 + sway-core/src/lib.rs | 27 ++- sway-lib-std/src/lib.sw | 2 +- test/src/e2e_vm_tests/harness.rs | 1 + .../configurable_consts/json_abi_oracle.json | 21 ++- .../json_abi_oracle_new_encoding.json | 20 +- .../json_abi_oracle_new_encoding.json | 2 +- .../array_of_structs_caller/src/main.sw | 2 +- .../asset_ops_test/src/main.sw | 4 +- .../bal_opcode/src/main.sw | 2 +- .../call_abi_with_tuples/src/main.sw | 2 +- .../call_basic_storage/src/main.sw | 2 +- .../src/main.sw | 2 +- .../call_increment_contract/src/main.sw | 2 +- .../call_storage_enum/src/main.sw | 2 +- .../caller_auth_test/src/main.sw | 2 +- .../caller_context_test/src/main.sw | 2 +- .../nested_struct_args_caller/src/main.sw | 2 +- .../storage_access_caller/src/main.sw | 2 +- .../contract_multi_test/src/main.sw | 4 +- test/src/sdk-harness/Forc.lock | 10 + test/src/sdk-harness/Forc.toml | 5 +- .../src/sdk-harness/test_projects/auth/mod.rs | 2 +- .../test_projects/run_external_proxy/mod.rs | 176 +++++++++++------- .../run_external_proxy/src/main.sw | 5 + .../run_external_target/src/main.sw | 4 + 41 files changed, 324 insertions(+), 185 deletions(-) diff --git a/forc-pkg/src/manifest/build_profile.rs b/forc-pkg/src/manifest/build_profile.rs index d3e8d00435a..468da8c56df 100644 --- a/forc-pkg/src/manifest/build_profile.rs +++ b/forc-pkg/src/manifest/build_profile.rs @@ -24,6 +24,8 @@ pub struct BuildProfile { #[serde(default)] pub print_intermediate_asm: bool, #[serde(default)] + pub print_bytecode: bool, + #[serde(default)] pub terse: bool, #[serde(default)] pub time_phases: bool, @@ -57,6 +59,7 @@ impl BuildProfile { print_ir: false, print_finalized_asm: false, print_intermediate_asm: false, + print_bytecode: false, terse: false, time_phases: false, metrics_outfile: None, @@ -80,6 +83,7 @@ impl BuildProfile { print_ir: false, print_finalized_asm: false, print_intermediate_asm: false, + print_bytecode: false, terse: false, time_phases: false, metrics_outfile: None, @@ -133,6 +137,7 @@ mod tests { print_ir: true, print_finalized_asm: true, print_intermediate_asm: true, + print_bytecode: true, terse: true, time_phases: true, metrics_outfile: Some("metrics_outfile".into()), diff --git a/forc-pkg/src/pkg.rs b/forc-pkg/src/pkg.rs index 672f17e0064..0527c846468 100644 --- a/forc-pkg/src/pkg.rs +++ b/forc-pkg/src/pkg.rs @@ -266,6 +266,8 @@ pub struct PrintOpts { /// This is the state of the ASM prior to performing register allocation and other ASM /// optimisations. pub intermediate_asm: bool, + /// Print the bytecode. This is the final output of the compiler. + pub bytecode: bool, /// Print the generated Sway IR (Intermediate Representation). pub ir: bool, /// Output build errors and warnings in reverse order. @@ -1554,6 +1556,7 @@ pub fn sway_build_config( .with_print_dca_graph_url_format(build_profile.print_dca_graph_url_format.clone()) .with_print_finalized_asm(build_profile.print_finalized_asm) .with_print_intermediate_asm(build_profile.print_intermediate_asm) + .with_print_bytecode(build_profile.print_bytecode) .with_print_ir(build_profile.print_ir) .with_include_tests(build_profile.include_tests) .with_time_phases(build_profile.time_phases) @@ -1893,8 +1896,8 @@ pub fn compile( let bc_res = time_expr!( "compile asm to bytecode", "compile_asm_to_bytecode", - sway_core::asm_to_bytecode(&handler, asm, source_map, engines.se()), - Some(sway_build_config), + sway_core::asm_to_bytecode(&handler, asm, source_map, engines.se(), &sway_build_config), + Some(sway_build_config.clone()), metrics ); @@ -2079,6 +2082,7 @@ fn build_profile_from_opts( } profile.print_ir |= print.ir; profile.print_finalized_asm |= print.finalized_asm; + profile.print_bytecode |= print.bytecode; profile.print_intermediate_asm |= print.intermediate_asm; profile.terse |= pkg.terse; profile.time_phases |= time_phases; diff --git a/forc-pkg/tests/sections/Forc.toml b/forc-pkg/tests/sections/Forc.toml index f0c1fe48033..56c3de6d058 100644 --- a/forc-pkg/tests/sections/Forc.toml +++ b/forc-pkg/tests/sections/Forc.toml @@ -13,6 +13,7 @@ print-dca-graph-url-format = "print_dca_graph_url_format" print-ir = true print-finalized-asm = true print-intermediate-asm = true +print-bytecode = true terse = true time-phases = true metrics-outfile = "metrics_outfile" diff --git a/forc-plugins/forc-client/src/op/deploy.rs b/forc-plugins/forc-client/src/op/deploy.rs index b6104f99ad7..a29945f8c4d 100644 --- a/forc-plugins/forc-client/src/op/deploy.rs +++ b/forc-plugins/forc-client/src/op/deploy.rs @@ -330,6 +330,7 @@ fn build_opts_from_cmd(cmd: &cmd::Deploy) -> pkg::BuildOpts { dca_graph_url_format: cmd.print.dca_graph_url_format.clone(), finalized_asm: cmd.print.finalized_asm, intermediate_asm: cmd.print.intermediate_asm, + bytecode: cmd.print.bytecode, ir: cmd.print.ir, reverse_order: cmd.print.reverse_order, }, diff --git a/forc-plugins/forc-client/src/op/run/mod.rs b/forc-plugins/forc-client/src/op/run/mod.rs index f95819fdb27..d6bee326b5e 100644 --- a/forc-plugins/forc-client/src/op/run/mod.rs +++ b/forc-plugins/forc-client/src/op/run/mod.rs @@ -222,6 +222,7 @@ fn build_opts_from_cmd(cmd: &cmd::Run) -> pkg::BuildOpts { dca_graph_url_format: cmd.print.dca_graph_url_format.clone(), finalized_asm: cmd.print.finalized_asm, intermediate_asm: cmd.print.intermediate_asm, + bytecode: cmd.print.bytecode, ir: cmd.print.ir, reverse_order: cmd.print.reverse_order, }, diff --git a/forc/src/cli/commands/test.rs b/forc/src/cli/commands/test.rs index 3c36d628ffe..837db68e8f7 100644 --- a/forc/src/cli/commands/test.rs +++ b/forc/src/cli/commands/test.rs @@ -216,6 +216,7 @@ fn opts_from_cmd(cmd: Command) -> forc_test::TestOpts { dca_graph_url_format: cmd.build.print.dca_graph_url_format, finalized_asm: cmd.build.print.finalized_asm, intermediate_asm: cmd.build.print.intermediate_asm, + bytecode: cmd.build.print.bytecode, ir: cmd.build.print.ir, reverse_order: cmd.build.print.reverse_order, }, diff --git a/forc/src/cli/shared.rs b/forc/src/cli/shared.rs index ecb71d8a1b9..81874d5c0c5 100644 --- a/forc/src/cli/shared.rs +++ b/forc/src/cli/shared.rs @@ -78,6 +78,9 @@ pub struct Print { /// optimisations. #[clap(long)] pub intermediate_asm: bool, + /// Print the bytecode. This is the final output of the compiler. + #[clap(long)] + pub bytecode: bool, /// Print the generated Sway IR (Intermediate Representation). #[clap(long)] pub ir: bool, diff --git a/forc/src/ops/forc_build.rs b/forc/src/ops/forc_build.rs index 7113580240e..b4660717ced 100644 --- a/forc/src/ops/forc_build.rs +++ b/forc/src/ops/forc_build.rs @@ -26,6 +26,7 @@ fn opts_from_cmd(cmd: BuildCommand) -> pkg::BuildOpts { dca_graph_url_format: cmd.build.print.dca_graph_url_format, finalized_asm: cmd.build.print.finalized_asm, intermediate_asm: cmd.build.print.intermediate_asm, + bytecode: cmd.build.print.bytecode, ir: cmd.build.print.ir, reverse_order: cmd.build.print.reverse_order, }, diff --git a/forc/src/ops/forc_contract_id.rs b/forc/src/ops/forc_contract_id.rs index 4bfed434101..a51a5d5db9c 100644 --- a/forc/src/ops/forc_contract_id.rs +++ b/forc/src/ops/forc_contract_id.rs @@ -61,6 +61,7 @@ fn build_opts_from_cmd(cmd: &ContractIdCommand) -> pkg::BuildOpts { dca_graph_url_format: cmd.print.dca_graph_url_format.clone(), finalized_asm: cmd.print.finalized_asm, intermediate_asm: cmd.print.intermediate_asm, + bytecode: cmd.print.bytecode, ir: cmd.print.ir, reverse_order: cmd.print.reverse_order, }, diff --git a/forc/src/ops/forc_predicate_root.rs b/forc/src/ops/forc_predicate_root.rs index 2ad5cc57adb..7061302815d 100644 --- a/forc/src/ops/forc_predicate_root.rs +++ b/forc/src/ops/forc_predicate_root.rs @@ -30,6 +30,7 @@ fn build_opts_from_cmd(cmd: PredicateRootCommand) -> pkg::BuildOpts { dca_graph_url_format: cmd.print.dca_graph_url_format.clone(), finalized_asm: cmd.print.finalized_asm, intermediate_asm: cmd.print.intermediate_asm, + bytecode: cmd.print.bytecode, ir: cmd.print.ir, reverse_order: cmd.print.reverse_order, }, diff --git a/sway-core/src/asm_generation/finalized_asm.rs b/sway-core/src/asm_generation/finalized_asm.rs index 2bcc393d420..5de93b021c9 100644 --- a/sway-core/src/asm_generation/finalized_asm.rs +++ b/sway-core/src/asm_generation/finalized_asm.rs @@ -7,6 +7,7 @@ use super::{ use crate::asm_lang::allocated_ops::{AllocatedOp, AllocatedOpcode}; use crate::decl_engine::DeclRefFunction; use crate::source_map::SourceMap; +use crate::BuildConfig; use etk_asm::asm::Assembler; use sway_error::error::CompileError; @@ -54,15 +55,16 @@ impl FinalizedAsm { handler: &Handler, source_map: &mut SourceMap, source_engine: &SourceEngine, + build_config: &BuildConfig, ) -> Result { match &self.program_section { - InstructionSet::Fuel { ops } => to_bytecode_mut( - handler, + InstructionSet::Fuel { ops } => Ok(to_bytecode_mut( ops, &mut self.data_section, source_map, source_engine, - ), + build_config, + )), InstructionSet::Evm { ops } => { let mut assembler = Assembler::new(); if let Err(e) = assembler.push_all(ops.clone()) { @@ -98,67 +100,99 @@ impl fmt::Display for FinalizedAsm { } fn to_bytecode_mut( - handler: &Handler, ops: &[AllocatedOp], data_section: &mut DataSection, source_map: &mut SourceMap, source_engine: &SourceEngine, -) -> Result { - if ops.len() & 1 != 0 { - tracing::info!("ops len: {}", ops.len()); - return Err(handler.emit_err(CompileError::Internal( - "Non-word-aligned (odd-number) ops generated. This is an invariant violation.", - Span::new(" ".into(), 0, 0, None).unwrap(), - ))); - } - // The below invariant is introduced to word-align the data section. - // A noop is inserted in ASM generation if there is an odd number of ops. - assert_eq!(ops.len() & 1, 0); - // this points at the byte (*4*8) address immediately following (+1) the last instruction - // Some LWs are expanded into two ops to allow for data larger than one word, so we calculate - // exactly how many ops will be generated to calculate the offset. - let offset_to_data_section_in_bytes = ops.iter().fold(0, |acc, item| match &item.opcode { - AllocatedOpcode::LoadDataId(_reg, data_label) - if !data_section - .has_copy_type(data_label) - .expect("data label references non existent data -- internal error") => - { - acc + 8 + build_config: &BuildConfig, +) -> CompiledBytecode { + fn op_size_in_bytes(data_section: &DataSection, item: &AllocatedOp) -> u64 { + match &item.opcode { + AllocatedOpcode::LoadDataId(_reg, data_label) + if !data_section + .has_copy_type(data_label) + .expect("data label references non existent data -- internal error") => + { + 8 + } + AllocatedOpcode::DataSectionOffsetPlaceholder => 8, + AllocatedOpcode::BLOB(count) => count.value as u64 * 4, + AllocatedOpcode::CFEI(i) | AllocatedOpcode::CFSI(i) if i.value == 0 => 0, + _ => 4, } - AllocatedOpcode::BLOB(count) => acc + count.value as u64 * 4, - _ => acc + 4, - }) + 4; + } - // each op is four bytes, so the length of the buf is the number of ops times four. - let mut buf = vec![0; (ops.len() * 4) + 4]; + // Some instructions may be omitted or expanded into multiple instructions, so we compute, + // using `op_size_in_bytes`, exactly how many ops will be generated to calculate the offset. + let mut offset_to_data_section_in_bytes = ops + .iter() + .fold(0, |acc, item| acc + op_size_in_bytes(data_section, item)); + + // A noop is inserted in ASM generation if required, to word-align the data section. + let mut ops_padded = Vec::new(); + let ops = if offset_to_data_section_in_bytes & 7 == 0 { + ops + } else { + ops_padded.reserve(ops.len() + 1); + ops_padded.extend(ops.iter().cloned()); + ops_padded.push(AllocatedOp { + opcode: AllocatedOpcode::NOOP, + comment: "word-alignment of data section".into(), + owning_span: None, + }); + offset_to_data_section_in_bytes += 4; + &ops_padded + }; + + let mut buf = Vec::with_capacity(offset_to_data_section_in_bytes as usize); + + if build_config.print_bytecode { + println!(";; --- START OF TARGET BYTECODE ---\n"); + } let mut half_word_ix = 0; + let mut offset_from_instr_start = 0; for op in ops.iter() { let span = op.owning_span.clone(); - let op = op.to_fuel_asm(offset_to_data_section_in_bytes, data_section); - match op { + let fuel_op = op.to_fuel_asm( + offset_to_data_section_in_bytes, + offset_from_instr_start, + data_section, + ); + offset_from_instr_start += op_size_in_bytes(data_section, op); + + match fuel_op { Either::Right(data) => { - for i in 0..data.len() { - buf[(half_word_ix * 4) + i] = data[i]; + if build_config.print_bytecode { + println!("{:?}", data); } + // Static assert to ensure that we're only dealing with DataSectionOffsetPlaceholder, + // a one-word (8 bytes) data within the code. No other uses are known. + let _: [u8; 8] = data; + buf.extend(data.iter().cloned()); half_word_ix += 2; } Either::Left(ops) => { - if ops.len() > 1 { - buf.resize(buf.len() + ((ops.len() - 1) * 4), 0); - } for op in ops { + if build_config.print_bytecode { + println!("{:?}", op); + } if let Some(span) = &span { source_map.insert(source_engine, half_word_ix, span); } - let read_range_upper_bound = - core::cmp::min(half_word_ix * 4 + std::mem::size_of_val(&op), buf.len()); - buf[half_word_ix * 4..read_range_upper_bound].copy_from_slice(&op.to_bytes()); + buf.extend(op.to_bytes().iter()); half_word_ix += 1; } } } } + if build_config.print_bytecode { + println!("{}", data_section); + println!(";; --- END OF TARGET BYTECODE ---\n"); + } + + assert_eq!(half_word_ix * 4, offset_to_data_section_in_bytes as usize); + assert_eq!(buf.len(), offset_to_data_section_in_bytes as usize); let config_offsets = data_section .config_map @@ -175,10 +209,10 @@ fn to_bytecode_mut( buf.append(&mut data_section); - Ok(CompiledBytecode { + CompiledBytecode { bytecode: buf, config_const_offsets: config_offsets, - }) + } } /// Checks for disallowed opcodes in non-contract code. diff --git a/sway-core/src/asm_generation/fuel/abstract_instruction_set.rs b/sway-core/src/asm_generation/fuel/abstract_instruction_set.rs index a06b7e51c7d..91f0673247c 100644 --- a/sway-core/src/asm_generation/fuel/abstract_instruction_set.rs +++ b/sway-core/src/asm_generation/fuel/abstract_instruction_set.rs @@ -3,8 +3,7 @@ use crate::{ allocated_abstract_instruction_set::AllocatedAbstractInstructionSet, register_allocator, }, asm_lang::{ - allocated_ops::{AllocatedOp, AllocatedOpcode}, - Op, OrganizationalOp, RealizedOp, VirtualOp, VirtualRegister, + allocated_ops::AllocatedOp, Op, OrganizationalOp, RealizedOp, VirtualOp, VirtualRegister, }, }; @@ -192,9 +191,8 @@ pub struct RealizedAbstractInstructionSet { } impl RealizedAbstractInstructionSet { - pub(crate) fn pad_to_even(self) -> Vec { - let mut ops = self - .ops + pub(crate) fn allocated_ops(self) -> Vec { + self.ops .into_iter() .map( |RealizedOp { @@ -209,16 +207,6 @@ impl RealizedAbstractInstructionSet { } }, ) - .collect::>(); - - if ops.len() & 1 != 0 { - ops.push(AllocatedOp { - opcode: AllocatedOpcode::NOOP, - comment: "word-alignment of data section".into(), - owning_span: None, - }); - } - - ops + .collect::>() } } diff --git a/sway-core/src/asm_generation/fuel/data_section.rs b/sway-core/src/asm_generation/fuel/data_section.rs index 5eb9999692a..cbc811e99ac 100644 --- a/sway-core/src/asm_generation/fuel/data_section.rs +++ b/sway-core/src/asm_generation/fuel/data_section.rs @@ -252,8 +252,8 @@ impl DataSection { /// static values that have a length longer than one word. /// This method appends pointers to the end of the data section (thus, not altering the data /// offsets of previous data). - /// `pointer_value` is in _bytes_ and refers to the offset from instruction start to the data - /// in question. + /// `pointer_value` is in _bytes_ and refers to the offset from instruction start or + /// relative to the current (load) instruction. pub(crate) fn append_pointer(&mut self, pointer_value: u64) -> DataId { // The 'pointer' is just a literal 64 bit address. self.insert_data_value(Entry::new_word(pointer_value, None, None)) diff --git a/sway-core/src/asm_generation/programs/allocated.rs b/sway-core/src/asm_generation/programs/allocated.rs index 6354f81d772..f8cf928262d 100644 --- a/sway-core/src/asm_generation/programs/allocated.rs +++ b/sway-core/src/asm_generation/programs/allocated.rs @@ -14,7 +14,7 @@ impl AllocatedProgram { let (realized_ops, mut label_offsets) = abstract_ops.realize_labels(&mut self.data_section)?; - let ops = realized_ops.pad_to_even(); + let ops = realized_ops.allocated_ops(); // Collect the entry point offsets. let entries = self diff --git a/sway-core/src/asm_lang/allocated_ops.rs b/sway-core/src/asm_lang/allocated_ops.rs index 19d52df011b..7d336298136 100644 --- a/sway-core/src/asm_lang/allocated_ops.rs +++ b/sway-core/src/asm_lang/allocated_ops.rs @@ -523,6 +523,7 @@ impl AllocatedOp { pub(crate) fn to_fuel_asm( &self, offset_to_data_section: u64, + offset_from_instr_start: u64, data_section: &mut DataSection, ) -> Either, DoubleWideData> { use AllocatedOpcode::*; @@ -677,7 +678,13 @@ impl AllocatedOp { return Either::Right(offset_to_data_section.to_be_bytes()) } LoadDataId(a, b) => { - return Either::Left(realize_load(a, b, data_section, offset_to_data_section)) + return Either::Left(realize_load( + a, + b, + data_section, + offset_to_data_section, + offset_from_instr_start, + )) } Undefined => unreachable!("Sway cannot generate undefined ASM opcodes"), }]) @@ -693,6 +700,7 @@ fn realize_load( data_id: &DataId, data_section: &mut DataSection, offset_to_data_section: u64, + offset_from_instr_start: u64, ) -> Vec { // if this data is larger than a word, instead of loading the data directly // into the register, we want to load a pointer to the data into the register @@ -723,13 +731,14 @@ fn realize_load( }; if !has_copy_type { - // load the pointer itself into the register - // `offset_to_data_section` is in bytes. We want a byte - // address here - let pointer_offset_from_instruction_start = offset_to_data_section + offset_bytes; + // load the pointer itself into the register. `offset_to_data_section` is in bytes. + // The -4 is because $pc is added in the *next* instruction. + let pointer_offset_from_current_instr = + offset_to_data_section - offset_from_instr_start + offset_bytes - 4; + // insert the pointer as bytes as a new data section entry at the end of the data - let data_id_for_pointer = - data_section.append_pointer(pointer_offset_from_instruction_start); + let data_id_for_pointer = data_section.append_pointer(pointer_offset_from_current_instr); + // now load the pointer we just created into the `dest`ination let mut buf = Vec::with_capacity(2); buf.append(&mut realize_load( @@ -737,13 +746,14 @@ fn realize_load( &data_id_for_pointer, data_section, offset_to_data_section, + offset_from_instr_start, )); - // add $is to the pointer since it is relative to the data section + // add $pc to the pointer since it is relative to the current instruction. buf.push( fuel_asm::op::ADD::new( dest.to_reg_id(), dest.to_reg_id(), - ConstantRegister::InstructionStart.to_reg_id(), + ConstantRegister::ProgramCounter.to_reg_id(), ) .into(), ); diff --git a/sway-core/src/build_config.rs b/sway-core/src/build_config.rs index 7462bdd7612..ceb1ac6c168 100644 --- a/sway-core/src/build_config.rs +++ b/sway-core/src/build_config.rs @@ -62,6 +62,7 @@ pub struct BuildConfig { pub(crate) print_dca_graph_url_format: Option, pub(crate) print_intermediate_asm: bool, pub(crate) print_finalized_asm: bool, + pub(crate) print_bytecode: bool, pub(crate) print_ir: bool, pub(crate) include_tests: bool, pub(crate) optimization_level: OptLevel, @@ -109,6 +110,7 @@ impl BuildConfig { print_dca_graph_url_format: None, print_intermediate_asm: false, print_finalized_asm: false, + print_bytecode: false, print_ir: false, include_tests: false, time_phases: false, @@ -149,6 +151,13 @@ impl BuildConfig { } } + pub fn with_print_bytecode(self, a: bool) -> Self { + Self { + print_bytecode: a, + ..self + } + } + pub fn with_print_ir(self, a: bool) -> Self { Self { print_ir: a, diff --git a/sway-core/src/lib.rs b/sway-core/src/lib.rs index c112e47e2a3..529d9e1ce51 100644 --- a/sway-core/src/lib.rs +++ b/sway-core/src/lib.rs @@ -937,14 +937,39 @@ pub(crate) fn compile_ast_to_ir_to_asm( Ok(final_asm) } +/// Given input Sway source code, compile to [CompiledBytecode], containing the asm in bytecode form. +#[allow(clippy::too_many_arguments)] +pub fn compile_to_bytecode( + handler: &Handler, + engines: &Engines, + input: Arc, + initial_namespace: namespace::Root, + build_config: &BuildConfig, + source_map: &mut SourceMap, + package_name: &str, +) -> Result { + let asm_res = compile_to_asm( + handler, + engines, + input, + initial_namespace, + build_config, + package_name, + )?; + asm_to_bytecode(handler, asm_res, source_map, engines.se(), build_config) +} + /// Given the assembly (opcodes), compile to [CompiledBytecode], containing the asm in bytecode form. pub fn asm_to_bytecode( handler: &Handler, mut asm: CompiledAsm, source_map: &mut SourceMap, source_engine: &SourceEngine, + build_config: &BuildConfig, ) -> Result { - let compiled_bytecode = asm.0.to_bytecode_mut(handler, source_map, source_engine)?; + let compiled_bytecode = + asm.0 + .to_bytecode_mut(handler, source_map, source_engine, build_config)?; Ok(compiled_bytecode) } diff --git a/sway-lib-std/src/lib.sw b/sway-lib-std/src/lib.sw index 249ffc21ce5..943c520ca8f 100644 --- a/sway-lib-std/src/lib.sw +++ b/sway-lib-std/src/lib.sw @@ -21,7 +21,7 @@ pub mod alias; pub mod hash; pub mod asset_id; pub mod contract_id; -// pub mod execution; +pub mod execution; pub mod constants; pub mod call_frames; pub mod context; diff --git a/test/src/e2e_vm_tests/harness.rs b/test/src/e2e_vm_tests/harness.rs index e9b09447c46..2ad3fbd242e 100644 --- a/test/src/e2e_vm_tests/harness.rs +++ b/test/src/e2e_vm_tests/harness.rs @@ -277,6 +277,7 @@ pub(crate) async fn compile_to_bytes(file_name: &str, run_config: &RunConfig) -> dca_graph_url_format: None, finalized_asm: false, intermediate_asm: false, + bytecode: false, ir: false, reverse_order: false, }, diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_consts/json_abi_oracle.json b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_consts/json_abi_oracle.json index 273f9b12649..ed892799c25 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_consts/json_abi_oracle.json +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_consts/json_abi_oracle.json @@ -7,7 +7,7 @@ "typeArguments": null }, "name": "C0", - "offset": 4724 + "offset": 4776 }, { "configurableType": { @@ -16,7 +16,7 @@ "typeArguments": null }, "name": "C1", - "offset": 4740 + "offset": 4792 }, { "configurableType": { @@ -25,7 +25,7 @@ "typeArguments": null }, "name": "C2", - "offset": 4756 + "offset": 4808 }, { "configurableType": { @@ -34,7 +34,7 @@ "typeArguments": [] }, "name": "C3", - "offset": 4788 + "offset": 4840 }, { "configurableType": { @@ -43,7 +43,7 @@ "typeArguments": [] }, "name": "C4", - "offset": 4804 + "offset": 4856 }, { "configurableType": { @@ -52,7 +52,7 @@ "typeArguments": [] }, "name": "C5", - "offset": 4820 + "offset": 4872 }, { "configurableType": { @@ -61,7 +61,7 @@ "typeArguments": null }, "name": "C6", - "offset": 4836 + "offset": 4888 }, { "configurableType": { @@ -70,7 +70,7 @@ "typeArguments": null }, "name": "C7", - "offset": 4852 + "offset": 4904 }, { "configurableType": { @@ -79,7 +79,7 @@ "typeArguments": null }, "name": "C7_2", - "offset": 4956 + "offset": 4976 }, { "configurableType": { @@ -88,9 +88,10 @@ "typeArguments": null }, "name": "C9", - "offset": 4900 + "offset": 4952 } ], + "encoding": "1", "functions": [ { "attributes": null, diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_consts/json_abi_oracle_new_encoding.json b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_consts/json_abi_oracle_new_encoding.json index f686fdf0927..ed892799c25 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_consts/json_abi_oracle_new_encoding.json +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_consts/json_abi_oracle_new_encoding.json @@ -7,7 +7,7 @@ "typeArguments": null }, "name": "C0", - "offset": 4812 + "offset": 4776 }, { "configurableType": { @@ -16,7 +16,7 @@ "typeArguments": null }, "name": "C1", - "offset": 4828 + "offset": 4792 }, { "configurableType": { @@ -25,7 +25,7 @@ "typeArguments": null }, "name": "C2", - "offset": 4844 + "offset": 4808 }, { "configurableType": { @@ -34,7 +34,7 @@ "typeArguments": [] }, "name": "C3", - "offset": 4876 + "offset": 4840 }, { "configurableType": { @@ -43,7 +43,7 @@ "typeArguments": [] }, "name": "C4", - "offset": 4892 + "offset": 4856 }, { "configurableType": { @@ -52,7 +52,7 @@ "typeArguments": [] }, "name": "C5", - "offset": 4908 + "offset": 4872 }, { "configurableType": { @@ -61,7 +61,7 @@ "typeArguments": null }, "name": "C6", - "offset": 4924 + "offset": 4888 }, { "configurableType": { @@ -70,7 +70,7 @@ "typeArguments": null }, "name": "C7", - "offset": 4940 + "offset": 4904 }, { "configurableType": { @@ -79,7 +79,7 @@ "typeArguments": null }, "name": "C7_2", - "offset": 5012 + "offset": 4976 }, { "configurableType": { @@ -88,7 +88,7 @@ "typeArguments": null }, "name": "C9", - "offset": 4988 + "offset": 4952 } ], "encoding": "1", diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/u256/u256_abi/json_abi_oracle_new_encoding.json b/test/src/e2e_vm_tests/test_programs/should_pass/language/u256/u256_abi/json_abi_oracle_new_encoding.json index 8ac4cd9c64b..15b0a83e812 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/u256/u256_abi/json_abi_oracle_new_encoding.json +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/u256/u256_abi/json_abi_oracle_new_encoding.json @@ -7,7 +7,7 @@ "typeArguments": null }, "name": "SOME_U256", - "offset": 812 + "offset": 808 } ], "encoding": "1", diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/array_of_structs_caller/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/array_of_structs_caller/src/main.sw index 3aae9dd814a..e62e1b1572e 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/array_of_structs_caller/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/array_of_structs_caller/src/main.sw @@ -6,7 +6,7 @@ use std::hash::*; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0x7fae96947a8cad59cc2a25239f9f80897955d4c1b10d31510681f15842b93265; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0x51106f3df741291f2aaef8a246ab6311e23abbafd3a7b3e10623e088fcc37451; +const CONTRACT_ID = 0x72ee7fae4f8adfebbc4c69ecd994624ebafc496dac1570c058c13f76be3cb866; fn main() -> u64 { let addr = abi(TestContract, CONTRACT_ID); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/asset_ops_test/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/asset_ops_test/src/main.sw index f649f3f82a0..8556253b118 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/asset_ops_test/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/asset_ops_test/src/main.sw @@ -9,12 +9,12 @@ use test_fuel_coin_abi::*; #[cfg(experimental_new_encoding = false)] const FUEL_COIN_CONTRACT_ID = 0x9e84e7e3006c94d5e23545829dbc926f50f90c6809c6e599ecddbf9a119e8104; #[cfg(experimental_new_encoding = true)] -const FUEL_COIN_CONTRACT_ID = 0xce6ae40e4e24b52d0f6046923b4ac59ed6899a8f590c86994def3e200f9ea7ec; +const FUEL_COIN_CONTRACT_ID = 0xecd6eeff9cfd449b038e8b9d5025b7f58eb7959af26b1d84636aab641ecf8ebf; #[cfg(experimental_new_encoding = false)] const BALANCE_CONTRACT_ID = 0x3b8cb681056f61a41e138b8884d7e3bb9332fbd7a8e38e3e0b0ada766cabfa4e; #[cfg(experimental_new_encoding = true)] -const BALANCE_CONTRACT_ID = 0xdcd79a58e8c7f562009109211e8855c023eb91d3d387ba9477e505e6a6643893; +const BALANCE_CONTRACT_ID = 0xf14fd5b5d028dd6c0db49803f886deb2b1dc87de092857795d77c8a04a0926ad; fn main() -> bool { let default_gas = 1_000_000_000_000; diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/bal_opcode/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/bal_opcode/src/main.sw index 74b924a3b8a..28510e964ca 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/bal_opcode/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/bal_opcode/src/main.sw @@ -5,7 +5,7 @@ use balance_test_abi::BalanceTest; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0x3b8cb681056f61a41e138b8884d7e3bb9332fbd7a8e38e3e0b0ada766cabfa4e; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0xdcd79a58e8c7f562009109211e8855c023eb91d3d387ba9477e505e6a6643893; +const CONTRACT_ID = 0xf14fd5b5d028dd6c0db49803f886deb2b1dc87de092857795d77c8a04a0926ad; fn main() -> bool { let balance_test_contract = abi(BalanceTest, CONTRACT_ID); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_abi_with_tuples/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_abi_with_tuples/src/main.sw index 6bc1533f741..54058628bf5 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_abi_with_tuples/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_abi_with_tuples/src/main.sw @@ -5,7 +5,7 @@ use abi_with_tuples::*; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0xb351aff8258ce46d16a71be666dd2b0b09d72243105c51f4423765824e59cac9; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0xa3eb70744fd03ddbfceffbd640d0fe4d704925ff8773b9f009e5939f12aa3439; +const CONTRACT_ID = 0x0212eba3f33371c30e065501183f9403b1e3abbc5c8e7445bcb6cd46075f3c8e; fn main() -> bool { let the_abi = abi(MyContract, CONTRACT_ID); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_basic_storage/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_basic_storage/src/main.sw index 89438789f8f..ce2f7725fb0 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_basic_storage/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_basic_storage/src/main.sw @@ -4,7 +4,7 @@ use basic_storage_abi::{BasicStorage, Quad}; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0x5c0aef0c1af7601aa6b9fa0fc9efff0e956dcb93f855788222e172e67e717072; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0x0ebd782b27bfa57a7525afd472e4cee41c9c7dfaaf0afb70df4a378da0025e23; +const CONTRACT_ID = 0x3ea788acce08fe964578f5a5743a07f18f879638b1707581f2979493663761f7; fn main() -> u64 { let addr = abi(BasicStorage, CONTRACT_ID); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_contract_with_type_aliases/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_contract_with_type_aliases/src/main.sw index 2c1cf6dfd38..527a417fe30 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_contract_with_type_aliases/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_contract_with_type_aliases/src/main.sw @@ -5,7 +5,7 @@ use contract_with_type_aliases_abi::*; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0x9d76ecbf446c30ef659efd1157d67d156de02b1e6c2ac2f9c744125571efa229; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0xbd2ab800338002ff56708e5ca457e678a714b25b93031bcd0e7a352212c0affc; +const CONTRACT_ID = 0x3e7e99214e2a0071de932ad864ca24e0a34794640996474d6afa5db9d0a6f549; fn main() { let caller = abi(MyContract, CONTRACT_ID); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_increment_contract/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_increment_contract/src/main.sw index cafe8ca239c..57a7867526a 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_increment_contract/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_increment_contract/src/main.sw @@ -6,7 +6,7 @@ use dynamic_contract_call::*; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0x080ca4b6a4661d3cc2138f733cbe54095ce8b910eee73d913c1f43ecad6bf0d2; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0x41166689b47e0f03434ba72957e66afdbf02f23518a0f2c9e48f887fbd4e67d8; +const CONTRACT_ID = 0x3aa626699732479de5bad989c439ea79811e2762a9d1f631cd22339f0d4a2968; fn main() -> bool { let the_abi = abi(Incrementor, CONTRACT_ID); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_storage_enum/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_storage_enum/src/main.sw index f271aca5b4b..a6625c561ed 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_storage_enum/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_storage_enum/src/main.sw @@ -5,7 +5,7 @@ use storage_enum_abi::*; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0x0436d54f976e2dee0d77c81abc0d32cc7be985d8e0c97eeba27acd1caffdcea1; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0x028e88f07ba7bf51d0b5d2e3cda7ccea35f8bdf788defa74ddb34841f074fcfd; +const CONTRACT_ID = 0xf93af673274e1fceb7104408a7abaaba12c076bfbe0b9fc7cd7cdd07487657e4; fn main() -> u64 { let caller = abi(StorageEnum, CONTRACT_ID); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/caller_auth_test/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/caller_auth_test/src/main.sw index 2e14d54549d..81e12f69179 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/caller_auth_test/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/caller_auth_test/src/main.sw @@ -5,7 +5,7 @@ use auth_testing_abi::AuthTesting; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0xd7ef57c654a7e52ee8b85f34c64fa2f8e1a250eceb446cfe9805b175a0a7680f; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0xad9e118ed616de791d5b5d82882cb34b069348e1cbcb07d0c7eb166eb10f1715; +const CONTRACT_ID = 0x2a596bb097e6e8f02b7e5d5e4e04cdb363ba933aa9dc6b1c825463267dbe9718; // should be false in the case of a script fn main() -> bool { diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/caller_context_test/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/caller_context_test/src/main.sw index 9899a283f60..a62c48afaa7 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/caller_context_test/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/caller_context_test/src/main.sw @@ -6,7 +6,7 @@ use context_testing_abi::*; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0xe83ed45906627117f00f60e47140c6100b4b69133389a2dafd35bc3282329385; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0xc9fbdf664bb7bf94574839521fcc950f1fa1b618efe0018a33e0c1209ff70792; +const CONTRACT_ID = 0x76476a00d78209e08a19b8f6d56fc9750e4862c19c8607640127a844a2d6a5ff; fn main() -> bool { let gas: u64 = u64::max(); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/nested_struct_args_caller/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/nested_struct_args_caller/src/main.sw index 711d7b2e5ec..98bbe6c6afb 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/nested_struct_args_caller/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/nested_struct_args_caller/src/main.sw @@ -5,7 +5,7 @@ use nested_struct_args_abi::*; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0xc615be7b48402210cbec3bc1667ab5a8093d449d5d8d1fdcc26e6f18e7942ea9; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0x1d23766d1bdb9f97151d33f4ae2f470a1792df5efef3c94ce7e60dd55e6e110d; +const CONTRACT_ID = 0x9d00e98f60e2f09550861b1ddfbf26d999171696d161ba1df36fc2fd10e73097; fn main() -> bool { let caller = abi(NestedStructArgs, CONTRACT_ID); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/storage_access_caller/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/storage_access_caller/src/main.sw index 6f4044ac113..d17d0c0898e 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/storage_access_caller/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/storage_access_caller/src/main.sw @@ -6,7 +6,7 @@ use std::hash::*; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0x0a58692bee60559887f0ac181c8a3b14ffb7a3a66256eec3f08e3135bfbecac9; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0x061235f2d1470151789ff3df04bd61b7034084b0dc22298c7167c4e0d38e29e0; +const CONTRACT_ID = 0x4afce106db8ef3bac5e2ec3c87043dd1df9bfd961a7bb4bfb997377ea5f4159e; fn main() -> bool { let caller = abi(StorageAccess, CONTRACT_ID); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/workspace_test/contract_multi_test/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/workspace_test/contract_multi_test/src/main.sw index f695a195534..206c6bb6647 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/workspace_test/contract_multi_test/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/unit_tests/workspace_test/contract_multi_test/src/main.sw @@ -17,7 +17,7 @@ fn test_foo() { #[test(should_revert)] fn test_fail() { - let contract_id = 0x9609f25a506fa3a692aee8e86458132e2909d866f4adcad3d60ce7550795c717; + let contract_id = 0x22f840cd4af724e7257dd01ce315d907d694e417778b5f16b205a918baee092e; let caller = abi(MyContract, contract_id); let result = caller.test_function {}(); assert(result == false) @@ -25,7 +25,7 @@ fn test_fail() { #[test] fn test_success() { - let contract_id = 0x9609f25a506fa3a692aee8e86458132e2909d866f4adcad3d60ce7550795c717; + let contract_id = 0x22f840cd4af724e7257dd01ce315d907d694e417778b5f16b205a918baee092e; let caller = abi(MyContract, contract_id); let result = caller.test_function {}(); assert(result == true) diff --git a/test/src/sdk-harness/Forc.lock b/test/src/sdk-harness/Forc.lock index 66182f2e91a..5760d872bbf 100644 --- a/test/src/sdk-harness/Forc.lock +++ b/test/src/sdk-harness/Forc.lock @@ -246,6 +246,16 @@ name = "result_option_expect" source = "member" dependencies = ["std"] +[[package]] +name = "run_external_proxy" +source = "member" +dependencies = ["std"] + +[[package]] +name = "run_external_target" +source = "member" +dependencies = ["std"] + [[package]] name = "script_bytecode" source = "member" diff --git a/test/src/sdk-harness/Forc.toml b/test/src/sdk-harness/Forc.toml index 2fb760f4644..1346c99b5f1 100644 --- a/test/src/sdk-harness/Forc.toml +++ b/test/src/sdk-harness/Forc.toml @@ -27,9 +27,8 @@ members = [ "test_projects/registers", "test_projects/result_in_abi", "test_projects/result_option_expect", - # Disabled until LDC is stabilized - # "test_projects/run_external_proxy", - # "test_projects/run_external_target", + "test_projects/run_external_proxy", + "test_projects/run_external_target", "test_projects/script_bytecode", "test_projects/script_data", "test_projects/storage", diff --git a/test/src/sdk-harness/test_projects/auth/mod.rs b/test/src/sdk-harness/test_projects/auth/mod.rs index 54148e24580..eb93f046f95 100644 --- a/test/src/sdk-harness/test_projects/auth/mod.rs +++ b/test/src/sdk-harness/test_projects/auth/mod.rs @@ -123,7 +123,7 @@ async fn can_get_predicate_address() { // Setup Predciate let hex_predicate_address: &str = - "0x01e9cb3d189e429b8c25dd7e96bbc01d36b02a51dd05874eab7142a04516aeb1"; + "0xb91f2b368b7784611ca0a4df5530c5eea31d01f0d16d393aa000c00c0d7125ca"; let predicate_address = Address::from_str(hex_predicate_address).expect("failed to create Address from string"); let predicate_bech32_address = Bech32Address::from(predicate_address); diff --git a/test/src/sdk-harness/test_projects/run_external_proxy/mod.rs b/test/src/sdk-harness/test_projects/run_external_proxy/mod.rs index dab266b86ab..95ab61f5341 100644 --- a/test/src/sdk-harness/test_projects/run_external_proxy/mod.rs +++ b/test/src/sdk-harness/test_projects/run_external_proxy/mod.rs @@ -1,79 +1,113 @@ -// use fuels::prelude::*; +use fuels::{ + prelude::*, + types::{Bits256, ContractId}, +}; -// abigen!(Contract( -// name = "RunExternalProxyContract", -// abi = "test_projects/run_external_proxy/out/release/run_external_proxy-abi.json", -// )); +abigen!(Contract( + name = "RunExternalProxyContract", + abi = "test_projects/run_external_proxy/out/release/run_external_proxy-abi.json", +)); -// #[tokio::test] -// #[ignore] -// async fn run_external_can_proxy_call() { -// let wallet = launch_provider_and_get_wallet().await.unwrap(); +#[tokio::test] +#[ignore] +async fn run_external_can_proxy_call() { + let wallet = launch_provider_and_get_wallet().await.unwrap(); -// let target_id = Contract::load_from( -// "test_projects/run_external_target/out/release/run_external_target.bin", -// LoadConfiguration::default() -// .with_storage_configuration(StorageConfiguration::default().with_autoload(false)), -// ) -// .unwrap() -// .deploy(&wallet, TxPolicies::default()) -// .await -// .unwrap(); + let target_id = Contract::load_from( + "test_projects/run_external_target/out/release/run_external_target.bin", + LoadConfiguration::default() + .with_storage_configuration(StorageConfiguration::default().with_autoload(false)), + ) + .unwrap() + .deploy(&wallet, TxPolicies::default()) + .await + .unwrap(); -// let configurables = RunExternalProxyContractConfigurables::default() -// .with_TARGET(target_id.clone().into()) -// .unwrap(); -// let id = Contract::load_from( -// "test_projects/run_external_proxy/out/release/run_external_proxy.bin", -// LoadConfiguration::default().with_configurables(configurables), -// ) -// .unwrap() -// .deploy(&wallet, TxPolicies::default()) -// .await -// .unwrap(); + let configurables = RunExternalProxyContractConfigurables::default() + .with_TARGET(target_id.clone().into()) + .unwrap(); + let id = Contract::load_from( + "test_projects/run_external_proxy/out/release/run_external_proxy.bin", + LoadConfiguration::default().with_configurables(configurables), + ) + .unwrap() + .deploy(&wallet, TxPolicies::default()) + .await + .unwrap(); -// let instance = RunExternalProxyContract::new(id.clone(), wallet); + let instance = RunExternalProxyContract::new(id.clone(), wallet); -// // Call "double_value" -// // Will call run_external_proxy::double_value -// // that will call run_external_target::double_value -// // and return the value doubled. -// let result = instance -// .methods() -// .double_value(42) -// .with_contract_ids(&[target_id.clone().into()]) -// .call() -// .await -// .unwrap(); -// // TODO: this can be removed after the string slice bug is fixed. -// for r in result.receipts.iter() { -// match r { -// Receipt::LogData { data, .. } => { -// if let Some(data) = data { -// if data.len() > 8 { -// if let Ok(s) = std::str::from_utf8(&data[8..]) { -// print!("{:?} ", s); -// } -// } + // Call "large_value" + // Will call run_external_proxy::large_value + // that will call run_external_target::large_value + // and return the value doubled. + let result = instance + .methods() + .large_value() + .with_contract_ids(&[target_id.clone().into()]) + .call() + .await + .unwrap(); + for r in result.receipts.iter() { + match r { + Receipt::LogData { data, .. } => { + if let Some(data) = data { + if data.len() > 8 { + if let Ok(s) = std::str::from_utf8(&data[8..]) { + print!("{:?} ", s); + } + } -// println!("{:?}", data); -// } -// } -// _ => {} -// } -// } -// assert_eq!(result.value, 84); + println!("{:?}", data); + } + } + _ => {} + } + } + let expected_large = + Bits256::from_hex_str("0x00000000000000000000000059F2f1fCfE2474fD5F0b9BA1E73ca90b143Eb8d0") + .unwrap(); + assert_eq!(result.value, expected_large); -// // Call "does_not_exist_in_the_target" -// // Will call run_external_proxy::does_not_exist_in_the_target -// // it will proxy the call to run_external_target, -// // and endup in the fallback, fn that will triple the input value -// let result = instance -// .methods() -// .does_not_exist_in_the_target(42) -// .with_contract_ids(&[target_id.into()]) -// .call() -// .await -// .unwrap(); -// assert_eq!(result.value, 126); -// } + // Call "double_value" + // Will call run_external_proxy::double_value + // that will call run_external_target::double_value + // and return the value doubled. + let result = instance + .methods() + .double_value(42) + .with_contract_ids(&[target_id.clone().into()]) + .call() + .await + .unwrap(); + for r in result.receipts.iter() { + match r { + Receipt::LogData { data, .. } => { + if let Some(data) = data { + if data.len() > 8 { + if let Ok(s) = std::str::from_utf8(&data[8..]) { + print!("{:?} ", s); + } + } + + println!("{:?}", data); + } + } + _ => {} + } + } + assert_eq!(result.value, 84); + + // Call "does_not_exist_in_the_target" + // Will call run_external_proxy::does_not_exist_in_the_target + // it will proxy the call to run_external_target, + // and endup in the fallback, fn that will triple the input value + let result = instance + .methods() + .does_not_exist_in_the_target(42) + .with_contract_ids(&[target_id.into()]) + .call() + .await + .unwrap(); + assert_eq!(result.value, 126); +} diff --git a/test/src/sdk-harness/test_projects/run_external_proxy/src/main.sw b/test/src/sdk-harness/test_projects/run_external_proxy/src/main.sw index 65bd591e339..36636bf7273 100644 --- a/test/src/sdk-harness/test_projects/run_external_proxy/src/main.sw +++ b/test/src/sdk-harness/test_projects/run_external_proxy/src/main.sw @@ -9,6 +9,7 @@ configurable { abi RunExternalTest { fn double_value(foo: u64) -> u64; + fn large_value() -> b256; fn does_not_exist_in_the_target(foo: u64) -> u64; } @@ -18,6 +19,10 @@ impl RunExternalTest for Contract { run_external(TARGET) } + fn large_value() -> b256 { + run_external(TARGET) + } + fn does_not_exist_in_the_target(_foo: u64) -> u64 { run_external(TARGET) } diff --git a/test/src/sdk-harness/test_projects/run_external_target/src/main.sw b/test/src/sdk-harness/test_projects/run_external_target/src/main.sw index 1bf0659817f..07e0629898e 100644 --- a/test/src/sdk-harness/test_projects/run_external_target/src/main.sw +++ b/test/src/sdk-harness/test_projects/run_external_target/src/main.sw @@ -2,6 +2,7 @@ contract; abi RunExternalTest { fn double_value(foo: u64) -> u64; + fn large_value() -> b256; } impl RunExternalTest for Contract { @@ -9,6 +10,9 @@ impl RunExternalTest for Contract { __log(2); foo * 2 } + fn large_value() -> b256 { + 0x00000000000000000000000059F2f1fCfE2474fD5F0b9BA1E73ca90b143Eb8d0 + } } #[fallback]