Skip to content

Commit

Permalink
enha: rework errors
Browse files Browse the repository at this point in the history
  • Loading branch information
carneiro-cw committed Jan 3, 2025
1 parent edd8bda commit 5db199b
Show file tree
Hide file tree
Showing 19 changed files with 341 additions and 284 deletions.
26 changes: 12 additions & 14 deletions src/eth/executor/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ use crate::eth::primitives::Log;
use crate::eth::primitives::Slot;
use crate::eth::primitives::SlotIndex;
use crate::eth::primitives::StratusError;
use crate::eth::primitives::TransactionError;
use crate::eth::primitives::UnexpectedError;
use crate::eth::storage::Storage;
use crate::eth::storage::StratusStorage;
use crate::ext::not;
Expand Down Expand Up @@ -150,14 +152,16 @@ impl Evm {
Ok(result) => Ok(parse_revm_execution(result, session_input, session_storage_changes)?),

// nonce errors
Err(EVMError::Transaction(InvalidTransaction::NonceTooHigh { tx, state })) => Err(StratusError::TransactionNonce {
Err(EVMError::Transaction(InvalidTransaction::NonceTooHigh { tx, state })) => Err(TransactionError::Nonce {
transaction: tx.into(),
account: state.into(),
}),
Err(EVMError::Transaction(InvalidTransaction::NonceTooLow { tx, state })) => Err(StratusError::TransactionNonce {
}
.into()),
Err(EVMError::Transaction(InvalidTransaction::NonceTooLow { tx, state })) => Err(TransactionError::Nonce {
transaction: tx.into(),
account: state.into(),
}),
}
.into()),

// storage error
Err(EVMError::Database(e)) => {
Expand All @@ -168,7 +172,7 @@ impl Evm {
// unexpected errors
Err(e) => {
tracing::warn!(reason = ?e, "evm transaction error");
Err(StratusError::TransactionEvmFailed(e.to_string()))
Err(TransactionError::EvmFailed(e.to_string()).into())
}
};

Expand Down Expand Up @@ -242,7 +246,7 @@ impl Database for RevmSession {
if let Some(ref to_address) = self.input.to {
if account.bytecode.is_none() && &address == to_address && self.input.is_contract_call() {
if self.config.executor_reject_not_contract {
return Err(StratusError::TransactionAccountNotContract { address: *to_address });
return Err(TransactionError::AccountNotContract { address: *to_address }.into());
} else {
tracing::warn!(%address, "evm to_account is not a contract because does not have bytecode");
}
Expand Down Expand Up @@ -283,10 +287,7 @@ impl Database for RevmSession {
}
None => {
tracing::error!(reason = "reading slot without account loaded", %address, %index);
return Err(StratusError::Unexpected(anyhow!(
"Account '{}' was expected to be loaded by EVM, but it was not",
address
)));
return Err(UnexpectedError::Unexpected(anyhow!("Account '{}' was expected to be loaded by EVM, but it was not", address)).into());
}
};
}
Expand Down Expand Up @@ -387,10 +388,7 @@ fn parse_revm_state(revm_state: RevmState, mut execution_changes: ExecutionChang
} else if account_touched {
let Some(account_changes) = execution_changes.get_mut(&address) else {
tracing::error!(keys = ?execution_changes.keys(), %address, "account touched, but not loaded by evm");
return Err(StratusError::Unexpected(anyhow!(
"Account '{}' was expected to be loaded by EVM, but it was not",
address
)));
return Err(UnexpectedError::Unexpected(anyhow!("Account '{}' was expected to be loaded by EVM, but it was not", address)).into());
};
account_changes.apply_modifications(account, account_modified_slots);
}
Expand Down
16 changes: 10 additions & 6 deletions src/eth/executor/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,13 @@ use crate::eth::primitives::ExternalReceipts;
use crate::eth::primitives::ExternalTransaction;
use crate::eth::primitives::ExternalTransactionExecution;
use crate::eth::primitives::PointInTime;
use crate::eth::primitives::RpcError;
use crate::eth::primitives::StorageError;
use crate::eth::primitives::StratusError;
use crate::eth::primitives::TransactionError;
use crate::eth::primitives::TransactionExecution;
use crate::eth::primitives::TransactionInput;
use crate::eth::primitives::UnexpectedError;
use crate::eth::primitives::UnixTime;
use crate::eth::storage::Storage;
use crate::eth::storage::StratusStorage;
Expand Down Expand Up @@ -160,7 +164,7 @@ impl Evms {

match execution_rx.recv() {
Ok(result) => result,
Err(_) => Err(StratusError::UnexpectedChannelClosed { channel: "evm" }),
Err(_) => Err(UnexpectedError::ChannelClosed { channel: "evm" }.into()),
}
}
}
Expand Down Expand Up @@ -411,7 +415,7 @@ impl Executor {
match parallel_attempt {
Ok(tx_execution) => Ok(tx_execution),
Err(e) =>
if let StratusError::TransactionConflict(_) = e {
if let StratusError::Storage(StorageError::TransactionConflict(_)) = e {
self.execute_local_transaction_attempts(tx.clone(), EvmRoute::Serial, INFINITE_ATTEMPTS)
} else {
Err(e)
Expand All @@ -430,7 +434,7 @@ impl Executor {
fn execute_local_transaction_attempts(&self, tx_input: TransactionInput, evm_route: EvmRoute, max_attempts: usize) -> Result<(), StratusError> {
// validate
if tx_input.signer.is_zero() {
return Err(StratusError::TransactionFromZeroAddress);
return Err(TransactionError::FromZeroAddress.into());
}

// executes transaction until no more conflicts
Expand Down Expand Up @@ -498,14 +502,14 @@ impl Executor {
return Ok(());
}
Err(e) => match e {
StratusError::TransactionConflict(ref conflicts) => {
StratusError::Storage(StorageError::TransactionConflict(ref conflicts)) => {
tracing::warn!(%attempt, ?conflicts, "temporary storage conflict detected when saving execution");
if attempt >= max_attempts {
return Err(e);
}
continue;
}
StratusError::TransactionEvmInputMismatch { ref expected, ref actual } => {
StratusError::Storage(StorageError::EvmInputMismatch { ref expected, ref actual }) => {
tracing::warn!(?expected, ?actual, "evm input and block header mismatch");
if attempt >= max_attempts {
return Err(e);
Expand Down Expand Up @@ -543,7 +547,7 @@ impl Executor {
PointInTime::MinedPast(number) => {
let Some(block) = self.storage.read_block(BlockFilter::Number(number))? else {
let filter = BlockFilter::Number(number);
return Err(StratusError::RpcBlockFilterInvalid { filter });
return Err(RpcError::BlockFilterInvalid { filter }.into());
};
Some(block)
}
Expand Down
11 changes: 7 additions & 4 deletions src/eth/follower/importer/importer_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ use crate::eth::executor::Executor;
use crate::eth::follower::consensus::Consensus;
use crate::eth::follower::importer::Importer;
use crate::eth::miner::Miner;
use crate::eth::primitives::ConsensusError;
use crate::eth::primitives::ImporterError;
use crate::eth::primitives::StateError;
use crate::eth::primitives::StratusError;
use crate::eth::rpc::RpcContext;
use crate::eth::storage::StratusStorage;
Expand Down Expand Up @@ -96,12 +99,12 @@ impl ImporterConfig {
pub async fn init_follower_importer(&self, ctx: Arc<RpcContext>) -> Result<serde_json::Value, StratusError> {
if GlobalState::get_node_mode() != NodeMode::Follower {
tracing::error!("node is currently not a follower");
return Err(StratusError::StratusNotFollower);
return Err(StateError::StratusNotFollower.into());
}

if not(GlobalState::is_importer_shutdown()) {
tracing::error!("importer is already running");
return Err(StratusError::ImporterAlreadyRunning);
return Err(ImporterError::AlreadyRunning.into());
}

GlobalState::set_importer_shutdown(false);
Expand All @@ -114,7 +117,7 @@ impl ImporterConfig {
Err(e) => {
tracing::error!(reason = ?e, "failed to initialize importer");
GlobalState::set_importer_shutdown(true);
return Err(StratusError::ImporterInitError);
return Err(ImporterError::InitError.into());
}
};

Expand All @@ -125,7 +128,7 @@ impl ImporterConfig {
None => {
tracing::error!("failed to update consensus: Consensus is not set.");
GlobalState::set_importer_shutdown(true);
return Err(StratusError::ConsensusNotSet);
return Err(ConsensusError::NotSet.into());
}
}

Expand Down
17 changes: 10 additions & 7 deletions src/eth/miner/miner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use crate::eth::primitives::LocalTransactionExecution;
use crate::eth::primitives::LogMined;
use crate::eth::primitives::PendingBlockHeader;
use crate::eth::primitives::Size;
use crate::eth::primitives::StorageError;
use crate::eth::primitives::StratusError;
use crate::eth::primitives::TransactionExecution;
use crate::eth::primitives::TransactionMined;
Expand Down Expand Up @@ -254,7 +255,7 @@ impl Miner {

/// Same as [`Self::mine_local`], but automatically commits the block instead of returning it.
/// mainly used when is_automine is enabled.
pub fn mine_local_and_commit(&self) -> anyhow::Result<()> {
pub fn mine_local_and_commit(&self) -> anyhow::Result<(), StorageError> {
let _mine_and_commit_lock = self.locks.mine_and_commit.lock();

let block = self.mine_local()?;
Expand All @@ -264,7 +265,7 @@ impl Miner {
/// Mines local transactions.
///
/// External transactions are not allowed to be part of the block.
pub fn mine_local(&self) -> anyhow::Result<Block> {
pub fn mine_local(&self) -> anyhow::Result<Block, StorageError> {
#[cfg(feature = "tracing")]
let _span = info_span!("miner::mine_local", block_number = field::Empty).entered();

Expand All @@ -281,15 +282,17 @@ impl Miner {
if let TransactionExecution::Local(tx) = tx {
local_txs.push(tx);
} else {
return log_and_err!("failed to mine local block because one of the transactions is not a local transaction");
return Err(StorageError::Unexpected {
msg: "failed to mine local block because one of the transactions is not a local transaction".to_owned(),
});
}
}

block_from_local(block.header, local_txs)
Ok(block_from_local(block.header, local_txs))
}

/// Persists a mined block to permanent storage and prepares new block.
pub fn commit(&self, block: Block) -> anyhow::Result<()> {
pub fn commit(&self, block: Block) -> anyhow::Result<(), StorageError> {
let block_number = block.number();

// track
Expand Down Expand Up @@ -354,7 +357,7 @@ fn block_from_external(external_block: ExternalBlock, mined_txs: Vec<Transaction
})
}

pub fn block_from_local(pending_header: PendingBlockHeader, txs: Vec<LocalTransactionExecution>) -> anyhow::Result<Block> {
pub fn block_from_local(pending_header: PendingBlockHeader, txs: Vec<LocalTransactionExecution>) -> Block {
let mut block = Block::new(pending_header.number, *pending_header.timestamp);
block.transactions.reserve(txs.len());
block.header.size = Size::from(txs.len() as u64);
Expand Down Expand Up @@ -415,7 +418,7 @@ pub fn block_from_local(pending_header: PendingBlockHeader, txs: Vec<LocalTransa
}

// TODO: calculate state_root, receipts_root and parent_hash
Ok(block)
block
}

// -----------------------------------------------------------------------------
Expand Down
7 changes: 7 additions & 0 deletions src/eth/primitives/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,14 @@ pub use size::Size;
pub use slot::Slot;
pub use slot_index::SlotIndex;
pub use slot_value::SlotValue;
pub use stratus_error::ConsensusError;
pub use stratus_error::ImporterError;
pub use stratus_error::RpcError;
pub use stratus_error::StateError;
pub use stratus_error::StorageError;
pub use stratus_error::StratusError;
pub use stratus_error::TransactionError;
pub use stratus_error::UnexpectedError;
pub use transaction_execution::ExternalTransactionExecution;
pub use transaction_execution::LocalTransactionExecution;
pub use transaction_execution::TransactionExecution;
Expand Down
Loading

0 comments on commit 5db199b

Please sign in to comment.