-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* add cuprated skeleton * fmt and add deny exception * add main chain batch handler * add blockchain init * very rough block manager * misc changes * move more config values * add new tables & types * add function to fully add an alt block * resolve current todo!s * add new requests * WIP: starting re-orgs * add last service request * commit Cargo.lock * add test * more docs + cleanup + alt blocks request * clippy + fmt * document types * move tx_fee to helper * more doc updates * fmt * fix imports * remove config files * fix merge errors * fix generated coins * handle more p2p requests + alt blocks * clean up handler code * add function for incoming blocks * add docs to handler functions * broadcast new blocks + add commands * add fluffy block handler * fix new block handling * small cleanup * increase outbound peer count * fix merge * clean up the blockchain manger * add more docs + cleanup imports * fix typo * fix doc * remove unrelated changes * improve interface globals * manger -> manager * enums instead of bools * move chain service to separate file * more review fixes * add link to issue * fix syncer + update comment * fmt
- Loading branch information
Showing
22 changed files
with
1,275 additions
and
31 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,101 @@ | ||
//! Blockchain | ||
//! | ||
//! Will contain the chain manager and syncer. | ||
//! Contains the blockchain manager, syncer and an interface to mutate the blockchain. | ||
use std::sync::Arc; | ||
|
||
use futures::FutureExt; | ||
use tokio::sync::{mpsc, Notify}; | ||
use tower::{BoxError, Service, ServiceExt}; | ||
|
||
use cuprate_blockchain::service::{BlockchainReadHandle, BlockchainWriteHandle}; | ||
use cuprate_consensus::{generate_genesis_block, BlockChainContextService, ContextConfig}; | ||
use cuprate_cryptonight::cryptonight_hash_v0; | ||
use cuprate_p2p::{block_downloader::BlockDownloaderConfig, NetworkInterface}; | ||
use cuprate_p2p_core::{ClearNet, Network}; | ||
use cuprate_types::{ | ||
blockchain::{BlockchainReadRequest, BlockchainWriteRequest}, | ||
VerifiedBlockInformation, | ||
}; | ||
|
||
use crate::constants::PANIC_CRITICAL_SERVICE_ERROR; | ||
|
||
mod chain_service; | ||
pub mod interface; | ||
mod manager; | ||
mod syncer; | ||
mod types; | ||
|
||
use types::{ | ||
ConcreteBlockVerifierService, ConcreteTxVerifierService, ConsensusBlockchainReadHandle, | ||
}; | ||
|
||
/// Checks if the genesis block is in the blockchain and adds it if not. | ||
pub async fn check_add_genesis( | ||
blockchain_read_handle: &mut BlockchainReadHandle, | ||
blockchain_write_handle: &mut BlockchainWriteHandle, | ||
network: Network, | ||
) { | ||
// Try to get the chain height, will fail if the genesis block is not in the DB. | ||
if blockchain_read_handle | ||
.ready() | ||
.await | ||
.expect(PANIC_CRITICAL_SERVICE_ERROR) | ||
.call(BlockchainReadRequest::ChainHeight) | ||
.await | ||
.is_ok() | ||
{ | ||
return; | ||
} | ||
|
||
let genesis = generate_genesis_block(network); | ||
|
||
assert_eq!(genesis.miner_transaction.prefix().outputs.len(), 1); | ||
assert!(genesis.transactions.is_empty()); | ||
|
||
blockchain_write_handle | ||
.ready() | ||
.await | ||
.expect(PANIC_CRITICAL_SERVICE_ERROR) | ||
.call(BlockchainWriteRequest::WriteBlock( | ||
VerifiedBlockInformation { | ||
block_blob: genesis.serialize(), | ||
txs: vec![], | ||
block_hash: genesis.hash(), | ||
pow_hash: cryptonight_hash_v0(&genesis.serialize_pow_hash()), | ||
height: 0, | ||
generated_coins: genesis.miner_transaction.prefix().outputs[0] | ||
.amount | ||
.unwrap(), | ||
weight: genesis.miner_transaction.weight(), | ||
long_term_weight: genesis.miner_transaction.weight(), | ||
cumulative_difficulty: 1, | ||
block: genesis, | ||
}, | ||
)) | ||
.await | ||
.expect(PANIC_CRITICAL_SERVICE_ERROR); | ||
} | ||
|
||
/// Initializes the consensus services. | ||
pub async fn init_consensus( | ||
blockchain_read_handle: BlockchainReadHandle, | ||
context_config: ContextConfig, | ||
) -> Result< | ||
( | ||
ConcreteBlockVerifierService, | ||
ConcreteTxVerifierService, | ||
BlockChainContextService, | ||
), | ||
BoxError, | ||
> { | ||
let read_handle = ConsensusBlockchainReadHandle::new(blockchain_read_handle, BoxError::from); | ||
|
||
let ctx_service = | ||
cuprate_consensus::initialize_blockchain_context(context_config, read_handle.clone()) | ||
.await?; | ||
|
||
let (block_verifier_svc, tx_verifier_svc) = | ||
cuprate_consensus::initialize_verifier(read_handle, ctx_service.clone()); | ||
|
||
Ok((block_verifier_svc, tx_verifier_svc, ctx_service)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
use std::task::{Context, Poll}; | ||
|
||
use futures::{future::BoxFuture, FutureExt, TryFutureExt}; | ||
use tower::Service; | ||
|
||
use cuprate_blockchain::service::BlockchainReadHandle; | ||
use cuprate_p2p::block_downloader::{ChainSvcRequest, ChainSvcResponse}; | ||
use cuprate_types::blockchain::{BlockchainReadRequest, BlockchainResponse}; | ||
|
||
/// That service that allows retrieving the chain state to give to the P2P crates, so we can figure out | ||
/// what blocks we need. | ||
/// | ||
/// This has a more minimal interface than [`BlockchainReadRequest`] to make using the p2p crates easier. | ||
#[derive(Clone)] | ||
pub struct ChainService(pub BlockchainReadHandle); | ||
|
||
impl Service<ChainSvcRequest> for ChainService { | ||
type Response = ChainSvcResponse; | ||
type Error = tower::BoxError; | ||
type Future = BoxFuture<'static, Result<Self::Response, Self::Error>>; | ||
|
||
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { | ||
self.0.poll_ready(cx).map_err(Into::into) | ||
} | ||
|
||
fn call(&mut self, req: ChainSvcRequest) -> Self::Future { | ||
let map_res = |res: BlockchainResponse| match res { | ||
BlockchainResponse::CompactChainHistory { | ||
block_ids, | ||
cumulative_difficulty, | ||
} => ChainSvcResponse::CompactHistory { | ||
block_ids, | ||
cumulative_difficulty, | ||
}, | ||
BlockchainResponse::FindFirstUnknown(res) => ChainSvcResponse::FindFirstUnknown(res), | ||
_ => unreachable!(), | ||
}; | ||
|
||
match req { | ||
ChainSvcRequest::CompactHistory => self | ||
.0 | ||
.call(BlockchainReadRequest::CompactChainHistory) | ||
.map_ok(map_res) | ||
.map_err(Into::into) | ||
.boxed(), | ||
ChainSvcRequest::FindFirstUnknown(req) => self | ||
.0 | ||
.call(BlockchainReadRequest::FindFirstUnknown(req)) | ||
.map_ok(map_res) | ||
.map_err(Into::into) | ||
.boxed(), | ||
ChainSvcRequest::CumulativeDifficulty => self | ||
.0 | ||
.call(BlockchainReadRequest::CompactChainHistory) | ||
.map_ok(|res| { | ||
// TODO create a custom request instead of hijacking this one. | ||
// TODO: use the context cache. | ||
let BlockchainResponse::CompactChainHistory { | ||
cumulative_difficulty, | ||
.. | ||
} = res | ||
else { | ||
unreachable!() | ||
}; | ||
|
||
ChainSvcResponse::CumulativeDifficulty(cumulative_difficulty) | ||
}) | ||
.map_err(Into::into) | ||
.boxed(), | ||
} | ||
} | ||
} |
Oops, something went wrong.