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

Address version seed and extend account data size #196 #198

Merged
merged 7 commits into from
Aug 31, 2021
Merged
Show file tree
Hide file tree
Changes from 5 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
15 changes: 11 additions & 4 deletions evm_loader/cli/src/account_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use solana_sdk::{
use serde::{Deserialize, Serialize};
use std::collections::{HashMap};
use evm_loader::{
account_data::AccountData,
account_data::{AccountData, ACCOUNT_VERSION},
solana_backend::AccountStorage,
solidity_account::SolidityAccount,
solana_backend::SolanaBackend,
Expand Down Expand Up @@ -154,7 +154,7 @@ impl<'a> EmulatorAccountStorage<'a> {
}

pub fn get_account_from_solana(config: &'a Config, address: &H160) -> Option<(Account, Option<Account>)> {
let solana_address = Pubkey::find_program_address(&[&address.to_fixed_bytes()], &config.evm_loader).0;
let (solana_address, _solana_nonce) = make_solana_program_address(address, &config.evm_loader);
eprintln!("Not found account for 0x{} => {}", &hex::encode(&address.as_fixed_bytes()), &solana_address.to_string());

if let Some(acc) = config.rpc_client.get_account_with_commitment(&solana_address, CommitmentConfig::processed()).unwrap().value {
Expand Down Expand Up @@ -201,7 +201,7 @@ impl<'a> EmulatorAccountStorage<'a> {
let mut accounts = self.accounts.borrow_mut();
let mut new_accounts = self.new_accounts.borrow_mut();
if accounts.get(address).is_none() {
let solana_address = Pubkey::find_program_address(&[&address.to_fixed_bytes()], &self.config.evm_loader).0;
let (solana_address, _solana_nonce) = make_solana_program_address(address, &self.config.evm_loader);
if let Some((acc, code_account)) = Self::get_account_from_solana(self.config, address) {
accounts.insert(*address, SolanaAccount::new(acc, solana_address, code_account));
true
Expand Down Expand Up @@ -257,7 +257,7 @@ impl<'a> EmulatorAccountStorage<'a> {

let accounts = self.accounts.borrow();
for (address, acc) in accounts.iter() {
let solana_address = Pubkey::find_program_address(&[&address.to_fixed_bytes()], &self.config.evm_loader).0;
let (solana_address, _solana_nonce) = make_solana_program_address(address, &self.config.evm_loader);

let contract_address = {
let addr = AccountData::unpack(&acc.account.data).unwrap().get_account().unwrap().code_account;
Expand Down Expand Up @@ -298,6 +298,13 @@ impl<'a> EmulatorAccountStorage<'a> {
}
}

pub fn make_solana_program_address(
ether_address: &H160,
program_id: &Pubkey
) -> (Pubkey, u8) {
Pubkey::find_program_address(&[&ACCOUNT_VERSION.to_le_bytes(), ether_address.as_bytes()], program_id)
}

pub fn retry_rpc_operation<T, F>(mut retries: usize, op: F) -> client_error::Result<T>
where
F: Fn() -> client_error::Result<T>,
Expand Down
35 changes: 16 additions & 19 deletions evm_loader/cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
mod account_storage;
use crate::{
account_storage::{
make_solana_program_address,
EmulatorAccountStorage,
AccountJSON,
},
Expand All @@ -12,7 +13,11 @@ use crate::{
use evm_loader::{
instruction::EvmInstruction,
solana_backend::SolanaBackend,
account_data::{AccountData, Account, Contract},
account_data::{
AccountData,
Account,
Contract
},
payment::collateral_pool_base,
};

Expand Down Expand Up @@ -132,7 +137,7 @@ fn command_emulate(config: &Config, contract_id: Option<H160>, caller_id: H160,
EmulatorAccountStorage::new(config, *program_id, caller_id)
},
None => {
let solana_address = Pubkey::find_program_address(&[&caller_id.to_fixed_bytes()], &config.evm_loader).0;
let (solana_address, _nonce) = make_solana_program_address(&caller_id, &config.evm_loader);
let trx_count = get_ether_account_nonce(config, &solana_address)?;
let trx_count= trx_count.0;
let program_id = get_program_ether(&caller_id, trx_count);
Expand Down Expand Up @@ -241,17 +246,10 @@ fn command_emulate(config: &Config, contract_id: Option<H160>, caller_id: H160,

fn command_create_program_address (
config: &Config,
seed: &str,
ether_address: &H160,
) {
let strings = seed.split_whitespace().collect::<Vec<_>>();
let mut seeds = vec![];
let mut seeds_vec = vec![];
for s in strings {
seeds_vec.push(hex::decode(s).unwrap());
}
for i in &seeds_vec {seeds.push(&i[..]);}
let (address,nonce) = Pubkey::find_program_address(&seeds, &config.evm_loader);
println!("{} {}", address, nonce);
let (solana_address, nonce) = make_solana_program_address(ether_address, &config.evm_loader);
println!("{} {}", solana_address, nonce);
}

fn command_create_ether_account (
Expand All @@ -260,7 +258,7 @@ fn command_create_ether_account (
lamports: u64,
space: u64
) -> CommandResult {
let (solana_address, nonce) = Pubkey::find_program_address(&[ether_address.as_bytes()], &config.evm_loader);
let (solana_address, nonce) = make_solana_program_address(ether_address, &config.evm_loader);
let token_address = spl_associated_token_account::get_associated_token_address(&solana_address, &evm_loader::token::token_mint::id());
debug!("Create ethereum account {} <- {} {}", solana_address, hex::encode(ether_address), nonce);

Expand Down Expand Up @@ -586,7 +584,7 @@ fn fill_holder_account(
// };
// let caller_public = PublicKey::from_secret_key(&caller_private);
// let caller_ether: H160 = keccak256_h256(&caller_public.serialize()[1..]).into();
// let (caller_sol, caller_nonce) = Pubkey::find_program_address(&[&caller_ether.to_fixed_bytes()], &config.evm_loader);
// let (caller_sol, caller_nonce) = make_solana_program_address(&caller_ether, &config.evm_loader);
// let caller_token = spl_associated_token_account::get_associated_token_address(&caller_sol, &evm_loader::token::token_mint::id());
// let caller_holder = create_block_token_account(config, &caller_ether, &caller_sol).unwrap();
// debug!("caller_sol = {}", caller_sol);
Expand Down Expand Up @@ -647,8 +645,7 @@ fn get_ethereum_contract_account_credentials(

let (program_id, program_ether, program_nonce) = {
let ether = get_program_ether(caller_ether, trx_count);
let seeds = [ether.as_bytes()];
let (address, nonce) = Pubkey::find_program_address(&seeds[..], &config.evm_loader);
let (address, nonce) = make_solana_program_address(&ether, &config.evm_loader);
(address, ether, nonce)
};
debug!("Create account: {} with {} {}", program_id, program_ether, program_nonce);
Expand Down Expand Up @@ -963,7 +960,7 @@ fn command_get_ether_account_data (
) {
match EmulatorAccountStorage::get_account_from_solana(config, ether_address) {
Some((acc, code_account)) => {
let solana_address = Pubkey::find_program_address(&[&ether_address.to_fixed_bytes()], &config.evm_loader).0;
let (solana_address, _solana_nonce) = make_solana_program_address(ether_address, &config.evm_loader);
let account_data = AccountData::unpack(&acc.data).unwrap();
let account_data = AccountData::get_account(&account_data).unwrap();

Expand Down Expand Up @@ -1354,9 +1351,9 @@ fn main() {
command_emulate(&config, contract, sender, data, value)
}
("create-program-address", Some(arg_matches)) => {
let seed = arg_matches.value_of("seed").unwrap().to_string();
let ether = h160_of(arg_matches, "seed").unwrap();

command_create_program_address(&config, &seed);
command_create_program_address(&config, &ether);

Ok(())
}
Expand Down
5 changes: 5 additions & 0 deletions evm_loader/program/src/account_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ use solana_program::{
pubkey::Pubkey,
};

/// Ethereum account version
pub const ACCOUNT_VERSION: u32 = 1_u32;
Copy link
Contributor

Choose a reason for hiding this comment

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

I suggest renaming to ACCOUNT_SEED_VERSION and change the type to u8. In the feature, we can increase it to u16 without any problems.

/// Ethereum account allocated data size
pub const ACCOUNT_MAX_SIZE: u64 = 256;

/// Ethereum account data
#[derive(Debug,Clone)]
pub struct Account {
Expand Down
6 changes: 3 additions & 3 deletions evm_loader/program/src/account_storage.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! `AccountStorage` for solana program realisation
use crate::{
account_data::AccountData,
account_data::{AccountData, ACCOUNT_VERSION},
solana_backend::{AccountStorage, SolanaBackend},
solidity_account::SolidityAccount,
// utils::keccak256_h256,
Expand Down Expand Up @@ -372,11 +372,11 @@ impl<'a> AccountStorage for ProgramAccountStorage<'a> {
account_infos: &[AccountInfo]
) -> ProgramResult {
let (contract_eth, contract_nonce) = self.seeds(&self.contract()).unwrap(); // do_call already check existence of Ethereum account with such index
let contract_seeds = [contract_eth.as_bytes(), &[contract_nonce]];
let contract_seeds = [&ACCOUNT_VERSION.to_le_bytes(), contract_eth.as_bytes(), &[contract_nonce]];

match self.seeds(&self.origin()) {
Some((sender_eth, sender_nonce)) => {
let sender_seeds = [sender_eth.as_bytes(), &[sender_nonce]];
let sender_seeds = [&ACCOUNT_VERSION.to_le_bytes(), sender_eth.as_bytes(), &[sender_nonce]];
invoke_signed(
instruction,
account_infos,
Expand Down
10 changes: 5 additions & 5 deletions evm_loader/program/src/entrypoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use solana_program::{

use crate::{
// bump_allocator::BumpAllocator,
account_data::{Account, AccountData, Contract},
account_data::{Account, AccountData, Contract, ACCOUNT_VERSION, ACCOUNT_MAX_SIZE},
account_storage::{ProgramAccountStorage, /* Sender */ },
solana_backend::{SolanaBackend, AccountStorage},
solidity_account::SolidityAccount,
Expand Down Expand Up @@ -132,7 +132,8 @@ fn process_instruction<'a>(

debug_print!("Ether: {} {}", &(hex::encode(ether)), &hex::encode([nonce]));

let expected_address = Pubkey::create_program_address(&[ether.as_bytes(), &[nonce]], program_id)?;
let program_seeds = [&ACCOUNT_VERSION.to_le_bytes(), ether.as_bytes(), &[nonce]];
let expected_address = Pubkey::create_program_address(&program_seeds, program_id)?;
if expected_address != *account_info.key {
return Err!(ProgramError::InvalidArgument; "expected_address<{:?}> != *account_info.key<{:?}>", expected_address, *account_info.key);
};
Expand Down Expand Up @@ -165,9 +166,8 @@ fn process_instruction<'a>(

let account_lamports = rent.minimum_balance(account_data.size()) + lamports;

let program_seeds = [ether.as_bytes(), &[nonce]];
invoke_signed(
&create_account(funding_info.key, account_info.key, account_lamports, account_data.size() as u64, program_id),
&create_account(funding_info.key, account_info.key, account_lamports, ACCOUNT_MAX_SIZE, program_id),
accounts, &[&program_seeds[..]]
)?;
debug_print!("create_account done");
Expand Down Expand Up @@ -200,7 +200,7 @@ fn process_instruction<'a>(
let account_lamports = Rent::get()?.minimum_balance(space_as_usize) + lamports;

let (caller_ether, caller_nonce) = caller.get_seeds();
let program_seeds = [caller_ether.as_bytes(), &[caller_nonce]];
let program_seeds = [&ACCOUNT_VERSION.to_le_bytes(), caller_ether.as_bytes(), &[caller_nonce]];
let seed = std::str::from_utf8(&seed).map_err(|e| E!(ProgramError::InvalidArgument; "Utf8Error={:?}", e))?;
debug_print!("{}", account_lamports);
debug_print!("{}", space);
Expand Down
6 changes: 3 additions & 3 deletions evm_loader/program/src/token.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
//! `EVMLoader` token functions
use crate::{
account_data::{AccountData},
account_data::{AccountData, ACCOUNT_VERSION},
solidity_account::SolidityAccount
};
use evm::{U256};

use solana_program::{
instruction::{AccountMeta, Instruction},
account_info::{AccountInfo},
Expand Down Expand Up @@ -158,7 +157,8 @@ pub fn transfer_token(
)?;

let (ether, nonce) = source_solidity_account.get_seeds();
invoke_signed(&instruction, accounts, &[&[ether.as_bytes(), &[nonce]]])?;
let program_seeds = [&ACCOUNT_VERSION.to_le_bytes(), ether.as_bytes(), &[nonce]];
invoke_signed(&instruction, accounts, &[&program_seeds[..]])?;

Ok(())
}
4 changes: 2 additions & 2 deletions evm_loader/solana_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -684,8 +684,8 @@ def getAccountData(client, account, expected_length):
raise Exception("Can't get information about {}".format(account))

data = base64.b64decode(info['data'][0])
if len(data) != expected_length:
print("len(data)({}) != expected_length({})".format(len(data), expected_length))
if len(data) < expected_length:
print("len(data)({}) < expected_length({})".format(len(data), expected_length))
raise Exception("Wrong data length for account data {}".format(account))
return data

Expand Down