Add Qc to block (#99)

* Added Qc type to Tally trait

* Add generic Qc to block header

* Use blockid instead of unnecessary header

* Expand Qc over generics

* Build up block with proper qc header
This commit is contained in:
Daniel Sanchez 2023-03-17 06:23:50 -07:00 committed by GitHub
parent 91ce4e6fa1
commit 1ec4231a7a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 86 additions and 78 deletions

View File

@ -10,25 +10,29 @@ pub type TxHash = [u8; 32];
/// A block /// A block
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Block<TxId: Clone + Eq + Hash> { pub struct Block<Qc: Clone, TxId: Clone + Eq + Hash> {
header: BlockHeader, header: BlockHeader<Qc>,
transactions: IndexSet<TxId>, transactions: IndexSet<TxId>,
} }
/// A block header /// A block header
#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize)] #[derive(Copy, Clone, Default, Debug, Serialize, Deserialize)]
pub struct BlockHeader { pub struct BlockHeader<Qc: Clone> {
id: BlockId, id: BlockId,
qc: Qc,
} }
/// Identifier of a block /// Identifier of a block
pub type BlockId = [u8; 32]; pub type BlockId = [u8; 32];
impl<TxId: Clone + Eq + Hash> Block<TxId> { impl<Qc: Clone, TxId: Clone + Eq + Hash> Block<Qc, TxId> {
pub fn new(header: BlockHeader, txs: impl Iterator<Item = TxId>) -> Self { pub fn new(qc: Qc, txs: impl Iterator<Item = TxId>) -> Self {
let transactions = txs.collect();
// FIXME: Calculate header Id
let header = BlockHeader { id: [0; 32], qc };
Self { Self {
header, header,
transactions: txs.collect(), transactions,
} }
} }
@ -37,8 +41,8 @@ impl<TxId: Clone + Eq + Hash> Block<TxId> {
Bytes::new() Bytes::new()
} }
pub fn header(&self) -> BlockHeader { pub fn header(&self) -> BlockHeader<Qc> {
self.header self.header.clone()
} }
pub fn transactions(&self) -> impl Iterator<Item = &TxId> + '_ { pub fn transactions(&self) -> impl Iterator<Item = &TxId> + '_ {
@ -46,8 +50,12 @@ impl<TxId: Clone + Eq + Hash> Block<TxId> {
} }
} }
impl BlockHeader { impl<Qc: Clone> BlockHeader<Qc> {
pub fn id(&self) -> BlockId { pub fn id(&self) -> BlockId {
self.id self.id
} }
pub fn qc(&self) -> &Qc {
&self.qc
}
} }

View File

@ -71,7 +71,8 @@ pub struct CarnotTally {
#[async_trait::async_trait] #[async_trait::async_trait]
impl Tally for CarnotTally { impl Tally for CarnotTally {
type Vote = Vote; type Vote = Vote;
type Outcome = QuorumCertificate; type Qc = QuorumCertificate;
type Outcome = ();
type TallyError = CarnotTallyError; type TallyError = CarnotTallyError;
type Settings = CarnotTallySettings; type Settings = CarnotTallySettings;
@ -83,7 +84,7 @@ impl Tally for CarnotTally {
&self, &self,
view: u64, view: u64,
mut vote_stream: S, mut vote_stream: S,
) -> Result<Self::Outcome, Self::TallyError> { ) -> Result<(Self::Qc, Self::Outcome), Self::TallyError> {
let mut approved = 0usize; let mut approved = 0usize;
let mut seen = HashSet::new(); let mut seen = HashSet::new();
while let Some(vote) = vote_stream.next().await { while let Some(vote) = vote_stream.next().await {
@ -106,10 +107,13 @@ impl Tally for CarnotTally {
seen.insert(vote.voter); seen.insert(vote.voter);
approved += 1; approved += 1;
if approved >= self.settings.threshold { if approved >= self.settings.threshold {
return Ok(QuorumCertificate::Simple(SimpleQuorumCertificate { return Ok((
view, QuorumCertificate::Simple(SimpleQuorumCertificate {
block: vote.block, view,
})); block: vote.block,
}),
(),
));
} }
} }
Err(CarnotTallyError::InsufficientVotes) Err(CarnotTallyError::InsufficientVotes)

View File

@ -46,7 +46,8 @@ impl MockQc {
#[async_trait::async_trait] #[async_trait::async_trait]
impl Tally for MockTally { impl Tally for MockTally {
type Vote = MockVote; type Vote = MockVote;
type Outcome = MockQc; type Qc = MockQc;
type Outcome = ();
type TallyError = Error; type TallyError = Error;
type Settings = MockTallySettings; type Settings = MockTallySettings;
@ -59,7 +60,7 @@ impl Tally for MockTally {
&self, &self,
view: u64, view: u64,
mut vote_stream: S, mut vote_stream: S,
) -> Result<Self::Outcome, Self::TallyError> { ) -> Result<(Self::Qc, Self::Outcome), Self::TallyError> {
let mut count_votes = 0; let mut count_votes = 0;
while let Some(vote) = vote_stream.next().await { while let Some(vote) = vote_stream.next().await {
if vote.view() != view { if vote.view() != view {
@ -67,7 +68,7 @@ impl Tally for MockTally {
} }
count_votes += 1; count_votes += 1;
if count_votes > self.threshold { if count_votes > self.threshold {
return Ok(MockQc { count_votes }); return Ok((MockQc { count_votes }, ()));
} }
} }
Err(Error("Not enough votes".into())) Err(Error("Not enough votes".into()))

View File

@ -6,6 +6,7 @@ use futures::Stream;
#[async_trait::async_trait] #[async_trait::async_trait]
pub trait Tally { pub trait Tally {
type Vote; type Vote;
type Qc;
type Outcome; type Outcome;
type TallyError; type TallyError;
type Settings: Clone; type Settings: Clone;
@ -14,5 +15,5 @@ pub trait Tally {
&self, &self,
view: u64, view: u64,
vote_stream: S, vote_stream: S,
) -> Result<Self::Outcome, Self::TallyError>; ) -> Result<(Self::Qc, Self::Outcome), Self::TallyError>;
} }

View File

@ -2,8 +2,8 @@
use std::marker::PhantomData; use std::marker::PhantomData;
// crates // crates
// internal // internal
use nomos_core::crypto::PrivateKey;
use nomos_core::tx::Transaction; use nomos_core::tx::Transaction;
use nomos_core::{block::BlockHeader, crypto::PrivateKey};
use nomos_mempool::MempoolMsg; use nomos_mempool::MempoolMsg;
use super::*; use super::*;
@ -18,9 +18,9 @@ pub struct Leadership<Tx: Transaction> {
mempool: OutboundRelay<MempoolMsg<Tx>>, mempool: OutboundRelay<MempoolMsg<Tx>>,
} }
pub enum LeadershipResult<'view, TxId: Clone + Eq + core::hash::Hash> { pub enum LeadershipResult<'view, Qc: Clone, TxId: Clone + Eq + core::hash::Hash> {
Leader { Leader {
block: Block<TxId>, block: Block<Qc, TxId>,
_view: PhantomData<&'view u8>, _view: PhantomData<&'view u8>,
}, },
NotLeader { NotLeader {
@ -41,12 +41,12 @@ where
} }
#[allow(unused, clippy::diverging_sub_expression)] #[allow(unused, clippy::diverging_sub_expression)]
pub async fn try_propose_block<'view, Qc>( pub async fn try_propose_block<'view, Qc: Clone>(
&self, &self,
view: &'view View, view: &'view View,
tip: &Tip, tip: &Tip,
qc: Qc, qc: Qc,
) -> LeadershipResult<'view, Tx::Hash> { ) -> LeadershipResult<'view, Qc, Tx::Hash> {
// TODO: get the correct ancestor for the tip // TODO: get the correct ancestor for the tip
// let ancestor_hint = todo!("get the ancestor from the tip"); // let ancestor_hint = todo!("get the ancestor from the tip");
let ancestor_hint = [0; 32]; let ancestor_hint = [0; 32];
@ -60,10 +60,7 @@ where
LeadershipResult::Leader { LeadershipResult::Leader {
_view: PhantomData, _view: PhantomData,
block: Block::new( block: Block::new(qc, iter.map(|ref tx| <Tx as Transaction>::hash(tx))),
BlockHeader::default(),
iter.map(|ref tx| <Tx as Transaction>::hash(tx)),
),
} }
} else { } else {
LeadershipResult::NotLeader { _view: PhantomData } LeadershipResult::NotLeader { _view: PhantomData }

View File

@ -80,6 +80,7 @@ where
M: MempoolAdapter<Tx = P::Tx>, M: MempoolAdapter<Tx = P::Tx>,
P: MemPool, P: MemPool,
T: Tally, T: Tally,
T::Qc: Clone,
O: Overlay<A, F, T, <P::Tx as Transaction>::Hash>, O: Overlay<A, F, T, <P::Tx as Transaction>::Hash>,
P::Tx: Transaction + Debug + 'static, P::Tx: Transaction + Debug + 'static,
<P::Tx as Transaction>::Hash: Debug, <P::Tx as Transaction>::Hash: Debug,
@ -101,6 +102,7 @@ where
A: NetworkAdapter, A: NetworkAdapter,
P: MemPool, P: MemPool,
T: Tally, T: Tally,
T::Qc: Clone,
P::Tx: Transaction + Debug, P::Tx: Transaction + Debug,
<P::Tx as Transaction>::Hash: Debug, <P::Tx as Transaction>::Hash: Debug,
M: MempoolAdapter<Tx = P::Tx>, M: MempoolAdapter<Tx = P::Tx>,
@ -122,6 +124,7 @@ where
T: Tally + Send + Sync + 'static, T: Tally + Send + Sync + 'static,
T::Settings: Send + Sync + 'static, T::Settings: Send + Sync + 'static,
T::Outcome: Send + Sync, T::Outcome: Send + Sync,
T::Qc: Clone + Send + Sync,
P::Settings: Send + Sync + 'static, P::Settings: Send + Sync + 'static,
P::Tx: Debug + Clone + serde::de::DeserializeOwned + Send + Sync + 'static, P::Tx: Debug + Clone + serde::de::DeserializeOwned + Send + Sync + 'static,
<P::Tx as Transaction>::Hash: Debug + Send + Sync, <P::Tx as Transaction>::Hash: Debug + Send + Sync,
@ -198,7 +201,7 @@ where
mempool_relay mempool_relay
.send(nomos_mempool::MempoolMsg::MarkInBlock { .send(nomos_mempool::MempoolMsg::MarkInBlock {
ids: block.transactions().cloned().collect(), ids: block.transactions().cloned().collect(),
block: block.header(), block: block.header().id(),
}) })
.await .await
.map_err(|(e, _)| { .map_err(|(e, _)| {
@ -237,7 +240,7 @@ impl View {
fountain: &F, fountain: &F,
tally: &T, tally: &T,
leadership: &Leadership<Tx>, leadership: &Leadership<Tx>,
) -> Result<(Block<Tx::Hash>, View), Box<dyn std::error::Error + Send + Sync + 'static>> ) -> Result<(Block<T::Qc, Tx::Hash>, View), Box<dyn std::error::Error + Send + Sync + 'static>>
where where
A: NetworkAdapter + Send + Sync + 'static, A: NetworkAdapter + Send + Sync + 'static,
F: FountainCode, F: FountainCode,
@ -245,6 +248,7 @@ impl View {
Tx::Hash: Debug, Tx::Hash: Debug,
T: Tally + Send + Sync + 'static, T: Tally + Send + Sync + 'static,
T::Outcome: Send + Sync, T::Outcome: Send + Sync,
T::Qc: Clone,
O: Overlay<A, F, T, Tx::Hash>, O: Overlay<A, F, T, Tx::Hash>,
{ {
let res = if self.is_leader(node_id) { let res = if self.is_leader(node_id) {
@ -277,12 +281,13 @@ impl View {
fountain: &F, fountain: &F,
tally: &T, tally: &T,
leadership: &Leadership<Tx>, leadership: &Leadership<Tx>,
) -> Result<Block<<Tx as Transaction>::Hash>, ()> ) -> Result<Block<T::Qc, <Tx as Transaction>::Hash>, ()>
where where
A: NetworkAdapter + Send + Sync + 'static, A: NetworkAdapter + Send + Sync + 'static,
F: FountainCode, F: FountainCode,
T: Tally + Send + Sync + 'static, T: Tally + Send + Sync + 'static,
T::Outcome: Send + Sync, T::Outcome: Send + Sync,
T::Qc: Clone,
Tx: Transaction, Tx: Transaction,
Tx::Hash: Debug, Tx::Hash: Debug,
O: Overlay<A, F, T, Tx::Hash>, O: Overlay<A, F, T, Tx::Hash>,
@ -309,11 +314,12 @@ impl View {
adapter: &A, adapter: &A,
fountain: &F, fountain: &F,
tally: &T, tally: &T,
) -> Result<(Block<Tx::Hash>, View), ()> ) -> Result<(Block<T::Qc, Tx::Hash>, View), ()>
where where
A: NetworkAdapter + Send + Sync + 'static, A: NetworkAdapter + Send + Sync + 'static,
F: FountainCode, F: FountainCode,
T: Tally + Send + Sync + 'static, T: Tally + Send + Sync + 'static,
T::Qc: Clone,
Tx: Transaction, Tx: Transaction,
Tx::Hash: Debug, Tx::Hash: Debug,
O: Overlay<A, F, T, Tx::Hash>, O: Overlay<A, F, T, Tx::Hash>,
@ -356,12 +362,15 @@ impl View {
} }
// Verifies the block is new and the previous leader did not fail // Verifies the block is new and the previous leader did not fail
fn pipelined_safe_block<TxId: Clone + Eq + Hash>(&self, _: &Block<TxId>) -> bool { fn pipelined_safe_block<Qc: Clone, TxId: Clone + Eq + Hash>(
&self,
_: &Block<Qc, TxId>,
) -> bool {
// return b.view_n >= self.view_n && b.view_n == b.qc.view_n // return b.view_n >= self.view_n && b.view_n == b.qc.view_n
true true
} }
fn generate_next_view<TxId: Clone + Eq + Hash>(&self, _b: &Block<TxId>) -> View { fn generate_next_view<Qc: Clone, TxId: Clone + Eq + Hash>(&self, _b: &Block<Qc, TxId>) -> View {
let mut seed = self.seed; let mut seed = self.seed;
seed[0] += 1; seed[0] += 1;
View { View {

View File

@ -117,6 +117,7 @@ where
Network: NetworkAdapter + Sync, Network: NetworkAdapter + Sync,
Fountain: FountainCode + Sync, Fountain: FountainCode + Sync,
VoteTally: Tally + Sync, VoteTally: Tally + Sync,
VoteTally::Qc: serde::de::DeserializeOwned + Clone + Send + Sync + 'static,
TxId: serde::de::DeserializeOwned + Clone + Hash + Eq + Send + Sync + 'static, TxId: serde::de::DeserializeOwned + Clone + Hash + Eq + Send + Sync + 'static,
{ {
// we still need view here to help us initialize // we still need view here to help us initialize
@ -130,13 +131,13 @@ where
view: &View, view: &View,
adapter: &Network, adapter: &Network,
fountain: &Fountain, fountain: &Fountain,
) -> Result<Block<TxId>, FountainError> { ) -> Result<Block<VoteTally::Qc, TxId>, FountainError> {
assert_eq!(view.view_n, self.view_n, "view_n mismatch"); assert_eq!(view.view_n, self.view_n, "view_n mismatch");
let committee = self.committee; let committee = self.committee;
let message_stream = adapter.proposal_chunks_stream(committee, view).await; let message_stream = adapter.proposal_chunks_stream(committee, view).await;
fountain.decode(message_stream).await.and_then(|b| { fountain.decode(message_stream).await.and_then(|b| {
deserializer(&b) deserializer(&b)
.deserialize::<Block<TxId>>() .deserialize::<Block<VoteTally::Qc, TxId>>()
.map_err(|e| FountainError::from(e.to_string().as_str())) .map_err(|e| FountainError::from(e.to_string().as_str()))
}) })
} }
@ -144,7 +145,7 @@ where
async fn broadcast_block( async fn broadcast_block(
&self, &self,
view: &View, view: &View,
block: Block<TxId>, block: Block<VoteTally::Qc, TxId>,
adapter: &Network, adapter: &Network,
fountain: &Fountain, fountain: &Fountain,
) { ) {
@ -173,7 +174,7 @@ where
async fn approve_and_forward( async fn approve_and_forward(
&self, &self,
view: &View, view: &View,
_block: &Block<TxId>, _block: &Block<VoteTally::Qc, TxId>,
_adapter: &Network, _adapter: &Network,
_tally: &VoteTally, _tally: &VoteTally,
_next_view: &View, _next_view: &View,
@ -189,12 +190,7 @@ where
todo!() todo!()
} }
async fn build_qc( async fn build_qc(&self, view: &View, _adapter: &Network, _tally: &VoteTally) -> VoteTally::Qc {
&self,
view: &View,
_adapter: &Network,
_tally: &VoteTally,
) -> VoteTally::Outcome {
assert_eq!(view.view_n, self.view_n, "view_n mismatch"); assert_eq!(view.view_n, self.view_n, "view_n mismatch");
// maybe the leader publishing the QC? // maybe the leader publishing the QC?
todo!() todo!()

View File

@ -18,36 +18,32 @@ const FLAT_COMMITTEE: Committee = Committee::root();
/// As far as the API is concerned, this should be equivalent to any other /// As far as the API is concerned, this should be equivalent to any other
/// overlay and far simpler to implement. /// overlay and far simpler to implement.
/// For this reason, this might act as a 'reference' overlay for testing. /// For this reason, this might act as a 'reference' overlay for testing.
pub struct Flat<TxId> { pub struct Flat {
// TODO: this should be a const param, but we can't do that yet // TODO: this should be a const param, but we can't do that yet
node_id: NodeId, node_id: NodeId,
view_n: u64, view_n: u64,
_marker: std::marker::PhantomData<TxId>,
} }
impl<TxId: Clone + Eq + Hash> Flat<TxId> { impl Flat {
pub fn new(view_n: u64, node_id: NodeId) -> Self { pub fn new(view_n: u64, node_id: NodeId) -> Self {
Self { Self { node_id, view_n }
node_id,
view_n,
_marker: Default::default(),
}
} }
fn approve(&self, _block: &Block<TxId>) -> Approval { fn approve<Qc: Clone, TxId: Clone + Eq + Hash>(&self, _block: &Block<Qc, TxId>) -> Approval {
// we still need to define how votes look like // we still need to define how votes look like
Approval Approval
} }
} }
#[async_trait::async_trait] #[async_trait::async_trait]
impl<Network, Fountain, VoteTally, TxId> Overlay<Network, Fountain, VoteTally, TxId> for Flat<TxId> impl<Network, Fountain, VoteTally, TxId> Overlay<Network, Fountain, VoteTally, TxId> for Flat
where where
TxId: serde::de::DeserializeOwned + Clone + Eq + Hash + Send + Sync + 'static, TxId: serde::de::DeserializeOwned + Clone + Eq + Hash + Send + Sync + 'static,
Network: NetworkAdapter + Sync, Network: NetworkAdapter + Sync,
Fountain: FountainCode + Sync, Fountain: FountainCode + Sync,
VoteTally: Tally + Sync, VoteTally: Tally + Sync,
VoteTally::Vote: Serialize + DeserializeOwned + Send, VoteTally::Vote: Serialize + DeserializeOwned + Send,
VoteTally::Qc: Clone + DeserializeOwned + Send + Sync + 'static,
{ {
fn new(view: &View, node: NodeId) -> Self { fn new(view: &View, node: NodeId) -> Self {
Flat::new(view.view_n, node) Flat::new(view.view_n, node)
@ -58,12 +54,12 @@ where
view: &View, view: &View,
adapter: &Network, adapter: &Network,
fountain: &Fountain, fountain: &Fountain,
) -> Result<Block<TxId>, FountainError> { ) -> Result<Block<VoteTally::Qc, TxId>, FountainError> {
assert_eq!(view.view_n, self.view_n, "view_n mismatch"); assert_eq!(view.view_n, self.view_n, "view_n mismatch");
let message_stream = adapter.proposal_chunks_stream(FLAT_COMMITTEE, view).await; let message_stream = adapter.proposal_chunks_stream(FLAT_COMMITTEE, view).await;
fountain.decode(message_stream).await.and_then(|b| { fountain.decode(message_stream).await.and_then(|b| {
deserializer(&b) deserializer(&b)
.deserialize::<Block<TxId>>() .deserialize::<Block<VoteTally::Qc, TxId>>()
.map_err(|e| FountainError::from(e.to_string().as_str())) .map_err(|e| FountainError::from(e.to_string().as_str()))
}) })
} }
@ -71,7 +67,7 @@ where
async fn broadcast_block( async fn broadcast_block(
&self, &self,
view: &View, view: &View,
block: Block<TxId>, block: Block<VoteTally::Qc, TxId>,
adapter: &Network, adapter: &Network,
fountain: &Fountain, fountain: &Fountain,
) { ) {
@ -91,7 +87,7 @@ where
async fn approve_and_forward( async fn approve_and_forward(
&self, &self,
view: &View, view: &View,
block: &Block<TxId>, block: &Block<VoteTally::Qc, TxId>,
adapter: &Network, adapter: &Network,
_tally: &VoteTally, _tally: &VoteTally,
_next_view: &View, _next_view: &View,
@ -112,12 +108,7 @@ where
Ok(()) Ok(())
} }
async fn build_qc( async fn build_qc(&self, view: &View, adapter: &Network, tally: &VoteTally) -> VoteTally::Qc {
&self,
view: &View,
adapter: &Network,
tally: &VoteTally,
) -> VoteTally::Outcome {
assert_eq!(view.view_n, self.view_n, "view_n mismatch"); assert_eq!(view.view_n, self.view_n, "view_n mismatch");
// for now, let's pretend that consensus is reached as soon as the // for now, let's pretend that consensus is reached as soon as the
@ -126,7 +117,7 @@ where
// Shadow the original binding so that it can't be directly accessed // Shadow the original binding so that it can't be directly accessed
// ever again. // ever again.
if let Ok(qc) = tally.tally(view.view_n, stream).await { if let Ok((qc, _)) = tally.tally(view.view_n, stream).await {
qc qc
} else { } else {
unimplemented!("consensus not reached") unimplemented!("consensus not reached")

View File

@ -20,7 +20,8 @@ pub trait Overlay<
Fountain: FountainCode, Fountain: FountainCode,
VoteTally: Tally, VoteTally: Tally,
TxId: Clone + Eq + Hash, TxId: Clone + Eq + Hash,
> > where
VoteTally::Qc: Clone,
{ {
fn new(view: &View, node: NodeId) -> Self; fn new(view: &View, node: NodeId) -> Self;
@ -29,11 +30,11 @@ pub trait Overlay<
view: &View, view: &View,
adapter: &Network, adapter: &Network,
fountain: &Fountain, fountain: &Fountain,
) -> Result<Block<TxId>, FountainError>; ) -> Result<Block<VoteTally::Qc, TxId>, FountainError>;
async fn broadcast_block( async fn broadcast_block(
&self, &self,
view: &View, view: &View,
block: Block<TxId>, block: Block<VoteTally::Qc, TxId>,
adapter: &Network, adapter: &Network,
fountain: &Fountain, fountain: &Fountain,
); );
@ -43,7 +44,7 @@ pub trait Overlay<
async fn approve_and_forward( async fn approve_and_forward(
&self, &self,
view: &View, view: &View,
block: &Block<TxId>, block: &Block<VoteTally::Qc, TxId>,
adapter: &Network, adapter: &Network,
vote_tally: &VoteTally, vote_tally: &VoteTally,
next_view: &View, next_view: &View,
@ -54,5 +55,5 @@ pub trait Overlay<
view: &View, view: &View,
adapter: &Network, adapter: &Network,
vote_tally: &VoteTally, vote_tally: &VoteTally,
) -> VoteTally::Outcome; ) -> VoteTally::Qc;
} }

View File

@ -6,7 +6,7 @@ use std::{collections::BTreeMap, time::UNIX_EPOCH};
// crates // crates
// internal // internal
use crate::backend::{MemPool, MempoolError}; use crate::backend::{MemPool, MempoolError};
use nomos_core::block::{BlockHeader, BlockId}; use nomos_core::block::BlockId;
use nomos_core::tx::Transaction; use nomos_core::tx::Transaction;
/// A mock mempool implementation that stores all transactions in memory in the order received. /// A mock mempool implementation that stores all transactions in memory in the order received.
@ -73,16 +73,16 @@ where
Box::new(pending_txs.into_iter()) Box::new(pending_txs.into_iter())
} }
fn mark_in_block(&mut self, txs: &[<Self::Tx as Transaction>::Hash], block: BlockHeader) { fn mark_in_block(&mut self, txs: &[<Self::Tx as Transaction>::Hash], block: BlockId) {
let mut txs_in_block = Vec::with_capacity(txs.len()); let mut txs_in_block = Vec::with_capacity(txs.len());
for tx_id in txs.iter() { for tx_id in txs.iter() {
if let Some(tx) = self.pending_txs.remove(tx_id) { if let Some(tx) = self.pending_txs.remove(tx_id) {
txs_in_block.push(tx); txs_in_block.push(tx);
} }
} }
let block_entry = self.in_block_txs.entry(block.id()).or_default(); let block_entry = self.in_block_txs.entry(block).or_default();
self.in_block_txs_by_id self.in_block_txs_by_id
.extend(txs.iter().cloned().map(|tx| (tx, block.id()))); .extend(txs.iter().cloned().map(|tx| (tx, block)));
block_entry.append(&mut txs_in_block); block_entry.append(&mut txs_in_block);
} }

View File

@ -1,7 +1,7 @@
#[cfg(feature = "mock")] #[cfg(feature = "mock")]
pub mod mockpool; pub mod mockpool;
use nomos_core::block::{BlockHeader, BlockId}; use nomos_core::block::BlockId;
use nomos_core::tx::Transaction; use nomos_core::tx::Transaction;
#[derive(thiserror::Error, Debug)] #[derive(thiserror::Error, Debug)]
@ -30,7 +30,7 @@ pub trait MemPool {
fn view(&self, ancestor_hint: BlockId) -> Box<dyn Iterator<Item = Self::Tx> + Send>; fn view(&self, ancestor_hint: BlockId) -> Box<dyn Iterator<Item = Self::Tx> + Send>;
/// Record that a set of transactions were included in a block /// Record that a set of transactions were included in a block
fn mark_in_block(&mut self, txs: &[<Self::Tx as Transaction>::Hash], block: BlockHeader); fn mark_in_block(&mut self, txs: &[<Self::Tx as Transaction>::Hash], block: BlockId);
/// Returns all of the transactions for the block /// Returns all of the transactions for the block
#[cfg(test)] #[cfg(test)]

View File

@ -10,7 +10,7 @@ use tokio::sync::oneshot::Sender;
// internal // internal
use crate::network::NetworkAdapter; use crate::network::NetworkAdapter;
use backend::MemPool; use backend::MemPool;
use nomos_core::block::{BlockHeader, BlockId}; use nomos_core::block::BlockId;
use nomos_core::tx::Transaction; use nomos_core::tx::Transaction;
use nomos_network::NetworkService; use nomos_network::NetworkService;
use overwatch_rs::services::{ use overwatch_rs::services::{
@ -57,7 +57,7 @@ pub enum MempoolMsg<Tx: Transaction> {
}, },
MarkInBlock { MarkInBlock {
ids: Vec<Tx::Hash>, ids: Vec<Tx::Hash>,
block: BlockHeader, block: BlockId,
}, },
Metrics { Metrics {
reply_channel: Sender<MempoolMetrics>, reply_channel: Sender<MempoolMetrics>,