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

feat(contract-verifier): Partial matching & automatic verification #3527

Merged
merged 20 commits into from
Jan 30, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Add tests for partial verification
  • Loading branch information
popzxc committed Jan 24, 2025
commit 300fdc15ee7763dedbed36f4aa92c7d670f737e4
4 changes: 2 additions & 2 deletions .github/workflows/ci-core-reusable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ jobs:
ci_run zkstack dev contracts

- name: Download compilers for contract verifier tests
run: ci_run zkstack contract-verifier init --zksolc-version=v1.5.3 --zkvyper-version=v1.5.4 --solc-version=0.8.26 --vyper-version=v0.3.10 --era-vm-solc-version=0.8.26-1.0.1 --only --chain era
run: ci_run zkstack contract-verifier init --zksolc-version=v1.5.10 --zkvyper-version=v1.5.4 --solc-version=0.8.26 --vyper-version=v0.3.10 --era-vm-solc-version=0.8.26-1.0.1 --only --chain era

- name: Rust unit tests
run: |
Expand Down Expand Up @@ -431,7 +431,7 @@ jobs:

- name: Initialize Contract verifier
run: |
ci_run zkstack contract-verifier init --zksolc-version=v1.5.3 --zkvyper-version=v1.5.4 --solc-version=0.8.26 --vyper-version=v0.3.10 --era-vm-solc-version=0.8.26-1.0.1 --only --chain era
ci_run zkstack contract-verifier init --zksolc-version=v1.5.10 --zkvyper-version=v1.5.4 --solc-version=0.8.26 --vyper-version=v0.3.10 --era-vm-solc-version=0.8.26-1.0.1 --only --chain era
ci_run zkstack contract-verifier run --chain era &> ${{ env.SERVER_LOGS_DIR }}/contract-verifier-rollup.log &
ci_run zkstack contract-verifier wait --chain era --verbose

Expand Down
24 changes: 20 additions & 4 deletions core/lib/contract_verifier/src/compilers/zksolc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ pub(crate) struct Optimizer {
/// Whether the optimizer is enabled.
pub enabled: bool,
/// The optimization mode string.
#[serde(skip_serializing_if = "Option::is_none")]
pub mode: Option<char>,
}

Expand Down Expand Up @@ -148,12 +149,24 @@ impl ZkSolc {
fn parse_single_file_yul_output(
output: &str,
) -> Result<CompilationArtifacts, ContractVerifierError> {
let re = Regex::new(r"Contract `.*` bytecode: 0x([\da-f]+)").unwrap();
let cap = re
.captures(output)
.context("Yul output doesn't match regex")?;
let cap = if output.contains("Binary:\n") {
// Format of the new output
// ======= /tmp/input.yul:Empty =======
// Binary:
// 00000001002 <..>
let re = Regex::new(r"Binary:\n([\da-f]+)").unwrap();
re.captures(output)
.with_context(|| format!("Yul output doesn't match regex. Output: {output}"))?
} else {
// Old compiler versions
let re_old = Regex::new(r"Contract `.*` bytecode: 0x([\da-f]+)").unwrap();
re_old
.captures(output)
.with_context(|| format!("Yul output doesn't match regex. Output: {output}"))?
};
let bytecode_str = cap.get(1).context("no matches in Yul output")?.as_str();
let bytecode = hex::decode(bytecode_str).context("invalid Yul output bytecode")?;

Ok(CompilationArtifacts {
bytecode,
deployed_bytecode: None,
Expand Down Expand Up @@ -265,6 +278,9 @@ impl Compiler<ZkSolcInput> for ZkSolc {
.context("cannot create temporary Yul file")?;
file.write_all(source_code.as_bytes())
.context("failed writing Yul file")?;

// TODO: `zksolc` support standard JSON for `yul` since 1.5.0, so we don't have
// to parse `--bin` output.
let child = command
.arg(file.path().to_str().unwrap())
.arg("--optimization")
Expand Down
Empty file.
10 changes: 8 additions & 2 deletions core/lib/contract_verifier/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -446,14 +446,15 @@ async fn contract_verifier_basics(contract: TestContract) {
let (_stop_sender, stop_receiver) = watch::channel(false);
verifier.run(stop_receiver, Some(1)).await.unwrap();

assert_request_success(&mut storage, request_id, address, &expected_bytecode).await;
assert_request_success(&mut storage, request_id, address, &expected_bytecode, &[]).await;
}

async fn assert_request_success(
storage: &mut Connection<'_, Core>,
request_id: usize,
address: Address,
expected_bytecode: &[u8],
verification_problems: &[VerificationProblem],
) -> VerificationInfo {
let status = storage
.contract_verification_dal()
Expand All @@ -476,6 +477,11 @@ async fn assert_request_success(
without_internal_types(verification_info.artifacts.abi.clone()),
without_internal_types(counter_contract_abi())
);
assert_eq!(
&verification_info.verification_problems,
verification_problems
);

verification_info
}

Expand Down Expand Up @@ -554,7 +560,7 @@ async fn verifying_evm_bytecode(contract: TestContract) {
let (_stop_sender, stop_receiver) = watch::channel(false);
verifier.run(stop_receiver, Some(1)).await.unwrap();

assert_request_success(&mut storage, request_id, address, &creation_bytecode).await;
assert_request_success(&mut storage, request_id, address, &creation_bytecode, &[]).await;
}

#[tokio::test]
Expand Down
Loading