diff --git a/src/mapper/byron.rs b/src/mapper/byron.rs index 168146c1..3843ed73 100644 --- a/src/mapper/byron.rs +++ b/src/mapper/byron.rs @@ -6,6 +6,7 @@ use crate::model::{BlockRecord, Era, EventData, TransactionRecord, TxInputRecord use crate::{model::EventContext, Error}; use pallas::crypto::hash::Hash; +use pallas::ledger::primitives::byron::MainBlock; use pallas::ledger::primitives::{byron, Fragment}; impl EventWriter { @@ -98,6 +99,21 @@ impl EventWriter { Ok(record) } + pub fn collect_byron_tx_records( + &self, + block: &MainBlock, + ) -> Result, Error> { + block + .body + .tx_payload + .iter() + .map(|tx| { + let tx_hash = tx.transaction.to_hash().to_string(); + self.to_byron_transaction_record(tx, &tx_hash) + }) + .collect() + } + fn crawl_byron_transaction( &self, source: &byron::TxPayload, @@ -142,7 +158,7 @@ impl EventWriter { hash: &Hash<32>, cbor: &[u8], ) -> Result { - Ok(BlockRecord { + let mut record = BlockRecord { era: Era::Byron, body_size: cbor.len() as usize, issuer_vkey: source.header.consensus_data.1.to_hex(), @@ -157,7 +173,14 @@ impl EventWriter { true => hex::encode(cbor).into(), false => None, }, - }) + transactions: None, + }; + + if self.config.include_block_details { + record.transactions = Some(self.collect_byron_tx_records(source)?); + } + + Ok(record) } fn crawl_byron_main_block( @@ -210,6 +233,7 @@ impl EventWriter { true => hex::encode(cbor).into(), false => None, }, + transactions: None, }) } diff --git a/src/mapper/collect.rs b/src/mapper/collect.rs index 1ae580ce..7d5d77ad 100644 --- a/src/mapper/collect.rs +++ b/src/mapper/collect.rs @@ -1,13 +1,16 @@ use pallas::ledger::primitives::alonzo::{ - AuxiliaryData, Multiasset, TransactionInput, TransactionOutput, Value, + crypto, AuxiliaryData, Block, Multiasset, TransactionInput, TransactionOutput, Value, }; use crate::{ - model::{MetadataRecord, MintRecord, OutputAssetRecord, TxInputRecord, TxOutputRecord}, + model::{ + MetadataRecord, MintRecord, OutputAssetRecord, TransactionRecord, TxInputRecord, + TxOutputRecord, + }, Error, }; -use super::EventWriter; +use super::{map::ToHex, EventWriter}; impl EventWriter { pub fn collect_input_records(&self, source: &[TransactionInput]) -> Vec { @@ -72,4 +75,26 @@ impl EventWriter { None => Ok(vec![]), } } + + pub fn collect_shelley_tx_records( + &self, + block: &Block, + ) -> Result, Error> { + block + .transaction_bodies + .iter() + .enumerate() + .map(|(idx, tx)| { + let aux_data = block + .auxiliary_data_set + .iter() + .find(|(k, _)| *k == (idx as u32)) + .map(|(_, v)| v); + + let tx_hash = crypto::hash_transaction(tx).to_hex(); + + self.to_transaction_record(tx, &tx_hash, aux_data) + }) + .collect() + } } diff --git a/src/mapper/map.rs b/src/mapper/map.rs index 982be2ec..4a3edd1b 100644 --- a/src/mapper/map.rs +++ b/src/mapper/map.rs @@ -366,7 +366,7 @@ impl EventWriter { .as_ref() .map(|time| time.absolute_slot_to_relative(source.header.header_body.slot)); - Ok(BlockRecord { + let mut record = BlockRecord { era, body_size: source.header.header_body.block_body_size as usize, issuer_vkey: source.header.header_body.issuer_vkey.to_hex(), @@ -381,7 +381,14 @@ impl EventWriter { true => hex::encode(cbor).into(), false => None, }, - }) + transactions: None, + }; + + if self.config.include_block_details { + record.transactions = Some(self.collect_shelley_tx_records(source)?); + } + + Ok(record) } pub(crate) fn append_rollback_event(&self, point: &Point) -> Result<(), Error> { diff --git a/src/mapper/prelude.rs b/src/mapper/prelude.rs index 21f0a44d..9b90b6a7 100644 --- a/src/mapper/prelude.rs +++ b/src/mapper/prelude.rs @@ -25,6 +25,9 @@ pub struct Config { #[serde(default)] pub include_transaction_end_events: bool, + #[serde(default)] + pub include_block_details: bool, + #[serde(default)] pub include_block_cbor: bool, diff --git a/src/model.rs b/src/model.rs index aaf1115c..ec48b740 100644 --- a/src/model.rs +++ b/src/model.rs @@ -22,7 +22,7 @@ pub enum Era { Alonzo, } -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] #[serde(rename_all = "snake_case")] pub enum MetadatumRendition { MapJson(JsonValue), @@ -44,7 +44,7 @@ impl Display for MetadatumRendition { } } -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] pub struct MetadataRecord { pub label: String, @@ -76,7 +76,7 @@ impl From for EventData { } } -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] pub struct TxInputRecord { pub tx_id: String, pub index: u64, @@ -88,7 +88,7 @@ impl From for EventData { } } -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct OutputAssetRecord { pub policy: String, pub asset: String, @@ -101,7 +101,7 @@ impl From for EventData { } } -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct TxOutputRecord { pub address: String, pub amount: u64, @@ -114,7 +114,7 @@ impl From for EventData { } } -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct MintRecord { pub policy: String, pub asset: String, @@ -127,7 +127,7 @@ impl From for EventData { } } -#[derive(Serialize, Deserialize, Debug, Clone, Default)] +#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Eq)] pub struct TransactionRecord { pub hash: String, pub fee: u64, @@ -172,7 +172,7 @@ pub enum StakeCredential { Scripthash(String), } -#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] pub struct BlockRecord { pub era: Era, pub epoch: Option, @@ -185,6 +185,7 @@ pub struct BlockRecord { pub number: u64, pub previous_hash: String, pub cbor_hex: Option, + pub transactions: Option>, } impl From for EventData {