Skip to content

Commit

Permalink
NDEV-3096. Add db request: get_accounts_in_transaction for tracer deb…
Browse files Browse the repository at this point in the history
…ug_traceTransaction
  • Loading branch information
ancientmage committed Aug 21, 2024
1 parent d256719 commit 4e2206e
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 18 deletions.
16 changes: 13 additions & 3 deletions evm_loader/lib/src/commands/emulate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::account_data::AccountData;
use crate::commands::get_config::BuildConfigSimulator;
use crate::rpc::Rpc;
use crate::tracing::tracers::Tracer;
use crate::types::{EmulateRequest, TxParams};
use crate::types::{AccountInfoLevel, EmulateRequest, TxParams};
use crate::{
account_storage::{EmulatorAccountStorage, SyncedAccountStorage},
errors::NeonError,
Expand Down Expand Up @@ -158,8 +158,12 @@ pub async fn execute<T: Tracer>(
}
}

if emulate_request.provide_account_info.unwrap_or(false) {
result.0.accounts_data = Some(provide_account_data(&storage, &result.0.solana_accounts));
if let Some(level) = emulate_request.provide_account_info {
result.0.accounts_data = Some(provide_account_data(
&storage,
&result.0.solana_accounts,
&level,
));
}

Ok(result)
Expand Down Expand Up @@ -251,9 +255,15 @@ async fn emulate_trx<T: Tracer>(
fn provide_account_data(
storage: &EmulatorAccountStorage<impl Rpc>,
solana_accounts: &Vec<SolanaAccount>,
level: &AccountInfoLevel,
) -> Vec<AccountData> {
let mut accounts_data = Vec::<AccountData>::new();

for account in solana_accounts {
if !account.is_writable && AccountInfoLevel::Changed == *level {
continue;
}

if let Some(account_data) = storage.accounts_get(&account.pubkey) {
accounts_data.push(account_data.clone());
}
Expand Down
14 changes: 11 additions & 3 deletions evm_loader/lib/src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,13 @@ impl From<&SerializedAccount> for Account {
}
}

#[serde_as]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum AccountInfoLevel {
Changed,
All,
}

#[serde_as]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EmulateRequest {
Expand All @@ -169,7 +176,7 @@ pub struct EmulateRequest {
pub accounts: Vec<Pubkey>,
#[serde_as(as = "Option<HashMap<DisplayFromStr,_>>")]
pub solana_overrides: Option<HashMap<Pubkey, Option<SerializedAccount>>>,
pub provide_account_info: Option<bool>,
pub provide_account_info: Option<AccountInfoLevel>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
Expand Down Expand Up @@ -382,8 +389,9 @@ mod tests {
"rent_epoch": 0,
"data": "0102030405"
}
}
}
},
"provide_account_info": null
}
"#;

let request: super::EmulateRequest = serde_json::from_str(txt).unwrap();
Expand Down
40 changes: 34 additions & 6 deletions evm_loader/lib/src/types/tracer_ch_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ use std::collections::BTreeMap;
use std::time::Instant;
use thiserror::Error;

use crate::account_data::AccountData;

pub const ROOT_BLOCK_DELAY: u8 = 100;

#[derive(Error, Debug)]
Expand Down Expand Up @@ -65,6 +67,7 @@ pub struct RevisionRow {

#[derive(Row, serde::Deserialize, Clone)]
pub struct AccountRow {
pub pubkey: Vec<u8>,
pub owner: Vec<u8>,
pub lamports: u64,
pub executable: bool,
Expand All @@ -78,6 +81,7 @@ impl fmt::Debug for AccountRow {
let mut debug_struct = f.debug_struct("AccountRow");

debug_struct
.field("pubkey", &bs58::encode(&self.pubkey).into_string())
.field("owner", &bs58::encode(&self.owner).into_string())
.field("lamports", &self.lamports)
.field("executable", &self.executable)
Expand All @@ -101,16 +105,20 @@ impl fmt::Debug for AccountRow {
}
}

fn pubkey_from(src: Vec<u8>) -> Result<Pubkey, String> {
Pubkey::try_from(src).map_err(|src| {
format!(
"Incorrect slice length ({}) while converting owner from: {src:?}",
src.len(),
)
})
}

impl TryInto<Account> for AccountRow {
type Error = String;

fn try_into(self) -> Result<Account, Self::Error> {
let owner = Pubkey::try_from(self.owner).map_err(|src| {
format!(
"Incorrect slice length ({}) while converting owner from: {src:?}",
src.len(),
)
})?;
let owner = pubkey_from(self.owner)?;

Ok(Account {
lamports: self.lamports,
Expand All @@ -122,6 +130,26 @@ impl TryInto<Account> for AccountRow {
}
}

impl TryInto<AccountData> for AccountRow {
type Error = String;

fn try_into(self) -> Result<AccountData, Self::Error> {
let owner = pubkey_from(self.owner)?;
let pubkey = pubkey_from(self.pubkey)?;

Ok(AccountData::new_from_account(
pubkey,
&Account {
lamports: self.lamports,
data: self.data,
owner,
rent_epoch: self.rent_epoch,
executable: self.executable,
},
))
}
}

pub enum EthSyncStatus {
Syncing(EthSyncing),
Synced,
Expand Down
39 changes: 36 additions & 3 deletions evm_loader/lib/src/types/tracer_ch_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::{

use super::tracer_ch_common::{ChResult, EthSyncStatus, EthSyncing, RevisionMap, SlotParentRooted};

use crate::account_data::AccountData;
use crate::types::ChDbConfig;
use clickhouse::Client;
use log::{debug, error, info};
Expand Down Expand Up @@ -265,7 +266,7 @@ impl ClickHouseDb {
None
} else {
let query = r"
SELECT owner, lamports, executable, rent_epoch, data, txn_signature
SELECT pubkey, owner, lamports, executable, rent_epoch, data, txn_signature
FROM events.update_account_distributed
WHERE pubkey = ?
AND slot IN ?
Expand Down Expand Up @@ -326,7 +327,7 @@ impl ClickHouseDb {
);

let query = r"
SELECT owner, lamports, executable, rent_epoch, data, txn_signature
SELECT pubkey, owner, lamports, executable, rent_epoch, data, txn_signature
FROM events.update_account_distributed
WHERE pubkey = ?
AND slot = ?
Expand Down Expand Up @@ -363,6 +364,38 @@ impl ClickHouseDb {
Ok(account)
}

pub async fn get_accounts_in_transaction(
&self,
sol_sig: &[u8],
slot: u64,
) -> ChResult<Vec<AccountData>> {
info!("get_accounts_in_transaction {{signature: {sol_sig:?} }}");

let query = r"
SELECT DISTINCT ON (pubkey)
pubkey, owner, lamports, executable, rent_epoch, data, txn_signature
FROM events.update_account_distributed
WHERE txn_signature = ?
AND slot = ?
ORDER BY write_version DESC
";

let rows = self
.client
.query(query)
.bind(sol_sig)
.bind(slot)
.fetch_all::<AccountRow>()
.await?;

rows.into_iter()
.map(|row: AccountRow| {
row.try_into()
.map_err(|err| ChError::Db(clickhouse::error::Error::Custom(err)))
})
.collect()
}

async fn get_older_account_row_at(
&self,
pubkey: &str,
Expand Down Expand Up @@ -478,7 +511,7 @@ impl ClickHouseDb {
// Try to find account changes within the given slot.
let query = r"
SELECT DISTINCT ON (pubkey, txn_signature, write_version)
owner, lamports, executable, rent_epoch, data, txn_signature
pubkey, owner, lamports, executable, rent_epoch, data, txn_signature
FROM events.update_account_distributed
WHERE slot = ? AND pubkey = ?
ORDER BY write_version DESC
Expand Down
6 changes: 3 additions & 3 deletions evm_loader/program/src/account/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pub use crate::{account_storage::FAKE_OPERATOR, config::ACCOUNT_SEED_VERSION};

pub use ether_balance::{BalanceAccount, Header as BalanceHeader};
pub use ether_contract::{AllocateResult, ContractAccount, Header as ContractHeader};
pub use ether_storage::{Header as StorageCellHeader, StorageCell, StorageCellAddress};
pub use ether_storage::{Cell, Header as StorageCellHeader, StorageCell, StorageCellAddress};
pub use holder::{Header as HolderHeader, Holder};
pub use incinerator::Incinerator;
pub use operator::Operator;
Expand All @@ -20,8 +20,8 @@ pub use treasury::{MainTreasury, Treasury};
use self::program::System;

mod ether_balance;
pub mod ether_contract;
pub mod ether_storage;
mod ether_contract;
mod ether_storage;
mod holder;
mod incinerator;
pub mod legacy;
Expand Down

0 comments on commit 4e2206e

Please sign in to comment.