Skip to content
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
4 changes: 3 additions & 1 deletion crates/archive/src/archive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use sqd_data::evm::tables::EvmChunkBuilder;
use sqd_data::hyperliquid_fills::tables::HyperliquidFillsChunkBuilder;
use sqd_data::hyperliquid_replica_cmds::tables::HyperliquidReplicaCmdsChunkBuilder;
use sqd_data::solana::tables::SolanaChunkBuilder;
use sqd_data::tron::tables::TronChunkBuilder;
use sqd_primitives::BlockNumber;
use std::time::Duration;

Expand Down Expand Up @@ -70,7 +71,8 @@ pub async fn run(args: Cli) -> anyhow::Result<()> {
NetworkKind::Solana => proc!(SolanaChunkBuilder::default()),
NetworkKind::HyperliquidFills => proc!(HyperliquidFillsChunkBuilder::default()),
NetworkKind::HyperliquidReplicaCmds => proc!(HyperliquidReplicaCmdsChunkBuilder::default()),
NetworkKind::Evm => proc!(EvmChunkBuilder::default())
NetworkKind::Evm => proc!(EvmChunkBuilder::default()),
NetworkKind::Tron => proc!(TronChunkBuilder::default())
};

let attach_idx_field = args.attach_idx_field;
Expand Down
1 change: 1 addition & 0 deletions crates/archive/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub enum NetworkKind {
HyperliquidFills,
HyperliquidReplicaCmds,
Evm,
Tron
}


Expand Down
1 change: 1 addition & 0 deletions crates/data/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ pub mod evm;
pub mod hyperliquid_fills;
pub mod hyperliquid_replica_cmds;
pub mod solana;
pub mod tron;
mod types;
2 changes: 2 additions & 0 deletions crates/data/src/tron/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod model;
pub mod tables;
142 changes: 142 additions & 0 deletions crates/data/src/tron/model.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
use crate::types::{HexBytes, JsonValue};
use serde::Deserialize;
use sqd_primitives::{BlockNumber, ItemIndex};


#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct BlockHeader {
pub height: BlockNumber,
pub hash: HexBytes,
pub parent_hash: HexBytes,
pub tx_trie_root: HexBytes,
pub version: Option<i32>,
pub timestamp: i64,
pub witness_address: HexBytes,
pub witness_signature: Option<HexBytes>,
}


#[derive(Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TransactionResult {
pub contract_ret: Option<String>, // eg. "SUCCESS", "REVERT", etc.
}


#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Transaction {
pub transaction_index: ItemIndex,
pub hash: HexBytes,
pub ret: Option<Vec<TransactionResult>>,
pub signature: Option<Vec<HexBytes>>,
#[serde(rename = "type")]
pub r#type: String,
pub parameter: JsonValue,
pub permission_id: Option<i32>,
pub ref_block_bytes: Option<HexBytes>,
pub ref_block_hash: Option<HexBytes>,
#[serde(deserialize_with="sqd_data_core::serde::decode_string_option", default)]
pub fee_limit: Option<u64>,
pub expiration: Option<i64>,
#[serde(deserialize_with="sqd_data_core::serde::decode_string_option", default)]
pub timestamp: Option<i64>,
pub raw_data_hex: HexBytes,
#[serde(deserialize_with="sqd_data_core::serde::decode_string_option", default)]
pub fee: Option<u64>,
pub contract_result: Option<HexBytes>,
pub contract_address: Option<HexBytes>,
pub res_message: Option<HexBytes>,
#[serde(deserialize_with="sqd_data_core::serde::decode_string_option", default)]
pub withdraw_amount: Option<u64>,
#[serde(deserialize_with="sqd_data_core::serde::decode_string_option", default)]
pub unfreeze_amount: Option<u64>,
#[serde(deserialize_with="sqd_data_core::serde::decode_string_option", default)]
pub withdraw_expire_amount: Option<u64>,
pub cancel_unfreeze_v2_amount: Option<JsonValue>,
pub result: Option<String>, // Result from receipt, eg. "SUCCESS", "REVERT", etc.
#[serde(deserialize_with="sqd_data_core::serde::decode_string_option", default)]
pub energy_fee: Option<u64>,
#[serde(deserialize_with="sqd_data_core::serde::decode_string_option", default)]
pub energy_usage: Option<u64>,
#[serde(deserialize_with="sqd_data_core::serde::decode_string_option", default)]
pub energy_usage_total: Option<u64>,
#[serde(deserialize_with="sqd_data_core::serde::decode_string_option", default)]
pub net_usage: Option<u64>,
#[serde(deserialize_with="sqd_data_core::serde::decode_string_option", default)]
pub net_fee: Option<u64>,
#[serde(deserialize_with="sqd_data_core::serde::decode_string_option", default)]
pub origin_energy_usage: Option<u64>,
#[serde(deserialize_with="sqd_data_core::serde::decode_string_option", default)]
pub energy_penalty_total: Option<u64>,
}


#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Log {
pub transaction_index: ItemIndex,
pub log_index: ItemIndex,
pub address: HexBytes,
pub data: Option<HexBytes>,
pub topics: Option<Vec<HexBytes>>,
}


#[derive(Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CallValueInfo {
#[serde(deserialize_with="sqd_data_core::serde::decode_string_option", default)]
pub call_value: Option<u64>,
pub token_id: Option<String>,
}


#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct InternalTransaction {
pub transaction_index: ItemIndex,
pub internal_transaction_index: ItemIndex,
pub hash: HexBytes,
pub caller_address: HexBytes,
pub transfer_to_address: Option<HexBytes>,
pub call_value_info: Vec<CallValueInfo>,
pub note: HexBytes,
pub rejected: Option<bool>,
pub extra: Option<HexBytes>,
}


#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Block {
pub header: BlockHeader,
pub transactions: Vec<Transaction>,
pub logs: Vec<Log>,
pub internal_transactions: Vec<InternalTransaction>,
}


impl sqd_primitives::Block for Block {
fn number(&self) -> BlockNumber {
self.header.height
}

fn hash(&self) -> &str {
&self.header.hash
}

fn parent_number(&self) -> BlockNumber {
self.header.height.saturating_sub(1)
}

fn parent_hash(&self) -> &str {
&self.header.parent_hash
}

fn timestamp(&self) -> Option<i64> {
// Tron timestamps are already in milliseconds
Some(self.header.timestamp)
}
}
39 changes: 39 additions & 0 deletions crates/data/src/tron/tables/block.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use crate::tron::model::BlockHeader;
use crate::tron::tables::common::*;
use sqd_array::builder::{Int32Builder, TimestampMillisecondBuilder, UInt64Builder};
use sqd_data_core::table_builder;


table_builder! {
BlockBuilder {
number: UInt64Builder,
hash: HexBytesBuilder,
parent_hash: HexBytesBuilder,
tx_trie_root: HexBytesBuilder,
version: Int32Builder,
timestamp: TimestampMillisecondBuilder,
witness_address: HexBytesBuilder,
witness_signature: HexBytesBuilder,
}

description(d) {
d.downcast.block_number = vec!["number"];
d.sort_key = vec!["number"];
d.options.add_stats("number");
d.options.row_group_size = 5_000;
}
}


impl BlockBuilder {
pub fn push(&mut self, row: &BlockHeader) {
self.number.append(row.height);
self.hash.append(&row.hash);
self.parent_hash.append(&row.parent_hash);
self.tx_trie_root.append(&row.tx_trie_root);
self.version.append_option(row.version);
self.timestamp.append(row.timestamp);
self.witness_address.append(&row.witness_address);
self.witness_signature.append_option(row.witness_signature.as_deref());
}
}
8 changes: 8 additions & 0 deletions crates/data/src/tron/tables/common.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use sqd_array::builder::{StringBuilder};

pub type HexBytesBuilder = StringBuilder;
pub type JsonBuilder = StringBuilder;

pub fn sighash(bytes: &str) -> Option<&str> {
(bytes.len() >= 8).then(|| { &bytes[0..8] })
}
57 changes: 57 additions & 0 deletions crates/data/src/tron/tables/internal_transaction.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use crate::tron::model::{Block, InternalTransaction};
use crate::tron::tables::common::*;
use sqd_array::builder::{BooleanBuilder, UInt32Builder, UInt64Builder};
use sqd_data_core::table_builder;


table_builder! {
InternalTransactionBuilder {
block_number: UInt64Builder,
transaction_index: UInt32Builder,
internal_transaction_index: UInt32Builder,
hash: HexBytesBuilder,
caller_address: HexBytesBuilder,
transfer_to_address: HexBytesBuilder,
call_value_info: JsonBuilder,
note: HexBytesBuilder,
rejected: BooleanBuilder,
extra: JsonBuilder,
}

description(d) {
d.downcast.block_number = vec!["block_number"];
d.downcast.item_index = vec!["transaction_index", "internal_transaction_index"];
d.sort_key = vec![
"transfer_to_address",
"caller_address",
"block_number",
"transaction_index",
"internal_transaction_index",
];
d.options.add_stats("block_number");
d.options.add_stats("transaction_index");
d.options.add_stats("internal_transaction_index");
d.options.add_stats("transfer_to_address");
d.options.add_stats("caller_address");
d.options.row_group_size = 10_000;
}
}


impl InternalTransactionBuilder {
pub fn push(&mut self, block: &Block, row: &InternalTransaction) {
self.block_number.append(block.header.height);
self.transaction_index.append(row.transaction_index);
self.internal_transaction_index.append(row.internal_transaction_index);
self.hash.append(&row.hash);
self.caller_address.append(&row.caller_address);
self.transfer_to_address.append_option(row.transfer_to_address.as_deref());

let call_value_info = serde_json::to_string(&row.call_value_info).unwrap();
self.call_value_info.append(&call_value_info);

self.note.append(&row.note);
self.rejected.append_option(row.rejected);
self.extra.append_option(row.extra.as_deref());
}
}
53 changes: 53 additions & 0 deletions crates/data/src/tron/tables/log.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use crate::tron::model::{Block, Log};
use crate::tron::tables::common::HexBytesBuilder;
use sqd_array::builder::{UInt32Builder, UInt64Builder};
use sqd_data_core::table_builder;


table_builder! {
LogBuilder {
block_number: UInt64Builder,
log_index: UInt32Builder,
transaction_index: UInt32Builder,
address: HexBytesBuilder,
data: HexBytesBuilder,
topic0: HexBytesBuilder,
topic1: HexBytesBuilder,
topic2: HexBytesBuilder,
topic3: HexBytesBuilder,
data_size: UInt64Builder,
}

description(d) {
d.downcast.block_number = vec!["block_number"];
d.downcast.item_index = vec!["transaction_index", "log_index"];
d.sort_key = vec!["topic0", "address", "block_number", "transaction_index", "log_index"];
d.options.add_stats("block_number");
d.options.add_stats("log_index");
d.options.add_stats("transaction_index");
d.options.add_stats("address");
d.options.add_stats("topic0");
d.options.use_dictionary("address");
d.options.use_dictionary("topic0");
d.options.row_group_size = 10_000;
}
}


impl LogBuilder {
pub fn push(&mut self, block: &Block, row: &Log) {
self.block_number.append(block.header.height);
self.log_index.append(row.log_index);
self.transaction_index.append(row.transaction_index);
self.address.append(&row.address);
self.data.append_option(row.data.as_deref());

let topics = row.topics.as_deref().unwrap_or(&[]);
self.topic0.append_option(topics.first().map(|x| x.as_str()));
self.topic1.append_option(topics.get(1).map(|x| x.as_str()));
self.topic2.append_option(topics.get(2).map(|x| x.as_str()));
self.topic3.append_option(topics.get(3).map(|x| x.as_str()));

self.data_size.append(row.data.as_ref().map_or(0, |d| d.len() as u64));
}
}
46 changes: 46 additions & 0 deletions crates/data/src/tron/tables/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
mod common;
mod block;
mod transaction;
mod log;
mod internal_transaction;

pub use block::*;
pub use transaction::*;
pub use log::*;
pub use internal_transaction::*;

use super::model::Block;
use sqd_data_core::chunk_builder;


chunk_builder! {
TronChunkBuilder {
blocks: BlockBuilder,
transactions: TransactionBuilder,
logs: LogBuilder,
internal_transactions: InternalTransactionBuilder,
}
}


impl sqd_data_core::BlockChunkBuilder for TronChunkBuilder {
type Block = Block;

fn push(&mut self, block: &Self::Block) -> anyhow::Result<()> {
self.blocks.push(&block.header);

for row in block.transactions.iter() {
self.transactions.push(block, row);
}

for row in block.logs.iter() {
self.logs.push(block, row);
}

for row in block.internal_transactions.iter() {
self.internal_transactions.push(block, row);
}

Ok(())
}
}
Loading
Loading