2023-10-20 00:04:26 +00:00
|
|
|
use std::collections::{HashMap, HashSet};
|
|
|
|
|
2023-09-28 11:21:06 +00:00
|
|
|
pub mod block;
|
2023-10-22 16:27:37 +00:00
|
|
|
pub mod context;
|
2023-09-03 22:50:38 +00:00
|
|
|
pub mod genesis;
|
2023-10-15 19:35:33 +00:00
|
|
|
mod helper;
|
2023-10-03 21:10:31 +00:00
|
|
|
#[cfg(feature = "binaries")]
|
2023-09-03 22:50:38 +00:00
|
|
|
pub mod rpc;
|
2023-10-28 23:39:22 +00:00
|
|
|
#[cfg(test)]
|
|
|
|
mod test_utils;
|
2023-10-20 00:04:26 +00:00
|
|
|
pub mod transactions;
|
2023-10-22 16:27:37 +00:00
|
|
|
|
2023-10-23 18:14:40 +00:00
|
|
|
pub use block::{VerifiedBlockInformation, VerifyBlockRequest};
|
|
|
|
pub use context::{ContextConfig, HardFork, UpdateBlockchainCacheRequest};
|
|
|
|
pub use transactions::{VerifyTxRequest, VerifyTxResponse};
|
2023-10-22 16:27:37 +00:00
|
|
|
|
|
|
|
pub async fn initialize_verifier<D>(
|
|
|
|
database: D,
|
|
|
|
cfg: ContextConfig,
|
|
|
|
) -> Result<
|
|
|
|
(
|
2023-10-23 18:14:40 +00:00
|
|
|
impl tower::Service<
|
|
|
|
VerifyBlockRequest,
|
|
|
|
Response = VerifiedBlockInformation,
|
|
|
|
Error = ConsensusError,
|
|
|
|
>,
|
|
|
|
impl tower::Service<VerifyTxRequest, Response = VerifyTxResponse, Error = ConsensusError>,
|
|
|
|
impl tower::Service<UpdateBlockchainCacheRequest, Response = (), Error = tower::BoxError>,
|
2023-10-22 16:27:37 +00:00
|
|
|
),
|
|
|
|
ConsensusError,
|
|
|
|
>
|
|
|
|
where
|
|
|
|
D: Database + Clone + Send + Sync + 'static,
|
|
|
|
D::Future: Send + 'static,
|
|
|
|
{
|
2023-10-24 19:17:16 +00:00
|
|
|
let (context_svc, context_svc_updater) =
|
|
|
|
context::initialize_blockchain_context(cfg, database.clone()).await?;
|
2023-10-22 16:27:37 +00:00
|
|
|
let tx_svc = transactions::TxVerifierService::new(database);
|
2023-10-23 18:14:40 +00:00
|
|
|
let block_svc = block::BlockVerifierService::new(context_svc.clone(), tx_svc.clone());
|
|
|
|
Ok((block_svc, tx_svc, context_svc_updater))
|
2023-10-22 16:27:37 +00:00
|
|
|
}
|
2023-09-03 22:50:38 +00:00
|
|
|
|
2023-10-24 19:17:16 +00:00
|
|
|
// TODO: split this enum up.
|
2023-09-03 22:50:38 +00:00
|
|
|
#[derive(Debug, thiserror::Error)]
|
2023-10-02 20:07:11 +00:00
|
|
|
pub enum ConsensusError {
|
2023-10-23 18:14:40 +00:00
|
|
|
#[error("Miner transaction invalid: {0}")]
|
|
|
|
MinerTransaction(&'static str),
|
2023-10-20 00:04:26 +00:00
|
|
|
#[error("Transaction sig invalid: {0}")]
|
|
|
|
TransactionSignatureInvalid(&'static str),
|
2023-10-24 19:17:16 +00:00
|
|
|
#[error("Transaction has too high output amount")]
|
|
|
|
TransactionOutputsTooMuch,
|
2023-10-20 00:04:26 +00:00
|
|
|
#[error("Transaction inputs overflow")]
|
|
|
|
TransactionInputsOverflow,
|
|
|
|
#[error("Transaction outputs overflow")]
|
|
|
|
TransactionOutputsOverflow,
|
|
|
|
#[error("Transaction has an invalid output: {0}")]
|
|
|
|
TransactionInvalidOutput(&'static str),
|
|
|
|
#[error("Transaction has an invalid version")]
|
|
|
|
TransactionVersionInvalid,
|
|
|
|
#[error("Transaction an invalid input: {0}")]
|
|
|
|
TransactionHasInvalidInput(&'static str),
|
|
|
|
#[error("Transaction has invalid ring: {0}")]
|
|
|
|
TransactionHasInvalidRing(&'static str),
|
|
|
|
#[error("Block has an invalid proof of work")]
|
|
|
|
BlockPOWInvalid,
|
2023-10-15 19:35:33 +00:00
|
|
|
#[error("Block has a timestamp outside of the valid range")]
|
|
|
|
BlockTimestampInvalid,
|
|
|
|
#[error("Block is too large")]
|
|
|
|
BlockIsTooLarge,
|
2023-09-03 22:50:38 +00:00
|
|
|
#[error("Invalid hard fork version: {0}")]
|
|
|
|
InvalidHardForkVersion(&'static str),
|
2023-10-05 16:54:19 +00:00
|
|
|
#[error("The block has a different previous hash than expected")]
|
|
|
|
BlockIsNotApartOfChain,
|
2023-09-03 22:50:38 +00:00
|
|
|
#[error("Database error: {0}")]
|
|
|
|
Database(#[from] tower::BoxError),
|
|
|
|
}
|
|
|
|
|
|
|
|
pub trait Database:
|
|
|
|
tower::Service<DatabaseRequest, Response = DatabaseResponse, Error = tower::BoxError>
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: tower::Service<DatabaseRequest, Response = DatabaseResponse, Error = tower::BoxError>>
|
|
|
|
Database for T
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2023-10-22 16:27:37 +00:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct OutputOnChain {
|
|
|
|
height: u64,
|
|
|
|
time_lock: monero_serai::transaction::Timelock,
|
|
|
|
key: curve25519_dalek::EdwardsPoint,
|
2023-10-28 23:39:22 +00:00
|
|
|
//mask: curve25519_dalek::EdwardsPoint,
|
2023-10-22 16:27:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Copy, Clone)]
|
|
|
|
pub struct ExtendedBlockHeader {
|
|
|
|
pub version: HardFork,
|
|
|
|
pub vote: HardFork,
|
|
|
|
|
|
|
|
pub timestamp: u64,
|
|
|
|
pub cumulative_difficulty: u128,
|
|
|
|
|
|
|
|
pub block_weight: usize,
|
|
|
|
pub long_term_weight: usize,
|
|
|
|
}
|
|
|
|
|
2023-09-05 18:13:46 +00:00
|
|
|
#[derive(Debug, Clone)]
|
2023-09-03 22:50:38 +00:00
|
|
|
pub enum DatabaseRequest {
|
2023-10-22 16:27:37 +00:00
|
|
|
BlockExtendedHeader(cuprate_common::BlockID),
|
2023-10-05 16:54:19 +00:00
|
|
|
BlockHash(u64),
|
2023-09-28 11:21:06 +00:00
|
|
|
|
2023-10-22 16:27:37 +00:00
|
|
|
BlockExtendedHeaderInRange(std::ops::Range<u64>),
|
2023-09-28 11:21:06 +00:00
|
|
|
|
2023-09-03 22:50:38 +00:00
|
|
|
ChainHeight,
|
2023-10-23 18:14:40 +00:00
|
|
|
GeneratedCoins,
|
2023-10-03 21:10:31 +00:00
|
|
|
|
2023-10-20 00:04:26 +00:00
|
|
|
Outputs(HashMap<u64, HashSet<u64>>),
|
|
|
|
NumberOutputsWithAmount(u64),
|
2023-10-28 23:39:22 +00:00
|
|
|
|
2023-10-24 19:17:16 +00:00
|
|
|
CheckKIsNotSpent(HashSet<[u8; 32]>),
|
2023-10-20 00:04:26 +00:00
|
|
|
|
2023-10-03 21:10:31 +00:00
|
|
|
#[cfg(feature = "binaries")]
|
|
|
|
BlockBatchInRange(std::ops::Range<u64>),
|
2023-09-03 22:50:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum DatabaseResponse {
|
2023-10-22 16:27:37 +00:00
|
|
|
BlockExtendedHeader(ExtendedBlockHeader),
|
2023-10-05 16:54:19 +00:00
|
|
|
BlockHash([u8; 32]),
|
2023-09-28 11:21:06 +00:00
|
|
|
|
2023-10-22 16:27:37 +00:00
|
|
|
BlockExtendedHeaderInRange(Vec<ExtendedBlockHeader>),
|
2023-09-28 11:21:06 +00:00
|
|
|
|
2023-10-22 16:27:37 +00:00
|
|
|
ChainHeight(u64, [u8; 32]),
|
2023-10-23 18:14:40 +00:00
|
|
|
GeneratedCoins(u64),
|
2023-10-03 21:10:31 +00:00
|
|
|
|
2023-10-22 16:27:37 +00:00
|
|
|
Outputs(HashMap<u64, HashMap<u64, OutputOnChain>>),
|
2023-10-20 00:04:26 +00:00
|
|
|
NumberOutputsWithAmount(usize),
|
|
|
|
|
2023-10-24 19:17:16 +00:00
|
|
|
CheckKIsNotSpent(bool),
|
|
|
|
|
2023-10-03 21:10:31 +00:00
|
|
|
#[cfg(feature = "binaries")]
|
2023-10-05 16:54:19 +00:00
|
|
|
BlockBatchInRange(
|
|
|
|
Vec<(
|
|
|
|
monero_serai::block::Block,
|
|
|
|
Vec<monero_serai::transaction::Transaction>,
|
|
|
|
)>,
|
|
|
|
),
|
2023-09-03 22:50:38 +00:00
|
|
|
}
|