diff --git a/Cargo.toml b/Cargo.toml index 58bf781a..520c022b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ authors = ["Santiago Carmuega "] [dependencies] -pallas = "0.18.0" +pallas = { git = "https://github.com/lisicky/pallas", branch = "hotfix/v0.18" } # pallas = { git = "https://github.com/txpipe/pallas" } # pallas = { path = "../pallas/pallas" } hex = "0.4.3" 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/mapper/map.rs b/src/mapper/map.rs index 17157a52..dc92af7d 100644 --- a/src/mapper/map.rs +++ b/src/mapper/map.rs @@ -17,11 +17,11 @@ 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, UnitIntervalRecord, UnRegCertRecord, UnRegDRepCertRecord, UpdateDRepCertRecord, UpdateRecord, VKeyWitnessRecord, VoteDelegCertRecord, VoteRegDelegCertRecord}; use crate::utils::time::TimeProvider; use crate::Error; -use crate::model::ScriptRefRecord::{NativeScript, PlutusV1, PlutusV2}; +use crate::model::ScriptRefRecord::{NativeScript, PlutusV1, PlutusV2, PlutusV3}; use super::EventWriter; @@ -56,6 +56,34 @@ 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]) } @@ -312,6 +340,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(), @@ -395,6 +427,83 @@ impl EventWriter { 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) => CertificateRecord::ResignCommitteeCold( + ResignCommitteeColdCertRecord { + committee_cold_credential: cold.into(), + } + ), + 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), + } + ), } } @@ -495,6 +604,30 @@ impl EventWriter { 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), } } diff --git a/src/model.rs b/src/model.rs index 35b05064..1b628104 100644 --- a/src/model.rs +++ b/src/model.rs @@ -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,19 @@ 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 +303,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 +319,92 @@ 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, +} + +#[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/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..ee7db1c8 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")?), }; 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()), } }