From 1b3e8ddf806a06adea74bd096abfa965bde3f177 Mon Sep 17 00:00:00 2001 From: Vadim Date: Wed, 5 Oct 2022 15:51:36 +0300 Subject: [PATCH 1/4] Feature(evm-loader): derive BorshSchema, silence dead code warnings --- .../evm_loader/src/instructions/mod.rs | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/evm-utils/programs/evm_loader/src/instructions/mod.rs b/evm-utils/programs/evm_loader/src/instructions/mod.rs index 4849bd13d4..45214f94fc 100644 --- a/evm-utils/programs/evm_loader/src/instructions/mod.rs +++ b/evm-utils/programs/evm_loader/src/instructions/mod.rs @@ -1,5 +1,6 @@ +#![allow(dead_code)] use super::scope::*; -use borsh::{BorshDeserialize, BorshSerialize}; +use borsh::{BorshDeserialize, BorshSchema, BorshSerialize}; use evm_state::{Address, Transaction, UnsignedTransaction}; use serde::{Deserialize, Serialize}; @@ -10,8 +11,7 @@ pub const EVM_INSTRUCTION_BORSH_PREFIX: u8 = 255u8; #[derive( BorshSerialize, BorshDeserialize, - // TODO: add schema generation custom command - // BorshSchema, + BorshSchema, Clone, Debug, PartialEq, @@ -37,12 +37,10 @@ impl FeePayerType { /// Solana blockchain limit amount of data that transaction can have. /// To get around this limitation, we use design that is similar to LoaderInstruction in sdk. - #[derive( BorshSerialize, BorshDeserialize, - // TODO: add schema generation custom command - // BorshSchema, + BorshSchema, Clone, Debug, PartialEq, @@ -52,8 +50,6 @@ impl FeePayerType { Serialize, Deserialize, )] - -// #[allow(clippy::dead_code)] pub enum EvmBigTransaction { /// Allocate data in storage, pay fee should be taken from EVM. EvmTransactionAllocate { size: u64 }, @@ -65,8 +61,7 @@ pub enum EvmBigTransaction { #[derive( BorshSerialize, BorshDeserialize, - // TODO: add schema generation custom command - // BorshSchema, + BorshSchema, Clone, Debug, PartialEq, @@ -96,8 +91,7 @@ impl ExecuteTransaction { #[derive( BorshSerialize, BorshDeserialize, - // TODO: add schema generation custom command - // BorshSchema, + BorshSchema, Clone, Debug, PartialEq, From 05ba23b95465dfaa82d3b3b93049f671fc32d4df Mon Sep 17 00:00:00 2001 From: Vadim Date: Mon, 17 Oct 2022 12:19:16 +0300 Subject: [PATCH 2/4] Feature(cli): add subcommand for Borsh schema generation --- Cargo.lock | 26 ++++++++++++++++++++++++++ cli/Cargo.toml | 2 ++ cli/src/evm.rs | 50 ++++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 74 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f84ebffdcc..ce104f6fdf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -27,6 +27,30 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "agsol-borsh-schema" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "689a15901649a39efba997c9b75b10496f0d8fc4b57244833dbbf17091a9f55e" +dependencies = [ + "agsol-borsh-schema-derive", + "anyhow", + "heck 0.3.3", + "proc-macro2 1.0.43", + "quote 1.0.21", + "syn 1.0.99", +] + +[[package]] +name = "agsol-borsh-schema-derive" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60811a9517ead003173bfb969dd3fb86fd4454deacc1d84ea59d26a74452c751" +dependencies = [ + "quote 1.0.21", + "syn 1.0.99", +] + [[package]] name = "ahash" version = "0.7.6" @@ -5937,8 +5961,10 @@ dependencies = [ name = "solana-cli" version = "1.9.29" dependencies = [ + "agsol-borsh-schema", "anyhow", "bincode", + "borsh", "bs58", "clap 2.34.0", "console 0.15.1", diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 84929f58d4..db33bef81b 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -10,7 +10,9 @@ homepage = "https://solana.com/" documentation = "https://docs.rs/solana-cli" [dependencies] +agsol-borsh-schema = { version = "0.0.2", features = ["full"] } bincode = "1.3.3" +borsh = "0.9.3" bs58 = "0.4.0" clap = "2.33.1" criterion-stats = "0.3.0" diff --git a/cli/src/evm.rs b/cli/src/evm.rs index f2d9f95209..d36953862a 100644 --- a/cli/src/evm.rs +++ b/cli/src/evm.rs @@ -68,6 +68,29 @@ impl EvmSubCommands for App<'_, '_> { .long("lamports") .help("Amount in lamports"))) + .subcommand( + SubCommand::with_name("generate-borsh-schema") + .about("Generate Borsh schema for EVM instructions") + .display_order(3) + .arg( + Arg::with_name("input_path") + .short("i") + .long("input") + .value_name("DIR") + .takes_value(true) + .required(true) + .help("Parse Rust files from DIR for a borsh schema"), + ) + .arg( + Arg::with_name("output_path") + .short("o") + .long("output") + .value_name("DIR") + .takes_value(true) + .default_value("schema") + .help("Use DIR as generated schema location"), + )) + // Hidden commands @@ -152,6 +175,11 @@ pub enum EvmCliCommand { amount: u64, }, + GenerateBorshSchema { + input_path: PathBuf, + output_path: PathBuf, + }, + // Hidden commands SendRawTx { raw_tx: PathBuf, @@ -192,6 +220,9 @@ impl EvmCliCommand { Self::TransferToEvm { address, amount } => { transfer(rpc_client, config, *address, *amount)?; } + Self::GenerateBorshSchema { input_path, output_path } => { + generate_borsh_schema(input_path, output_path)?; + } // Hidden commands Self::SendRawTx { raw_tx } => { send_raw_tx(rpc_client, config, raw_tx)?; @@ -262,8 +293,8 @@ fn transfer( let message = Message::new(&ixs, Some(&from.pubkey())); let mut create_account_tx = Transaction::new_unsigned(message); - let (blockhash, _last_height) = rpc_client - .get_latest_blockhash_with_commitment(CommitmentConfig::default())?; + let (blockhash, _last_height) = + rpc_client.get_latest_blockhash_with_commitment(CommitmentConfig::default())?; create_account_tx.sign(&config.signers, blockhash); @@ -276,6 +307,12 @@ fn transfer( Ok(()) } +fn generate_borsh_schema>(input_path: P, output_path: P) -> anyhow::Result<()> { + fs::create_dir_all(&output_path)?; + let layouts = agsol_borsh_schema::generate_layouts(input_path)?; + agsol_borsh_schema::generate_output(&layouts, output_path) +} + fn find_block_header( rpc_client: &RpcClient, expected_block_hash: evm::H256, @@ -332,8 +369,8 @@ fn send_raw_tx>( let msg = Message::new(&[ix], Some(&signer.pubkey())); let mut tx = Transaction::new_unsigned(msg); - let (blockhash, _last_height) = rpc_client - .get_latest_blockhash_with_commitment(CommitmentConfig::default())?; + let (blockhash, _last_height) = + rpc_client.get_latest_blockhash_with_commitment(CommitmentConfig::default())?; tx.sign(&config.signers, blockhash); debug!("sending tx: {:?}", tx); @@ -431,6 +468,11 @@ pub fn parse_evm_subcommand(matches: &ArgMatches<'_>) -> Result { + let input_path = value_t_or_exit!(matches, "input_path", PathBuf); + let output_path = value_t_or_exit!(matches, "output_path", PathBuf); + EvmCliCommand::GenerateBorshSchema { input_path, output_path } + } ("send-raw-tx", Some(matches)) => { let raw_tx = value_t_or_exit!(matches, "raw_tx", PathBuf); EvmCliCommand::SendRawTx { raw_tx } From dc946a5d192f8d340c616499b517abfc9cd0b60a Mon Sep 17 00:00:00 2001 From: Vadim Date: Mon, 17 Oct 2022 13:32:05 +0300 Subject: [PATCH 3/4] Fix(cli): fix tests --- Cargo.lock | 1 - cli/Cargo.toml | 1 - cli/src/evm.rs | 21 ++++++++++----------- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ce104f6fdf..744dec80a8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5964,7 +5964,6 @@ dependencies = [ "agsol-borsh-schema", "anyhow", "bincode", - "borsh", "bs58", "clap 2.34.0", "console 0.15.1", diff --git a/cli/Cargo.toml b/cli/Cargo.toml index db33bef81b..ea50da70ae 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -12,7 +12,6 @@ documentation = "https://docs.rs/solana-cli" [dependencies] agsol-borsh-schema = { version = "0.0.2", features = ["full"] } bincode = "1.3.3" -borsh = "0.9.3" bs58 = "0.4.0" clap = "2.33.1" criterion-stats = "0.3.0" diff --git a/cli/src/evm.rs b/cli/src/evm.rs index d36953862a..d8e0b29011 100644 --- a/cli/src/evm.rs +++ b/cli/src/evm.rs @@ -82,9 +82,8 @@ impl EvmSubCommands for App<'_, '_> { .help("Parse Rust files from DIR for a borsh schema"), ) .arg( - Arg::with_name("output_path") - .short("o") - .long("output") + Arg::with_name("schema_path") + .long("schema-dir") .value_name("DIR") .takes_value(true) .default_value("schema") @@ -177,7 +176,7 @@ pub enum EvmCliCommand { GenerateBorshSchema { input_path: PathBuf, - output_path: PathBuf, + schema_path: PathBuf, }, // Hidden commands @@ -220,8 +219,8 @@ impl EvmCliCommand { Self::TransferToEvm { address, amount } => { transfer(rpc_client, config, *address, *amount)?; } - Self::GenerateBorshSchema { input_path, output_path } => { - generate_borsh_schema(input_path, output_path)?; + Self::GenerateBorshSchema { input_path, schema_path } => { + generate_borsh_schema(input_path, schema_path)?; } // Hidden commands Self::SendRawTx { raw_tx } => { @@ -307,10 +306,10 @@ fn transfer( Ok(()) } -fn generate_borsh_schema>(input_path: P, output_path: P) -> anyhow::Result<()> { - fs::create_dir_all(&output_path)?; +fn generate_borsh_schema>(input_path: P, schema_path: P) -> anyhow::Result<()> { + fs::create_dir_all(&schema_path)?; let layouts = agsol_borsh_schema::generate_layouts(input_path)?; - agsol_borsh_schema::generate_output(&layouts, output_path) + agsol_borsh_schema::generate_output(&layouts, schema_path) } fn find_block_header( @@ -470,8 +469,8 @@ pub fn parse_evm_subcommand(matches: &ArgMatches<'_>) -> Result { let input_path = value_t_or_exit!(matches, "input_path", PathBuf); - let output_path = value_t_or_exit!(matches, "output_path", PathBuf); - EvmCliCommand::GenerateBorshSchema { input_path, output_path } + let schema_path = value_t_or_exit!(matches, "schema_path", PathBuf); + EvmCliCommand::GenerateBorshSchema { input_path, schema_path } } ("send-raw-tx", Some(matches)) => { let raw_tx = value_t_or_exit!(matches, "raw_tx", PathBuf); From a43338d0f62862346962e66e1a1c7162200e9983 Mon Sep 17 00:00:00 2001 From: Vadim Date: Tue, 24 Jan 2023 14:56:05 +0200 Subject: [PATCH 4/4] fix types for schema generation --- .../evm_loader/src/instructions/mod.rs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/evm-utils/programs/evm_loader/src/instructions/mod.rs b/evm-utils/programs/evm_loader/src/instructions/mod.rs index 45214f94fc..40ee194ccc 100644 --- a/evm-utils/programs/evm_loader/src/instructions/mod.rs +++ b/evm-utils/programs/evm_loader/src/instructions/mod.rs @@ -77,7 +77,7 @@ pub enum ExecuteTransaction { }, ProgramAuthorized { tx: Option, - from: evm::Address, + from: Address, }, } @@ -116,7 +116,7 @@ pub enum EvmInstruction { /// SwapNativeToEther { lamports: u64, - evm_address: evm::Address, + evm_address: Address, }, /// Transfer user account ownership back to system program. @@ -279,9 +279,9 @@ mod test { #[derive(Clone, Debug)] struct Generator(T); - impl Arbitrary for Generator { + impl Arbitrary for Generator
{ fn arbitrary(g: &mut Gen) -> Self { - Generator(evm::Address::from_low_u64_ne(u64::arbitrary(g))) + Generator(Address::from_low_u64_ne(u64::arbitrary(g))) } } @@ -290,7 +290,7 @@ mod test { let action = if bool::arbitrary(g) { evm::TransactionAction::Create } else { - evm::TransactionAction::Call(evm::Address::from_low_u64_ne(u64::arbitrary(g))) + evm::TransactionAction::Call(Address::from_low_u64_ne(u64::arbitrary(g))) }; let tx = evm::UnsignedTransaction { nonce: evm::U256::from(u64::arbitrary(g)), @@ -309,7 +309,7 @@ mod test { let action = if bool::arbitrary(g) { evm::TransactionAction::Create } else { - evm::TransactionAction::Call(evm::Address::from_low_u64_ne(u64::arbitrary(g))) + evm::TransactionAction::Call(Address::from_low_u64_ne(u64::arbitrary(g))) }; let tx = evm::Transaction { nonce: evm::U256::from(u64::arbitrary(g)), @@ -329,8 +329,8 @@ mod test { } #[quickcheck] - fn test_serialize_swap_native_to_ether_layout(lamports: u64, addr: Generator) { - fn custom_serialize(lamports: u64, addr: evm::Address) -> Vec { + fn test_serialize_swap_native_to_ether_layout(lamports: u64, addr: Generator
) { + fn custom_serialize(lamports: u64, addr: Address) -> Vec { use byteorder::{LittleEndian, WriteBytesExt}; let tag: [u8; 4] = [1, 0, 0, 0]; @@ -391,14 +391,14 @@ mod test { #[quickcheck] fn test_serialize_unsigned_transaction( - addr: Generator, + addr: Generator
, tx: Generator, ) { let data = EvmInstruction::new_execute_authorized_tx(tx.0.clone(), addr.0, FeePayerType::Evm); fn custom_serialize( - from: evm::Address, + from: Address, nonce: evm::U256, gas_price: evm::U256, gas_limit: evm::U256,