Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
750ff58
feat: first pass at a chain store
SupernaviX Sep 2, 2025
49d0888
feat: wire block queries up to API
SupernaviX Sep 3, 2025
3bacc44
feat: store block cbor
SupernaviX Sep 4, 2025
ce3a99b
feat: add BlockInfo fields
SupernaviX Sep 5, 2025
f895149
feat: populate remaining BlockInfo fields
SupernaviX Sep 5, 2025
62cba55
feat: support getting blocks by epoch+slot
SupernaviX Sep 5, 2025
704ad6a
feat: support getting next and previous blocks
SupernaviX Sep 5, 2025
1e9f1a1
feat: return transactions and transactions cbor
SupernaviX Sep 5, 2025
2c21d6b
feat: accept hash or number in state query
SupernaviX Sep 5, 2025
f0183fe
Add blocks/latest blockfrost REST endpoint
alexwoods Sep 10, 2025
642e0fa
Implement some serialization for BlockInfo
alexwoods Sep 12, 2025
89ae89b
Add more handlers for blocks endpoints
alexwoods Sep 17, 2025
07866db
Add blocks endpoints for txs and txs/cbor
alexwoods Sep 19, 2025
dcae45d
Add blocks next and previous endpoints for blockfrost
alexwoods Sep 19, 2025
3fddbd7
Standardise some blocks handler function names
alexwoods Sep 19, 2025
d161cc5
Merge branch 'main' into sg/chain-store
alexwoods Sep 26, 2025
f307dfe
Correct placement of use for tests
alexwoods Sep 26, 2025
92cc028
cargo fmt of uses
alexwoods Sep 26, 2025
8c8d23d
Add paging to blocks /next and /previous endpoints
alexwoods Sep 26, 2025
651fc55
Correct function parameters for previous
alexwoods Sep 26, 2025
b228345
Add missing paging parameters to queries (still need implementing)
alexwoods Sep 26, 2025
c35850f
Apply paging and ordering to /txs and /txs/cbor endpoints
alexwoods Oct 1, 2025
7ccbb9f
Add /blocks/{hash_or_number}/addresses endpoint
alexwoods Oct 3, 2025
e542e38
Merge remote-tracking branch 'origin/main' into sg/chain-store
alexwoods Oct 8, 2025
60ada5d
Add delegates to protocol params
alexwoods Oct 8, 2025
61a3464
Merge remote-tracking branch 'origin/main' into sg/chain-store
alexwoods Oct 10, 2025
eb5942c
Add serde serialisation hints to fix Shelley params read/write
alexwoods Oct 10, 2025
5120ce7
cargo fmt cleanup
alexwoods Oct 10, 2025
e50bd8c
Correct matching of byron and shelley genesis slot issuers
alexwoods Oct 10, 2025
e1c5d24
Add clear-on-start option to chain store module
alexwoods Oct 15, 2025
368f201
Create a type for VRFKey
alexwoods Oct 15, 2025
575d094
Add lookups for block hashes and tx hashes
alexwoods Oct 15, 2025
c29152d
Merge remote-tracking branch 'origin/main' into sg/chain-store
alexwoods Oct 15, 2025
b24bd0f
Restore setting
alexwoods Oct 17, 2025
1e6c620
Move codec lib to top
alexwoods Oct 17, 2025
8daf1d8
Use crypto::keyhash_244 instead of cryptoxide
alexwoods Oct 17, 2025
cec7395
Make import of GenesisDelegate consistent with other types imports
alexwoods Oct 17, 2025
251fd26
Add comments for params message reading
alexwoods Oct 17, 2025
ab113f2
Get block number from key if possible
alexwoods Oct 17, 2025
80d42ce
Tidy up redundant code
alexwoods Oct 17, 2025
70005d5
Add unit test for get_blocks_by_number_range
alexwoods Oct 17, 2025
4c89113
Add a helper function for REST queries
alexwoods Oct 17, 2025
67acca4
Merge remote-tracking branch 'origin/main' into sg/chain-store
alexwoods Oct 22, 2025
6f6ab7b
Move bech-order address helper to common
alexwoods Oct 22, 2025
669921f
Move byte array types into own mod
alexwoods Oct 22, 2025
90a757f
Add FromHex impl for byte arrays
alexwoods Oct 22, 2025
acae2ee
Remove incorrect old comment
alexwoods Oct 22, 2025
88dedb9
Add self to authors
Oct 22, 2025
0e54ebd
cargo fmt run
Oct 22, 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
333 changes: 280 additions & 53 deletions Cargo.lock

Large diffs are not rendered by default.

12 changes: 8 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
[workspace]
members = [
# Global message and common definitions
"codec",
"common",

# Modules
Expand All @@ -21,11 +22,12 @@ members = [
"modules/epochs_state", # Tracks fees and blocks minted and epochs history
"modules/accounts_state", # Tracks stake and reward accounts
"modules/assets_state", # Tracks native asset mints and burns
"modules/chain_store", # Tracks historical information about blocks and TXs

# Process builds
"processes/omnibus", # All-inclusive omnibus process
"processes/replayer", # All-inclusive process to replay messages
"processes/golden_tests", #All-inclusive golden tests process
"processes/golden_tests", # All-inclusive golden tests process
]
resolver = "2"

Expand All @@ -41,9 +43,11 @@ config = "0.15.11"
dashmap = "6.1.0"
hex = "0.4"
imbl = { version = "5.0.0", features = ["serde"] }
pallas = "0.32.1"
pallas-addresses = "0.32.0"
pallas-crypto = "0.32.0"
pallas = "0.33.0"
pallas-addresses = "0.33.0"
pallas-crypto = "0.33.0"
pallas-primitives = "0.33.0"
pallas-traverse = "0.33.0"
serde = { version = "1.0.214", features = ["derive"] }
serde_json = "1.0.132"
serde_with = { version = "3.12.0", features = ["hex"] }
Expand Down
13 changes: 13 additions & 0 deletions codec/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "acropolis_codec"
version = "0.1.0"
edition = "2024"

[dependencies]
acropolis_common = { path = "../common" }

anyhow = { workspace = true }
pallas = { workspace = true }
pallas-primitives = { workspace = true }
pallas-traverse = { workspace = true }
tracing = { workspace = true }
43 changes: 43 additions & 0 deletions codec/src/block.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
use acropolis_common::{
GenesisDelegate, HeavyDelegate, crypto::keyhash_224, queries::blocks::BlockIssuer,
};
use pallas_primitives::byron::BlockSig::DlgSig;
use pallas_traverse::MultiEraHeader;
use std::collections::HashMap;

pub fn map_to_block_issuer(
header: &MultiEraHeader,
byron_heavy_delegates: &HashMap<Vec<u8>, HeavyDelegate>,
shelley_genesis_delegates: &HashMap<Vec<u8>, GenesisDelegate>,
) -> Option<BlockIssuer> {
match header.issuer_vkey() {
Some(vkey) => match header {
MultiEraHeader::ShelleyCompatible(_) => {
let digest = keyhash_224(vkey);
if let Some(issuer) = shelley_genesis_delegates
.values()
.find(|v| v.delegate == digest)
.map(|i| BlockIssuer::GenesisDelegate(i.clone()))
{
Some(issuer)
} else {
Some(BlockIssuer::SPO(vkey.to_vec()))
}
}
_ => Some(BlockIssuer::SPO(vkey.to_vec())),
},
None => match header {
MultiEraHeader::Byron(_) => match header.as_byron() {
Some(block_head) => match &block_head.consensus_data.3 {
DlgSig(sig) => byron_heavy_delegates
.values()
.find(|v| v.issuer_pk == *sig.0.issuer)
.map(|i| BlockIssuer::HeavyDelegate(i.clone())),
_ => None,
},
None => None,
},
_ => None,
},
}
}
2 changes: 2 additions & 0 deletions codec/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod block;
pub mod map_parameters;
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
//! Acropolis transaction unpacker module for Caryatid
//! Performs conversion from Pallas library data to Acropolis

use anyhow::{anyhow, bail, Result};
use anyhow::{Result, anyhow, bail};
use pallas::ledger::{
primitives::{
alonzo, babbage, conway, ExUnitPrices as PallasExUnitPrices, Nullable,
ProtocolVersion as PallasProtocolVersion, Relay as PallasRelay, ScriptHash,
StakeCredential as PallasStakeCredential,
ExUnitPrices as PallasExUnitPrices, Nullable, ProtocolVersion as PallasProtocolVersion,
Relay as PallasRelay, ScriptHash, StakeCredential as PallasStakeCredential, alonzo,
babbage, conway,
},
traverse::{MultiEraCert, MultiEraPolicyAssets, MultiEraValue},
*,
Expand Down Expand Up @@ -145,7 +145,7 @@ pub fn map_gov_action_id(pallas_action_id: &conway::GovActionId) -> Result<GovAc
};

Ok(GovActionId {
transaction_id: *pallas_action_id.transaction_id,
transaction_id: TxHash(*pallas_action_id.transaction_id),
action_index: act_idx_u8,
})
}
Expand Down
17 changes: 17 additions & 0 deletions common/src/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use anyhow::{anyhow, bail, Result};
use crc::{Crc, CRC_32_ISO_HDLC};
use minicbor::data::IanaTag;
use serde_with::{hex::Hex, serde_as};
use std::cmp::Ordering;

/// a Byron-era address
#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
Expand Down Expand Up @@ -517,6 +518,22 @@ impl Address {
}
}

/// Used for ordering addresses by their bech representation
#[derive(Eq, PartialEq)]
pub struct BechOrdAddress(pub Address);

impl Ord for BechOrdAddress {
fn cmp(&self, other: &Self) -> Ordering {
self.0.to_string().into_iter().cmp(other.0.to_string())
}
}

impl PartialOrd for BechOrdAddress {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}

// -- Tests --
#[cfg(test)]
mod tests {
Expand Down
89 changes: 89 additions & 0 deletions common/src/byte_array.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
use crate::serialization::{Bech32Conversion, Bech32WithHrp};
use anyhow::Error;
use hex::{FromHex, FromHexError};
use serde_with::{hex::Hex, serde_as};
use std::ops::Deref;

macro_rules! declare_byte_array_type {
($name:ident, $size:expr) => {
/// $name
#[serde_as]
#[derive(
Default, Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize,
)]
pub struct $name(#[serde_as(as = "Hex")] pub [u8; $size]);

impl From<[u8; $size]> for $name {
fn from(bytes: [u8; $size]) -> Self {
Self(bytes)
}
}

impl FromHex for $name {
type Error = FromHexError;

fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, Self::Error> {
Ok(match Self::try_from(Vec::<u8>::from_hex(hex)?) {
Ok(b) => Ok(b),
Err(_) => Err(FromHexError::InvalidStringLength),
}?)
}
}

impl TryFrom<Vec<u8>> for $name {
type Error = Vec<u8>;
fn try_from(vec: Vec<u8>) -> Result<Self, Self::Error> {
Ok($name(vec.try_into()?))
}
}

impl TryFrom<&[u8]> for $name {
type Error = std::array::TryFromSliceError;
fn try_from(arr: &[u8]) -> Result<Self, Self::Error> {
Ok($name(arr.try_into()?))
}
}

impl AsRef<[u8]> for $name {
fn as_ref(&self) -> &[u8] {
&self.0
}
}

impl Deref for $name {
type Target = [u8; $size];
fn deref(&self) -> &Self::Target {
&self.0
}
}
};
}

macro_rules! declare_byte_array_type_with_bech32 {
($name:ident, $size:expr, $hrp:expr) => {
declare_byte_array_type!($name, $size);
impl Bech32Conversion for $name {
fn to_bech32(&self) -> Result<String, anyhow::Error> {
self.0.to_vec().to_bech32_with_hrp($hrp)
}
fn from_bech32(s: &str) -> Result<Self, anyhow::Error> {
match Vec::<u8>::from_bech32_with_hrp(s, $hrp) {
Ok(v) => match Self::try_from(v) {
Ok(s) => Ok(s),
Err(_) => Err(Error::msg(format!(
"Bad vector input to {}",
stringify!($name)
))),
},
Err(e) => Err(e),
}
}
}
};
}

declare_byte_array_type!(BlockHash, 32);

declare_byte_array_type!(TxHash, 32);

declare_byte_array_type_with_bech32!(VRFKey, 32, "vrf_vk");
2 changes: 2 additions & 0 deletions common/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Acropolis common library - main library exports

pub mod address;
pub mod byte_array;
pub mod calculations;
pub mod cip19;
pub mod crypto;
Expand All @@ -23,4 +24,5 @@ pub mod types;

// Flattened re-exports
pub use self::address::*;
pub use self::byte_array::*;
pub use self::types::*;
1 change: 1 addition & 0 deletions common/src/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use crate::queries::{
transactions::{TransactionsStateQuery, TransactionsStateQueryResponse},
};

use crate::byte_array::*;
use crate::types::*;

// Caryatid core messages which we re-export
Expand Down
22 changes: 19 additions & 3 deletions common/src/protocol_params.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
use crate::{
genesis_values::GenesisValues,
rational_number::{ChameleonFraction, RationalNumber},
BlockVersionData, Committee, Constitution, CostModel, DRepVotingThresholds, Era, ExUnitPrices,
ExUnits, NetworkId, PoolVotingThresholds, ProtocolConsts,
BlockHash, BlockVersionData, Committee, Constitution, CostModel, DRepVotingThresholds, Era,
ExUnitPrices, ExUnits, GenesisDelegate, HeavyDelegate, NetworkId, PoolVotingThresholds,
ProtocolConsts,
};
use anyhow::Result;
use blake2::{digest::consts::U32, Blake2b, Digest};
use chrono::{DateTime, Utc};
use serde_with::serde_as;
use serde_with::{hex::Hex, serde_as};
use std::collections::HashMap;
use std::ops::Deref;

#[derive(Debug, Default, PartialEq, Clone, serde::Serialize, serde::Deserialize)]
pub struct ProtocolParams {
Expand All @@ -28,6 +31,7 @@ pub struct ByronParams {
pub fts_seed: Option<Vec<u8>>,
pub protocol_consts: ProtocolConsts,
pub start_time: u64,
pub heavy_delegation: HashMap<Vec<u8>, HeavyDelegate>,
}

//
Expand Down Expand Up @@ -122,6 +126,9 @@ pub struct ShelleyParams {
pub slots_per_kes_period: u32,
pub system_start: DateTime<Utc>,
pub update_quorum: u32,

#[serde_as(as = "HashMap<Hex, _>")]
pub gen_delegs: HashMap<Vec<u8>, GenesisDelegate>,
}

#[serde_as]
Expand Down Expand Up @@ -264,6 +271,15 @@ impl From<NonceHash> for Nonce {
}
}

impl From<BlockHash> for Nonce {
fn from(hash: BlockHash) -> Self {
Self {
tag: NonceVariant::Nonce,
hash: Some(*hash.deref()),
}
}
}

#[derive(
Default, Debug, PartialEq, Eq, PartialOrd, Ord, Clone, serde::Serialize, serde::Deserialize,
)]
Expand Down
Loading