diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 61efe51be..577da3eaa 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -15,10 +15,11 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@stable - with: - targets: wasm32-unknown-unknown - - uses: Swatinem/rust-cache@v2 + - name: Install Toolchain + run: | + rustup update stable && rustup default stable + rustup target add wasm32-unknown-unknown + - uses: taiki-e/install-action@sccache - uses: taiki-e/install-action@nextest - uses: foundry-rs/foundry-toolchain@v1 diff --git a/compiler/src/compiler.rs b/compiler/src/compiler.rs index 44e6801dd..242d14455 100644 --- a/compiler/src/compiler.rs +++ b/compiler/src/compiler.rs @@ -1,6 +1,7 @@ //! Zink compiler use crate::{parser::Parser, Artifact, Config, Error, Result}; +use std::collections::HashMap; use zabi::Abi; use zingen::{ wasm::{self, Env}, @@ -11,7 +12,7 @@ use zingen::{ #[derive(Default)] pub struct Compiler { /// ABIs of the compiled contract. - pub(crate) abi: Vec, + pub(crate) abi: HashMap, /// EVM bytecode buffer. pub(crate) buffer: Buffer, /// Compiler configuration. @@ -59,7 +60,7 @@ impl Compiler { tracing::debug!("code length: {}", buffer.len()); Ok(Artifact { - abi, + abi: abi.into_values().collect(), config, runtime_bytecode: buffer.to_vec(), }) @@ -73,7 +74,9 @@ impl Compiler { let env = parser.env.clone(); if !self.config.dispatcher { - self.abi.append(&mut env.load_abis(&selectors)?); + for abi in env.load_abis(&selectors)? { + self.abi.insert(abi.name.clone(), abi); + } return Ok(()); } @@ -84,7 +87,9 @@ impl Compiler { return Err(Error::BufferOverflow(self.buffer.len())); } - self.abi.append(&mut dispatcher.abi); + for abi in dispatcher.abi { + self.abi.insert(abi.name.clone(), abi); + } Ok(()) } @@ -124,6 +129,6 @@ impl Compiler { /// Get abi from env and function index fn abi(&self, env: &Env, index: u32) -> Option { let name = env.exports.get(&index)?; - self.abi.iter().find(|a| name == &a.name).cloned() + self.abi.get(name).cloned() } } diff --git a/zink/examples/log.rs b/zink/examples/log.rs index 50c8ca8b9..14b22384f 100644 --- a/zink/examples/log.rs +++ b/zink/examples/log.rs @@ -126,6 +126,42 @@ mod tests { assert_eq!(info.logs[0].topics()[0].to_vec(), value4.bytes32().to_vec()); } } + + #[test] + fn test_log_abi() { + let contract = Contract::search("log") + .unwrap() + .compile() + .expect("failed to compile"); + let abi = contract.artifact.abi; + + assert_eq!(abi.len(), 5); + + let test_log0 = abi.iter().find(|a| a.name == "test_log0").unwrap(); + assert_eq!(test_log0.inputs.len(), 0); + + let test_log1 = abi.iter().find(|a| a.name == "test_log1").unwrap(); + assert_eq!(test_log1.inputs.len(), 1); + assert_eq!(test_log1.inputs[0].ty.to_string(), "uint256"); + + let test_log2 = abi.iter().find(|a| a.name == "test_log2").unwrap(); + assert_eq!(test_log2.inputs.len(), 2); + assert_eq!(test_log2.inputs[0].ty.to_string(), "uint256"); + assert_eq!(test_log2.inputs[1].ty.to_string(), "uint256"); + + let test_log3 = abi.iter().find(|a| a.name == "test_log3").unwrap(); + assert_eq!(test_log3.inputs.len(), 3); + assert_eq!(test_log3.inputs[0].ty.to_string(), "uint256"); + assert_eq!(test_log3.inputs[1].ty.to_string(), "uint256"); + assert_eq!(test_log3.inputs[2].ty.to_string(), "uint256"); + + let test_log4 = abi.iter().find(|a| a.name == "test_log4").unwrap(); + assert_eq!(test_log4.inputs.len(), 4); + assert_eq!(test_log4.inputs[0].ty.to_string(), "uint256"); + assert_eq!(test_log4.inputs[1].ty.to_string(), "uint256"); + assert_eq!(test_log4.inputs[2].ty.to_string(), "uint256"); + assert_eq!(test_log4.inputs[3].ty.to_string(), "uint256"); + } } #[cfg(not(target_arch = "wasm32"))]