Skip to content

Commit

Permalink
Merge branch 'main' into refactor/chain-follower-decoder
Browse files Browse the repository at this point in the history
  • Loading branch information
apskhem authored Dec 2, 2024
2 parents de7fa87 + dbe3d4c commit 69115b5
Show file tree
Hide file tree
Showing 47 changed files with 2,211 additions and 497 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/semantic_pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ jobs:
rust/c509-certificate
rust/cardano-chain-follower
rust/catalyst-voting
rust/immutable-ledger
rust/vote-tx-v1
rust/vote-tx-v2
rust/cbork
rust/hermes-ipfs
dart
Expand Down
1 change: 1 addition & 0 deletions Earthfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ VERSION 0.8
IMPORT github.com/input-output-hk/catalyst-ci/earthly/mdlint:v3.2.23 AS mdlint-ci
IMPORT github.com/input-output-hk/catalyst-ci/earthly/cspell:v3.2.23 AS cspell-ci


FROM debian:stable-slim

# check-markdown : markdown check using catalyst-ci.
Expand Down
1 change: 1 addition & 0 deletions docs/Earthfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ VERSION 0.8

IMPORT github.com/input-output-hk/catalyst-ci/earthly/docs:v3.2.23 AS docs-ci


IMPORT .. AS repo

# Copy all the source we need to build the docs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ tx-body<choice-t, proof-t, prop-id-t> = [
vote-type
event,
votes<choice-t, proof-t, prop-id-t>,
voters-data,
voter-data,
]

vote-type = UUID ; e.g. Public or Private vote
Expand All @@ -25,7 +25,7 @@ choice<choice-t> = #6.24(bytes .cbor choice-t) ; encoded-cbor
proof<proof-t> = #6.24(bytes .cbor proof-t) ; encoded-cbor
prop-id<prop-id-t> = #6.24(bytes .cbor prop-id-t) ; encoded-cbor

voters-data = encoded-cbor
voter-data = encoded-cbor

UUID = #6.37(bytes) ; UUID type
signature = #6.98(cose.COSE_Sign) ; COSE signature
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Vote:
so it's redundant to provide an additional identifier for the proposal,
so it could be placed `null`.

`voters-data` - an any additional voter's specific data.
`voter-data` - an any additional voter's specific data.

### Transaction signing

Expand Down
6 changes: 5 additions & 1 deletion rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ members = [
"cbork",
"cbork-abnf-parser",
"cbork-cddl-parser",
"catalyst-voting", "jormungandr-vote-tx",
"catalyst-voting",
"catalyst-voting",
"immutable-ledger",
"vote-tx-v1",
"vote-tx-v2",
]

[workspace.package]
Expand Down
8 changes: 4 additions & 4 deletions rust/Earthfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ COPY_SRC:
.cargo .config \
c509-certificate \
cardano-chain-follower \
catalyst-voting jormungandr-vote-tx \
catalyst-voting vote-tx-v1 vote-tx-v2 \
cbork cbork-abnf-parser cbork-cddl-parser \
hermes-ipfs \
.
immutable-ledger .

# builder : Set up our target toolchains, and copy our files.
builder:
Expand Down Expand Up @@ -53,7 +53,7 @@ build:
--cmd="/scripts/std_build.py" \
--args1="--libs=c509-certificate --libs=cardano-chain-follower --libs=hermes-ipfs" \
--args2="--libs=cbork-cddl-parser --libs=cbork-abnf-parser" \
--args3="--libs=catalyst-voting --libs=jormungandr-vote-tx" \
--args3="--libs=catalyst-voting --libs=vote-tx-v1 --libs=vote-tx-v2" \
--args4="--bins=cbork/cbork" \
--args5="--cov_report=$HOME/build/coverage-report.info" \
--output="release/[^\./]+" \
Expand Down Expand Up @@ -90,4 +90,4 @@ check-builder-src-cache:
# local-ci-run: This step simulates the full CI run for local purposes only.
local-ci-run:
BUILD +check
BUILD +build
BUILD +build
1 change: 1 addition & 0 deletions rust/c509-certificate/Earthfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ VERSION 0.8

IMPORT github.com/input-output-hk/catalyst-ci/earthly/rust::v3.2.23 AS rust-ci


IMPORT .. AS rust-local
IMPORT ../.. AS repo

Expand Down
2 changes: 1 addition & 1 deletion rust/cardano-chain-follower/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "cardano-chain-follower"
version = "0.0.4"
version = "0.0.5"
edition.workspace = true
authors.workspace = true
homepage.workspace = true
Expand Down
185 changes: 182 additions & 3 deletions rust/cardano-chain-follower/src/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,38 @@ impl Network {
///
/// The Slot does not have to be a valid slot present in the blockchain.
#[must_use]
pub fn time_to_slot(&self, _time: DateTime<Utc>) -> Option<u64> {
// TODO: Implement this, for now just return None.
None
pub fn time_to_slot(&self, time: DateTime<Utc>) -> Option<u64> {
let genesis = self.genesis_values();

let byron_start_time = i64::try_from(genesis.byron_known_time)
.map(|time| DateTime::<Utc>::from_timestamp(time, 0))
.ok()??;
let shelley_start_time = i64::try_from(genesis.shelley_known_time)
.map(|time| DateTime::<Utc>::from_timestamp(time, 0))
.ok()??;

// determine if the given time is in Byron or Shelley era.
if time < byron_start_time {
return None;
}

if time < shelley_start_time {
// Byron era
let time_diff = time - byron_start_time;
let elapsed_slots = time_diff.num_seconds() / i64::from(genesis.byron_slot_length);

u64::try_from(elapsed_slots)
.map(|elapsed_slots| Some(genesis.byron_known_slot + elapsed_slots))
.ok()?
} else {
// Shelley era
let time_diff = time - shelley_start_time;
let elapsed_slots = time_diff.num_seconds() / i64::from(genesis.shelley_slot_length);

u64::try_from(elapsed_slots)
.map(|elapsed_slots| Some(genesis.shelley_known_slot + elapsed_slots))
.ok()?
}
}
}

Expand All @@ -191,6 +220,7 @@ mod tests {
use std::str::FromStr;

use anyhow::Ok;
use chrono::{TimeZone, Utc};

use super::*;

Expand All @@ -214,4 +244,153 @@ mod tests {

Ok(())
}

#[test]
fn test_time_to_slot_before_blockchain() {
let network = Network::Mainnet;
let genesis = network.genesis_values();

let before_blockchain = Utc
.timestamp_opt(i64::try_from(genesis.byron_known_time).unwrap() - 1, 0)
.unwrap();

assert_eq!(network.time_to_slot(before_blockchain), None);
}

#[test]
fn test_time_to_slot_byron_era() {
let network = Network::Mainnet;
let genesis = network.genesis_values();

let byron_start_time = Utc
.timestamp_opt(i64::try_from(genesis.byron_known_time).unwrap(), 0)
.unwrap();
let byron_slot_length = i64::from(genesis.byron_slot_length);

// a time in the middle of the Byron era.
let time = byron_start_time + chrono::Duration::seconds(byron_slot_length * 100);
let expected_slot = genesis.byron_known_slot + 100;

assert_eq!(network.time_to_slot(time), Some(expected_slot));
}

#[test]
fn test_time_to_slot_transition_to_shelley() {
let network = Network::Mainnet;
let genesis = network.genesis_values();

let shelley_start_time = Utc
.timestamp_opt(i64::try_from(genesis.shelley_known_time).unwrap(), 0)
.unwrap();
let byron_slot_length = i64::from(genesis.byron_slot_length);

// a time just before Shelley era starts.
let time = shelley_start_time - chrono::Duration::seconds(1);
let elapsed_slots = (time
- Utc
.timestamp_opt(i64::try_from(genesis.byron_known_time).unwrap(), 0)
.unwrap())
.num_seconds()
/ byron_slot_length;
let expected_slot = genesis.byron_known_slot + u64::try_from(elapsed_slots).unwrap();

assert_eq!(network.time_to_slot(time), Some(expected_slot));
}

#[test]
fn test_time_to_slot_shelley_era() {
let network = Network::Mainnet;
let genesis = network.genesis_values();

let shelley_start_time = Utc
.timestamp_opt(i64::try_from(genesis.shelley_known_time).unwrap(), 0)
.unwrap();
let shelley_slot_length = i64::from(genesis.shelley_slot_length);

// a time in the middle of the Shelley era.
let time = shelley_start_time + chrono::Duration::seconds(shelley_slot_length * 200);
let expected_slot = genesis.shelley_known_slot + 200;

assert_eq!(network.time_to_slot(time), Some(expected_slot));
}

#[test]
fn test_slot_to_time_to_slot_consistency() {
let network = Network::Mainnet;

// a few arbitrary slots in different ranges.
let slots_to_test = vec![0, 10_000, 1_000_000, 50_000_000];

for slot in slots_to_test {
let time = network.slot_to_time(slot);
let calculated_slot = network.time_to_slot(time);

assert_eq!(calculated_slot, Some(slot), "Failed for slot: {slot}");
}
}

#[test]
#[allow(clippy::panic)]
fn test_time_to_slot_to_time_consistency() {
let network = Network::Mainnet;
let genesis = network.genesis_values();

// Byron, Shelley, and Conway.
let times_to_test = vec![
Utc.timestamp_opt(i64::try_from(genesis.byron_known_time).unwrap() + 100, 0)
.unwrap(),
Utc.timestamp_opt(
i64::try_from(genesis.shelley_known_time).unwrap() + 1_000,
0,
)
.unwrap(),
Utc.timestamp_opt(
i64::try_from(genesis.shelley_known_time).unwrap() + 10_000_000,
0,
)
.unwrap(),
];

for time in times_to_test {
if let Some(slot) = network.time_to_slot(time) {
let calculated_time = network.slot_to_time(slot);

assert_eq!(
calculated_time.timestamp(),
time.timestamp(),
"Failed for time: {time}"
);
} else {
panic!("time_to_slot returned None for a valid time: {time}");
}
}
}

#[test]
fn test_conway_era_time_to_slot_and_back() {
let network = Network::Mainnet;
let genesis = network.genesis_values();

// a very late time, far in the Conway era.
let conway_time = Utc
.timestamp_opt(
i64::try_from(genesis.shelley_known_time).unwrap() + 20_000_000,
0,
)
.unwrap();

let slot = network.time_to_slot(conway_time);
assert!(
slot.is_some(),
"Failed to calculate slot for Conway era time"
);

let calculated_time = network.slot_to_time(slot.unwrap());

assert_eq!(
calculated_time.timestamp(),
conway_time.timestamp(),
"Inconsistency for Conway era time"
);
}
}
2 changes: 1 addition & 1 deletion rust/catalyst-voting/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ curve25519-dalek = { version = "4.1.3", features = ["digest", "rand_core"] }
ed25519-dalek = { version = "2.1.1", features = ["rand_core"] }
blake2b_simd = "1.0.2"
rayon = "1.10.0"
proptest = { version = "1.5.0" }

[dev-dependencies]
criterion = "0.5.1"
proptest = { version = "1.5.0" }
# Potentially it could be replaced with using `proptest::property_test` attribute macro,
# after this PR will be merged https://github.com/proptest-rs/proptest/pull/523
test-strategy = "0.4.0"
8 changes: 7 additions & 1 deletion rust/catalyst-voting/src/crypto/ed25519/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use ed25519_dalek::{
ed25519::signature::Signer, Signature as Ed25519Signature, SigningKey, VerifyingKey,
};

use super::rng::default_rng;
use crate::crypto::rng::rand_core::CryptoRngCore;

/// `Ed25519` private key struct.
Expand All @@ -19,6 +20,11 @@ impl PrivateKey {
Self(SigningKey::generate(rng))
}

/// Randomly generate the `ElectionSecretKey` with the `crypto::default_rng`.
pub fn random_with_default_rng() -> Self {
Self::random(&mut default_rng())
}

/// Get associated `Ed25519` public key.
pub fn public_key(&self) -> PublicKey {
PublicKey(self.0.verifying_key())
Expand Down Expand Up @@ -46,7 +52,7 @@ pub fn verify_signature(pk: &PublicKey, msg: &[u8], sig: &Signature) -> bool {
pk.0.verify_strict(msg, &sig.0).is_ok()
}

#[allow(missing_docs, clippy::missing_docs_in_private_items)]
#[cfg(test)]
mod arbitrary_impl {
use proptest::prelude::{any, Arbitrary, BoxedStrategy, Strategy};

Expand Down
2 changes: 1 addition & 1 deletion rust/catalyst-voting/src/crypto/elgamal/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ impl Add<&Ciphertext> for &Ciphertext {
}
}

#[allow(missing_docs, clippy::missing_docs_in_private_items)]
#[cfg(test)]
mod arbitrary_impl {
use proptest::{
arbitrary::any,
Expand Down
2 changes: 1 addition & 1 deletion rust/catalyst-voting/src/crypto/group/ristretto255/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ impl Sub<&GroupElement> for &GroupElement {
}
}

#[allow(missing_docs, clippy::missing_docs_in_private_items)]
#[cfg(test)]
mod arbitrary_impl {
use proptest::{
arbitrary::any,
Expand Down
2 changes: 1 addition & 1 deletion rust/catalyst-voting/src/crypto/zk_unit_vector/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ fn check_2(
&right_1 + &right_2 == left
}

#[allow(missing_docs, clippy::missing_docs_in_private_items)]
#[cfg(test)]
mod arbitrary_impl {
use proptest::{
prelude::{any_with, Arbitrary, BoxedStrategy, Strategy},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ impl ResponseRandomness {
}
}

#[allow(missing_docs, clippy::missing_docs_in_private_items)]
#[cfg(test)]
mod arbitrary_impl {
use proptest::{
arbitrary::any,
Expand Down
Loading

0 comments on commit 69115b5

Please sign in to comment.