Skip to content

Conversation

@0xOmarA
Copy link
Contributor

@0xOmarA 0xOmarA commented Jul 13, 2025

Summary

This PR fixes a problem in the driver which made it unable to find the ABI of the contracts that it deployed.

Description

I found the following error log when trying to run a simple test through this framework:

  2025-07-13T12:43:00.398341Z ERROR revive_dt_core::driver: Follower deployment failed for Main: No metadata found for contract Callable
    at crates/core/src/driver/mod.rs:421 on main ThreadId(1)
    in revive_dt_core::driver::Executing case with case: "first", case_idx: 0
    in retester::Running driver with metadata_file_path: "era-compiler-tests/solidity/complex/array_one_element/test.json"

This error stems from the the following piece of code:

if let Some(Value::String(metadata_json_str)) = &contract.metadata {
    tracing::trace!(
        "metadata found for contract {contract_name}, {metadata_json_str}"
    );

    match serde_json::from_str::<serde_json::Value>(metadata_json_str) {
        Ok(metadata_json) => {
            if let Some(abi_value) =
                metadata_json.get("output").and_then(|o| o.get("abi"))
            {
                match serde_json::from_value::<JsonAbi>(abi_value.clone()) {
                    Ok(parsed_abi) => {
                        tracing::trace!(
                            "ABI found in metadata for contract {}",
                            &contract_name
                        );
                        self.deployed_abis
                            .insert(contract_name.clone(), parsed_abi);
                    }
                    Err(err) => {
                        anyhow::bail!(
                            "Failed to parse ABI from metadata for contract {}: {}",
                            contract_name,
                            err
                        );
                    }
                }
            } else {
                anyhow::bail!(
                    "No ABI found in metadata for contract {}",
                    contract_name
                );
            }
        }
        Err(err) => {
            anyhow::bail!(
                "Failed to parse metadata JSON string for contract {}: {}",
                contract_name,
                err
            );
        }
    }
} else {
    anyhow::bail!("No metadata found for contract {}", contract_name);
}

Which is attempting to find the ABI of the contract that's being deployed in the JSON output of the compiler. The above works with solc but doesn't work with resolc. The reason for this is that the JSON schema of the output of both compilers is different. Here's an example:

  • Output of the solc compiler:
    {
        "metadata": "{\"compiler\":{\"version\":\"0.8.29+commit.ab55807c\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256[1]\",\"name\":\"p1\",\"type\":\"uint256[1]\"}],\"name\":\"f\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"/Users/omarabdulla/parity/era-compiler-tests/solidity/complex/array_one_element/callable.sol\":\"Callable\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"details\":{\"constantOptimizer\":false,\"cse\":false,\"deduplicate\":false,\"inliner\":true,\"jumpdestRemover\":false,\"orderLiterals\":false,\"peephole\":false,\"simpleCounterForLoopUncheckedIncrement\":true,\"yul\":true,\"yulDetails\":{\"optimizerSteps\":\"dhfoDgvulfnTUtnIfxa[r]EscLMVcul [j]Trpeulxa[r]cLgvifMCTUca[r]LSsTFOtfDnca[r]IulcscCTUtgvifMx[scCTUt] TOntnfDIulgvifMjmul[jul] VcTOcul jmul:fDnTOcmuO\",\"stackAllocation\":true}},\"runs\":200},\"remappings\":[],\"viaIR\":true},\"sources\":{\"/Users/omarabdulla/parity/era-compiler-tests/solidity/complex/array_one_element/callable.sol\":{\"keccak256\":\"0x6d0e7b9c3d7fc7a06fac7413ce4f0f02a110fe552ef33c642cf94c192fee5963\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://36f00835b9466e8697d13994e557f240e491f9515ef1e65c83aef134f0d1e1e4\",\"dweb:/ipfs/QmafYebPHZp6iwxY5NuD9FP8C9Y7X3vfcqNtm4Np8REcTt\"]}},\"version\":1}",
        "evm": {
            "bytecode": {
                "object": "REMOVED TO SAVE SPACE"
            },
            "deployedBytecode": {
                "object": "REMOVED TO SAVE SPACE"
            },
            "methodIdentifiers": {
                "f(uint256[1])": "09a31ea4"
            }
        },
        "irOptimized": "REMOVED TO SAVE SPACE"
    }
  • Output of the resolc compiler:
    {
        "metadata": {
            "llvm_arguments": [],
            "optimizer_settings": {
                "is_debug_logging_enabled": false,
                "is_fallback_to_size_enabled": false,
                "is_verify_each_enabled": false,
                "level_back_end": "Aggressive",
                "level_middle_end": "Default",
                "level_middle_end_size": "Z"
            },
            "revive_pallet_version": null,
            "revive_version": "0.3.0+commit.b238913.llvm-18.1.8",
            "solc_metadata": "{\"compiler\":{\"version\":\"0.8.30+commit.73712a01\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256[1]\",\"name\":\"p1\",\"type\":\"uint256[1]\"}],\"name\":\"f\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"/Users/omarabdulla/parity/era-compiler-tests/solidity/complex/array_one_element/callable.sol\":\"Callable\"},\"evmVersion\":\"prague\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"details\":{\"constantOptimizer\":false,\"cse\":false,\"deduplicate\":false,\"inliner\":false,\"jumpdestRemover\":false,\"orderLiterals\":false,\"peephole\":false,\"simpleCounterForLoopUncheckedIncrement\":true,\"yul\":true,\"yulDetails\":{\"optimizerSteps\":\"dhfoDgvulfnTUtnIfxa[r]EscLMVcul [j]Trpeulxa[r]cLgvifMCTUca[r]LSsTFOtfDnca[r]IulcscCTUtgvifMx[scCTUt] TOntnfDIulgvifMjmul[jul] VcTOcul jmul:fDnTOcmuO\",\"stackAllocation\":true}},\"runs\":200},\"remappings\":[]},\"sources\":{\"/Users/omarabdulla/parity/era-compiler-tests/solidity/complex/array_one_element/callable.sol\":{\"keccak256\":\"0x6d0e7b9c3d7fc7a06fac7413ce4f0f02a110fe552ef33c642cf94c192fee5963\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://36f00835b9466e8697d13994e557f240e491f9515ef1e65c83aef134f0d1e1e4\",\"dweb:/ipfs/QmafYebPHZp6iwxY5NuD9FP8C9Y7X3vfcqNtm4Np8REcTt\"]}},\"version\":1}",
            "solc_version": "0.8.30+commit.73712a01.Darwin.appleclang"
        },
        "evm": {
            "assembly": "REMOVED TO SAVE SPACE",
            "bytecode": {
                "object": "REMOVED TO SAVE SPACE"
            },
            "deployedBytecode": {
                "object": "REMOVED TO SAVE SPACE"
            },
            "methodIdentifiers": {
                "f(uint256[1])": "09a31ea4"
            }
        },
        "irOptimized": "REMOVED TO SAVE SPACE",
        "hash": "10335929ebaafc99c69b0bd9524253a31e13c491caf3e88c63fe40676d359a10",
        "factoryDependencies": {}
    }

We can see that for the two compilers the path that the metadata (and the abi) exist at are a little different. For solc it's at .metadata.output.abi and for resolc it's at .metadata.solc_metadata.output.abi.

I implemented a short term solution to this (and described the more ideal long term solution in the code comments) where the driver is aware of the differences of the formats and it attempts to find the metadata and the ABI at the two paths listed above.

Once we get everything working and we want to productize the code we can implement something that's cleaner and respects the abstractions that we have a bit more.

Copy link
Member

@xermicus xermicus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is an oversight from implementing the compiler trait for resolc. Would you mind just fixing it there so that the compiler output is compatible with what solc returns and no special case handling is required here? I'd like to have as logic as possible in the driver (since we have those traits anyways it's much better to put any implementation specific code there).

@0xOmarA
Copy link
Contributor Author

0xOmarA commented Jul 14, 2025

@xermicus Yeah that sounds good. I was planning on doing what you described in the long-term but it turned out to be simpler than I thought. I just made this change.

@0xOmarA 0xOmarA mentioned this pull request Jul 16, 2025
@0xOmarA 0xOmarA added this pull request to the merge queue Jul 18, 2025
Merged via the queue into main with commit 2bee2d5 Jul 18, 2025
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants