Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Use pallas traverse library #28

Merged
merged 4 commits into from
Jun 15, 2022
Merged
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
38 changes: 26 additions & 12 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ authors = ["Santiago Carmuega <santiago@carmuega.me>"]


[dependencies]
pallas = "0.11.0-alpha.0"
pallas = "0.11.0-alpha.1"
# pallas = { path = "../pallas/pallas" }
hex = "0.4.3"
net2 = "0.2.37"
Expand Down
13 changes: 13 additions & 0 deletions src/crosscut/addresses.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
fn get_bit_at(input: u8, n: u8) -> bool {
if n < 32 {
input & (1 << n) != 0
} else {
false
}
}

// https://github.com/input-output-hk/cardano-ledger/blob/master/eras/alonzo/test-suite/cddl-files/alonzo.cddl#L135
pub fn is_smart_contract(address: &[u8]) -> bool {
let byte_1 = address[0];
return get_bit_at(byte_1, 4);
}
33 changes: 0 additions & 33 deletions src/crosscut/epoch_calculator.rs

This file was deleted.

33 changes: 33 additions & 0 deletions src/crosscut/epochs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// TODO this is temporary, we should actually use this code from Pallas as this
// is very generic code

use pallas::ledger::traverse::MultiEraBlock;

fn post_byron_epoch_for_slot(shelley_known_slot: u64, shelley_epoch_length: u32, slot: u64) -> u64 {
let last_byron_epoch_no = 208;

let shelley_known_slot = shelley_known_slot as u64;
let shelley_epoch_length = shelley_epoch_length as u64;

let shelley_epoch_no = (slot - shelley_known_slot) / shelley_epoch_length;

return last_byron_epoch_no + shelley_epoch_no;
}

fn byron_epoch_for_slot(byron_epoch_length: u32, byron_slot_length: u32, slot: u64) -> u64 {
let byron_epoch_length = byron_epoch_length as u64;
let byron_slot_length = byron_slot_length as u64;

return slot / (byron_epoch_length / byron_slot_length);
}

pub fn block_epoch(chain: &super::ChainWellKnownInfo, block: &MultiEraBlock) -> u64 {
let slot = block.slot();

match block.era() {
pallas::ledger::traverse::Era::Byron => {
byron_epoch_for_slot(chain.byron_epoch_length, chain.byron_slot_length, slot)
}
_ => post_byron_epoch_for_slot(chain.shelley_known_slot, chain.shelley_epoch_length, slot),
}
}
4 changes: 2 additions & 2 deletions src/crosscut/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
pub mod addresses;
mod args;
mod epoch_calculator;
pub mod epochs;

pub use args::*;
pub use epoch_calculator::*;
7 changes: 7 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ pub enum Error {
#[error("ouroboros error: {0}")]
OuroborosError(String),

#[error("cbor error: {0}")]
CborError(String),

#[error("ledger error: {0}")]
LedgerError(String),

Expand Down Expand Up @@ -49,6 +52,10 @@ impl Error {
Error::NetworkError(format!("network error: {}", error))
}

pub fn cbor(error: impl Display) -> Error {
Error::CborError(format!("cbor error: {}", error))
}

pub fn ouroboros(error: impl Display) -> Error {
Error::OuroborosError(format!("ouroboros error: {}", error))
}
Expand Down
74 changes: 8 additions & 66 deletions src/model.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
use std::{collections::HashSet, ops::Deref};
use std::collections::HashSet;

use pallas::{
ledger::primitives::{alonzo, byron, probing, Era, Fragment, ToHash},
network::miniprotocols::Point,
};

use crate::Error;
use pallas::{ledger::traverse::MultiEraBlock, network::miniprotocols::Point};

#[derive(Debug)]
pub enum ChainSyncCommand {
Expand Down Expand Up @@ -47,63 +42,6 @@ impl ChainSyncCommandEx {
}
}

#[derive(Debug)]
pub enum MultiEraBlock<'b> {
AlonzoCompatible(alonzo::BlockWrapper<'b>),
Byron(byron::Block),
}

pub fn parse_block_content(body: &[u8]) -> Result<MultiEraBlock, Error> {
match probing::probe_block_cbor_era(&body) {
probing::Outcome::Matched(era) => match era {
Era::Byron => {
let primitive = byron::Block::decode_fragment(&body)?;
let block = MultiEraBlock::Byron(primitive);
Ok(block)
}
_ => {
let primitive = alonzo::BlockWrapper::decode_fragment(&body)?;
let block = MultiEraBlock::AlonzoCompatible(primitive);
Ok(block)
}
},
// TODO: we're assuming that the genesis block is Byron-compatible. Is this a safe
// assumption?
probing::Outcome::GenesisBlock => {
let primitive = byron::Block::decode_fragment(&body)?;
let block = MultiEraBlock::Byron(primitive);
Ok(block)
}
probing::Outcome::Inconclusive => {
let msg = format!("can't infer primitive block from cbor, inconclusive probing. CBOR hex for debugging: {}", hex::encode(body));
return Err(Error::Message(msg));
}
}
}

impl<'b> MultiEraBlock<'b> {
pub fn point(&self) -> Result<Point, Error> {
match self {
MultiEraBlock::Byron(x) => match x.deref() {
byron::Block::EbBlock(x) => {
let hash = x.header.to_hash();
let slot = x.header.to_abs_slot();
Ok(Point::Specific(slot, hash.to_vec()))
}
byron::Block::MainBlock(x) => {
let hash = x.header.to_hash();
let slot = x.header.consensus_data.0.to_abs_slot();
Ok(Point::Specific(slot, hash.to_vec()))
}
},
MultiEraBlock::AlonzoCompatible(x) => {
let hash = &x.1.header.to_hash();
Ok(Point::Specific(x.1.header.header_body.slot, hash.to_vec()))
}
}
}
}

pub type Set = String;
pub type Member = String;
pub type Key = String;
Expand All @@ -127,12 +65,16 @@ pub enum CRDTCommand {

impl CRDTCommand {
pub fn block_starting(block: &MultiEraBlock) -> CRDTCommand {
let point = block.point().expect("block has defined point");
let hash = block.hash();
let slot = block.slot();
let point = Point::Specific(slot, hash.to_vec());
CRDTCommand::BlockStarting(point)
}

pub fn block_finished(block: &MultiEraBlock) -> CRDTCommand {
let point = block.point().expect("block has defined point");
let hash = block.hash();
let slot = block.slot();
let point = Point::Specific(slot, hash.to_vec());
CRDTCommand::BlockFinished(point)
}
}
Expand Down
Loading