Skip to content

Commit

Permalink
add block ops
Browse files Browse the repository at this point in the history
  • Loading branch information
kariy committed Apr 6, 2024
1 parent 90a5edd commit 8315097
Show file tree
Hide file tree
Showing 8 changed files with 176 additions and 16 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 11 additions & 1 deletion bin/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,14 @@ use rika_ops as ops;
fn main() -> Result<()> {
color_eyre::install()?;
let args = App::parse();
execute(args.command)

match execute(args.command) {
Ok(()) => Ok(()),
Err(e) => {
eprintln!("{e}");
std::process::exit(1);
}
}
}

fn execute(command: Commands) -> Result<()> {
Expand All @@ -20,6 +27,9 @@ fn execute(command: Commands) -> Result<()> {
Commands::TxStatus(args) => ops::transaction::status(args)?,
Commands::Receipt(args) => ops::transaction::receipt(args)?,
Commands::Rpc(args) => ops::rpc::send(args)?,
Commands::Block(args) => ops::block::get(args)?,
Commands::Age(args) => ops::block::age(args)?,
Commands::BlockNumber(args) => ops::block::number(args)?,

_ => {
unimplemented!("This command is not implemented yet")
Expand Down
27 changes: 14 additions & 13 deletions crates/args/src/commands/block.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use clap::ArgAction;
use clap::Parser;
use starknet::core::types::BlockId;

use crate::opts::display::DisplayOptions;
use crate::opts::starknet::StarknetOptions;
use crate::parser::BlockIdParser;

Expand All @@ -13,15 +13,15 @@ pub struct AgeArgs {
#[arg(
help = "The hash of the requested block, or number (height) of the requested block, or a block tag (e.g. latest, pending)."
)]
block_id: BlockId,
pub block_id: BlockId,

#[arg(short = 'r', long)]
#[arg(help_heading = "Display options")]
human_readable: bool,
pub human_readable: bool,

#[command(flatten)]
#[command(next_help_heading = "Starknet options")]
starknet: StarknetOptions,
pub starknet: StarknetOptions,
}

#[derive(Debug, Parser)]
Expand All @@ -33,28 +33,29 @@ pub struct BlockArgs {
#[arg(
help = "The hash of the requested block, or number (height) of the requested block, or a block tag (e.g. latest, pending)."
)]
id: BlockId,
pub id: BlockId,

#[arg(long)]
#[arg(action(ArgAction::SetTrue))]
#[arg(conflicts_with = "compact")]
#[arg(help = "Get the full information (incl. transactions) of the block.")]
full: bool,
pub full: bool,

#[arg(long)]
field: Option<String>,
#[arg(help = "Get the block with the transaction hashes only, not the full transactions.")]
pub compact: bool,

#[arg(short = 'j', long = "json")]
#[arg(help_heading = "Display options")]
to_json: bool,
#[command(flatten)]
#[command(next_help_heading = "Display options")]
pub display: DisplayOptions,

#[command(flatten)]
#[command(next_help_heading = "Starknet options")]
starknet: StarknetOptions,
pub starknet: StarknetOptions,
}

#[derive(Debug, Parser)]
pub struct BlockNumberArgs {
#[command(flatten)]
#[command(next_help_heading = "Starknet options")]
starknet: StarknetOptions,
pub starknet: StarknetOptions,
}
59 changes: 58 additions & 1 deletion crates/args/src/fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use comfy_table::presets::UTF8_FULL;
use comfy_table::Table;
use starknet::core::types::{
DataAvailabilityMode, DeclareTransaction, DeployAccountTransaction, FieldElement,
TransactionExecutionStatus, TransactionStatus,
MaybePendingBlockWithTxHashes, TransactionExecutionStatus, TransactionStatus,
};
use starknet::core::types::{
Event, InvokeTransaction, MaybePendingBlockWithTxs, MaybePendingTransactionReceipt, MsgToL1,
Expand Down Expand Up @@ -406,6 +406,63 @@ impl Pretty for MaybePendingBlockWithTxs {
}
}

impl Pretty for MaybePendingBlockWithTxHashes {
fn prettify(&self) -> String {
let mut table = Table::new();
table
.load_preset(UTF8_FULL)
.apply_modifier(UTF8_SOLID_INNER_BORDERS);

match self {
Self::Block(block) => {
table
.add_row(vec!["BLOCK HASH", &block.block_hash.prettify()])
.add_row(vec!["PARENT HASH", &block.parent_hash.prettify()])
.add_row(vec!["BLOCK NUMBER", &block.block_number.prettify()])
.add_row(vec!["NEW ROOT", &block.new_root.prettify()])
.add_row(vec![
"TIMESTAMP",
&Local
.timestamp_opt(block.timestamp as i64, 0)
.unwrap()
.to_string(),
])
.add_row(vec![
"SEQUENCER ADDRESS",
&block.sequencer_address.prettify(),
])
.add_row(vec![
"STATUS",
serde_json::to_value(block.status)
.unwrap_or_default()
.as_str()
.unwrap_or_default(),
])
.add_row(vec!["TRANSACTIONS", &block.transactions.prettify()]);
}

Self::PendingBlock(block) => {
table
.add_row(vec!["PARENT HASH", &block.parent_hash.prettify()])
.add_row(vec![
"TIMESTAMP",
&Local
.timestamp_opt(block.timestamp as i64, 0)
.unwrap()
.to_string(),
])
.add_row(vec![
"SEQUENCER ADDRESS",
&block.sequencer_address.prettify(),
])
.add_row(vec!["TRANSACTIONS", &block.transactions.prettify()]);
}
}

format!("{table}")
}
}

pub fn pretty_block_without_txs(block: &MaybePendingBlockWithTxs) -> String {
let mut table = Table::new();
table
Expand Down
3 changes: 2 additions & 1 deletion crates/args/src/opts/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use serde_json::Value;
use crate::fmt::Pretty;

#[derive(Debug, thiserror::Error)]
#[error("Field not found: {field}.\nAvailable fields: {}", available_fields.join(", "))]
#[error("Field '{field}' doesn't exist.\nAvailable fields: {}", available_fields.join(", "))]
pub struct FieldNotFoundError {
/// The field that was not found.
field: String,
Expand Down Expand Up @@ -51,6 +51,7 @@ impl DisplayOptions {
"Unable to extract field '{field}'. Value is not an object."
);

// TODO: allow specifying nested fields using dot notation (e.g. "block.number") in the cli
match value.get(field) {
Some(field) => {
println!("{}", colored_json::to_colored_json_auto(field)?);
Expand Down
1 change: 1 addition & 0 deletions crates/ops/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ version.workspace = true
[dependencies]
alloy-primitives = "0.7.0"
bigdecimal = "0.4.3"
chrono.workspace = true
colored_json.workspace = true
eyre.workspace = true
reqwest = { workspace = true, features = [ "rustls-tls" ] }
Expand Down
88 changes: 88 additions & 0 deletions crates/ops/src/block.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
use eyre::Result;
use rika_args::{
commands::block::{AgeArgs, BlockArgs, BlockNumberArgs},
fmt::pretty_block_without_txs,
};
use starknet::{
core::types::{BlockId, MaybePendingBlockWithTxHashes, MaybePendingBlockWithTxs},
providers::{Provider, ProviderError},
};

use crate::utils;

pub fn age(args: AgeArgs) -> Result<()> {
let AgeArgs {
block_id,
starknet,
human_readable,
} = args;

let provider = starknet.provider();
let block = utils::block_on(get_block(provider, block_id))?;

let timestamp = match block {
MaybePendingBlockWithTxs::Block(b) => b.timestamp,
MaybePendingBlockWithTxs::PendingBlock(b) => b.timestamp,
};

if human_readable {
use chrono::{Local, TimeZone};
let formatted = Local.timestamp_opt(timestamp as i64, 0).unwrap();
println!("{formatted}");
} else {
println!("{timestamp}")
}

Ok(())
}

pub fn get(args: BlockArgs) -> Result<()> {
let BlockArgs {
id,
starknet,
full,
compact,
display,
} = args;

let provider = starknet.provider();

if compact {
let block = utils::block_on(get_block_compact(provider, id))?;
display.display(block)?;
return Ok(());
} else {
let block = utils::block_on(get_block(provider, id))?;
if full || display.field.is_some() {
display.display(block)?;
} else {
println!("{}", pretty_block_without_txs(&block));
}
}

Ok(())
}

pub fn number(args: BlockNumberArgs) -> Result<()> {
let provider = args.starknet.provider();
let number = utils::block_on(provider.block_number())?;
println!("{number:#x}");
Ok(())
}

async fn get_block<P>(provider: P, id: BlockId) -> Result<MaybePendingBlockWithTxs, ProviderError>
where
P: Provider,
{
provider.get_block_with_txs(id).await
}

async fn get_block_compact<P>(
provider: P,
id: BlockId,
) -> Result<MaybePendingBlockWithTxHashes, ProviderError>
where
P: Provider,
{
provider.get_block_with_tx_hashes(id).await
}
1 change: 1 addition & 0 deletions crates/ops/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![feature(future_join)]
#![cfg_attr(not(test), warn(unused_crate_dependencies))]

pub mod block;
pub mod balance;
pub mod call;
pub mod rpc;
Expand Down

0 comments on commit 8315097

Please sign in to comment.