Skip to content

Commit

Permalink
ci: add weekly cargo update workflow (foundry-rs#5497) (#6)
Browse files Browse the repository at this point in the history
Co-authored-by: Enrique Ortiz <[email protected]>
Co-authored-by: AA <aa@aa>
Co-authored-by: evalir <[email protected]>
Co-authored-by: Rahul Ravindran <[email protected]>
Co-authored-by: Matt Solomon <[email protected]>
Co-authored-by: DaniPopes <[email protected]>
Co-authored-by: Arsenii Kulikov <[email protected]>
Co-authored-by: Andrew Athan <[email protected]>
Co-authored-by: Rahul Ravindran <[email protected]>
Co-authored-by: grandizzy <[email protected]>
Co-authored-by: Roman Krasiuk <[email protected]>
  • Loading branch information
11 people authored Aug 3, 2023
1 parent e94f78d commit faead4e
Show file tree
Hide file tree
Showing 25 changed files with 253 additions and 63 deletions.
61 changes: 61 additions & 0 deletions .github/workflows/dependencies.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Automatically run `cargo update` periodically

name: Update Dependencies

on:
schedule:
# Run weekly
- cron: "0 0 * * SUN"
workflow_dispatch:
# Needed so we can run it manually

env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BRANCH: cargo-update
TITLE: "chore(deps): weekly `cargo update`"
BODY: |
Automation to keep dependencies in `Cargo.lock` current.
<details><summary><strong>cargo update log</strong></summary>
<p>
```log
$cargo_update_log
```
</p>
</details>
jobs:
update:
name: Update
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@nightly

- name: cargo update
# Remove first line that always just says "Updating crates.io index"
run: cargo update --color never 2>&1 | sed '/crates.io index/d' | tee -a cargo_update.log

- name: craft commit message and PR body
id: msg
run: |
export cargo_update_log="$(cat cargo_update.log)"
echo "commit_message<<EOF" >> $GITHUB_OUTPUT
printf "$TITLE\n\n$cargo_update_log\n" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
echo "body<<EOF" >> $GITHUB_OUTPUT
echo "$BODY" | envsubst >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Create Pull Request
uses: peter-evans/create-pull-request@v5
with:
add-paths: ./Cargo.lock
commit-message: ${{ steps.msg.outputs.commit_message }}
title: ${{ env.TITLE }}
body: ${{ steps.msg.outputs.body }}
branch: ${{ env.BRANCH }}
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,4 @@ To use the latest pinned nightly on your CI, modify your Foundry installation st
- [precompiles will not be compatible with all cheatcodes](https://github.com/foundry-rs/foundry/pull/4905).
- The difficulty and prevrandao cheatcodes now [fail if not used with the correct EVM version](https://github.com/foundry-rs/foundry/pull/4904).
- The default EVM version will be Shanghai. If you're using an EVM chain which is not compatible with [EIP-3855](https://eips.ethereum.org/EIPS/eip-3855) you need to change your EVM version. See [Matt Solomon's thread](https://twitter.com/msolomon44/status/1656411871635972096) for more information.
- Non-existent JSON keys are now processed correctly, and `parseJson` returns non-decodable empty bytes if they do not exist. https://github.com/foundry-rs/foundry/pull/5511
7 changes: 4 additions & 3 deletions anvil/src/eth/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2053,7 +2053,7 @@ impl EthApi {

// Exceptional case: init used too much gas, we need to increase the gas limit and try
// again
if let Err(BlockchainError::InvalidTransaction(InvalidTransactionError::GasTooHigh)) =
if let Err(BlockchainError::InvalidTransaction(InvalidTransactionError::GasTooHigh(_))) =
ethres
{
// if price or limit was included in the request then we can execute the request
Expand Down Expand Up @@ -2125,8 +2125,9 @@ impl EthApi {

// Exceptional case: init used too much gas, we need to increase the gas limit and try
// again
if let Err(BlockchainError::InvalidTransaction(InvalidTransactionError::GasTooHigh)) =
ethres
if let Err(BlockchainError::InvalidTransaction(InvalidTransactionError::GasTooHigh(
_,
))) = ethres
{
// increase the lowest gas limit
lowest_gas_limit = mid_gas_limit;
Expand Down
8 changes: 4 additions & 4 deletions anvil/src/eth/backend/mem/inspector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub struct Inspector {
pub gas: Option<Rc<RefCell<GasInspector>>>,
pub tracer: Option<Tracer>,
/// collects all `console.sol` logs
pub logs: LogCollector,
pub log_collector: LogCollector,
}

// === impl Inspector ===
Expand All @@ -33,7 +33,7 @@ impl Inspector {
///
/// This will log all `console.sol` logs
pub fn print_logs(&self) {
print_logs(&self.logs.logs)
print_logs(&self.log_collector.logs)
}

/// Configures the `Tracer` [`revm::Inspector`]
Expand Down Expand Up @@ -99,7 +99,7 @@ impl<DB: Database> revm::Inspector<DB> for Inspector {
[
&mut self.gas.as_deref().map(|gas| gas.borrow_mut()),
&mut self.tracer,
Some(&mut self.logs)
Some(&mut self.log_collector)
],
{
inspector.log(evm_data, address, topics, data);
Expand Down Expand Up @@ -135,7 +135,7 @@ impl<DB: Database> revm::Inspector<DB> for Inspector {
[
&mut self.gas.as_deref().map(|gas| gas.borrow_mut()),
&mut self.tracer,
Some(&mut self.logs)
Some(&mut self.log_collector)
],
{
inspector.call(data, call, is_static);
Expand Down
7 changes: 4 additions & 3 deletions anvil/src/eth/backend/mem/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::{
time::{utc_from_secs, TimeManager},
validate::TransactionValidator,
},
error::{BlockchainError, InvalidTransactionError},
error::{BlockchainError, ErrDetail, InvalidTransactionError},
fees::{FeeDetails, FeeManager},
macros::node_info,
pool::transactions::PoolTransaction,
Expand Down Expand Up @@ -1192,7 +1192,6 @@ impl Backend {
}

if let Some(fork) = self.get_fork() {
let filter = filter;
return Ok(fork.logs(&filter).await?)
}

Expand Down Expand Up @@ -2180,7 +2179,9 @@ impl TransactionValidator for Backend {
// Check gas limit, iff block gas limit is set.
if !env.cfg.disable_block_gas_limit && tx.gas_limit() > env.block.gas_limit.into() {
warn!(target: "backend", "[{:?}] gas too high", tx.hash());
return Err(InvalidTransactionError::GasTooHigh)
return Err(InvalidTransactionError::GasTooHigh(ErrDetail {
detail: String::from("tx.gas_limit > env.block.gas_limit"),
}))
}

// check nonce
Expand Down
31 changes: 26 additions & 5 deletions anvil/src/eth/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ pub enum FeeHistoryError {
InvalidBlockRange,
}

#[derive(Debug)]
pub struct ErrDetail {
pub detail: String,
}

/// An error due to invalid transaction
#[derive(thiserror::Error, Debug)]
pub enum InvalidTransactionError {
Expand Down Expand Up @@ -150,8 +155,8 @@ pub enum InvalidTransactionError {
#[error("intrinsic gas too low")]
GasTooLow,
/// returned if the transaction gas exceeds the limit
#[error("intrinsic gas too high")]
GasTooHigh,
#[error("intrinsic gas too high -- {}",.0.detail)]
GasTooHigh(ErrDetail),
/// Thrown to ensure no one is able to specify a transaction with a tip higher than the total
/// fee cap.
#[error("max priority fee per gas higher than max fee per gas")]
Expand Down Expand Up @@ -185,8 +190,16 @@ impl From<revm::primitives::InvalidTransaction> for InvalidTransactionError {
InvalidTransactionError::TipAboveFeeCap
}
InvalidTransaction::GasPriceLessThanBasefee => InvalidTransactionError::FeeCapTooLow,
InvalidTransaction::CallerGasLimitMoreThanBlock => InvalidTransactionError::GasTooHigh,
InvalidTransaction::CallGasCostMoreThanGasLimit => InvalidTransactionError::GasTooHigh,
InvalidTransaction::CallerGasLimitMoreThanBlock => {
InvalidTransactionError::GasTooHigh(ErrDetail {
detail: String::from("CallerGasLimitMoreThanBlock"),
})
}
InvalidTransaction::CallGasCostMoreThanGasLimit => {
InvalidTransactionError::GasTooHigh(ErrDetail {
detail: String::from("CallGasCostMoreThanGasLimit"),
})
}
InvalidTransaction::RejectCallerWithCode => InvalidTransactionError::SenderNoEOA,
InvalidTransaction::LackOfFundForGasLimit { .. } => {
InvalidTransactionError::InsufficientFunds
Expand Down Expand Up @@ -272,7 +285,15 @@ impl<T: Serialize> ToRpcResponseResult for Result<T> {
data: serde_json::to_value(data).ok(),
}
}
InvalidTransactionError::GasTooLow | InvalidTransactionError::GasTooHigh => {
InvalidTransactionError::GasTooLow => {
// <https://eips.ethereum.org/EIPS/eip-1898>
RpcError {
code: ErrorCode::ServerError(-32000),
message: err.to_string().into(),
data: None,
}
}
InvalidTransactionError::GasTooHigh(_) => {
// <https://eips.ethereum.org/EIPS/eip-1898>
RpcError {
code: ErrorCode::ServerError(-32000),
Expand Down
13 changes: 13 additions & 0 deletions cli/assets/generated/TestTemplate.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

import {Test, console2} from "forge-std/Test.sol";
import {{contract_name}} from "../src/{contract_name}.sol";

contract {contract_name}Test is Test {
{contract_name} public {instance_name};

function setUp() public {
{instance_name} = new {contract_name}();
}
}
14 changes: 11 additions & 3 deletions cli/src/cmd/cast/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,17 @@ impl RunArgs {
})?;
} else {
trace!(tx=?tx.hash, "executing previous create transaction");
executor.deploy_with_env(env.clone(), None).wrap_err_with(|| {
format!("Failed to deploy transaction: {:?}", tx.hash())
})?;
if let Err(error) = executor.deploy_with_env(env.clone(), None) {
match error {
// Reverted transactions should be skipped
EvmError::Execution(_) => (),
error => {
return Err(error).wrap_err_with(|| {
format!("Failed to deploy transaction: {:?}", tx.hash())
})
}
}
}
}

update_progress!(pb, index);
Expand Down
71 changes: 71 additions & 0 deletions cli/src/cmd/forge/generate/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
//! generate command
use clap::{Parser, Subcommand};
use foundry_common::fs;
use std::path::Path;
use yansi::Paint;

/// CLI arguments for `forge generate`.
#[derive(Debug, Parser)]
pub struct GenerateArgs {
#[clap(subcommand)]
pub sub: GenerateSubcommands,
}

#[derive(Debug, Subcommand)]
pub enum GenerateSubcommands {
/// Scaffolds test file for given contract.
Test(GenerateTestArgs),
}

#[derive(Debug, Parser)]
pub struct GenerateTestArgs {
/// Contract name for test generation.
#[clap(long, short, value_name = "CONTRACT_NAME")]
pub contract_name: String,
}

impl GenerateTestArgs {
pub fn run(self) -> eyre::Result<()> {
let contract_name = format_identifier(&self.contract_name, true);
let instance_name = format_identifier(&self.contract_name, false);

// Create the test file content.
let test_content = include_str!("../../../../assets/generated/TestTemplate.t.sol");
let test_content = test_content
.replace("{contract_name}", &contract_name)
.replace("{instance_name}", &instance_name);

// Create the test directory if it doesn't exist.
fs::create_dir_all("test")?;

// Define the test file path
let test_file_path = Path::new("test").join(format!("{}.t.sol", contract_name));

// Write the test content to the test file.
fs::write(&test_file_path, test_content)?;

println!("{} test file: {}", Paint::green("Generated"), test_file_path.to_str().unwrap());
Ok(())
}
}

/// Utility function to convert an identifier to pascal or camel case.
fn format_identifier(input: &str, is_pascal_case: bool) -> String {
let mut result = String::new();
let mut capitalize_next = is_pascal_case;

for word in input.split_whitespace() {
if !word.is_empty() {
let (first, rest) = word.split_at(1);
let formatted_word = if capitalize_next {
format!("{}{}", first.to_uppercase(), rest)
} else {
format!("{}{}", first.to_lowercase(), rest)
};
capitalize_next = true;
result.push_str(&formatted_word);
}
}
result
}
4 changes: 2 additions & 2 deletions cli/src/cmd/forge/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ impl Installer<'_> {
let n = if s.is_empty() { Ok(1) } else { s.parse() };
// match user input, 0 indicates skipping and use original tag
match n {
Ok(i) if i == 0 => return Ok(tag.into()),
Ok(0) => return Ok(tag.into()),
Ok(i) if (1..=n_candidates).contains(&i) => {
let c = &candidates[i];
println!("[{i}] {c} selected");
Expand Down Expand Up @@ -470,7 +470,7 @@ impl Installer<'_> {

// match user input, 0 indicates skipping and use original tag
match input.parse::<usize>() {
Ok(i) if i == 0 => Ok(Some(tag.into())),
Ok(0) => Ok(Some(tag.into())),
Ok(i) if (1..=n_candidates).contains(&i) => {
let c = &candidates[i];
println!("[{i}] {c} selected");
Expand Down
1 change: 1 addition & 0 deletions cli/src/cmd/forge/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ pub mod flatten;
pub mod fmt;
pub mod fourbyte;
pub mod geiger;
pub mod generate;
pub mod init;
pub mod inspect;
pub mod install;
Expand Down
8 changes: 4 additions & 4 deletions cli/src/cmd/forge/script/broadcast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ impl ScriptArgs {
&self,
mut result: ScriptResult,
libraries: Libraries,
decoder: &mut CallTraceDecoder,
decoder: &CallTraceDecoder,
mut script_config: ScriptConfig,
verify: VerifyBundle,
) -> Result<()> {
Expand Down Expand Up @@ -360,7 +360,7 @@ impl ScriptArgs {
txs: BroadcastableTransactions,
script_result: &ScriptResult,
script_config: &mut ScriptConfig,
decoder: &mut CallTraceDecoder,
decoder: &CallTraceDecoder,
known_contracts: &ContractsByArtifact,
) -> Result<Vec<ScriptSequence>> {
if !txs.is_empty() {
Expand Down Expand Up @@ -391,8 +391,8 @@ impl ScriptArgs {
async fn fills_transactions_with_gas(
&self,
txs: BroadcastableTransactions,
script_config: &mut ScriptConfig,
decoder: &mut CallTraceDecoder,
script_config: &ScriptConfig,
decoder: &CallTraceDecoder,
known_contracts: &ContractsByArtifact,
) -> Result<VecDeque<TransactionWithMetadata>> {
let gas_filled_txs = if self.skip_simulation {
Expand Down
10 changes: 2 additions & 8 deletions cli/src/cmd/forge/script/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,14 +119,8 @@ impl ScriptArgs {
verify.known_contracts = flatten_contracts(&highlevel_known_contracts, false);
self.check_contract_sizes(&result, &highlevel_known_contracts)?;

self.handle_broadcastable_transactions(
result,
libraries,
&mut decoder,
script_config,
verify,
)
.await
self.handle_broadcastable_transactions(result, libraries, &decoder, script_config, verify)
.await
}

// In case there are libraries to be deployed, it makes sure that these are added to the list of
Expand Down
Loading

0 comments on commit faead4e

Please sign in to comment.