Skip to content

Commit 7e7af59

Browse files
tac0turtleclaude
andauthored
chore: better error handling (#25)
* swarm: add revert_reason to transaction receipts for error observability Propagate ErrorCode information from failed TxResult responses through the receipt pipeline so Ethereum tooling (ethers, viem, Foundry) can surface revert reasons via the revertReason field. Changes: - RpcReceipt: add optional revert_reason field (skip_serializing_if None) - RpcReceipt::success(): set revert_reason: None - RpcReceipt::failure(): accept revert_reason: Option<String> parameter - StoredReceipt: add optional revert_reason field - StoredReceipt::to_rpc_receipt(): pass through revert_reason - SQLite receipts table: add revert_reason TEXT column - insert_receipt(): include revert_reason in INSERT - get_receipt() SELECT: include receipts.revert_reason (column index 12) - row_to_stored_receipt(): read revert_reason at index 12 - build_stored_receipt(): format ErrorCode(id=0x{id:04x}, arg={arg}) on Err - Test helpers updated with revert_reason: None Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * add more tests and clearer startup paths * tests and stability * comments and linting * fixes * fixes++ * ++ * ++ --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 06ed3c7 commit 7e7af59

16 files changed

Lines changed: 2200 additions & 284 deletions

File tree

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
use std::path::PathBuf;
2+
use std::sync::mpsc;
3+
4+
use clap::Parser;
5+
use commonware_runtime::tokio::{Config as TokioConfig, Runner};
6+
use commonware_runtime::Runner as RunnerTrait;
7+
use evolve_node::HasTokenAccountId;
8+
use evolve_server::load_chain_state;
9+
use evolve_storage::{QmdbStorage, StorageConfig};
10+
use evolve_testapp::GenesisAccounts;
11+
use evolve_tx_eth::derive_runtime_contract_address;
12+
13+
#[derive(Debug, Parser)]
14+
#[command(name = "print_token_address")]
15+
#[command(about = "Print the testapp token contract address for an initialized data dir")]
16+
struct Cli {
17+
/// Path to the initialized node data directory
18+
#[arg(long)]
19+
data_dir: PathBuf,
20+
}
21+
22+
fn main() {
23+
let cli = Cli::parse();
24+
let data_dir = cli.data_dir;
25+
let (tx, rx) = mpsc::channel();
26+
27+
let runtime_config = TokioConfig::default()
28+
.with_storage_directory(&data_dir)
29+
.with_worker_threads(2);
30+
31+
Runner::new(runtime_config).start(move |context| async move {
32+
let storage = QmdbStorage::new(
33+
context,
34+
StorageConfig {
35+
path: data_dir,
36+
..Default::default()
37+
},
38+
)
39+
.await
40+
.expect("open qmdb storage");
41+
42+
let state =
43+
load_chain_state::<GenesisAccounts, _>(&storage).expect("load initialized chain state");
44+
let token_address =
45+
derive_runtime_contract_address(state.genesis_result.token_account_id());
46+
47+
tx.send(token_address).expect("send token address");
48+
});
49+
50+
let token_address = rx.recv().expect("receive token address");
51+
println!("{token_address:#x}");
52+
}

bin/testapp/src/genesis_config.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,29 @@ pub struct TokenConfig {
2828
#[derive(Deserialize)]
2929
pub struct AccountConfig {
3030
pub eth_address: String,
31+
#[serde(deserialize_with = "deserialize_u128_balance")]
3132
pub balance: u128,
3233
}
3334

35+
fn deserialize_u128_balance<'de, D>(deserializer: D) -> Result<u128, D::Error>
36+
where
37+
D: serde::Deserializer<'de>,
38+
{
39+
use serde::de::Error;
40+
41+
let value = serde_json::Value::deserialize(deserializer)?;
42+
match value {
43+
serde_json::Value::Number(number) => number
44+
.to_string()
45+
.parse::<u128>()
46+
.map_err(|e| Error::custom(format!("invalid balance number: {e}"))),
47+
serde_json::Value::String(text) => text
48+
.parse::<u128>()
49+
.map_err(|e| Error::custom(format!("invalid balance string: {e}"))),
50+
_ => Err(Error::custom("expected balance as number or string")),
51+
}
52+
}
53+
3454
/// Persisted genesis result (replaces testapp's GenesisAccounts for evd).
3555
#[derive(Debug, Clone, Copy, BorshSerialize, BorshDeserialize)]
3656
pub struct EvdGenesisResult {

0 commit comments

Comments
 (0)