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(l1, l2): show rich wallets on startup #2045

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions cmd/ethrex/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ local-ip-address = "0.6"
tokio-util.workspace = true
redb = { workspace = true, optional = true }
lazy_static.workspace = true
secp256k1.workspace = true

cfg-if = "1.0.0"

Expand Down
62 changes: 61 additions & 1 deletion cmd/ethrex/ethrex.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
use bytes::Bytes;
use directories::ProjectDirs;
use ethrex_blockchain::{add_block, fork_choice::apply_fork_choice};
use ethrex_common::types::{Block, Genesis};
use ethrex_common::{
types::{Block, Genesis},
H160, H256, U256,
};
use ethrex_p2p::{
kademlia::KademliaTable,
network::{node_id_from_signing_key, peer_table},
sync::{SyncManager, SyncMode},
types::{Node, NodeRecord},
};
use ethrex_rlp::decode::RLPDecode;
use ethrex_rpc::clients::eth::get_address_from_secret_key;
use ethrex_storage::{EngineType, Store};
use ethrex_vm::{backends::EVM, EVM_BACKEND};
use k256::ecdsa::SigningKey;
use secp256k1::SecretKey;

use local_ip_address::local_ip;
use rand::rngs::OsRng;
use std::{
collections::HashMap,
fs::{self, File},
future::IntoFuture,
io,
Expand Down Expand Up @@ -292,13 +299,17 @@ async fn main() {
error!("Cannot run with DEV_MODE if the `l2` feature is enabled.");
panic!("Run without the --dev argument.");
}
let l2_pks = include_str!("../../test_data/private_keys.txt");
show_rich_accounts(&genesis, l2_pks);
Comment on lines +302 to +303
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I use this so we can run the print independent where we execute it

let l2_proposer = ethrex_l2::start_proposer(store).into_future();
tracker.spawn(l2_proposer);
} else if #[cfg(feature = "dev")] {
use ethrex_dev;
// Start the block_producer module if devmode was set
if dev_mode {
info!("Runnning in DEV_MODE");
let l1_pks = include_str!("../../test_data/private_keys_l1.txt");
show_rich_accounts(&genesis, l1_pks);
let authrpc_jwtsecret =
std::fs::read(authrpc_jwtsecret).expect("Failed to read JWT secret");
let head_block_hash = {
Expand Down Expand Up @@ -497,3 +508,52 @@ fn read_known_peers(file_path: PathBuf) -> Result<Vec<Node>, serde_json::Error>

serde_json::from_reader(file)
}

fn show_rich_accounts(genesis: &Genesis, contents: &str) {
let private_keys: Vec<String> = contents
.lines()
.filter(|line| !line.trim().is_empty())
.map(|line| line.trim().to_string())
.collect();

let mut address_to_pk = HashMap::new();
for pk in private_keys.iter() {
let pk_str = pk.strip_prefix("0x").unwrap_or(pk);
let Ok(pk_h256) = pk_str.parse::<H256>() else {
return;
};
Comment on lines +522 to +524
Copy link
Contributor Author

Choose a reason for hiding this comment

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

If there is any error, don't print the addresses so we don't stop the ethrex client

let pk_bytes = pk_h256.as_bytes();
let Ok(secret_key) = SecretKey::from_slice(pk_bytes) else {
return;
};
let Ok(address) = get_address_from_secret_key(&secret_key) else {
return;
};
address_to_pk.insert(address, pk);
}

let mut top_accounts: Vec<(&H160, U256)> = genesis
.alloc
.iter()
.map(|(address, account)| (address, account.balance))
.collect();
top_accounts.sort_by(|a, b| b.1.cmp(&a.1)); // sort by greater balance
let number_of_top_accounts = 10;
top_accounts.truncate(number_of_top_accounts);

println!("Showing first {} accounts", number_of_top_accounts);
println!("-------------------------------------------------------------------------------");
for (address, balance) in top_accounts {
let Some(pk) = address_to_pk.get(address) else {
continue;
};
println!("Private Key: {}", pk);
println!("Address: {:?} (Ξ {})", address, wei_to_eth(balance));
println!("-------------------------------------------------------------------------------");
}
}

fn wei_to_eth(wei: U256) -> U256 {
wei.checked_div(U256::from_dec_str("1000000000000000000").unwrap())
.unwrap_or(U256::zero())
}
5 changes: 4 additions & 1 deletion cmd/ethrex_l2/src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{
commands::{autocomplete, config, info, prove, stack, test, wallet},
commands::{autocomplete, config, info, prove, stack, test, utils, wallet},
config::load_selected_config,
};
use clap::{Parser, Subcommand};
Expand Down Expand Up @@ -33,6 +33,8 @@ enum EthrexL2Command {
Info(info::Command),
#[clap(about = "Read a test chain from disk and prove a block.")]
Prove(prove::Command),
#[clap(subcommand, about = "Utils commands.")]
Utils(utils::Command),
}

pub async fn start() -> eyre::Result<()> {
Expand All @@ -53,6 +55,7 @@ pub async fn start() -> eyre::Result<()> {
EthrexL2Command::Test(cmd) => cmd.run(cfg).await?,
EthrexL2Command::Info(cmd) => cmd.run(cfg).await?,
EthrexL2Command::Prove(_) => unreachable!(),
EthrexL2Command::Utils(cmd) => cmd.run()?,
};
Ok(())
}
1 change: 1 addition & 0 deletions cmd/ethrex_l2/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ pub(crate) mod info;
pub(crate) mod prove;
pub(crate) mod stack;
pub(crate) mod test;
pub(crate) mod utils;
pub(crate) mod wallet;
28 changes: 28 additions & 0 deletions cmd/ethrex_l2/src/commands/utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use clap::Subcommand;
use keccak_hash::H256;
use secp256k1::SecretKey;

#[derive(Subcommand)]
pub(crate) enum Command {
#[clap(about = "Convert private key to address.")]
PrivateKeyToAddress {
#[arg(long = "pk", help = "Private key in hex format.", required = true)]
private_key: String,
},
}

impl Command {
pub fn run(self) -> eyre::Result<()> {
match self {
Command::PrivateKeyToAddress { private_key } => {
let pk_str = private_key.strip_prefix("0x").unwrap_or(&private_key);
let pk_h256 = pk_str.parse::<H256>()?;
let pk_bytes = pk_h256.as_bytes();
let secret_key = SecretKey::from_slice(pk_bytes)?;
let address = ethrex_l2_sdk::get_address_from_secret_key(&secret_key)?;
println!("Address: {:#x}", address);
}
}
Ok(())
}
}
1 change: 0 additions & 1 deletion cmd/ethrex_l2/src/commands/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use crate::config::EthrexL2Config;
use bytes::Bytes;
use clap::Subcommand;
use ethereum_types::{Address, H256, U256};
use ethrex_common::types::Transaction;
use ethrex_l2_sdk::calldata::{encode_calldata, Value};
use ethrex_l2_sdk::merkle_tree::merkle_proof;
use ethrex_l2_sdk::{get_withdrawal_hash, COMMON_BRIDGE_L2_ADDRESS, L2_WITHDRAW_SIGNATURE};
Expand Down
21 changes: 21 additions & 0 deletions test_data/private_keys_l1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
0xbcdf20249abf0ed6d944c0288fad489e33f66b3960d9e6229c1cd214ed3bbe31
0x39725efee3fb28614de3bacaffe4cc4bd8c436257e2c8bb887c4b5c4be45e76d
0x53321db7c1e331d93a11a41d16f004d7ff63972ec8ec7c25db329728ceeb1710
0xab63b23eb7941c1251757e24b3d2350d2bc05c3c388d06f8fe6feafefb1e8c70
0x5d2344259f42259f82d2c140aa66102ba89b57b4883ee441a8b312622bd42491
0x27515f805127bebad2fb9b183508bdacb8c763da16f54e0678b16e8f28ef3fff
0x7ff1a4c1d57e5e784d327c4c7651e952350bc271f156afb3d00d20f5ef924856
0x3a91003acaf4c21b3953d94fa4a6db694fa69e5242b2e37be05dd82761058899
0xbb1d0f125b4fb2bb173c318cdead45468474ca71474e2247776b2b4c0fa2d3f5
0x850643a0224065ecce3882673c21f56bcf6eef86274cc21cadff15930b59fc8c
0x94eb3102993b41ec55c241060f47daa0f6372e2e3ad7e91612ae36c364042e44
0xdaf15504c22a352648a71ef2926334fe040ac1d5005019e09f6c979808024dc7
0xeaba42282ad33c8ef2524f07277c03a776d98ae19f581990ce75becb7cfa1c23
0x3fd98b5187bf6526734efaa644ffbb4e3670d66f5d0268ce0323ec09124bff61
0x5288e2f440c7f0cb61a9be8afdeb4295f786383f96f5e35eb0c94ef103996b64
0xf296c7802555da2a5a662be70e078cbd38b44f96f8615ae529da41122ce8db05
0xbf3beef3bd999ba9f2451e06936f0423cd62b815c9233dd3bc90f7e02a1e8673
0x6ecadc396415970e91293726c3f5775225440ea0844ae5616135fd10d66b5954
0xa492823c3e193d6c595f37a18e3c06650cf4c74558cc818b16130b293716106f
0xc5114526e042343c6d1899cad05e1c00ba588314de9b96929914ee0df18d46b2
0x04b9f63ecf84210c5366c66d68fa1f5da1fa4f634fad6dfc86178e4d79ff9e59
Loading