pub mod admission;
pub mod config;
pub mod epoch_manager;
pub mod error;
pub mod finality;
pub mod hotstuff2;
pub mod leader_reputation;
pub mod mempool;
pub mod proposer;
pub mod timeout;
pub mod traits;
pub mod validator;
pub mod vote_state;
pub mod voter;
pub use admission::{
AdmissionConfig, AdmissionController, AdmissionDecision, BucketSnapshot,
DefaultLaneResolver, Lane, LaneResolver, LaneStats,
};
pub use config::{BftThreshold, ConsensusConfig, ProposerElectionKind};
pub use epoch_manager::{Epoch, EpochManager, EpochStateStore, EpochStats};
pub use error::{ConsensusError, Result};
pub use finality::{FinalityNotification, FinalityTracker, ForkChoice};
pub use hotstuff2::{
BlockProvider, ConsensusOutMessage, HotStuff2Engine, Phase, StateRootProvider,
};
pub use leader_reputation::{
proposer_window, reputation_seed, voter_window, LeaderReputation, ProposerHistory,
ProposerRecord, ValidatorWeights, VoterHistory, VoterRecord, ACTIVE_WEIGHT, FAILED_WEIGHT,
FAILURE_THRESHOLD_PERCENT, INACTIVE_WEIGHT, NO_TEE_MULTIPLIER_BPS, TEE_MULTIPLIER_BPS,
};
pub use mempool::{Mempool, MempoolStats};
pub use proposer::BlockProposer;
pub use timeout::{
CollectOutcome, NecCollectOutcome, NecSigner, NoEndorsementCertificate, NoEndorsementCollector,
NoEndorsementMsg, TcSigner, TimeoutCertificate, TimeoutCollector, TimeoutMsg,
NO_ENDORSEMENT_CERTIFICATE_FORMAT_VERSION, NO_ENDORSEMENT_MSG_FORMAT_VERSION,
TIMEOUT_CERTIFICATE_FORMAT_VERSION, TIMEOUT_MSG_FORMAT_VERSION,
};
pub use traits::{ConsensusEngine, ConsensusNetwork, SlashingCallback, StateManager};
pub use validator::{
EquivocationDetector, EquivocationEvidence, ProposerElection, ReputationProposer,
RoundRobinProposer, ValidatorInfo, ValidatorSet, ValidatorStatus,
};
pub use vote_state::{
open_default_file_store, FileVoteStateStore, LastSignState, MemoryVoteStateStore,
VoteStateStore, VoteStep, VrsDecision,
};
pub use voter::{bls_payload_for_vote, QuorumCertificate, Vote, VoteCollector, VoteType};
#[cfg(test)]
mod tests {
use super::*;
use tenzro_crypto::bls::BlsKeyPair;
use tenzro_crypto::pq::MlDsaSigningKey;
use tenzro_crypto::{KeyPair, KeyType};
#[test]
fn test_crate_version() {
let config = ConsensusConfig::default();
assert_eq!(config.block_time_ms, 400);
}
fn convert_address(crypto_addr: tenzro_crypto::Address) -> tenzro_types::primitives::Address {
let mut addr_bytes = [0u8; 32];
addr_bytes[..20].copy_from_slice(crypto_addr.as_bytes());
tenzro_types::primitives::Address::new(addr_bytes)
}
#[test]
fn test_validator_creation() {
let keypair = KeyPair::generate(KeyType::Ed25519).unwrap();
let address = convert_address(keypair.address());
let pq = MlDsaSigningKey::generate();
let bls = BlsKeyPair::generate().unwrap();
let validator = ValidatorInfo::new(
address,
keypair.public_key().clone(),
pq.verifying_key_bytes().to_vec(),
bls.public_key().to_bytes().to_vec(),
1000,
);
assert_eq!(validator.stake, 1000);
assert!(validator.is_active());
}
#[test]
fn test_epoch_manager_creation() {
let keypair = KeyPair::generate(KeyType::Ed25519).unwrap();
let address = convert_address(keypair.address());
let pq = MlDsaSigningKey::generate();
let bls = BlsKeyPair::generate().unwrap();
let validators = vec![
ValidatorInfo::new(
address,
keypair.public_key().clone(),
pq.verifying_key_bytes().to_vec(),
bls.public_key().to_bytes().to_vec(),
1000,
),
];
let epoch_manager = EpochManager::new(validators, 100).unwrap();
let epoch = epoch_manager.current_epoch();
assert_eq!(epoch.number, 0);
assert_eq!(epoch.duration(), 100);
}
#[tokio::test]
async fn test_consensus_engine_creation() {
let keypair = KeyPair::generate(KeyType::Ed25519).unwrap();
let address = convert_address(keypair.address());
let pq = MlDsaSigningKey::generate();
let bls = BlsKeyPair::generate().unwrap();
let validators = vec![
ValidatorInfo::new(
address,
keypair.public_key().clone(),
pq.verifying_key_bytes().to_vec(),
bls.public_key().to_bytes().to_vec(),
1000,
),
];
let config = ConsensusConfig::default();
let epoch_manager = EpochManager::new(validators, 100).unwrap();
let pq_engine = MlDsaSigningKey::generate();
let bls_engine = BlsKeyPair::generate().unwrap();
let engine = HotStuff2Engine::new(keypair, pq_engine, bls_engine, config, epoch_manager);
assert_eq!(engine.finalized_height().await, tenzro_types::primitives::BlockHeight::from(0));
}
}