diff --git a/src/mapper/babbage.rs b/src/mapper/babbage.rs new file mode 100644 index 00000000..c623416f --- /dev/null +++ b/src/mapper/babbage.rs @@ -0,0 +1,346 @@ +use pallas::codec::utils::KeepRaw; +use pallas::ledger::primitives::ToHash; + +use pallas::ledger::primitives::babbage::{ + AuxiliaryData, MintedBlock, NetworkId, PostAlonzoTransactionOutput, TransactionBody, + TransactionOutput, TransactionWitnessSet, +}; + +use pallas::crypto::hash::Hash; + +use crate::model::{BlockRecord, Era, TransactionRecord}; +use crate::utils::time::TimeProvider; +use crate::{ + model::{EventContext, EventData}, + Error, +}; + +use super::{map::ToHex, EventWriter}; + +impl EventWriter { + pub fn to_babbage_transaction_record( + &self, + body: &TransactionBody, + tx_hash: &str, + aux_data: Option<&KeepRaw>, + witness_set: Option<&KeepRaw>, + ) -> Result { + let mut record = TransactionRecord::default(); + + record.hash.push_str(tx_hash); + + record.fee = body.fee; + record.ttl = body.ttl; + record.validity_interval_start = body.validity_interval_start; + + record.network_id = body.network_id.as_ref().map(|x| match x { + NetworkId::One => 1, + NetworkId::Two => 2, + }); + + let outputs = self.collect_any_output_records(&body.outputs)?; + record.output_count = outputs.len(); + record.total_output = outputs.iter().map(|o| o.amount).sum(); + + let inputs = self.collect_input_records(&body.inputs); + record.input_count = inputs.len(); + + if let Some(mint) = &body.mint { + let mints = self.collect_mint_records(mint); + record.mint_count = mints.len(); + + if self.config.include_transaction_details { + record.mint = mints.into(); + } + } + + // TODO + // TransactionBodyComponent::ScriptDataHash(_) + // TransactionBodyComponent::RequiredSigners(_) + // TransactionBodyComponent::AuxiliaryDataHash(_) + + if self.config.include_transaction_details { + record.outputs = outputs.into(); + record.inputs = inputs.into(); + + record.metadata = match aux_data { + Some(aux_data) => self.collect_metadata_records(aux_data)?.into(), + None => None, + }; + + if let Some(witnesses) = witness_set { + record.vkey_witnesses = self + .collect_vkey_witness_records(&witnesses.vkeywitness)? + .into(); + + record.native_witnesses = self + .collect_native_witness_records(&witnesses.native_script)? + .into(); + + record.plutus_witnesses = self + .collect_plutus_v1_witness_records(&witnesses.plutus_v1_script)? + .into(); + + record.plutus_redeemers = self + .collect_plutus_redeemer_records(&witnesses.redeemer)? + .into(); + + record.plutus_data = self + .collect_plutus_datum_records(&witnesses.plutus_data)? + .into(); + } + } + + Ok(record) + } + + pub fn to_babbage_block_record( + &self, + source: &MintedBlock, + hash: &Hash<32>, + cbor: &[u8], + ) -> Result { + let relative_epoch = self + .utils + .time + .as_ref() + .map(|time| time.absolute_slot_to_relative(source.header.header_body.slot)); + + let mut record = BlockRecord { + era: Era::Babbage, + body_size: source.header.header_body.block_body_size as usize, + issuer_vkey: source.header.header_body.issuer_vkey.to_hex(), + tx_count: source.transaction_bodies.len(), + hash: hex::encode(hash), + number: source.header.header_body.block_number, + slot: source.header.header_body.slot, + epoch: relative_epoch.map(|(epoch, _)| epoch), + epoch_slot: relative_epoch.map(|(_, epoch_slot)| epoch_slot), + previous_hash: hex::encode(source.header.header_body.prev_hash), + cbor_hex: match self.config.include_block_cbor { + true => hex::encode(cbor).into(), + false => None, + }, + transactions: None, + }; + + if self.config.include_block_details { + record.transactions = Some(self.collect_babbage_tx_records(source)?); + } + + Ok(record) + } + + pub fn collect_babbage_tx_records( + &self, + block: &MintedBlock, + ) -> 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 witness_set = block.transaction_witness_sets.get(idx); + + let tx_hash = tx.to_hash().to_hex(); + + self.to_babbage_transaction_record(tx, &tx_hash, aux_data, witness_set) + }) + .collect() + } + + fn crawl_post_alonzo_output(&self, output: &PostAlonzoTransactionOutput) -> Result<(), Error> { + let record = self.to_post_alonzo_output_record(output)?; + self.append(record.into())?; + + let child = &self.child_writer(EventContext { + output_address: self + .utils + .bech32 + .encode_address(output.address.as_slice())? + .into(), + ..EventContext::default() + }); + + child.crawl_transaction_output_amount(&output.value)?; + + Ok(()) + } + + fn crawl_babbage_transaction_output(&self, output: &TransactionOutput) -> Result<(), Error> { + match output { + TransactionOutput::Legacy(x) => self.crawl_legacy_output(x), + TransactionOutput::PostAlonzo(x) => self.crawl_post_alonzo_output(x), + } + } + + fn crawl_babbage_witness_set(&self, witness_set: &TransactionWitnessSet) -> Result<(), Error> { + if let Some(native) = &witness_set.native_script { + for script in native.iter() { + self.append_from(self.to_native_witness_record(script)?)?; + } + } + + if let Some(plutus) = &witness_set.plutus_v1_script { + for script in plutus.iter() { + self.append_from(self.to_plutus_v1_witness_record(script)?)?; + } + } + + if let Some(redeemers) = &witness_set.redeemer { + for redeemer in redeemers.iter() { + self.append_from(self.to_plutus_redeemer_record(redeemer)?)?; + } + } + + if let Some(datums) = &witness_set.plutus_data { + for datum in datums.iter() { + self.append_from(self.to_plutus_datum_record(datum)?)?; + } + } + + Ok(()) + } + + fn crawl_babbage_transaction( + &self, + tx: &TransactionBody, + tx_hash: &str, + aux_data: Option<&KeepRaw>, + witness_set: Option<&KeepRaw>, + ) -> Result<(), Error> { + let record = self.to_babbage_transaction_record(tx, tx_hash, aux_data, witness_set)?; + + self.append_from(record.clone())?; + + for (idx, input) in tx.inputs.iter().enumerate() { + let child = self.child_writer(EventContext { + input_idx: Some(idx), + ..EventContext::default() + }); + + child.crawl_transaction_input(input)?; + } + + for (idx, output) in tx.outputs.iter().enumerate() { + let child = self.child_writer(EventContext { + output_idx: Some(idx), + ..EventContext::default() + }); + + child.crawl_babbage_transaction_output(output)?; + } + + if let Some(certs) = &tx.certificates { + for (idx, cert) in certs.iter().enumerate() { + let child = self.child_writer(EventContext { + certificate_idx: Some(idx), + ..EventContext::default() + }); + + child.crawl_certificate(cert)?; + } + } + + if let Some(collateral) = &tx.collateral { + for (_idx, collateral) in collateral.iter().enumerate() { + // TODO: collateral context? + + self.crawl_collateral(collateral)?; + } + } + + if let Some(mint) = &tx.mint { + self.crawl_mints(mint)?; + } + + if let Some(aux_data) = aux_data { + self.crawl_auxdata(aux_data)?; + } + + if let Some(witness_set) = witness_set { + self.crawl_babbage_witness_set(witness_set)?; + } + + if self.config.include_transaction_end_events { + self.append(EventData::TransactionEnd(record))?; + } + + Ok(()) + } + + fn crawl_babbage_block( + &self, + block: &MintedBlock, + hash: &Hash<32>, + cbor: &[u8], + ) -> Result<(), Error> { + let record = self.to_babbage_block_record(block, hash, cbor)?; + + self.append(EventData::Block(record.clone()))?; + + for (idx, tx) in block.transaction_bodies.iter().enumerate() { + let aux_data = block + .auxiliary_data_set + .iter() + .find(|(k, _)| *k == (idx as u32)) + .map(|(_, v)| v); + + let witness_set = block.transaction_witness_sets.get(idx); + + let tx_hash = tx.to_hash().to_hex(); + + let child = self.child_writer(EventContext { + tx_idx: Some(idx), + tx_hash: Some(tx_hash.to_owned()), + ..EventContext::default() + }); + + child.crawl_babbage_transaction(tx, &tx_hash, aux_data, witness_set)?; + } + + if self.config.include_block_end_events { + self.append(EventData::BlockEnd(record))?; + } + + Ok(()) + } + + /// Mapper entry-point for decoded Babbage blocks + /// + /// Entry-point to start crawling a blocks for events. Meant to be used when + /// we already have a decoded block (for example, N2C). The raw CBOR is also + /// passed through in case we need to attach it to outbound events. + pub fn crawl_babbage_with_cbor<'b>( + &self, + block: &'b MintedBlock<'b>, + cbor: &'b [u8], + ) -> Result<(), Error> { + let hash = block.header.to_hash(); + + let child = self.child_writer(EventContext { + block_hash: Some(hex::encode(&hash)), + block_number: Some(block.header.header_body.block_number), + slot: Some(block.header.header_body.slot), + timestamp: self.compute_timestamp(block.header.header_body.slot), + ..EventContext::default() + }); + + child.crawl_babbage_block(block, &hash, cbor) + } + + /// Mapper entry-point for raw Babbage cbor blocks + /// + /// Entry-point to start crawling a blocks for events. Meant to be used when + /// we haven't decoded the CBOR yet (for example, N2N). + pub fn crawl_from_babbage_cbor(&self, cbor: &[u8]) -> Result<(), Error> { + let (_, block): (u16, MintedBlock) = pallas::codec::minicbor::decode(cbor)?; + self.crawl_babbage_with_cbor(&block, cbor) + } +} diff --git a/src/mapper/collect.rs b/src/mapper/collect.rs index 7255dda7..b31140c7 100644 --- a/src/mapper/collect.rs +++ b/src/mapper/collect.rs @@ -1,9 +1,15 @@ -use pallas::ledger::primitives::{ - alonzo::{ - AuxiliaryData, MintedBlock, Multiasset, TransactionInput, TransactionOutput, - TransactionWitnessSet, Value, +use pallas::{ + codec::utils::MaybeIndefArray, + ledger::primitives::{ + alonzo::{ + AuxiliaryData, MintedBlock, Multiasset, NativeScript, PlutusData, PlutusScript, + Redeemer, TransactionInput, VKeyWitness, Value, + }, + babbage::{ + LegacyTransacionOutput, PlutusV2Script, PostAlonzoTransactionOutput, TransactionOutput, + }, + ToHash, }, - ToHash, }; use crate::{ @@ -25,13 +31,36 @@ impl EventWriter { .collect() } - pub fn collect_output_records( + pub fn collect_legacy_output_records( + &self, + source: &[LegacyTransacionOutput], + ) -> Result, Error> { + source + .iter() + .map(|i| self.to_legacy_output_record(i)) + .collect() + } + + pub fn collect_post_alonzo_output_records( + &self, + source: &[PostAlonzoTransactionOutput], + ) -> Result, Error> { + source + .iter() + .map(|i| self.to_post_alonzo_output_record(i)) + .collect() + } + + pub fn collect_any_output_records( &self, source: &[TransactionOutput], ) -> Result, Error> { source .iter() - .map(|i| self.to_transaction_output_record(i)) + .map(|x| match x { + TransactionOutput::Legacy(x) => self.to_legacy_output_record(x), + TransactionOutput::PostAlonzo(x) => self.to_post_alonzo_output_record(x), + }) .collect() } @@ -80,9 +109,9 @@ impl EventWriter { pub fn collect_vkey_witness_records( &self, - witness_set: &TransactionWitnessSet, + witness_set: &Option>, ) -> Result, Error> { - match &witness_set.vkeywitness { + match witness_set { Some(all) => all.iter().map(|i| self.to_vkey_witness_record(i)).collect(), None => Ok(vec![]), } @@ -90,9 +119,9 @@ impl EventWriter { pub fn collect_native_witness_records( &self, - witness_set: &TransactionWitnessSet, + witness_set: &Option>, ) -> Result, Error> { - match &witness_set.native_script { + match witness_set { Some(all) => all .iter() .map(|i| self.to_native_witness_record(i)) @@ -101,14 +130,27 @@ impl EventWriter { } } - pub fn collect_plutus_witness_records( + pub fn collect_plutus_v1_witness_records( + &self, + witness_set: &Option>, + ) -> Result, Error> { + match &witness_set { + Some(all) => all + .iter() + .map(|i| self.to_plutus_v1_witness_record(i)) + .collect(), + None => Ok(vec![]), + } + } + + pub fn collect_plutus_v2_witness_records( &self, - witness_set: &TransactionWitnessSet, + witness_set: &Option>, ) -> Result, Error> { - match &witness_set.plutus_script { + match &witness_set { Some(all) => all .iter() - .map(|i| self.to_plutus_witness_record(i)) + .map(|i| self.to_plutus_v2_witness_record(i)) .collect(), None => Ok(vec![]), } @@ -116,9 +158,9 @@ impl EventWriter { pub fn collect_plutus_redeemer_records( &self, - witness_set: &TransactionWitnessSet, + witness_set: &Option>, ) -> Result, Error> { - match &witness_set.redeemer { + match &witness_set { Some(all) => all .iter() .map(|i| self.to_plutus_redeemer_record(i)) @@ -129,9 +171,9 @@ impl EventWriter { pub fn collect_plutus_datum_records( &self, - witness_set: &TransactionWitnessSet, + witness_set: &Option>, ) -> Result, Error> { - match &witness_set.plutus_data { + match &witness_set { Some(all) => all.iter().map(|i| self.to_plutus_datum_record(i)).collect(), None => Ok(vec![]), } diff --git a/src/mapper/map.rs b/src/mapper/map.rs index b6e7f389..25ca0f52 100644 --- a/src/mapper/map.rs +++ b/src/mapper/map.rs @@ -1,15 +1,19 @@ use std::collections::HashMap; -use pallas::codec::minicbor::bytes::ByteVec; -use pallas::codec::utils::KeepRaw; -use pallas::crypto::hash::Hash; -use pallas::ledger::primitives::alonzo::{ - self as alonzo, AuxiliaryData, Certificate, InstantaneousRewardSource, - InstantaneousRewardTarget, Metadatum, MetadatumLabel, MintedBlock, Relay, TransactionInput, - TransactionOutput, TransactionWitnessSet, Value, +use pallas::{ + codec::{minicbor::bytes::ByteVec, utils::KeepRaw}, + crypto::hash::Hash, + ledger::primitives::babbage::DatumOption, +}; + +use pallas::ledger::primitives::{ + alonzo::{ + self as alonzo, AuxiliaryData, Certificate, InstantaneousRewardSource, + InstantaneousRewardTarget, Metadatum, MetadatumLabel, MintedBlock, NetworkId, Relay, + TransactionBody, TransactionInput, TransactionWitnessSet, Value, + }, + babbage, ToCanonicalJson, ToHash, }; -use pallas::ledger::primitives::alonzo::{NetworkId, TransactionBody}; -use pallas::ledger::primitives::{ToCanonicalJson, ToHash}; use pallas::network::miniprotocols::Point; use serde_json::{json, Value as JsonValue}; @@ -162,9 +166,9 @@ impl EventWriter { } } - pub fn to_transaction_output_record( + pub fn to_legacy_output_record( &self, - output: &TransactionOutput, + output: &alonzo::TransactionOutput, ) -> Result { Ok(TxOutputRecord { address: self @@ -177,6 +181,24 @@ impl EventWriter { }) } + pub fn to_post_alonzo_output_record( + &self, + output: &babbage::PostAlonzoTransactionOutput, + ) -> Result { + Ok(TxOutputRecord { + address: self + .utils + .bech32 + .encode_address(output.address.as_slice())?, + amount: get_tx_output_coin_value(&output.value), + assets: self.collect_asset_records(&output.value).into(), + datum_hash: match output.datum_option { + Some(DatumOption::Hash(x)) => Some(x.to_string()), + _ => None, + }, + }) + } + pub fn to_transaction_output_asset_record( &self, policy: &ByteVec, @@ -241,7 +263,7 @@ impl EventWriter { }) } - pub fn to_plutus_witness_record( + pub fn to_plutus_v1_witness_record( &self, script: &alonzo::PlutusScript, ) -> Result { @@ -251,6 +273,16 @@ impl EventWriter { }) } + pub fn to_plutus_v2_witness_record( + &self, + script: &babbage::PlutusV2Script, + ) -> Result { + Ok(PlutusWitnessRecord { + script_hash: script.to_hash().to_hex(), + script_hex: script.as_ref().to_hex(), + }) + } + pub fn to_native_witness_record( &self, script: &alonzo::NativeScript, @@ -359,7 +391,7 @@ impl EventWriter { NetworkId::Two => 2, }); - let outputs = self.collect_output_records(&body.outputs)?; + let outputs = self.collect_legacy_output_records(&body.outputs)?; record.output_count = outputs.len(); record.total_output = outputs.iter().map(|o| o.amount).sum(); @@ -390,11 +422,25 @@ impl EventWriter { }; if let Some(witnesses) = witness_set { - record.vkey_witnesses = self.collect_vkey_witness_records(witnesses)?.into(); - record.native_witnesses = self.collect_native_witness_records(witnesses)?.into(); - record.plutus_witnesses = self.collect_plutus_witness_records(witnesses)?.into(); - record.plutus_redeemers = self.collect_plutus_redeemer_records(witnesses)?.into(); - record.plutus_data = self.collect_plutus_datum_records(witnesses)?.into(); + record.vkey_witnesses = self + .collect_vkey_witness_records(&witnesses.vkeywitness)? + .into(); + + record.native_witnesses = self + .collect_native_witness_records(&witnesses.native_script)? + .into(); + + record.plutus_witnesses = self + .collect_plutus_v1_witness_records(&witnesses.plutus_script)? + .into(); + + record.plutus_redeemers = self + .collect_plutus_redeemer_records(&witnesses.redeemer)? + .into(); + + record.plutus_data = self + .collect_plutus_datum_records(&witnesses.plutus_data)? + .into(); } } diff --git a/src/mapper/mod.rs b/src/mapper/mod.rs index d6134a76..a176e40f 100644 --- a/src/mapper/mod.rs +++ b/src/mapper/mod.rs @@ -1,3 +1,4 @@ +mod babbage; mod byron; mod cip15; mod cip25; diff --git a/src/mapper/shelley.rs b/src/mapper/shelley.rs index d3b7a773..330fd5a3 100644 --- a/src/mapper/shelley.rs +++ b/src/mapper/shelley.rs @@ -16,7 +16,7 @@ use crate::{ use super::{map::ToHex, EventWriter}; impl EventWriter { - fn crawl_metadata(&self, metadata: &Metadata) -> Result<(), Error> { + pub(crate) fn crawl_metadata(&self, metadata: &Metadata) -> Result<(), Error> { for (label, content) in metadata.iter() { let record = self.to_metadata_record(label, content)?; self.append_from(record)?; @@ -31,7 +31,7 @@ impl EventWriter { Ok(()) } - fn crawl_auxdata(&self, aux_data: &AuxiliaryData) -> Result<(), Error> { + pub(crate) fn crawl_auxdata(&self, aux_data: &AuxiliaryData) -> Result<(), Error> { match aux_data { AuxiliaryData::PostAlonzo(data) => { if let Some(metadata) = &data.metadata { @@ -67,11 +67,11 @@ impl EventWriter { Ok(()) } - fn crawl_transaction_input(&self, input: &TransactionInput) -> Result<(), Error> { + pub(crate) fn crawl_transaction_input(&self, input: &TransactionInput) -> Result<(), Error> { self.append_from(self.to_transaction_input_record(input)) } - fn crawl_transaction_output_amount(&self, amount: &Value) -> Result<(), Error> { + pub(crate) fn crawl_transaction_output_amount(&self, amount: &Value) -> Result<(), Error> { if let Value::Multiasset(_, policies) = amount { for (policy, assets) in policies.iter() { for (asset, amount) in assets.iter() { @@ -87,8 +87,8 @@ impl EventWriter { Ok(()) } - fn crawl_transaction_output(&self, output: &TransactionOutput) -> Result<(), Error> { - let record = self.to_transaction_output_record(output)?; + pub(crate) fn crawl_legacy_output(&self, output: &TransactionOutput) -> Result<(), Error> { + let record = self.to_legacy_output_record(output)?; self.append(record.into())?; let child = &self.child_writer(EventContext { @@ -105,20 +105,20 @@ impl EventWriter { Ok(()) } - fn crawl_certificate(&self, certificate: &Certificate) -> Result<(), Error> { + pub(crate) fn crawl_certificate(&self, certificate: &Certificate) -> Result<(), Error> { self.append(self.to_certificate_event(certificate)) // more complex event goes here (eg: pool metadata?) } - fn crawl_collateral(&self, collateral: &TransactionInput) -> Result<(), Error> { + pub(crate) fn crawl_collateral(&self, collateral: &TransactionInput) -> Result<(), Error> { self.append(self.to_collateral_event(collateral)) // TODO: should we have a collateral idx in context? // more complex event goes here (eg: ???) } - fn crawl_mints(&self, mints: &Multiasset) -> Result<(), Error> { + pub(crate) fn crawl_mints(&self, mints: &Multiasset) -> Result<(), Error> { // should we have a policy context? for (policy, assets) in mints.iter() { @@ -130,7 +130,10 @@ impl EventWriter { Ok(()) } - fn crawl_witness_set(&self, witness_set: &TransactionWitnessSet) -> Result<(), Error> { + pub(crate) fn crawl_witness_set( + &self, + witness_set: &TransactionWitnessSet, + ) -> Result<(), Error> { if let Some(native) = &witness_set.native_script { for script in native.iter() { self.append_from(self.to_native_witness_record(script)?)?; @@ -139,7 +142,7 @@ impl EventWriter { if let Some(plutus) = &witness_set.plutus_script { for script in plutus.iter() { - self.append_from(self.to_plutus_witness_record(script)?)?; + self.append_from(self.to_plutus_v1_witness_record(script)?)?; } } @@ -184,7 +187,7 @@ impl EventWriter { ..EventContext::default() }); - child.crawl_transaction_output(output)?; + child.crawl_legacy_output(output)?; } if let Some(certs) = &tx.certificates { diff --git a/src/sources/n2c/blocks.rs b/src/sources/n2c/blocks.rs index 2cd3414c..0791f379 100644 --- a/src/sources/n2c/blocks.rs +++ b/src/sources/n2c/blocks.rs @@ -1,6 +1,6 @@ use pallas::{ codec::minicbor::decode, - ledger::primitives::{alonzo, byron, ToHash}, + ledger::primitives::{alonzo, babbage, byron, ToHash}, ledger::traverse::{probe, Era}, network::miniprotocols::Point, }; @@ -25,7 +25,10 @@ impl<'b> CborHolder { let (_, block): (u16, alonzo::MintedBlock) = decode(&self.0)?; MultiEraBlock::AlonzoCompatible(Box::new(block), era) } - // TODO: handle babbage + Era::Babbage => { + let (_, block): (u16, babbage::MintedBlock) = decode(&self.0)?; + MultiEraBlock::Babbage(Box::new(block)) + } x => { return Err(format!("This version of Oura can't handle era: {}", x).into()); } @@ -53,6 +56,7 @@ pub(crate) enum MultiEraBlock<'b> { EpochBoundary(Box), Byron(Box>), AlonzoCompatible(Box>, Era), + Babbage(Box>), } impl MultiEraBlock<'_> { @@ -72,6 +76,10 @@ impl MultiEraBlock<'_> { let hash = x.header.to_hash(); Ok(Point::Specific(x.header.header_body.slot, hash.to_vec())) } + MultiEraBlock::Babbage(x) => { + let hash = x.header.to_hash(); + Ok(Point::Specific(x.header.header_body.slot, hash.to_vec())) + } } } } diff --git a/src/sources/n2c/run.rs b/src/sources/n2c/run.rs index deb0600d..d25f391d 100644 --- a/src/sources/n2c/run.rs +++ b/src/sources/n2c/run.rs @@ -82,6 +82,9 @@ impl chainsync::Observer for ChainObserver { MultiEraBlock::AlonzoCompatible(model, era) => self .event_writer .crawl_shelley_with_cbor(&model, block.cbor(), era.into())?, + MultiEraBlock::Babbage(model) => self + .event_writer + .crawl_babbage_with_cbor(&model, block.cbor())?, }; self.block_count += 1; diff --git a/src/sources/n2n/run.rs b/src/sources/n2n/run.rs index 398e8a6b..d92764f7 100644 --- a/src/sources/n2n/run.rs +++ b/src/sources/n2n/run.rs @@ -37,14 +37,18 @@ impl blockfetch::Observer for Block2EventMapper { Era::Byron => { writer .crawl_from_byron_cbor(&body) - .ok_or_warn("error crawling block for events"); + .ok_or_warn("error crawling byron block for events"); } Era::Allegra | Era::Alonzo | Era::Mary | Era::Shelley => { writer .crawl_from_shelley_cbor(&body, era.into()) - .ok_or_warn("error crawling block for events"); + .ok_or_warn("error crawling alonzo-compatible block for events"); + } + Era::Babbage => { + writer + .crawl_from_babbage_cbor(&body) + .ok_or_warn("error crawling babbage block for events"); } - // TODO: handle babbage x => { return Err(format!("This version of Oura can't handle era: {}", x).into()); }