Skip to content
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
490 changes: 490 additions & 0 deletions poi-rs/src/committee.rs

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions poi-rs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,19 @@
#![doc = include_str!("../README.md")]
#![warn(missing_docs, rustdoc::all)]

/// Shared boxed source error used by the crate's typed errors.
pub(crate) type BoxError = Box<dyn std::error::Error + Send + Sync + 'static>;

/// Committee resolution for checkpoint verification.
pub mod committee;
/// Proof data types and offline verification.
pub mod proof;
/// Sources for constructing proofs.
pub mod source;
/// Target claims authenticated by a proof.
pub mod target;

pub use committee::{CommitteeResolutionError, CommitteeResolutionErrorKind, CommitteeResolver};
pub use proof::{
Proof, ProofVerifier, ProofVersion, SerializationError, SerializationErrorKind, TransactionProof, VerifyError,
VerifyErrorKind, VersionError,
Expand Down
6 changes: 1 addition & 5 deletions poi-rs/src/proof.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// Copyright 2020-2026 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

use std::error::Error as StdError;

use iota_types::{
committee::Committee,
digests::ChainIdentifier,
Expand All @@ -12,9 +10,7 @@ use iota_types::{
};
use serde::{Deserialize, Serialize};

use crate::target::ProofTargets;

type BoxError = Box<dyn StdError + Send + Sync + 'static>;
use crate::{BoxError, target::ProofTargets};

/// Error returned when a proof-format version is not supported.
#[derive(Debug, thiserror::Error)]
Expand Down
6 changes: 2 additions & 4 deletions poi-rs/src/source.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2020-2026 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

use std::{error::Error as StdError, fmt};
use std::fmt;

use async_trait::async_trait;
use iota_grpc_client::{
Expand All @@ -20,9 +20,7 @@
transaction::Transaction,
};

use crate::{Proof, ProofTargets, TransactionProof};

type BoxError = Box<dyn StdError + Send + Sync + 'static>;
use crate::{BoxError, Proof, ProofTargets, TransactionProof};

/// Source target requested by the caller.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
Expand Down Expand Up @@ -301,7 +299,7 @@
},
)
})?
.try_into()

Check failure on line 302 in poi-rs/src/source.rs

View workflow job for this annotation

GitHub Actions / clippy (ubuntu-latest)

use of a fallible conversion when an infallible one could be used

error: use of a fallible conversion when an infallible one could be used --> poi-rs/src/source.rs:302:14 | 302 | .try_into() | ^^^^^^^^ | = note: converting `Object` to `Object` cannot fail = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.97.0/index.html#unnecessary_fallible_conversions = note: `-D clippy::unnecessary-fallible-conversions` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::unnecessary_fallible_conversions)]` help: use | 302 - .try_into() 302 + .into() |
.map_err(|source| {
SourceError::object(
object_ref,
Expand Down
43 changes: 43 additions & 0 deletions poi-rs/tests/committee.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2020-2026 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

use iota_grpc_client::Client as GrpcClient;
use iota_types::committee::Committee;
use poi_rs::{CommitteeResolutionErrorKind, CommitteeResolver};

fn committee_at(epoch: u64) -> Committee {
let (committee, _) = Committee::new_simple_test_committee();
Committee::new(epoch, committee.voting_rights.iter().cloned().collect())
}

fn disconnected_client() -> GrpcClient {
GrpcClient::new("http://127.0.0.1:1").expect("create lazy gRPC client")
}

#[tokio::test]
async fn anchor_mode_returns_the_trusted_committee_for_its_epoch() {
let trusted_committee = committee_at(7);
let resolver = CommitteeResolver::anchor(disconnected_client(), trusted_committee.clone());

let resolved = resolver.resolve(7).await.unwrap();

assert_eq!(resolved, trusted_committee);
}

#[tokio::test]
async fn anchor_mode_rejects_an_epoch_before_the_trust_anchor() {
let resolver = CommitteeResolver::anchor(disconnected_client(), committee_at(7));

let error = resolver.resolve(6).await.unwrap_err();

assert_eq!(error.target_epoch, 6);
assert!(matches!(
error.kind,
CommitteeResolutionErrorKind::TargetBeforeAnchor { anchor_epoch: 7 }
));
}

#[tokio::test]
async fn node_mode_has_an_explicit_constructor() {
let _resolver = CommitteeResolver::node(disconnected_client());
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading