Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
dba341c
feat(rust): add cardano-blockchain-types crate
stevenj Dec 17, 2024
f3871a8
fix(rust): Remove unused dependencies
stevenj Dec 17, 2024
23a5138
fix(cardano-blockchain-types): time_to_slot calculation
bkioshn Dec 17, 2024
0662020
fix(cardano-blockchain-types): remove justfile
bkioshn Dec 17, 2024
c9185b5
Merge branch 'main' into feat/cardano-blockchain-types
bkioshn Dec 17, 2024
aa6bd36
fix(cardano-blockchain-types): point new should take type Slot and Bl…
bkioshn Dec 17, 2024
e027d8b
fix(cardano-blockchain-types): Fork type
bkioshn Dec 17, 2024
7efac20
fix(cardano-blockchain-types): point and fuzzy point test
bkioshn Dec 17, 2024
8ddebf5
Merge branch 'main' into feat/cardano-blockchain-types
stevenj Dec 17, 2024
1d600bd
fix(cardano-blockchain-types): add Fork increment function
bkioshn Dec 18, 2024
bfc2e15
fix(cardano-blockchain-types): add comment on tag 259
bkioshn Dec 18, 2024
d48e32b
fix(cardano-blockchain-types): add Fork decrement function
bkioshn Dec 18, 2024
349642c
test(rust): try earthly no-cache
bkioshn Dec 18, 2024
8583611
test(rust): try earthly no-cache and fix doc artifact
bkioshn Dec 18, 2024
42f71d7
test(rust): remove no-cache
bkioshn Dec 18, 2024
c267593
fix(cardano-blockchain-types): expose Fork and Network
bkioshn Dec 18, 2024
5eb13da
Merge branch 'main' into feat/cardano-blockchain-types
bkioshn Dec 18, 2024
c80fa33
fix(cardano-blockchain-types): add partailOrd to Fork
bkioshn Dec 18, 2024
0b0152d
Update rust/cardano-blockchain-types/src/point.rs
stevenj Dec 19, 2024
347045a
fix(cardano-blockchain-types): cleanup
bkioshn Dec 19, 2024
8d04f53
fix(cardano-blockchain-types): testdoc
bkioshn Dec 19, 2024
e48399a
Update rust/cardano-blockchain-types/src/point.rs
stevenj Dec 19, 2024
d17adf7
Merge branch 'main' into feat/cardano-blockchain-types
bkioshn Dec 19, 2024
48ca937
fix(cardano-blockchain-types): cleanup
bkioshn Dec 20, 2024
60802ce
fix(cardano-blockchain-types): format
bkioshn Dec 20, 2024
ea19d3e
fix(cardano-blockchain-types): add validate PR title
bkioshn Dec 20, 2024
4e2bdc6
fix(cardano-blockchain-types): comments
bkioshn Dec 20, 2024
519c415
fix(cardano-blockchain-types): fix hash_or_default
bkioshn Dec 20, 2024
e9b8ee3
fix(cardano-blockchain-types): redundant code
bkioshn Dec 20, 2024
0d964fd
test: no cache
bkioshn Dec 20, 2024
b553132
test: revert change
bkioshn Dec 20, 2024
881f07c
test ci
bkioshn Dec 23, 2024
be14a11
test ci
bkioshn Dec 23, 2024
c68a4a5
test ci
bkioshn Dec 23, 2024
b082ccc
test ci
bkioshn Dec 23, 2024
e5a1c53
test ci
bkioshn Dec 23, 2024
02cea97
test ci
bkioshn Dec 23, 2024
87b7aa7
test ci
bkioshn Dec 23, 2024
5150b0c
test ci
bkioshn Dec 23, 2024
7b51b80
test ci
bkioshn Dec 23, 2024
1ccf814
test ci
bkioshn Dec 23, 2024
6178014
revert change
bkioshn Dec 23, 2024
4291806
test ci
bkioshn Dec 23, 2024
fe48d5a
revert change
bkioshn Dec 23, 2024
aed622e
Merge branch 'main' into feat/cardano-blockchain-types
bkioshn Dec 27, 2024
a4e8ecd
fix(rust): Bump rust version, and test everything using that version.
stevenj Jan 2, 2025
58b5f7a
feat(rust): Bump more dependencies
stevenj Jan 2, 2025
0f13a52
fix(rust): Use latest cat-ci release for latest rust compiler
stevenj Jan 2, 2025
434bd83
fix(rust): skip building the c509 crate as rust
stevenj Jan 2, 2025
a259fc1
fix(rust): Fix bad character in the file
stevenj Jan 2, 2025
e6e3759
fix(rust): Remove redundant Earthfile
stevenj Jan 2, 2025
f8408dc
fix(rust): Reduce runtime of excessively slow property tests
stevenj Jan 3, 2025
381f970
fix(rust): test serialized doctests in ci
stevenj Jan 3, 2025
e3e2e98
fix(rust): Try and fix broken test reports after cat-ci upgraded to f…
stevenj Jan 3, 2025
0ac183d
fix(rust): Disable code coverage in CI because its broken after cat-c…
stevenj Jan 3, 2025
4adadb3
fix(rust): Try and fix CI being totally broken now that allure report…
stevenj Jan 3, 2025
a61c87c
fix(rust): Use released cat-ci version
stevenj Jan 3, 2025
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
1 change: 1 addition & 0 deletions .config/dictionaries/project.dic
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Arissara
asyncio
Attributes
auditability
auxdata
babystep
backpressure
bech
Expand Down
1 change: 1 addition & 0 deletions rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
resolver = "2"
members = [
"c509-certificate",
"cardano-blockchain-types",
"cardano-chain-follower",
"hermes-ipfs",
"cbork",
Expand Down
3 changes: 2 additions & 1 deletion rust/Earthfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ COPY_SRC:
Cargo.toml clippy.toml deny.toml rustfmt.toml \
.cargo .config \
c509-certificate \
cardano-blockchain-types \
cardano-chain-follower \
catalyst-voting vote-tx-v1 vote-tx-v2 \
cbork cbork-abnf-parser cbork-cddl-parser \
Expand Down Expand Up @@ -53,7 +54,7 @@ build:

DO rust-ci+EXECUTE \
--cmd="/scripts/std_build.py" \
--args1="--libs=c509-certificate --libs=cardano-chain-follower --libs=hermes-ipfs" \
--args1="--libs=c509-certificate --libs=cardano-blockchain-types --libs=cardano-chain-follower --libs=hermes-ipfs" \
--args2="--libs=cbork-cddl-parser --libs=cbork-abnf-parser" \
--args3="--libs=catalyst-voting --libs=vote-tx-v1 --libs=vote-tx-v2" \
--args4="--bins=cbork/cbork --libs=rbac-registration --libs=signed_doc" \
Expand Down
36 changes: 36 additions & 0 deletions rust/cardano-blockchain-types/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
[package]
name = "cardano-blockchain-types"
description = "Common Cardano Blockchain data types for use in both applications and crates"
keywords = ["cardano", "catalyst",]
version = "0.0.1"
authors = [
"Steven Johnson <[email protected]>"
]
edition.workspace = true
license.workspace = true
homepage.workspace = true
repository.workspace = true

[lib]
crate-type = ["cdylib", "rlib"]

[lints]
workspace = true

[dependencies]
pallas = { version = "0.30.1", git = "https://github.com/input-output-hk/catalyst-pallas.git", rev = "9b5183c8b90b90fe2cc319d986e933e9518957b3" }
pallas-crypto = { version = "0.30.1", git = "https://github.com/input-output-hk/catalyst-pallas.git", rev = "9b5183c8b90b90fe2cc319d986e933e9518957b3" }
# pallas-hardano = { version = "0.30.1", git = "https://github.com/input-output-hk/catalyst-pallas.git", rev = "9b5183c8b90b90fe2cc319d986e933e9518957b3" }

ouroboros = "0.18.4"
tracing = "0.1.41"
anyhow = "1.0.94"
chrono = "0.4.39"
strum = { version = "0.26.3", features = ["derive"] }
dirs = "5.0.1"
hex = "0.4.3"
dashmap = "6.1.0"
blake2b_simd = "1.0.2"
minicbor = { version = "0.25.1", features = ["alloc"] }
num-traits = "0.2.19"
ed25519-dalek = "2.1.1"
6 changes: 6 additions & 0 deletions rust/cardano-blockchain-types/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Improved version of Pallas Multi Era Block

Adds features to the Pallas Multi Era Block to allow us to re-use it between the different cardano crates,
and the services that use them.

The original source was `cardano-chain-follower`.
62 changes: 62 additions & 0 deletions rust/cardano-blockchain-types/deps.tmp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@

rbac-registration = { version = "0.0.2", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "v0.0.8" }

thiserror = "1.0.64"
tokio = { version = "1.40.0", features = [
"macros",
"rt",
"net",
"rt-multi-thread",
] }
tracing = "0.1.40"
tracing-log = "0.2.0"
dashmap = "6.1.0"
url = "2.5.2"
anyhow = "1.0.89"
chrono = "0.4.38"
async-trait = "0.1.83"
dirs = "5.0.1"
futures = "0.3.31"
humantime = "2.1.0"
crossbeam-skiplist = "0.1.3"
crossbeam-channel = "0.5.13"
crossbeam-epoch = "0.9.18"
strum = "0.26.3"
ouroboros = "0.18.4"
hex = "0.4.3"
rayon = "1.10.0"
serde = "1.0.210"
serde_json = "1.0.128"
mimalloc = { version = "0.1.43", optional = true }
memx = "0.1.32"
fmmap = { version = "0.3.3", features = ["sync", "tokio-async"] }
minicbor = { version = "0.25.1", features = ["alloc", "derive", "half"] }
zstd = "0.13.2"
ed25519-dalek = "2.1.1"
blake2b_simd = "1.0.2"
num-traits = "0.2.19"
logcall = "0.1.9"
tar = "0.4.42"
ureq = { version = "2.10.1", features = ["native-certs"] }
http = "1.1.0"
hickory-resolver = { version = "0.24.1", features = ["dns-over-rustls"] }
moka = { version = "0.12.8", features = ["sync"] }

hex = "0.4.3"
anyhow = "1.0.89"
strum_macros = "0.26.4"
regex = "1.11.0"
minicbor = { version = "0.25.1", features = ["alloc", "derive", "half"] }
brotli = "7.0.0"
zstd = "0.13.2"
x509-cert = "0.2.5"
der-parser = "9.0.0"
bech32 = "0.11.0"
dashmap = "6.1.0"
blake2b_simd = "1.0.2"
tracing = "0.1.40"
ed25519-dalek = "2.1.1"
uuid = "1.11.0"

c509-certificate = { version = "0.0.3", git = "https://github.com/input-output-hk/catalyst-libs.git" , tag = "v0.0.3" }
pallas = { version = "0.30.1", git = "https://github.com/input-output-hk/catalyst-pallas.git", rev = "9b5183c8b90b90fe2cc319d986e933e9518957b3" }
170 changes: 170 additions & 0 deletions rust/cardano-blockchain-types/src/auxdata/aux_data.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
//! Auxiliary Data Decoding

use minicbor::Decode;

use super::{
metadatum::Metadata,
metadatum_label::MetadatumLabel,
metadatum_value::MetadatumValue,
scripts::{MutableTransactionScriptsMap, ScriptArray, ScriptType, TransactionScripts},
};

/// Auxiliary Data (Metadata) for a single Transaction in a block
#[derive(Clone, Debug)]
#[allow(clippy::module_name_repetitions)]
pub struct TransactionAuxData {
/// Metadata attached to a transaction
metadata: Metadata,
/// Scripts attached to a transaction
#[allow(dead_code)]
scripts: TransactionScripts,
}

impl Decode<'_, ()> for TransactionAuxData {
fn decode(
d: &mut minicbor::Decoder<'_>, _ctx: &mut (),
) -> Result<Self, minicbor::decode::Error> {
// Check what kind of aux data we have to deal with
match d.datatype() {
// Shelley: https://github.com/IntersectMBO/cardano-ledger/blob/78b32d585fd4a0340fb2b184959fb0d46f32c8d2/eras/conway/impl/cddl-files/conway.cddl#L522
Ok(minicbor::data::Type::Map) => {
Ok(TransactionAuxData {
metadata: Metadata::decode(d, &mut ())?,
scripts: TransactionScripts::default(),
})
},
// Shelley-MA: https://github.com/IntersectMBO/cardano-ledger/blob/78b32d585fd4a0340fb2b184959fb0d46f32c8d2/eras/conway/impl/cddl-files/conway.cddl#L523
Ok(minicbor::data::Type::Array) => Self::decode_shelley_ma_array(d),
// Maybe Alonzo and beyond: https://github.com/IntersectMBO/cardano-ledger/blob/78b32d585fd4a0340fb2b184959fb0d46f32c8d2/eras/conway/impl/cddl-files/conway.cddl#L526
Ok(minicbor::data::Type::Tag) => Self::decode_alonzo_plus_map(d),
Ok(unexpected) => {
let msg = format!(
"Error decoding Transaction Aux Data: Unexpected datatype {unexpected}"
);
Err(minicbor::decode::Error::message(&msg))
},
Err(error) => {
let msg = format!("Error decoding Transaction Aux Data: {error}");
Err(minicbor::decode::Error::message(msg))
},
}
}
}

impl TransactionAuxData {
/// Get metadata with the given label.
#[must_use]
pub fn metadata(&self, label: MetadatumLabel) -> Option<&MetadatumValue> {
self.metadata.get(label)
}

/// Decode a Shelley-MA Auxiliary Data Array
fn decode_shelley_ma_array(d: &mut minicbor::Decoder) -> Result<Self, minicbor::decode::Error> {
match d.array() {
Ok(Some(entries)) => {
if entries != 2 {
let msg = format!(
"Error decoding Transaction Aux Data: Script Data Array Expected 2 entries, found {entries}."
);
return Err(minicbor::decode::Error::message(&msg));
}
},
Ok(None) => {
return Err(minicbor::decode::Error::message(
"Error decoding Transaction Aux Data: Indefinite Array found decoding Metadata. Invalid."));
},
Err(error) => {
return Err(minicbor::decode::Error::message(format!(
"Error decoding Transaction Aux Data: {error}."
)));
},
};

let metadata = Metadata::decode(d, &mut ())?;
let script_array = ScriptArray::decode(d, &mut ScriptType::Native)?;

let scripts = MutableTransactionScriptsMap::default();
scripts.insert(ScriptType::Native, script_array);

Ok(Self {
metadata,
scripts: scripts.into(),
})
}

/// Decode an Alonzo Plus MAP
fn decode_alonzo_plus_map(d: &mut minicbor::Decoder) -> Result<Self, minicbor::decode::Error> {
match d.tag() {
Ok(tag) => {
if tag.as_u64() != 259 {
return Err(minicbor::decode::Error::message(format!(
"Invalid tag for Alonzo+ Aux Data. Expected 259, found {tag}."
)));
}
},
Err(error) => {
return Err(minicbor::decode::Error::message(format!(
"Error decoding Transaction Alonzo+ Aux Data: {error}."
)));
},
}

let entries = match d.map() {
Ok(Some(entries)) => entries,
Ok(None) => {
return Err(minicbor::decode::Error::message(
"Indefinite Map found decoding Alonzo+ Metadata. Invalid.",
))
},
Err(error) => {
return Err(minicbor::decode::Error::message(format!(
"Error decoding Transaction Alonzo+ Aux Data: {error}."
)))
},
};

// Make the default versions of the metadata and script types
let mut metadata = Metadata::default();
let scripts = MutableTransactionScriptsMap::default();

// iterate the map
for _ in 0..entries {
let script_type = match d.u64() {
Ok(key) => {
if let Ok(script_type) = ScriptType::try_from(key) {
script_type
} else {
// Only fails if its Metadata and not a script.
if metadata.is_empty() {
metadata = Metadata::decode(d, &mut ())?;
continue;
}
return Err(minicbor::decode::Error::message(
"Multiple Alonzo+ Metadata entries found. Invalid.",
));
}
},

Err(error) => {
return Err(minicbor::decode::Error::message(format!(
"Error decoding Alonzo+ Metadata Aux Data Type Key: {error}"
)));
},
};

let mut ctx = script_type;

let script_array = ScriptArray::decode(d, &mut ctx)?;
if scripts.insert(script_type, script_array).is_some() {
return Err(minicbor::decode::Error::message(
"Multiple Alonzo+ Script entries of type {script_type} found. Invalid.",
));
}
}

Ok(Self {
metadata,
scripts: scripts.into(),
})
}
}
68 changes: 68 additions & 0 deletions rust/cardano-blockchain-types/src/auxdata/block.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
//! Decoded Metadata for a Block

use std::sync::Arc;

use anyhow::bail;
use dashmap::DashMap;
use pallas::ledger::traverse::MultiEraBlock;

use super::aux_data::TransactionAuxData;
use crate::txn_index::TxnIndex;

/// Auxiliary Data for every transaction within a block.
#[derive(Debug)]
#[allow(clippy::module_name_repetitions)]
pub struct BlockAuxData(Arc<dashmap::ReadOnlyView<TxnIndex, TransactionAuxData>>);

impl BlockAuxData {
/// Get `TransactionAuxData` for the given `TxnIndex` if any.
#[must_use]
pub fn get(&self, txn_idx: TxnIndex) -> Option<&TransactionAuxData> {
self.0.get(&txn_idx)
}
}

impl Default for BlockAuxData {
fn default() -> Self {
BlockAuxData(Arc::new(DashMap::default().into_read_only()))
}
}

impl TryFrom<&MultiEraBlock<'_>> for BlockAuxData {
type Error = anyhow::Error;

fn try_from(block: &MultiEraBlock) -> Result<Self, Self::Error> {
let aux_data = DashMap::<TxnIndex, TransactionAuxData>::new();
// Note, while this code looks redundant, it is not because all the types are not
// compatible Even though they have similar names, and ultimately the same inner
// functionality. This means we need to distinctly encode the three different
// loops with the same code.
if block.has_aux_data() {
if let Some(_metadata) = block.as_byron() {
// Nothing to do here.
} else if let Some(alonzo_block) = block.as_alonzo() {
for (txn_idx, metadata) in alonzo_block.auxiliary_data_set.iter() {
let mut d = minicbor::Decoder::new(metadata.raw_cbor());
let txn_aux_data = d.decode::<TransactionAuxData>()?;
aux_data.insert(TxnIndex::from_saturating(*txn_idx), txn_aux_data);
}
} else if let Some(babbage_block) = block.as_babbage() {
for (txn_idx, metadata) in babbage_block.auxiliary_data_set.iter() {
let mut d = minicbor::Decoder::new(metadata.raw_cbor());
let txn_aux_data = d.decode::<TransactionAuxData>()?;
aux_data.insert(TxnIndex::from_saturating(*txn_idx), txn_aux_data);
}
} else if let Some(conway_block) = block.as_conway() {
for (txn_idx, metadata) in conway_block.auxiliary_data_set.iter() {
let mut d = minicbor::Decoder::new(metadata.raw_cbor());
let txn_aux_data = d.decode::<TransactionAuxData>()?;
aux_data.insert(TxnIndex::from_saturating(*txn_idx), txn_aux_data);
}
} else {
bail!("Undecodable metadata, unknown Era");
};
}

Ok(Self(Arc::new(aux_data.into_read_only())))
}
}
Loading
Loading