Skip to content

Commit

Permalink
Merge branch 'master' into evm_queue_state_root_tracking
Browse files Browse the repository at this point in the history
  • Loading branch information
Jouzo authored Sep 6, 2023
2 parents 2126e4e + 7224b45 commit 227b80c
Show file tree
Hide file tree
Showing 16 changed files with 931 additions and 186 deletions.
101 changes: 58 additions & 43 deletions lib/ain-contracts/build.rs
Original file line number Diff line number Diff line change
@@ -1,68 +1,83 @@
use std::{env, fs, path::PathBuf};

use anyhow::format_err;
use ethers_solc::{Project, ProjectPathsConfig, Solc};
use anyhow::{bail, Context, Result};
use ethers_solc::{artifacts::Optimizer, Project, ProjectPathsConfig, Solc, SolcConfig};

fn main() -> Result<(), Box<dyn std::error::Error>> {
// compile solidity project
// configure `root` as our project root
fn main() -> Result<()> {
let manifest_path = PathBuf::from(env::var("CARGO_MANIFEST_DIR")?);
let solc_path_str = env::var("SOLC_PATH")?;

// If TARGET_DIR is set, which we do from Makefile, uses that instead of OUT_DIR.
// Otherwise, use the path for OUT_DIR that cargo sets, as usual.
// Reason: Currently setting --out-dir is nightly only, so there's no way to get OUT_DIR
// out of cargo reliably for pointing deps determinisitcally.
let target_dir: PathBuf = PathBuf::from(env::var("CARGO_TARGET_DIR").or(env::var("OUT_DIR"))?);
let solc_artifact_dir = target_dir.join("sol_artifacts");

// Solidity project root and contract names relative to our project
let contracts = vec![
("dfi_intrinsics", "DFIIntrinsics"),
("dst20", "DST20"),
("system_reserved", "SystemReservedContract"),
("dfi_reserved", "DFIReserved"),
("transfer_domain", "TransferDomain"),
("dst20", "DST20"),
];

for (file_path, contract_name) in contracts {
let solc = Solc::new(env::var("SOLC_PATH")?);
let output_path = env::var("CARGO_TARGET_DIR")?;
let root = PathBuf::from(file_path);
if !root.exists() {
return Err("Project root {root:?} does not exists!".into());
for (sol_project_name, contract_name) in contracts {
let solc = Solc::new(&solc_path_str);

let sol_project_root = manifest_path.join(sol_project_name);
if !sol_project_root.exists() {
bail!("Solidity project missing: {sol_project_root:?}");
}

let paths = ProjectPathsConfig::builder()
.root(&root)
.sources(&root)
.root(&sol_project_root)
.sources(&sol_project_root)
.build()?;

let mut solc_config = SolcConfig::builder().build();

solc_config.settings.optimizer = Optimizer {
enabled: Some(true),
runs: Some(u32::MAX as usize),
details: None,
};

let project = Project::builder()
.solc(solc)
.solc_config(solc_config)
.paths(paths)
.set_auto_detect(true)
.no_artifacts()
.build()?;
let output = project.compile().unwrap();

let output = project.compile()?;
let artifacts = output.into_artifacts();
let sol_project_outdir = solc_artifact_dir.join(sol_project_name);

for (id, artifact) in artifacts {
if id.name == contract_name {
let abi = artifact.abi.ok_or_else(|| format_err!("ABI not found"))?;
let deployed_bytecode = artifact
.deployed_bytecode
.expect("No deployed_bytecode found");

let bytecode = artifact.bytecode.expect("No bytecode found");

fs::create_dir_all(format!("{output_path}/ain_contracts/{file_path}"))?;
fs::write(
PathBuf::from(format!(
"{output_path}/ain_contracts/{file_path}/bytecode.json"
)),
serde_json::to_string(&deployed_bytecode)
.unwrap()
.as_bytes(),
)?;
fs::write(
PathBuf::from(format!(
"{output_path}/ain_contracts/{file_path}/input.json"
)),
serde_json::to_string(&bytecode).unwrap().as_bytes(),
)?;
fs::write(
PathBuf::from(format!("{output_path}/ain_contracts/{file_path}/abi.json")),
serde_json::to_string(&abi).unwrap().as_bytes(),
)?;
if id.name != contract_name {
continue;
}

let abi = artifact.abi.context("ABI not found")?;
let bytecode = artifact.bytecode.context("Bytecode not found")?;
let deployed_bytecode = artifact
.deployed_bytecode
.context("Deployed bytecode not found")?;

let items = [
("abi.json", serde_json::to_string(&abi)?),
("bytecode.json", serde_json::to_string(&bytecode)?),
(
"deployed_bytecode.json",
serde_json::to_string(&deployed_bytecode)?,
),
];

fs::create_dir_all(&sol_project_outdir)?;
for (file_name, contents) in items {
fs::write(sol_project_outdir.join(file_name), contents.as_bytes())?
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,4 @@

pragma solidity ^0.8.0;

contract SystemReservedContract {
}
contract DFIReserved {}
File renamed without changes.
60 changes: 40 additions & 20 deletions lib/ain-contracts/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,30 @@ use sp_core::{Blake2Hasher, Hasher};

pub type Result<T> = std::result::Result<T, anyhow::Error>;

macro_rules! solc_artifact_path {
($project_name:literal, $artifact:literal) => {
concat!(
env!("CARGO_TARGET_DIR"),
"/sol_artifacts/",
$project_name,
"/",
$artifact
)
};
}

macro_rules! solc_artifact_content_str {
($project_name:literal, $artifact:literal) => {
include_str!(solc_artifact_path!($project_name, $artifact))
};
}

macro_rules! solc_artifact_bytecode_str {
($project_name:literal, $artifact:literal) => {
get_bytecode(solc_artifact_content_str!($project_name, $artifact)).unwrap()
};
}

fn get_bytecode(input: &str) -> Result<Vec<u8>> {
let bytecode_json: serde_json::Value = serde_json::from_str(input)?;
let bytecode_raw = bytecode_json["object"]
Expand Down Expand Up @@ -46,10 +70,7 @@ pub struct FixedContract {

lazy_static::lazy_static! {
pub static ref INTRINSIC_CONTRACT: FixedContract = {
let bytecode = get_bytecode(include_str!(concat!(
env!("CARGO_TARGET_DIR"),
"/ain_contracts/dfi_intrinsics/bytecode.json"
))).unwrap();
let bytecode = solc_artifact_bytecode_str!("dfi_intrinsics", "deployed_bytecode.json");

FixedContract {
contract: Contract {
Expand All @@ -65,14 +86,14 @@ lazy_static::lazy_static! {
};

pub static ref TRANSFERDOMAIN_CONTRACT: FixedContract = {
let bytecode = get_bytecode(include_str!(concat!(
env!("CARGO_TARGET_DIR"),
"/ain_contracts/transfer_domain/bytecode.json"
))).unwrap();
let input = get_bytecode(include_str!(concat!(
env!("CARGO_TARGET_DIR"),
"/ain_contracts/transfer_domain/input.json"
))).unwrap();
// Note that input, bytecode, and deployed bytecode is used in confusing ways since
// deployedBytecode was exposed as bytecode earlier in build script.
// TODO: Refactor terminology to align with the source of truth.
let bytecode = solc_artifact_bytecode_str!("transfer_domain", "deployed_bytecode.json");
let input = solc_artifact_bytecode_str!(
"transfer_domain",
"bytecode.json"
);

FixedContract {
contract: Contract {
Expand All @@ -88,10 +109,9 @@ lazy_static::lazy_static! {
};

pub static ref DST20_CONTRACT: Contract = {
let bytecode = get_bytecode(include_str!(concat!(
env!("CARGO_TARGET_DIR"),
"/ain_contracts/dst20/bytecode.json"
))).unwrap();
let bytecode = solc_artifact_bytecode_str!(
"dst20", "deployed_bytecode.json"
);
let input = get_bytecode(include_str!(
"../dst20/input.json"
)).unwrap();
Expand All @@ -104,10 +124,10 @@ lazy_static::lazy_static! {
};

pub static ref RESERVED_CONTRACT: Contract = {
let bytecode = get_bytecode(include_str!(concat!(
env!("CARGO_TARGET_DIR"),
"/ain_contracts/system_reserved/bytecode.json"
))).unwrap();
let bytecode = solc_artifact_bytecode_str!(
"dfi_reserved",
"deployed_bytecode.json"
);

Contract {
codehash: Blake2Hasher::hash(&bytecode),
Expand Down
25 changes: 17 additions & 8 deletions lib/ain-evm/src/txqueue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ use rand::Rng;
use crate::{
core::XHash,
receipt::Receipt,
transaction::{system::SystemTx, SignedTx},
transaction::{
system::{SystemTx, TransferDomainData},
SignedTx,
},
};

type Result<T> = std::result::Result<T, QueueError>;
Expand Down Expand Up @@ -269,15 +272,21 @@ impl TransactionQueue {
state_root: H256,
) -> Result<()> {
let mut data = self.data.lock().unwrap();
if let QueueTx::SignedTx(signed_tx) = &tx {
if let Some(nonce) = data.account_nonces.get(&signed_tx.sender) {
if signed_tx.nonce() != nonce + 1 {
return Err(QueueError::InvalidNonce((signed_tx.clone(), *nonce)));
match &tx {
QueueTx::SignedTx(signed_tx)
| QueueTx::SystemTx(SystemTx::TransferDomain(TransferDomainData {
signed_tx, ..
})) => {
if let Some(nonce) = data.account_nonces.get(&signed_tx.sender) {
if signed_tx.nonce() != nonce + 1 {
return Err(QueueError::InvalidNonce((signed_tx.clone(), *nonce)));
}
}
data.account_nonces
.insert(signed_tx.sender, signed_tx.nonce());
data.total_gas_used += gas_used;
}
data.account_nonces
.insert(signed_tx.sender, signed_tx.nonce());
data.total_gas_used += gas_used;
_ => (),
}
data.transactions.push(QueueTxItem {
tx,
Expand Down
Loading

0 comments on commit 227b80c

Please sign in to comment.