Skip to content

Commit

Permalink
fix: actualize output selection options (#196)
Browse files Browse the repository at this point in the history
Added `irOptimizedAst` and `transientStorageLayout` outputs. Also made
some patterns exhaustive to make it easier next time
  • Loading branch information
klkvr authored Sep 5, 2024
1 parent 6b66a6b commit e906f76
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 25 deletions.
4 changes: 4 additions & 0 deletions crates/artifacts/solc/src/configurable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ pub struct ConfigurableContractArtifact {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub storage_layout: Option<StorageLayout>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub transient_storage_layout: Option<StorageLayout>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub userdoc: Option<UserDoc>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub devdoc: Option<DevDoc>,
Expand All @@ -47,6 +49,8 @@ pub struct ConfigurableContractArtifact {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub ir_optimized: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub ir_optimized_ast: Option<serde_json::Value>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub ewasm: Option<Ewasm>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub ast: Option<Ast>,
Expand Down
4 changes: 4 additions & 0 deletions crates/artifacts/solc/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ pub struct Contract {
pub ir: Option<String>,
#[serde(default, skip_serializing_if = "StorageLayout::is_empty")]
pub storage_layout: StorageLayout,
#[serde(default, skip_serializing_if = "StorageLayout::is_empty")]
pub transient_storage_layout: StorageLayout,
/// EVM-related outputs
#[serde(default, skip_serializing_if = "Option::is_none")]
pub evm: Option<Evm>,
Expand All @@ -40,6 +42,8 @@ pub struct Contract {
pub ewasm: Option<Ewasm>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub ir_optimized: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub ir_optimized_ast: Option<serde_json::Value>,
}

impl<'a> From<&'a Contract> for CompactContractBytecodeCow<'a> {
Expand Down
4 changes: 4 additions & 0 deletions crates/artifacts/solc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -836,6 +836,10 @@ impl EvmVersion {
// <https://soliditylang.org/blog/2024/01/26/solidity-0.8.24-release-announcement/>
Some(Self::Shanghai)
}
Self::Prague if *version == Version::new(0, 8, 27) => {
// Prague was not set as default EVM version in 0.8.27.
Some(Self::Cancun)
}
_ => Some(default),
}
}
Expand Down
8 changes: 8 additions & 0 deletions crates/artifacts/solc/src/output_selection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,9 @@ pub enum ContractOutputSelection {
Metadata,
Ir,
IrOptimized,
IrOptimizedAst,
StorageLayout,
TransientStorageLayout,
Evm(EvmOutputSelection),
Ewasm(EwasmOutputSelection),
}
Expand Down Expand Up @@ -268,7 +270,9 @@ impl fmt::Display for ContractOutputSelection {
Self::Metadata => f.write_str("metadata"),
Self::Ir => f.write_str("ir"),
Self::IrOptimized => f.write_str("irOptimized"),
Self::IrOptimizedAst => f.write_str("irOptimizedAst"),
Self::StorageLayout => f.write_str("storageLayout"),
Self::TransientStorageLayout => f.write_str("transientStorageLayout"),
Self::Evm(e) => e.fmt(f),
Self::Ewasm(e) => e.fmt(f),
}
Expand All @@ -286,7 +290,11 @@ impl FromStr for ContractOutputSelection {
"metadata" => Ok(Self::Metadata),
"ir" => Ok(Self::Ir),
"ir-optimized" | "irOptimized" | "iroptimized" => Ok(Self::IrOptimized),
"irOptimizedAst" | "ir-optimized-ast" | "iroptimizedast" => Ok(Self::IrOptimizedAst),
"storage-layout" | "storagelayout" | "storageLayout" => Ok(Self::StorageLayout),
"transient-storage-layout" | "transientstoragelayout" | "transientStorageLayout" => {
Ok(Self::TransientStorageLayout)
}
s => EvmOutputSelection::from_str(s)
.map(ContractOutputSelection::Evm)
.or_else(|_| EwasmOutputSelection::from_str(s).map(ContractOutputSelection::Ewasm))
Expand Down
2 changes: 2 additions & 0 deletions crates/artifacts/vyper/src/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,10 @@ impl From<VyperContract> for solc_artifacts::Contract {
devdoc: Default::default(),
ir: None,
storage_layout: Default::default(),
transient_storage_layout: Default::default(),
ewasm: None,
ir_optimized: None,
ir_optimized_ast: None,
}
}
}
Expand Down
88 changes: 71 additions & 17 deletions crates/compilers/src/artifact_output/configurable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,54 +77,88 @@ impl ConfigurableArtifacts {

/// Returns the `Settings` this configuration corresponds to
pub fn solc_settings(&self) -> Settings {
SolcConfig::builder().additional_outputs(self.output_selection()).build().into()
SolcConfig::builder()
.additional_outputs(self.output_selection())
.ast(self.additional_values.ast)
.build()
}

/// Returns the output selection corresponding to this configuration
pub fn output_selection(&self) -> Vec<ContractOutputSelection> {
let mut selection = ContractOutputSelection::basic();

if self.additional_values.ir || self.additional_files.ir {
let ExtraOutputValues {
// handled above
ast: _,
userdoc,
devdoc,
method_identifiers,
storage_layout,
transient_storage_layout,
assembly,
gas_estimates,
metadata,
ir,
ir_optimized,
ir_optimized_ast,
ewasm,
function_debug_data,
generated_sources,
source_map,
opcodes,
__non_exhaustive,
} = self.additional_values;

if ir || self.additional_files.ir {
selection.push(ContractOutputSelection::Ir);
}
if self.additional_values.ir_optimized || self.additional_files.ir_optimized {
if ir_optimized || self.additional_files.ir_optimized {
selection.push(ContractOutputSelection::IrOptimized);
}
if self.additional_values.metadata || self.additional_files.metadata {
if metadata || self.additional_files.metadata {
selection.push(ContractOutputSelection::Metadata);
}
if self.additional_values.storage_layout {
if storage_layout {
selection.push(ContractOutputSelection::StorageLayout);
}
if self.additional_values.devdoc {
if devdoc {
selection.push(ContractOutputSelection::DevDoc);
}
if self.additional_values.userdoc {
if userdoc {
selection.push(ContractOutputSelection::UserDoc);
}
if self.additional_values.gas_estimates {
if gas_estimates {
selection.push(EvmOutputSelection::GasEstimates.into());
}
if self.additional_values.assembly || self.additional_files.assembly {
if assembly || self.additional_files.assembly {
selection.push(EvmOutputSelection::Assembly.into());
}
if self.additional_values.ewasm || self.additional_files.ewasm {
if ewasm || self.additional_files.ewasm {
selection.push(EwasmOutputSelection::All.into());
}
if self.additional_values.function_debug_data {
if function_debug_data {
selection.push(BytecodeOutputSelection::FunctionDebugData.into());
}
if self.additional_values.method_identifiers {
if method_identifiers {
selection.push(EvmOutputSelection::MethodIdentifiers.into());
}
if self.additional_values.generated_sources {
if generated_sources {
selection.push(
EvmOutputSelection::ByteCode(BytecodeOutputSelection::GeneratedSources).into(),
);
}
if self.additional_values.source_map {
if source_map {
selection.push(EvmOutputSelection::ByteCode(BytecodeOutputSelection::SourceMap).into());
}
if ir_optimized_ast {
selection.push(ContractOutputSelection::IrOptimizedAst);
}
if opcodes {
selection.push(EvmOutputSelection::ByteCode(BytecodeOutputSelection::Opcodes).into());
}
if transient_storage_layout {
selection.push(ContractOutputSelection::TransientStorageLayout);
}
selection
}
}
Expand Down Expand Up @@ -165,6 +199,7 @@ impl ArtifactOutput for ConfigurableArtifacts {
let mut artifact_metadata = None;
let mut artifact_ir = None;
let mut artifact_ir_optimized = None;
let mut artifact_ir_optimized_ast = None;
let mut artifact_ewasm = None;
let mut artifact_bytecode = None;
let mut artifact_deployed_bytecode = None;
Expand All @@ -173,6 +208,7 @@ impl ArtifactOutput for ConfigurableArtifacts {
let mut artifact_method_identifiers = None;
let mut artifact_assembly = None;
let mut artifact_storage_layout = None;
let mut artifact_transient_storage_layout = None;
let mut generated_sources = None;
let mut opcodes = None;

Expand All @@ -183,9 +219,11 @@ impl ArtifactOutput for ConfigurableArtifacts {
devdoc,
ir,
storage_layout,
transient_storage_layout,
evm,
ewasm,
ir_optimized,
ir_optimized_ast,
} = contract;

if self.additional_values.metadata {
Expand All @@ -209,9 +247,15 @@ impl ArtifactOutput for ConfigurableArtifacts {
if self.additional_values.ir_optimized {
artifact_ir_optimized = ir_optimized;
}
if self.additional_values.ir_optimized_ast {
artifact_ir_optimized_ast = ir_optimized_ast;
}
if self.additional_values.storage_layout {
artifact_storage_layout = Some(storage_layout);
}
if self.additional_values.transient_storage_layout {
artifact_transient_storage_layout = Some(transient_storage_layout);
}

if let Some(evm) = evm {
let Evm {
Expand Down Expand Up @@ -260,10 +304,12 @@ impl ArtifactOutput for ConfigurableArtifacts {
raw_metadata: artifact_raw_metadata,
metadata: artifact_metadata,
storage_layout: artifact_storage_layout,
transient_storage_layout: artifact_transient_storage_layout,
userdoc: artifact_userdoc,
devdoc: artifact_devdoc,
ir: artifact_ir,
ir_optimized: artifact_ir_optimized,
ir_optimized_ast: artifact_ir_optimized_ast,
ewasm: artifact_ewasm,
id: source_file.as_ref().map(|s| s.id),
ast: source_file.and_then(|s| s.ast.clone()),
Expand Down Expand Up @@ -376,12 +422,13 @@ pub struct ExtraOutputValues {
pub devdoc: bool,
pub method_identifiers: bool,
pub storage_layout: bool,
pub transient_storage_layout: bool,
pub assembly: bool,
pub gas_estimates: bool,
pub compact_format: bool,
pub metadata: bool,
pub ir: bool,
pub ir_optimized: bool,
pub ir_optimized_ast: bool,
pub ewasm: bool,
pub function_debug_data: bool,
pub generated_sources: bool,
Expand Down Expand Up @@ -409,12 +456,13 @@ impl ExtraOutputValues {
devdoc: true,
method_identifiers: true,
storage_layout: true,
transient_storage_layout: true,
assembly: true,
gas_estimates: true,
compact_format: true,
metadata: true,
ir: true,
ir_optimized: true,
ir_optimized_ast: true,
ewasm: true,
function_debug_data: true,
generated_sources: true,
Expand Down Expand Up @@ -484,7 +532,13 @@ impl ExtraOutputValues {
ContractOutputSelection::Ewasm(_) => {
config.ewasm = true;
}
_ => {}
ContractOutputSelection::IrOptimizedAst => {
config.ir_optimized_ast = true;
}
ContractOutputSelection::TransientStorageLayout => {
config.transient_storage_layout = true;
}
ContractOutputSelection::Abi => {}
}
}

Expand Down
21 changes: 15 additions & 6 deletions crates/compilers/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -925,6 +925,9 @@ pub struct SolcConfigBuilder {

/// additionally selected outputs that should be included in the `Contract` that solc creates.
output_selection: Vec<ContractOutputSelection>,

/// whether to include the AST in the output
ast: bool,
}

impl SolcConfigBuilder {
Expand Down Expand Up @@ -953,14 +956,20 @@ impl SolcConfigBuilder {
self
}

/// Creates the solc config
///
/// If no solc version is configured then it will be determined by calling `solc --version`.
pub fn build(self) -> SolcConfig {
let Self { settings, output_selection } = self;
pub fn ast(mut self, yes: bool) -> Self {
self.ast = yes;
self
}

/// Creates the solc settings
pub fn build(self) -> Settings {
let Self { settings, output_selection, ast } = self;
let mut settings = settings.unwrap_or_default();
settings.push_all(output_selection);
SolcConfig { settings }
if ast {
settings = settings.with_ast();
}
settings
}
}

Expand Down
3 changes: 1 addition & 2 deletions crates/core/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,7 @@ pub const SHANGHAI_SOLC: Version = Version::new(0, 8, 20);
pub const CANCUN_SOLC: Version = Version::new(0, 8, 24);

/// Prague support
/// <https://github.com/ethereum/solidity/pull/15152>
/// Was merged between 0.8.26 and 0.8.27, so we are expecting it to be available in 0.8.27
/// <https://soliditylang.org/blog/2024/09/04/solidity-0.8.27-release-announcement>
pub const PRAGUE_SOLC: Version = Version::new(0, 8, 27);

// `--base-path` was introduced in 0.6.9 <https://github.com/ethereum/solidity/releases/tag/v0.6.9>
Expand Down

0 comments on commit e906f76

Please sign in to comment.