Skip to content
Open
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
7 changes: 7 additions & 0 deletions crates/cardano/src/indexes/delta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,13 @@ impl CardanoIndexDeltaBuilder {
.push(Tag::new(archive::SPENT_TXO, bytes));
}

/// Add a script hash to the current block.
pub fn add_script_hash(&mut self, hash: Vec<u8>) {
self.current_block()
.tags
.push(Tag::new(archive::SCRIPT, hash));
}

/// Add certificate tags to the current block.
pub fn add_cert(&mut self, cert: &MultiEraCert) {
if let Some(cred) = pallas_extras::cert_as_stake_registration(cert) {
Expand Down
2 changes: 1 addition & 1 deletion crates/cardano/src/indexes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ mod query;
pub use delta::{index_delta_from_utxo_delta, CardanoIndexDeltaBuilder};
pub use dimensions::{archive as archive_dimensions, utxo as utxo_dimensions};
pub use ext::CardanoIndexExt;
pub use query::{AsyncCardanoQueryExt, SlotOrder};
pub use query::{AsyncCardanoQueryExt, ScriptData, ScriptLanguage, SlotOrder};
125 changes: 124 additions & 1 deletion crates/cardano/src/indexes/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
use pallas::{
crypto::hash::Hash,
ledger::{
primitives::conway::{DatumOption, PlutusData},
primitives::conway::{DatumOption, PlutusData, ScriptRef},
traverse::{ComputeHash, MultiEraBlock, OriginalHash},
},
};
Expand All @@ -28,6 +28,20 @@ pub enum SlotOrder {
Desc,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ScriptLanguage {
Native,
PlutusV1,
PlutusV2,
PlutusV3,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ScriptData {
pub language: ScriptLanguage,
pub script: Vec<u8>,
}

#[async_trait::async_trait]
pub trait AsyncCardanoQueryExt<D: Domain> {
fn blocks_by_address_stream(
Expand Down Expand Up @@ -124,6 +138,11 @@ pub trait AsyncCardanoQueryExt<D: Domain> {

async fn get_datum(&self, datum_hash: &Hash<32>) -> Result<Option<Vec<u8>>, DomainError>;

async fn script_by_hash(
&self,
script_hash: &Hash<28>,
) -> Result<Option<ScriptData>, DomainError>;

async fn tx_by_spent_txo(&self, spent_txo: &[u8]) -> Result<Option<TxHash>, DomainError>;
}

Expand Down Expand Up @@ -356,6 +375,110 @@ where
.await
}

async fn script_by_hash(
&self,
script_hash: &Hash<28>,
) -> Result<Option<ScriptData>, DomainError> {
let end_slot = self
.run_blocking(move |domain| {
Ok(domain
.archive()
.get_tip()?
.map(|(slot, _)| slot)
.unwrap_or_default())
})
.await?;

let script_hash = *script_hash;
find_first_by_tag(
self,
archive::SCRIPT,
script_hash.as_slice().to_vec(),
0,
end_slot,
|block| {
for tx in block.txs() {
for script in tx.native_scripts() {
if script.original_hash() == script_hash {
return Some(ScriptData {
language: ScriptLanguage::Native,
script: script.raw_cbor().to_vec(),
});
}
}

for script in tx.plutus_v1_scripts() {
if script.compute_hash() == script_hash {
return Some(ScriptData {
language: ScriptLanguage::PlutusV1,
script: script.as_ref().to_vec(),
});
}
}

for script in tx.plutus_v2_scripts() {
if script.compute_hash() == script_hash {
return Some(ScriptData {
language: ScriptLanguage::PlutusV2,
script: script.as_ref().to_vec(),
});
}
}

for script in tx.plutus_v3_scripts() {
if script.compute_hash() == script_hash {
return Some(ScriptData {
language: ScriptLanguage::PlutusV3,
script: script.as_ref().to_vec(),
});
}
}

for (_, output) in tx.produces() {
if let Some(script_ref) = output.script_ref() {
match script_ref {
ScriptRef::NativeScript(script) => {
if script.original_hash() == script_hash {
return Some(ScriptData {
language: ScriptLanguage::Native,
script: script.raw_cbor().to_vec(),
});
}
}
ScriptRef::PlutusV1Script(script) => {
if script.compute_hash() == script_hash {
return Some(ScriptData {
language: ScriptLanguage::PlutusV1,
script: script.as_ref().to_vec(),
});
}
}
ScriptRef::PlutusV2Script(script) => {
if script.compute_hash() == script_hash {
return Some(ScriptData {
language: ScriptLanguage::PlutusV2,
script: script.as_ref().to_vec(),
});
}
}
ScriptRef::PlutusV3Script(script) => {
if script.compute_hash() == script_hash {
return Some(ScriptData {
language: ScriptLanguage::PlutusV3,
script: script.as_ref().to_vec(),
});
}
}
}
}
}
}
None
},
)
.await
}

async fn tx_by_spent_txo(&self, spent_txo: &[u8]) -> Result<Option<TxHash>, DomainError> {
let spent = spent_txo.to_vec();

Expand Down
39 changes: 37 additions & 2 deletions crates/cardano/src/roll/batch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ use dolos_core::{
NsKey, RawBlock, RawUtxoMap, StateError, StateStore as _, StateWriter as _, TxoRef,
UtxoSetDelta, WalStore as _,
};
use pallas::ledger::{
primitives::conway::ScriptRef,
traverse::{ComputeHash as _, OriginalHash as _},
};

use crate::indexes::CardanoIndexDeltaBuilder;
use crate::{CardanoDelta, CardanoEntity, CardanoLogic, OwnedMultiEraBlock, OwnedMultiEraOutput};
Expand Down Expand Up @@ -396,11 +400,43 @@ impl WorkBatch {
if let Some(datum) = output.datum() {
builder.add_datum(&datum);
}

if let Some(script_ref) = output.script_ref() {
match script_ref {
ScriptRef::NativeScript(script) => {
builder.add_script_hash(script.original_hash().to_vec());
}
ScriptRef::PlutusV1Script(script) => {
builder.add_script_hash(script.compute_hash().to_vec());
}
ScriptRef::PlutusV2Script(script) => {
builder.add_script_hash(script.compute_hash().to_vec());
}
ScriptRef::PlutusV3Script(script) => {
builder.add_script_hash(script.compute_hash().to_vec());
}
}
}
}

// Witness scripts
{
for script in tx.native_scripts() {
builder.add_script_hash(script.original_hash().to_vec());
}
for script in tx.plutus_v1_scripts() {
builder.add_script_hash(script.compute_hash().to_vec());
}
for script in tx.plutus_v2_scripts() {
builder.add_script_hash(script.compute_hash().to_vec());
}
for script in tx.plutus_v3_scripts() {
builder.add_script_hash(script.compute_hash().to_vec());
}
}

// Witness datums
for datum in tx.plutus_data() {
use pallas::ledger::traverse::OriginalHash;
builder.add_datum_hash(datum.original_hash().to_vec());
}

Expand All @@ -411,7 +447,6 @@ impl WorkBatch {

// Redeemers
for redeemer in tx.redeemers() {
use pallas::ledger::traverse::ComputeHash;
builder.add_datum_hash(redeemer.data().compute_hash().to_vec());
}
}
Expand Down
Loading