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

Return error if name to address retry ends. #78

Merged
merged 5 commits into from
Oct 14, 2024
Merged
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
57 changes: 28 additions & 29 deletions translator/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use alloy_rlp::Encodable;
use antelope::chain::checksum::Checksum256;
use antelope::chain::name::Name;
use antelope::serializer::Packer;
use eyre::eyre;
use reth_primitives::ReceiptWithBloom;
use reth_rpc_types::ExecutionPayloadV1;
use reth_telos_rpc_engine_api::structs::TelosEngineAPIExtraFields;
Expand Down Expand Up @@ -239,7 +240,7 @@ impl ProcessingEVMBlock {
&mut self,
action: Box<dyn BasicTrace + Send>,
native_to_evm_cache: &NameToAddressCache,
) {
) -> eyre::Result<()> {
let action_name = action.action_name();
let action_account = action.action_account();
let action_receiver = action.receiver();
Expand All @@ -255,28 +256,25 @@ impl ProcessingEVMBlock {
} else if action_account == EOSIO_EVM && action_name == RAW {
// Normally signed EVM transaction
let raw: RawAction = decode(&action.data());
let printed_receipt = PrintedReceipt::from_console(action.console());
if printed_receipt.is_none() {
panic!(
"No printed receipt found for raw action in block: {}",
self.block_num
);
}
let transaction_result = TelosEVMTransaction::from_raw_action(
let printed_receipt =
PrintedReceipt::from_console(action.console()).ok_or_else(|| {
eyre::eyre!(
"No printed receipt found for raw action in block: {}",
self.block_num
)
})?;

let transaction = TelosEVMTransaction::from_raw_action(
self.chain_id,
self.transactions.len(),
self.block_hash,
raw,
printed_receipt.unwrap(),
printed_receipt,
)
.await;
.await?;

match transaction_result {
Ok(transaction) => self.add_transaction(transaction),
Err(e) => {
panic!("Error handling action. Error: {}", e);
}
}
self.add_transaction(transaction);
return Ok(());
} else if action_account == EOSIO_EVM && action_name == WITHDRAW {
// Withdrawal from EVM
let withdraw_action: WithdrawAction = decode(&action.data());
Expand All @@ -287,7 +285,7 @@ impl ProcessingEVMBlock {
withdraw_action,
native_to_evm_cache,
)
.await;
.await?;
self.add_transaction(transaction);
} else if action_account == EOSIO_TOKEN
&& action_name == TRANSFER
Expand All @@ -298,7 +296,7 @@ impl ProcessingEVMBlock {
if transfer_action.to.n != EOSIO_EVM
|| SYSTEM_ACCOUNTS.contains(&transfer_action.from.n)
{
return;
return Ok(());
}

let transaction = TelosEVMTransaction::from_transfer(
Expand All @@ -308,7 +306,7 @@ impl ProcessingEVMBlock {
transfer_action,
native_to_evm_cache,
)
.await;
.await?;
self.add_transaction(transaction);
} else if action_account == EOSIO_EVM && action_name == DORESOURCES {
let config_delta_row = self
Expand Down Expand Up @@ -339,14 +337,15 @@ impl ProcessingEVMBlock {
wallet_action,
));
}
Ok(())
}

pub async fn generate_evm_data(
&mut self,
parent_hash: FixedBytes<32>,
block_delta: u32,
native_to_evm_cache: &NameToAddressCache,
) -> (Header, ExecutionPayloadV1) {
) -> eyre::Result<(Header, ExecutionPayloadV1)> {
if self.signed_block.is_none()
|| self.block_traces.is_none()
|| self.contract_rows.is_none()
Expand Down Expand Up @@ -395,13 +394,13 @@ impl ProcessingEVMBlock {

let traces = self.block_traces.clone().unwrap_or_default();

for t in traces {
match t {
TransactionTrace::V0(t) => {
for action in t.action_traces {
self.handle_action(Box::new(action), native_to_evm_cache)
.await;
}
for TransactionTrace::V0(t) in traces {
for action in t.action_traces {
if let Err(e) = self
.handle_action(Box::new(action), native_to_evm_cache)
.await
{
return Err(eyre!("Error handling the action. {}", e));
}
}
}
Expand Down Expand Up @@ -497,7 +496,7 @@ impl ProcessingEVMBlock {
transactions,
};

(header, exec_payload)
Ok((header, exec_payload))
}
}

Expand Down
9 changes: 4 additions & 5 deletions translator/src/tasks/final_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ pub async fn final_processor(

let (header, exec_payload) = block
.generate_evm_data(parent_hash, block_delta, &native_to_evm_cache)
.await;
.await?;

let block_hash = exec_payload.block_hash;

Expand Down Expand Up @@ -151,7 +151,7 @@ pub async fn final_processor(
blocks_sec,
trx_sec
);
//info!("Block map is {} long", block_map.len());

unlogged_blocks = 0;
unlogged_transactions = 0;
last_log = Instant::now();
Expand All @@ -177,7 +177,7 @@ pub async fn final_processor(
DecodedRow::AccountState(removed, acc_state_diff, scope) => {
statediffs_accountstate.push(TelosAccountStateTableRow {
removed,
address: native_to_evm_cache.get_index(scope.n).await.unwrap(),
address: native_to_evm_cache.get_index(scope.n).await?,
key: U256::from_be_slice(&acc_state_diff.key.data),
value: U256::from_be_slice(&acc_state_diff.value.data),
});
Expand All @@ -197,8 +197,7 @@ pub async fn final_processor(
U256::from_be_slice(
native_to_evm_cache
.get(create_action.account.value())
.await
.unwrap()
.await?
.as_slice(),
),
)),
Expand Down
27 changes: 12 additions & 15 deletions translator/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,15 +107,12 @@ impl TelosEVMTransaction {
block_hash: Checksum256,
action: TransferAction,
native_to_evm_cache: &NameToAddressCache,
) -> Self {
) -> eyre::Result<Self> {
let address: Address =
if action.memo.len() == ADDRESS_HEX_SIZE && action.memo.starts_with("0x") {
action.memo.parse().unwrap()
action.memo.parse()?
} else {
native_to_evm_cache
.get(action.from.n)
.await
.expect("Failed to get address")
native_to_evm_cache.get(action.from.n).await?
};

let value = U256::from(action.quantity.amount()) * U256::from(100_000_000_000_000i64);
Expand All @@ -135,7 +132,7 @@ impl TelosEVMTransaction {
let mut raw: Vec<u8> = vec![];
tx_legacy.encode_with_signature_fields(&sig, &mut raw);
let envelope = TxEnvelope::Legacy(signed_legacy);
TelosEVMTransaction {
Ok(TelosEVMTransaction {
envelope,
receipt: PrintedReceipt {
charged_gas: "".to_string(),
Expand All @@ -149,7 +146,7 @@ impl TelosEVMTransaction {
output: "".to_string(),
errors: None,
},
}
})
}

pub async fn from_withdraw_no_cache(
Expand Down Expand Up @@ -196,15 +193,15 @@ impl TelosEVMTransaction {
block_hash: Checksum256,
action: WithdrawAction,
native_to_evm_cache: &NameToAddressCache,
) -> Self {
let address = native_to_evm_cache
.get(action.to.n)
.await
.expect("Failed to get address");
TelosEVMTransaction::from_withdraw_no_cache(
) -> eyre::Result<Self> {
let address = native_to_evm_cache.get(action.to.n).await?;

let telos_evm_transactions = TelosEVMTransaction::from_withdraw_no_cache(
chain_id, trx_index, block_hash, action, address,
)
.await
.await;

Ok(telos_evm_transactions)
}

pub fn hash(&self) -> &B256 {
Expand Down
116 changes: 58 additions & 58 deletions translator/src/types/translator_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,85 +41,85 @@ impl NameToAddressCache {
}
}

pub async fn get(&self, name: u64) -> Option<Address> {
pub async fn get(&self, name: u64) -> eyre::Result<Address> {
let evm_contract = Name::from_u64(EOSIO_EVM);
let address = Name::from_u64(name).as_string();
let cached = self.cache.get(&name);

debug!("getting {address} cache hit = {:?}", cached.is_some());

if cached.is_some() {
return cached;
}

let mut i = 0u8;
while i <= MAX_RETRY {
info!("Fetching address {address} try {i}");
let account_result: eyre::Result<GetTableRowsResponse<AccountRow>> = self
.get_account_address(name, evm_contract, IndexPosition::TERTIARY)
.await;

match account_result {
Ok(account_result) => {
if let Some(account_row) = account_result.rows.first() {
let address = Address::from(account_row.address.data);
self.cache.insert(name, address);
self.index_cache.insert(account_row.index, address);
return Some(address);
} else {
warn!("Got empty rows for {address}, retry attempt {i}");
if let Some(cached) = cached {
Ok(cached)
} else {
let mut i = 0u8;
while i <= MAX_RETRY {
info!("Fetching address {address} try {i}");
let account_result: eyre::Result<GetTableRowsResponse<AccountRow>> = self
.get_account_address(name, evm_contract, IndexPosition::TERTIARY)
.await;

match account_result {
Ok(account_result) => {
if let Some(account_row) = account_result.rows.first() {
let address = Address::from(account_row.address.data);
self.cache.insert(name, address);
self.index_cache.insert(account_row.index, address);
return Ok(address);
} else {
warn!("Got empty rows for {address}, retry attempt {i}");
}
}
Err(e) => {
warn!("Error {e} fetching {address}, retry attempt {i}");
}
}
Err(e) => {
warn!("Error {e} fetching {address}, retry attempt {i}");
}

sleep(BASE_DELAY * 2u32.pow(i as u32)).await;
i += 1;
}

sleep(BASE_DELAY * 2u32.pow(i as u32)).await;
i += 1;
error!("Could not get account after {i} attempts for {address}");
Err(eyre!("Can not get account retries for {address}"))
}

error!("Could not get account after {i} attempts for {address}");
None
}

pub async fn get_index(&self, index: u64) -> Option<Address> {
pub async fn get_index(&self, index: u64) -> eyre::Result<Address> {
let evm_contract = Name::from_u64(EOSIO_EVM);
let cached = self.index_cache.get(&index);
debug!("getting index {index} cache hit = {:?}", cached.is_some());

if cached.is_some() {
return cached;
}

let mut i = 0u8;
while i <= MAX_RETRY {
info!("Fetching index {index} try {i}");
let account_result: eyre::Result<GetTableRowsResponse<AccountRow>> = self
.get_account_address(index, evm_contract, IndexPosition::PRIMARY)
.await;

match account_result {
Ok(account_result) => {
if let Some(account_row) = account_result.rows.first() {
let address = Address::from(account_row.address.data);
self.cache.insert(index, address);
self.index_cache.insert(account_row.index, address);
return Some(address);
} else {
warn!("Got empty rows for index {index}, retry attempt {i}");
if let Some(cached) = cached {
Ok(cached)
} else {
let mut i = 0u8;
while i <= MAX_RETRY {
info!("Fetching index {index} try {i}");
let account_result: eyre::Result<GetTableRowsResponse<AccountRow>> = self
.get_account_address(index, evm_contract, IndexPosition::PRIMARY)
.await;

match account_result {
Ok(account_result) => {
if let Some(account_row) = account_result.rows.first() {
let address = Address::from(account_row.address.data);
self.cache.insert(index, address);
self.index_cache.insert(account_row.index, address);
return Ok(address);
} else {
warn!("Got empty rows for index {index}, retry attempt {i}");
}
}
Err(e) => {
warn!("Error {e} fetching index {index}, retry attempt {i}");
}
}
Err(e) => {
warn!("Error {e} fetching index {index}, retry attempt {i}");
}
}

sleep(BASE_DELAY * 2u32.pow(i as u32)).await;
i += 1;
sleep(BASE_DELAY * 2u32.pow(i as u32)).await;
i += 1;
}
error!("Could not get account after {i} attempts for index {index}");
Err(eyre!("Can not get account retries for index {index}"))
}
error!("Could not get account after {i} attempts for index {index}");
None
}

pub async fn get_account_address(
Expand Down
Loading
Loading