diff --git a/Cargo.toml b/Cargo.toml index 58bf781a..711c9a5e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,9 +12,9 @@ authors = ["Santiago Carmuega "] [dependencies] -pallas = "0.18.0" +pallas = { git = "https://github.com/Emurgo/pallas", tag = "conway_2" } # pallas = { git = "https://github.com/txpipe/pallas" } -# pallas = { path = "../pallas/pallas" } +# pallas = { path = "../../pallas/pallas" } hex = "0.4.3" net2 = "0.2.37" bech32 = "0.9.1" diff --git a/src/filters/fingerprint.rs b/src/filters/fingerprint.rs index f38e985a..2e805f15 100644 --- a/src/filters/fingerprint.rs +++ b/src/filters/fingerprint.rs @@ -214,6 +214,66 @@ fn build_fingerprint(event: &Event, seed: u32) -> Result { .with_prefix("move") .append_optional(&event.context.tx_hash)? .append_optional_to_string(&event.context.certificate_idx)?, + EventData::RegCert { .. } => b + .with_slot(&event.context.slot) + .with_prefix("regc") + .append_optional(&event.context.tx_hash)? + .append_optional_to_string(&event.context.certificate_idx)?, + EventData::UnRegCert { .. } => b + .with_slot(&event.context.slot) + .with_prefix("unrc") + .append_optional(&event.context.tx_hash)? + .append_optional_to_string(&event.context.certificate_idx)?, + EventData::VoteDeleg { .. } => b + .with_slot(&event.context.slot) + .with_prefix("vode") + .append_optional(&event.context.tx_hash)? + .append_optional_to_string(&event.context.certificate_idx)?, + EventData::StakeVoteDeleg { .. } => b + .with_slot(&event.context.slot) + .with_prefix("stvo") + .append_optional(&event.context.tx_hash)? + .append_optional_to_string(&event.context.certificate_idx)?, + EventData::StakeRegDeleg { .. } => b + .with_slot(&event.context.slot) + .with_prefix("stre") + .append_optional(&event.context.tx_hash)? + .append_optional_to_string(&event.context.certificate_idx)?, + EventData::VoteRegDeleg { .. } => b + .with_slot(&event.context.slot) + .with_prefix("vore") + .append_optional(&event.context.tx_hash)? + .append_optional_to_string(&event.context.certificate_idx)?, + EventData::StakeVoteRegDeleg { .. } => b + .with_slot(&event.context.slot) + .with_prefix("stvr") + .append_optional(&event.context.tx_hash)? + .append_optional_to_string(&event.context.certificate_idx)?, + EventData::AuthCommitteeHot { .. } => b + .with_slot(&event.context.slot) + .with_prefix("auth") + .append_optional(&event.context.tx_hash)? + .append_optional_to_string(&event.context.certificate_idx)?, + EventData::ResignCommitteeCold { .. } => b + .with_slot(&event.context.slot) + .with_prefix("resi") + .append_optional(&event.context.tx_hash)? + .append_optional_to_string(&event.context.certificate_idx)?, + EventData::RegDRepCert { .. } => b + .with_slot(&event.context.slot) + .with_prefix("regd") + .append_optional(&event.context.tx_hash)? + .append_optional_to_string(&event.context.certificate_idx)?, + EventData::UnRegDRepCert { .. } => b + .with_slot(&event.context.slot) + .with_prefix("unrd") + .append_optional(&event.context.tx_hash)? + .append_optional_to_string(&event.context.certificate_idx)?, + EventData::UpdateDRepCert { .. } => b + .with_slot(&event.context.slot) + .with_prefix("updd") + .append_optional(&event.context.tx_hash)? + .append_optional_to_string(&event.context.certificate_idx)?, EventData::RollBack { block_slot, block_hash, diff --git a/src/filters/selection.rs b/src/filters/selection.rs index 2b033f73..2000d164 100644 --- a/src/filters/selection.rs +++ b/src/filters/selection.rs @@ -157,11 +157,12 @@ fn metadata_any_sub_label_matches(event: &Event, sub_label: &str) -> bool { fn vkey_witnesses_matches(event: &Event, witness: &str) -> bool { match &event.data { EventData::VKeyWitness(x) => x.vkey_hex == witness, - EventData::Transaction(x) => - x.vkey_witnesses.as_ref() - .map(|vs| vs.iter().any(|v| v.vkey_hex == witness)) - .unwrap_or(false), - _ => false + EventData::Transaction(x) => x + .vkey_witnesses + .as_ref() + .map(|vs| vs.iter().any(|v| v.vkey_hex == witness)) + .unwrap_or(false), + _ => false, } } @@ -169,11 +170,12 @@ fn vkey_witnesses_matches(event: &Event, witness: &str) -> bool { fn native_scripts_matches(event: &Event, policy_id: &str) -> bool { match &event.data { EventData::NativeWitness(x) => x.policy_id == policy_id, - EventData::Transaction(x) => - x.native_witnesses.as_ref() - .map(|vs| vs.iter().any(|v| v.policy_id == policy_id)) - .unwrap_or(false), - _ => false + EventData::Transaction(x) => x + .native_witnesses + .as_ref() + .map(|vs| vs.iter().any(|v| v.policy_id == policy_id)) + .unwrap_or(false), + _ => false, } } @@ -181,11 +183,12 @@ fn native_scripts_matches(event: &Event, policy_id: &str) -> bool { fn plutus_scripts_matches(event: &Event, script_hash: &str) -> bool { match &event.data { EventData::PlutusWitness(x) => x.script_hash == script_hash, - EventData::Transaction(x) => - x.plutus_witnesses.as_ref() - .map(|vs| vs.iter().any(|v| v.script_hash == script_hash)) - .unwrap_or(false), - _ => false + EventData::Transaction(x) => x + .plutus_witnesses + .as_ref() + .map(|vs| vs.iter().any(|v| v.script_hash == script_hash)) + .unwrap_or(false), + _ => false, } } diff --git a/src/mapper/babbage.rs b/src/mapper/babbage.rs index 5ce1e033..d84590f6 100644 --- a/src/mapper/babbage.rs +++ b/src/mapper/babbage.rs @@ -1,13 +1,20 @@ -use std::collections::HashMap; use pallas::codec::utils::KeepRaw; +use std::collections::HashMap; -use pallas::ledger::primitives::babbage::{AuxiliaryData, CostMdls, Language, MintedBlock, MintedDatumOption, MintedPostAlonzoTransactionOutput, MintedTransactionBody, MintedTransactionOutput, MintedWitnessSet, NetworkId, ProtocolParamUpdate, Update}; +use pallas::ledger::primitives::babbage::{ + AuxiliaryData, CostMdls, Language, MintedBlock, MintedDatumOption, + MintedPostAlonzoTransactionOutput, MintedTransactionBody, MintedTransactionOutput, + MintedWitnessSet, NetworkId, ProtocolParamUpdate, Update, +}; use pallas::crypto::hash::Hash; use pallas::ledger::traverse::OriginalHash; use serde_json::json; -use crate::model::{BlockRecord, CostModelRecord, CostModelsRecord, Era, LanguageVersionRecord, ProtocolParamUpdateRecord, TransactionRecord, UpdateRecord}; +use crate::model::{ + BlockRecord, CostModelRecord, CostModelsRecord, Era, LanguageVersionRecord, + ProtocolParamUpdateRecord, TransactionRecord, UpdateRecord, +}; use crate::utils::time::TimeProvider; use crate::{ model::{EventContext, EventData}, @@ -74,7 +81,7 @@ impl EventWriter { } // Add Collateral Stuff - let collateral_inputs = &body.collateral.as_deref(); + let collateral_inputs = &body.collateral; record.collateral_input_count = collateral_inputs.iter().count(); record.has_collateral_output = body.collateral_return.is_some(); @@ -85,7 +92,7 @@ impl EventWriter { } if let Some(req_signers) = &body.required_signers { - let req_signers = self.collect_required_signers_records(req_signers)?; + let req_signers = self.collect_required_signers_records(req_signers.into())?; record.required_signers_count = req_signers.len(); if self.config.include_transaction_details { @@ -103,7 +110,7 @@ impl EventWriter { // transaction_details collateral stuff record.collateral_inputs = - collateral_inputs.map(|inputs| self.collect_input_records(inputs)); + collateral_inputs.as_ref().map(|inputs| self.collect_input_records(inputs)); record.collateral_output = body.collateral_return.as_ref().map(|output| match output { MintedTransactionOutput::Legacy(x) => self.to_legacy_output_record(x).unwrap(), @@ -119,15 +126,15 @@ impl EventWriter { if let Some(witnesses) = witness_set { record.vkey_witnesses = self - .collect_vkey_witness_records(&witnesses.vkeywitness)? + .collect_vkey_witness_records_babbage(&witnesses.vkeywitness)? .into(); record.native_witnesses = self - .collect_native_witness_records(&witnesses.native_script)? + .collect_native_witness_records_babbage(&witnesses.native_script)? .into(); record.plutus_witnesses = self - .collect_plutus_v1_witness_records(&witnesses.plutus_v1_script)? + .collect_plutus_v1_witness_records_babbage(&witnesses.plutus_v1_script)? .into(); record.plutus_redeemers = self @@ -135,7 +142,7 @@ impl EventWriter { .into(); record.plutus_data = self - .collect_witness_plutus_datum_records(&witnesses.plutus_data)? + .collect_witness_plutus_datum_records_babbage(&witnesses.plutus_data)? .into(); } @@ -271,7 +278,7 @@ impl EventWriter { } if let Some(datums) = &witness_set.plutus_data { - for datum in datums.iter() { + for datum in datums { self.append_from(self.to_plutus_datum_record(datum)?)?; } } @@ -383,7 +390,10 @@ impl EventWriter { Ok(()) } - pub fn to_babbage_cost_models_record(&self, cost_models: &Option) -> Option { + pub fn to_babbage_cost_models_record( + &self, + cost_models: &Option, + ) -> Option { match cost_models { Some(cost_models) => { let mut cost_models_record = HashMap::new(); @@ -399,19 +409,25 @@ impl EventWriter { } Some(CostModelsRecord(cost_models_record)) - }, + } None => None, } } - pub fn to_babbage_language_version_record(&self, language_version: &Language) -> LanguageVersionRecord { + pub fn to_babbage_language_version_record( + &self, + language_version: &Language, + ) -> LanguageVersionRecord { match language_version { Language::PlutusV1 => LanguageVersionRecord::PlutusV1, Language::PlutusV2 => LanguageVersionRecord::PlutusV2, } } - pub fn to_babbage_protocol_update_record(&self, update: &ProtocolParamUpdate) -> ProtocolParamUpdateRecord { + pub fn to_babbage_protocol_update_record( + &self, + update: &ProtocolParamUpdate, + ) -> ProtocolParamUpdateRecord { ProtocolParamUpdateRecord { minfee_a: update.minfee_a, minfee_b: update.minfee_b, @@ -422,7 +438,8 @@ impl EventWriter { pool_deposit: update.pool_deposit, maximum_epoch: update.maximum_epoch, desired_number_of_stake_pools: update.desired_number_of_stake_pools, - pool_pledge_influence: self.to_rational_number_record_option(&update.pool_pledge_influence), + pool_pledge_influence: self + .to_rational_number_record_option(&update.pool_pledge_influence), expansion_rate: self.to_unit_interval_record(&update.expansion_rate), treasury_growth_rate: self.to_unit_interval_record(&update.treasury_growth_rate), decentralization_constant: None, @@ -430,10 +447,11 @@ impl EventWriter { protocol_version: update.protocol_version, min_pool_cost: update.min_pool_cost, ada_per_utxo_byte: update.ada_per_utxo_byte, - cost_models_for_script_languages: self.to_babbage_cost_models_record(&update.cost_models_for_script_languages), + cost_models_for_script_languages: self + .to_babbage_cost_models_record(&update.cost_models_for_script_languages), execution_costs: match &update.execution_costs { Some(execution_costs) => Some(json!(execution_costs)), - None => None + None => None, }, max_tx_ex_units: self.to_ex_units_record(&update.max_tx_ex_units), max_block_ex_units: self.to_ex_units_record(&update.max_block_ex_units), @@ -446,10 +464,13 @@ impl EventWriter { pub fn to_babbage_update_record(&self, update: &Update) -> UpdateRecord { let mut updates = HashMap::new(); for update in update.proposed_protocol_parameter_updates.clone().to_vec() { - updates.insert(update.0.to_hex(), self.to_babbage_protocol_update_record(&update.1)); + updates.insert( + update.0.to_hex(), + self.to_babbage_protocol_update_record(&update.1), + ); } - UpdateRecord{ + UpdateRecord { proposed_protocol_parameter_updates: updates, epoch: update.epoch, } diff --git a/src/mapper/collect.rs b/src/mapper/collect.rs index 93a784d0..ed448f19 100644 --- a/src/mapper/collect.rs +++ b/src/mapper/collect.rs @@ -1,3 +1,5 @@ +use std::option::IntoIter; +use pallas::ledger::primitives::alonzo::{AddrKeyhash, AddrKeyhashes, Certificates, RequiredSigners, TransactionInputs}; use pallas::{ codec::utils::{KeepRaw, KeyValuePairs, MaybeIndefArray}, ledger::{ @@ -14,8 +16,9 @@ use pallas::{ traverse::OriginalHash, }, }; -use pallas::ledger::primitives::alonzo::{Certificate, RequiredSigners}; +use pallas::ledger::primitives::babbage::{KeepRawPlutusDatas, NativeScripts, PlutusV1Scripts, VKeyWitnesses}; +use crate::model::{CertificateRecord, RequiredSignerRecord}; use crate::{ model::{ MetadataRecord, MintRecord, NativeWitnessRecord, OutputAssetRecord, PlutusDatumRecord, @@ -24,12 +27,11 @@ use crate::{ }, Error, }; -use crate::model::{CertificateRecord, RequiredSignerRecord}; use super::{map::ToHex, EventWriter}; impl EventWriter { - pub fn collect_input_records(&self, source: &[TransactionInput]) -> Vec { + pub fn collect_input_records(&self, source: &TransactionInputs) -> Vec { source .iter() .map(|i| self.to_transaction_input_record(i)) @@ -95,7 +97,7 @@ impl EventWriter { pub fn collect_certificate_records( &self, - certificates: &Vec, + certificates: &Certificates, ) -> Vec { certificates .iter() @@ -148,6 +150,16 @@ impl EventWriter { } } + pub fn collect_vkey_witness_records_babbage( + &self, + witness_set: &Option, + ) -> Result, Error> { + match witness_set { + Some(all) => all.iter().map(|i| self.to_vkey_witness_record(i)).collect(), + None => Ok(vec![]), + } + } + pub fn collect_native_witness_records( &self, witness_set: &Option>, @@ -161,6 +173,19 @@ impl EventWriter { } } + pub fn collect_native_witness_records_babbage( + &self, + witness_set: &Option, + ) -> Result, Error> { + match witness_set { + Some(all) => all + .iter() + .map(|i| self.to_native_witness_record(i)) + .collect(), + None => Ok(vec![]), + } + } + pub fn collect_plutus_v1_witness_records( &self, witness_set: &Option>, @@ -174,6 +199,19 @@ impl EventWriter { } } + pub fn collect_plutus_v1_witness_records_babbage( + &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: &Option>, @@ -210,6 +248,16 @@ impl EventWriter { } } + pub fn collect_witness_plutus_datum_records_babbage( + &self, + witness_set: &Option, + ) -> Result, Error> { + match &witness_set { + Some(all) => all.into_iter().map(|i| self.to_plutus_datum_record(i)).collect(), + None => Ok(vec![]), + } + } + pub fn collect_shelley_tx_records( &self, block: &MintedBlock, @@ -234,7 +282,10 @@ impl EventWriter { .collect() } - pub fn collect_required_signers_records(&self, req_signers: &RequiredSigners) -> Result, Error> { + pub fn collect_required_signers_records( + &self, + req_signers: &Vec, + ) -> Result, Error> { let mut signers = vec![]; for req_sign in req_signers { let hex = req_sign.to_hex(); diff --git a/src/mapper/map.rs b/src/mapper/map.rs index 17157a52..c76d8355 100644 --- a/src/mapper/map.rs +++ b/src/mapper/map.rs @@ -1,6 +1,9 @@ use std::collections::HashMap; -use pallas::ledger::primitives::alonzo::{CostMdls, CostModel, ExUnits, Language, MintedWitnessSet, Nonce, NonceVariant, PositiveInterval, ProtocolParamUpdate, RationalNumber, UnitInterval, Update}; +use pallas::ledger::primitives::alonzo::{ + CostMdls, CostModel, ExUnits, Language, MintedWitnessSet, Nonce, NonceVariant, + PositiveInterval, ProtocolParamUpdate, RationalNumber, UnitInterval, Update, +}; use pallas::ledger::primitives::babbage::{MintedDatumOption, Script, ScriptRef}; use pallas::ledger::traverse::{ComputeHash, OriginalHash}; use pallas::{codec::utils::KeepRaw, crypto::hash::Hash}; @@ -17,11 +20,24 @@ use pallas::ledger::primitives::{ use pallas::network::miniprotocols::Point; use serde_json::{json, Value as JsonValue}; -use crate::model::{BlockRecord, CertificateRecord, CostModelRecord, CostModelsRecord, Era, EventData, ExUnitsRecord, GenesisKeyDelegationRecord, LanguageVersionRecord, MetadataRecord, MetadatumRendition, MintRecord, MoveInstantaneousRewardsCertRecord, NativeWitnessRecord, NonceRecord, NonceVariantRecord, OutputAssetRecord, PlutusDatumRecord, PlutusRedeemerRecord, PlutusWitnessRecord, PoolRegistrationRecord, PoolRetirementRecord, PositiveIntervalRecord, ProtocolParamUpdateRecord, RationalNumberRecord, ScriptRefRecord, StakeCredential, StakeDelegationRecord, StakeDeregistrationRecord, StakeRegistrationRecord, TransactionRecord, TxInputRecord, TxOutputRecord, UnitIntervalRecord, UpdateRecord, VKeyWitnessRecord}; +use crate::model::{ + AnchorRecord, AuthCommitteeHotCertRecord, BlockRecord, CertificateRecord, CostModelRecord, + CostModelsRecord, DRep, Era, EventData, ExUnitsRecord, GenesisKeyDelegationRecord, + LanguageVersionRecord, MetadataRecord, MetadatumRendition, MintRecord, + MoveInstantaneousRewardsCertRecord, NativeWitnessRecord, NonceRecord, NonceVariantRecord, + OutputAssetRecord, PlutusDatumRecord, PlutusRedeemerRecord, PlutusWitnessRecord, + PoolRegistrationRecord, PoolRetirementRecord, PositiveIntervalRecord, + ProtocolParamUpdateRecord, RationalNumberRecord, RegCertRecord, RegDRepCertRecord, + ResignCommitteeColdCertRecord, ScriptRefRecord, StakeCredential, StakeDelegationRecord, + StakeDeregistrationRecord, StakeRegDelegCertRecord, StakeRegistrationRecord, + StakeVoteDelegCertRecord, StakeVoteRegDelegCertRecord, TransactionRecord, TxInputRecord, + TxOutputRecord, UnRegCertRecord, UnRegDRepCertRecord, UnitIntervalRecord, UpdateDRepCertRecord, + UpdateRecord, VKeyWitnessRecord, VoteDelegCertRecord, VoteRegDelegCertRecord, +}; +use crate::model::ScriptRefRecord::{NativeScript, PlutusV1, PlutusV2, PlutusV3}; use crate::utils::time::TimeProvider; use crate::Error; -use crate::model::ScriptRefRecord::{NativeScript, PlutusV1, PlutusV2}; use super::EventWriter; @@ -56,6 +72,33 @@ impl From<&alonzo::StakeCredential> for StakeCredential { } } +impl From<&alonzo::DRep> for DRep { + fn from(other: &alonzo::DRep) -> Self { + match other { + alonzo::DRep::Key(x) => DRep::KeyHash(x.to_hex()), + alonzo::DRep::Script(x) => DRep::ScriptHash(x.to_hex()), + alonzo::DRep::Abstain => DRep::Abstain, + alonzo::DRep::NoConfidence => DRep::NoConfidence, + } + } +} + +impl From<&alonzo::Anchor> for AnchorRecord { + fn from(other: &alonzo::Anchor) -> Self { + AnchorRecord { + url: other.0.clone(), + data_hash: other.1.to_hex(), + } + } +} + +fn to_option_anchor_record(anchor: &Option) -> Option { + match anchor { + Some(anchor) => Some(anchor.into()), + None => None, + } +} + fn ip_string_from_bytes(bytes: &[u8]) -> String { format!("{}.{}.{}.{}", bytes[0], bytes[1], bytes[2], bytes[3]) } @@ -199,7 +242,7 @@ impl EventWriter { inlined_script: match &output.script_ref { Some(script) => Some(self.to_script_ref_record(script)?), None => None, - } + }, }) } @@ -302,7 +345,10 @@ impl EventWriter { }) } - pub fn to_script_ref_record(&self, script_ref: &ScriptRef) -> Result { + pub fn to_script_ref_record( + &self, + script_ref: &ScriptRef, + ) -> Result { match &script_ref.0 { Script::PlutusV1Script(script) => Ok(PlutusV1 { script_hash: script.compute_hash().to_hex(), @@ -312,6 +358,10 @@ impl EventWriter { script_hash: script.compute_hash().to_hex(), script_hex: script.as_ref().to_hex(), }), + Script::PlutusV3Script(script) => Ok(PlutusV3 { + script_hash: script.compute_hash().to_hex(), + script_hex: script.as_ref().to_hex(), + }), Script::NativeScript(script) => Ok(NativeScript { policy_id: script.compute_hash().to_hex(), script_json: script.to_json(), @@ -331,19 +381,22 @@ impl EventWriter { pub fn to_certificate_record(&self, certificate: &Certificate) -> CertificateRecord { match certificate { - Certificate::StakeRegistration(credential) => + Certificate::StakeRegistration(credential) => { CertificateRecord::StakeRegistration(StakeRegistrationRecord { - credential: credential.into(), - }), - Certificate::StakeDeregistration(credential) => + credential: credential.into(), + }) + } + Certificate::StakeDeregistration(credential) => { CertificateRecord::StakeDeregistration(StakeDeregistrationRecord { - credential: credential.into(), - }), - Certificate::StakeDelegation(credential, pool) => - CertificateRecord::StakeDelegation( StakeDelegationRecord { - credential: credential.into(), - pool_hash: pool.to_hex(), - }), + credential: credential.into(), + }) + } + Certificate::StakeDelegation(credential, pool) => { + CertificateRecord::StakeDelegation(StakeDelegationRecord { + credential: credential.into(), + pool_hash: pool.to_hex(), + }) + } Certificate::PoolRegistration { operator, vrf_keyhash, @@ -354,7 +407,7 @@ impl EventWriter { pool_owners, relays, pool_metadata, - } => CertificateRecord::PoolRegistration (PoolRegistrationRecord { + } => CertificateRecord::PoolRegistration(PoolRegistrationRecord { operator: operator.to_hex(), vrf_keyhash: vrf_keyhash.to_hex(), pledge: *pledge, @@ -366,35 +419,114 @@ impl EventWriter { pool_metadata: pool_metadata.as_ref().map(|m| m.url.clone()), pool_metadata_hash: pool_metadata.as_ref().map(|m| m.hash.clone().to_hex()), }), - Certificate::PoolRetirement(pool, epoch) => - CertificateRecord::PoolRetirement (PoolRetirementRecord { - pool: pool.to_hex(), - epoch: *epoch, - }), - Certificate::MoveInstantaneousRewardsCert(move_) => - CertificateRecord::MoveInstantaneousRewardsCert( MoveInstantaneousRewardsCertRecord { - from_reserves: matches!(move_.source, InstantaneousRewardSource::Reserves), - from_treasury: matches!(move_.source, InstantaneousRewardSource::Treasury), - to_stake_credentials: match &move_.target { - InstantaneousRewardTarget::StakeCredentials(creds) => { - let x = creds.iter().map(|(k, v)| (k.into(), *v)).collect(); - Some(x) - } - _ => None, - }, - to_other_pot: match move_.target { - InstantaneousRewardTarget::OtherAccountingPot(x) => Some(x), - _ => None, + Certificate::PoolRetirement(pool, epoch) => { + CertificateRecord::PoolRetirement(PoolRetirementRecord { + pool: pool.to_hex(), + epoch: *epoch, + }) + } + Certificate::MoveInstantaneousRewardsCert(move_) => { + CertificateRecord::MoveInstantaneousRewardsCert( + MoveInstantaneousRewardsCertRecord { + from_reserves: matches!(move_.source, InstantaneousRewardSource::Reserves), + from_treasury: matches!(move_.source, InstantaneousRewardSource::Treasury), + to_stake_credentials: match &move_.target { + InstantaneousRewardTarget::StakeCredentials(creds) => { + let x = creds.iter().map(|(k, v)| (k.into(), *v)).collect(); + Some(x) + } + _ => None, + }, + to_other_pot: match move_.target { + InstantaneousRewardTarget::OtherAccountingPot(x) => Some(x), + _ => None, + }, }, - }), - Certificate::GenesisKeyDelegation(genesis_hash, - genesis_delegate_hash, - vrf_key_hash) - => CertificateRecord::GenesisKeyDelegation (GenesisKeyDelegationRecord { + ) + } + Certificate::GenesisKeyDelegation( + genesis_hash, + genesis_delegate_hash, + vrf_key_hash, + ) => CertificateRecord::GenesisKeyDelegation(GenesisKeyDelegationRecord { genesis_hash: genesis_hash.to_hex(), genesis_delegate_hash: genesis_delegate_hash.to_hex(), vrf_key_hash: vrf_key_hash.to_hex(), }), + Certificate::Reg(credential, coin) => CertificateRecord::RegCert(RegCertRecord { + credential: credential.into(), + coin: *coin, + }), + Certificate::UnReg(credential, coin) => CertificateRecord::UnRegCert(UnRegCertRecord { + credential: credential.into(), + coin: *coin, + }), + Certificate::VoteDeleg(credential, drep) => { + CertificateRecord::VoteDeleg(VoteDelegCertRecord { + credential: credential.into(), + drep: drep.into(), + }) + } + Certificate::StakeVoteDeleg(credential, pool, drep) => { + CertificateRecord::StakeVoteDeleg(StakeVoteDelegCertRecord { + credential: credential.into(), + pool_keyhash: pool.to_hex(), + drep: drep.into(), + }) + } + Certificate::StakeRegDeleg(credential, pool, coin) => { + CertificateRecord::StakeRegDeleg(StakeRegDelegCertRecord { + credential: credential.into(), + pool_keyhash: pool.to_hex(), + coin: *coin, + }) + } + Certificate::VoteRegDeleg(credential, drep, coin) => { + CertificateRecord::VoteRegDeleg(VoteRegDelegCertRecord { + credential: credential.into(), + drep: drep.into(), + coin: *coin, + }) + } + Certificate::StakeVoteRegDeleg(credential, pool, drep, coin) => { + CertificateRecord::StakeVoteRegDeleg(StakeVoteRegDelegCertRecord { + credential: credential.into(), + pool_keyhash: pool.to_hex(), + drep: drep.into(), + coin: *coin, + }) + } + Certificate::AuthCommitteeHot(cold, hot) => { + CertificateRecord::AuthCommitteeHot(AuthCommitteeHotCertRecord { + committee_cold_credential: cold.into(), + committee_hot_credential: hot.into(), + }) + } + Certificate::ResignCommitteeCold(cold, anchor) => { + CertificateRecord::ResignCommitteeCold(ResignCommitteeColdCertRecord { + committee_cold_credential: cold.into(), + anchor: to_option_anchor_record(anchor), + }) + } + Certificate::RegDRepCert(drep, coin, anchor) => { + CertificateRecord::RegDRepCert(RegDRepCertRecord { + credential: drep.into(), + coin: *coin, + anchor: to_option_anchor_record(anchor), + }) + } + Certificate::UnRegDRepCert(drep, coin) => { + CertificateRecord::UnRegDRepCert(UnRegDRepCertRecord { + credential: drep.into(), + coin: *coin, + }) + } + Certificate::UpdateDRepCert(credential, anchor) => { + CertificateRecord::UpdateDRepCert(UpdateDRepCertRecord { + credential: credential.into(), + anchor: to_option_anchor_record(anchor), + }) + } } } @@ -405,24 +537,33 @@ impl EventWriter { } } - pub fn to_rational_number_record_option(&self, rational: &Option) -> Option { + pub fn to_rational_number_record_option( + &self, + rational: &Option, + ) -> Option { match rational { Some(rational) => Some(self.to_rational_number_record(rational)), None => None, } } - pub fn to_unit_interval_record(&self, interval: &Option) -> Option { + pub fn to_unit_interval_record( + &self, + interval: &Option, + ) -> Option { match interval { - Some(interval) => Some( - UnitIntervalRecord(interval.numerator as u64, interval.denominator)), + Some(interval) => Some(UnitIntervalRecord( + interval.numerator as u64, + interval.denominator, + )), None => None, } - } - pub fn to_positive_interval_record(&self, interval: &PositiveInterval) - -> PositiveIntervalRecord { + pub fn to_positive_interval_record( + &self, + interval: &PositiveInterval, + ) -> PositiveIntervalRecord { PositiveIntervalRecord(interval.numerator as u64, interval.denominator) } @@ -436,17 +577,21 @@ impl EventWriter { } } - pub fn to_cost_models_record(&self, cost_models: &Option) -> Option { + pub fn to_cost_models_record( + &self, + cost_models: &Option, + ) -> Option { match cost_models { Some(cost_models) => { let mut cost_models_record = HashMap::new(); for cost_model_pair in cost_models.clone().to_vec() { - let language_version_record = self.to_language_version_record(&cost_model_pair.0); + let language_version_record = + self.to_language_version_record(&cost_model_pair.0); let cost_model_record = self.to_cost_model_record(cost_model_pair.1); cost_models_record.insert(language_version_record, cost_model_record); } Some(CostModelsRecord(cost_models_record)) - }, + } None => None, } } @@ -481,20 +626,49 @@ impl EventWriter { pub fn to_certificate_event(&self, certificate: &Certificate) -> EventData { let certificate_record = self.to_certificate_record(certificate); match certificate_record { - CertificateRecord::StakeRegistration(cert_record) => - EventData::StakeRegistration(cert_record), - CertificateRecord::StakeDeregistration(cert_record) => - EventData::StakeDeregistration(cert_record), - CertificateRecord::StakeDelegation(cert_record) => - EventData::StakeDelegation(cert_record), - CertificateRecord::PoolRegistration(cert_record) => - EventData::PoolRegistration(cert_record), - CertificateRecord::PoolRetirement(cert_record) => - EventData::PoolRetirement(cert_record), - CertificateRecord::MoveInstantaneousRewardsCert(cert_record) => - EventData::MoveInstantaneousRewardsCert(cert_record), - CertificateRecord::GenesisKeyDelegation(cert_record) => - EventData::GenesisKeyDelegation(cert_record), + CertificateRecord::StakeRegistration(cert_record) => { + EventData::StakeRegistration(cert_record) + } + CertificateRecord::StakeDeregistration(cert_record) => { + EventData::StakeDeregistration(cert_record) + } + CertificateRecord::StakeDelegation(cert_record) => { + EventData::StakeDelegation(cert_record) + } + CertificateRecord::PoolRegistration(cert_record) => { + EventData::PoolRegistration(cert_record) + } + CertificateRecord::PoolRetirement(cert_record) => { + EventData::PoolRetirement(cert_record) + } + CertificateRecord::MoveInstantaneousRewardsCert(cert_record) => { + EventData::MoveInstantaneousRewardsCert(cert_record) + } + CertificateRecord::GenesisKeyDelegation(cert_record) => { + EventData::GenesisKeyDelegation(cert_record) + } + CertificateRecord::RegCert(cert_record) => EventData::RegCert(cert_record), + CertificateRecord::UnRegCert(cert_record) => EventData::UnRegCert(cert_record), + CertificateRecord::VoteDeleg(cert_record) => EventData::VoteDeleg(cert_record), + CertificateRecord::StakeVoteDeleg(cert_record) => { + EventData::StakeVoteDeleg(cert_record) + } + CertificateRecord::StakeRegDeleg(cert_record) => EventData::StakeRegDeleg(cert_record), + CertificateRecord::VoteRegDeleg(cert_record) => EventData::VoteRegDeleg(cert_record), + CertificateRecord::StakeVoteRegDeleg(cert_record) => { + EventData::StakeVoteRegDeleg(cert_record) + } + CertificateRecord::AuthCommitteeHot(cert_record) => { + EventData::AuthCommitteeHot(cert_record) + } + CertificateRecord::ResignCommitteeCold(cert_record) => { + EventData::ResignCommitteeCold(cert_record) + } + CertificateRecord::RegDRepCert(cert_record) => EventData::RegDRepCert(cert_record), + CertificateRecord::UnRegDRepCert(cert_record) => EventData::UnRegDRepCert(cert_record), + CertificateRecord::UpdateDRepCert(cert_record) => { + EventData::UpdateDRepCert(cert_record) + } } } @@ -663,7 +837,10 @@ impl EventWriter { Ok(record) } - pub fn to_protocol_update_record(&self, update: &ProtocolParamUpdate) -> ProtocolParamUpdateRecord { + pub fn to_protocol_update_record( + &self, + update: &ProtocolParamUpdate, + ) -> ProtocolParamUpdateRecord { ProtocolParamUpdateRecord { minfee_a: update.minfee_a, minfee_b: update.minfee_b, @@ -674,18 +851,21 @@ impl EventWriter { pool_deposit: update.pool_deposit, maximum_epoch: update.maximum_epoch, desired_number_of_stake_pools: update.desired_number_of_stake_pools, - pool_pledge_influence: self.to_rational_number_record_option(&update.pool_pledge_influence), + pool_pledge_influence: self + .to_rational_number_record_option(&update.pool_pledge_influence), expansion_rate: self.to_unit_interval_record(&update.expansion_rate), treasury_growth_rate: self.to_unit_interval_record(&update.treasury_growth_rate), - decentralization_constant: self.to_unit_interval_record(&update.decentralization_constant), + decentralization_constant: self + .to_unit_interval_record(&update.decentralization_constant), extra_entropy: self.to_nonce_record(&update.extra_entropy), protocol_version: update.protocol_version, min_pool_cost: update.min_pool_cost, ada_per_utxo_byte: update.ada_per_utxo_byte, - cost_models_for_script_languages: self.to_cost_models_record(&update.cost_models_for_script_languages), + cost_models_for_script_languages: self + .to_cost_models_record(&update.cost_models_for_script_languages), execution_costs: match &update.execution_costs { Some(execution_costs) => Some(json!(execution_costs)), - None => None + None => None, }, max_tx_ex_units: self.to_ex_units_record(&update.max_tx_ex_units), max_block_ex_units: self.to_ex_units_record(&update.max_block_ex_units), @@ -701,7 +881,7 @@ impl EventWriter { updates.insert(update.0.to_hex(), self.to_protocol_update_record(&update.1)); } - UpdateRecord{ + UpdateRecord { proposed_protocol_parameter_updates: updates, epoch: update.epoch, } diff --git a/src/mapper/prelude.rs b/src/mapper/prelude.rs index 4564bb92..95cd7bf4 100644 --- a/src/mapper/prelude.rs +++ b/src/mapper/prelude.rs @@ -115,6 +115,7 @@ impl From for Era { pallas::ledger::traverse::Era::Mary => Era::Mary, pallas::ledger::traverse::Era::Alonzo => Era::Alonzo, pallas::ledger::traverse::Era::Babbage => Era::Babbage, + pallas::ledger::traverse::Era::Conway => Era::Babbage, _ => Era::Unknown, } } diff --git a/src/model.rs b/src/model.rs index 35b05064..9f96af7b 100644 --- a/src/model.rs +++ b/src/model.rs @@ -1,5 +1,5 @@ -use std::fmt::Display; use std::collections::HashMap; +use std::fmt::Display; use merge::Merge; @@ -226,6 +226,10 @@ pub enum ScriptRefRecord { script_hash: String, script_hex: String, }, + PlutusV3 { + script_hash: String, + script_hex: String, + }, NativeScript { policy_id: String, script_json: JsonValue, @@ -241,6 +245,18 @@ pub enum CertificateRecord { PoolRetirement(PoolRetirementRecord), GenesisKeyDelegation(GenesisKeyDelegationRecord), MoveInstantaneousRewardsCert(MoveInstantaneousRewardsCertRecord), + RegCert(RegCertRecord), + UnRegCert(UnRegCertRecord), + VoteDeleg(VoteDelegCertRecord), + StakeVoteDeleg(StakeVoteDelegCertRecord), + StakeRegDeleg(StakeRegDelegCertRecord), + VoteRegDeleg(VoteRegDelegCertRecord), + StakeVoteRegDeleg(StakeVoteRegDelegCertRecord), + AuthCommitteeHot(AuthCommitteeHotCertRecord), + ResignCommitteeCold(ResignCommitteeColdCertRecord), + RegDRepCert(RegDRepCertRecord), + UnRegDRepCert(UnRegDRepCertRecord), + UpdateDRepCert(UpdateDRepCertRecord), } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd)] @@ -286,6 +302,14 @@ pub struct GenesisKeyDelegationRecord { pub vrf_key_hash: String, } +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] +pub enum DRep { + KeyHash(String), + ScriptHash(String), + Abstain, + NoConfidence, +} + #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct MoveInstantaneousRewardsCertRecord { pub from_reserves: bool, @@ -294,9 +318,93 @@ pub struct MoveInstantaneousRewardsCertRecord { pub to_other_pot: Option, } +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] +pub struct RegCertRecord { + pub credential: StakeCredential, + pub coin: u64, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] +pub struct UnRegCertRecord { + pub credential: StakeCredential, + pub coin: u64, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] +pub struct VoteDelegCertRecord { + pub credential: StakeCredential, + pub drep: DRep, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] +pub struct StakeVoteDelegCertRecord { + pub credential: StakeCredential, + pub pool_keyhash: String, + pub drep: DRep, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] +pub struct StakeRegDelegCertRecord { + pub credential: StakeCredential, + pub pool_keyhash: String, + pub coin: u64, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] +pub struct VoteRegDelegCertRecord { + pub credential: StakeCredential, + pub drep: DRep, + pub coin: u64, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] +pub struct StakeVoteRegDelegCertRecord { + pub credential: StakeCredential, + pub pool_keyhash: String, + pub drep: DRep, + pub coin: u64, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] +pub struct AuthCommitteeHotCertRecord { + pub committee_cold_credential: StakeCredential, + pub committee_hot_credential: StakeCredential, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] +pub struct ResignCommitteeColdCertRecord { + pub committee_cold_credential: StakeCredential, + pub anchor: Option, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] +pub struct RegDRepCertRecord { + pub credential: StakeCredential, + pub coin: u64, + pub anchor: Option, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] +pub struct UnRegDRepCertRecord { + pub credential: StakeCredential, + pub coin: u64, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] +pub struct UpdateDRepCertRecord { + pub credential: StakeCredential, + pub anchor: Option, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] +pub struct AnchorRecord { + pub url: String, + pub data_hash: String, +} + #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct RationalNumberRecord { - pub numerator: i64, + pub numerator: u64, pub denominator: u64, } @@ -469,6 +577,19 @@ pub enum EventData { PoolRetirement(PoolRetirementRecord), GenesisKeyDelegation(GenesisKeyDelegationRecord), MoveInstantaneousRewardsCert(MoveInstantaneousRewardsCertRecord), + RegCert(RegCertRecord), + UnRegCert(UnRegCertRecord), + VoteDeleg(VoteDelegCertRecord), + StakeVoteDeleg(StakeVoteDelegCertRecord), + StakeRegDeleg(StakeRegDelegCertRecord), + VoteRegDeleg(VoteRegDelegCertRecord), + StakeVoteRegDeleg(StakeVoteRegDelegCertRecord), + AuthCommitteeHot(AuthCommitteeHotCertRecord), + ResignCommitteeCold(ResignCommitteeColdCertRecord), + RegDRepCert(RegDRepCertRecord), + UnRegDRepCert(UnRegDRepCertRecord), + UpdateDRepCert(UpdateDRepCertRecord), + RollBack { block_slot: u64, block_hash: String, diff --git a/src/sinks/aws_s3/run.rs b/src/sinks/aws_s3/run.rs index 40af7cac..bc7b99f8 100644 --- a/src/sinks/aws_s3/run.rs +++ b/src/sinks/aws_s3/run.rs @@ -1,6 +1,6 @@ use aws_sdk_s3::{types::ByteStream, Client}; -use std::sync::Arc; use serde_json::json; +use std::sync::Arc; use crate::{ model::{BlockRecord, EventData}, @@ -45,7 +45,7 @@ fn define_obj_key(prefix: &str, policy: &Naming, record: &BlockRecord) -> String Naming::Hash => format!("{}{}", prefix, record.hash), Naming::SlotHash => format!("{}{}.{}", prefix, record.slot, record.hash), Naming::BlockHash => format!("{}{}.{}", prefix, record.number, record.hash), - Naming::BlockNumber => format!( "{}", record.number), + Naming::BlockNumber => format!("{}", record.number), Naming::EpochHash => format!( "{}{}.{}", prefix, diff --git a/src/sinks/terminal/format.rs b/src/sinks/terminal/format.rs index 2b4bd283..5f2766cd 100644 --- a/src/sinks/terminal/format.rs +++ b/src/sinks/terminal/format.rs @@ -272,6 +272,90 @@ impl LogLine { "{{ reserves: {0}, treasury: {1}, to_credentials: {2:?}, to_other_pot: {3:?} }}", cert.from_reserves, cert.from_treasury, cert.to_stake_credentials, cert.to_other_pot), ), + EventData::RegCert(cert) => LogLine::new_raw( + source, + "REG", + Color::Magenta, + max_width, + format!("{0:?}", serde_json::to_string(&cert).unwrap()), + ), + EventData::UnRegCert(cert) => LogLine::new_raw( + source, + "UNREG", + Color::DarkMagenta, + max_width, + format!("{0:?}", serde_json::to_string(&cert).unwrap()), + ), + EventData::VoteDeleg(cert) => LogLine::new_raw( + source, + "VOTE", + Color::Magenta, + max_width, + format!("{0:?}", serde_json::to_string(&cert).unwrap()), + ), + EventData::StakeVoteDeleg(cert) => LogLine::new_raw( + source, + "STAKEVOTE", + Color::Magenta, + max_width, + format!("{0:?}", serde_json::to_string(&cert).unwrap()), + ), + EventData::StakeRegDeleg(cert) => LogLine::new_raw( + source, + "STAKEREG", + Color::Magenta, + max_width, + format!("{0:?}", serde_json::to_string(&cert).unwrap()), + ), + EventData::VoteRegDeleg(cert) => LogLine::new_raw( + source, + "VOTEREG", + Color::Magenta, + max_width, + format!("{0:?}", serde_json::to_string(&cert).unwrap()), + ), + EventData::StakeVoteRegDeleg(cert) => LogLine::new_raw( + source, + "STAKEVOTEREG", + Color::Magenta, + max_width, + format!("{0:?}", serde_json::to_string(&cert).unwrap()), + ), + EventData::AuthCommitteeHot(cert) => LogLine::new_raw( + source, + "AUTHHOT", + Color::Magenta, + max_width, + format!("{0:?}", serde_json::to_string(&cert).unwrap()), + ), + EventData::ResignCommitteeCold(cert) => LogLine::new_raw( + source, + "RESIGNCOLD", + Color::DarkMagenta, + max_width, + format!("{0:?}", serde_json::to_string(&cert).unwrap()), + ), + EventData::RegDRepCert(cert) => LogLine::new_raw( + source, + "REGDREP", + Color::Magenta, + max_width, + format!("{0:?}", serde_json::to_string(&cert).unwrap()), + ), + EventData::UnRegDRepCert(cert) => LogLine::new_raw( + source, + "UNREGDREP", + Color::DarkMagenta, + max_width, + format!("{0:?}", serde_json::to_string(&cert).unwrap()), + ), + EventData::UpdateDRepCert(cert) => LogLine::new_raw( + source, + "UPDATEDREP", + Color::Magenta, + max_width, + format!("{0:?}", serde_json::to_string(&cert).unwrap()), + ), EventData::RollBack { block_slot, block_hash, diff --git a/src/sources/common.rs b/src/sources/common.rs index 4687561e..2640b48a 100644 --- a/src/sources/common.rs +++ b/src/sources/common.rs @@ -19,7 +19,7 @@ use crate::{ }; // TODO: these should come from Pallas -use crate::utils::{PREPROD_MAGIC, PREVIEW_MAGIC}; +use crate::utils::{PREPROD_MAGIC, PREVIEW_MAGIC, SANCHO_MAGIC}; #[derive(Debug, Deserialize, Clone)] pub enum BearerKind { @@ -98,6 +98,7 @@ impl FromStr for MagicArg { "mainnet" => MagicArg(MAINNET_MAGIC), "preview" => MagicArg(PREVIEW_MAGIC), "preprod" => MagicArg(PREPROD_MAGIC), + "sancho" => MagicArg(SANCHO_MAGIC), _ => MagicArg(u64::from_str(s).map_err(|_| "can't parse magic value")?), }; @@ -352,6 +353,11 @@ pub fn unknown_block_to_events(writer: &EventWriter, body: &Vec) -> Result<( .crawl_from_babbage_cbor(body) .ok_or_warn("error crawling babbage block for events"); } + Era::Conway => { + writer + .crawl_from_babbage_cbor(body) + .ok_or_warn("error crawling conway block for events"); + } x => { return Err(format!("This version of Oura can't handle era: {x}").into()); } diff --git a/src/sources/n2n/run.rs b/src/sources/n2n/run.rs index a3956d8e..dfff62ac 100644 --- a/src/sources/n2n/run.rs +++ b/src/sources/n2n/run.rs @@ -5,6 +5,7 @@ use pallas::network::{ multiplexer::StdChannel, }; +use pallas::network::miniprotocols::handshake::n2n::VersionData; use std::sync::mpsc::{Receiver, SyncSender}; use crate::{ diff --git a/src/utils/mod.rs b/src/utils/mod.rs index fe841b7f..3c0ff57c 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -13,6 +13,8 @@ use pallas::network::miniprotocols::{Point, MAINNET_MAGIC, TESTNET_MAGIC}; pub const PREPROD_MAGIC: u64 = 1; pub const PREVIEW_MAGIC: u64 = 2; +pub const SANCHO_MAGIC: u64 = 4; + use serde::{Deserialize, Serialize}; use crate::{model::Event, utils::time::NaiveProvider as NaiveTime}; @@ -144,6 +146,24 @@ impl ChainWellKnownInfo { adahandle_policy: "".to_string(), } } + pub fn sancho() -> Self { + ChainWellKnownInfo { + byron_epoch_length: 432000, + byron_slot_length: 20, + byron_known_slot: 0, + byron_known_hash: "9ad7ff320c9cf74e0f5ee78d22a85ce42bb0a487d0506bf60cfb5a91ea4497d2" + .to_string(), + byron_known_time: 1654041600, + shelley_epoch_length: 432000, + shelley_slot_length: 1, + shelley_known_slot: 86400, + shelley_known_hash: "c971bfb21d2732457f9febf79d9b02b20b9a3bef12c561a78b818bcb8b35a574" + .to_string(), + shelley_known_time: 1655769600, + address_hrp: "addr_test".to_string(), + adahandle_policy: "".to_string(), + } + } /// Try to identify the chain based on the specified magic value. pub fn try_from_magic(magic: u64) -> Result { @@ -152,6 +172,7 @@ impl ChainWellKnownInfo { TESTNET_MAGIC => Ok(Self::testnet()), PREVIEW_MAGIC => Ok(Self::preview()), PREPROD_MAGIC => Ok(Self::preprod()), + SANCHO_MAGIC => Ok(Self::sancho()), _ => Err(format!("can't identify chain from specified magic value: {magic}").into()), } }