mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-04-28 03:00:18 -04:00
consensus/state: unproposed txs from extending chain only.
Fix an index bug when generating a new fork chain.
This commit is contained in:
@@ -160,8 +160,8 @@ impl ValidatorState {
|
||||
/// chain the node is holding.
|
||||
pub fn propose(&self) -> Result<Option<BlockProposal>> {
|
||||
let epoch = self.current_epoch();
|
||||
let prev_hash = self.longest_notarized_chain_last_hash().unwrap();
|
||||
let unproposed_txs = self.unproposed_txs();
|
||||
let (prev_hash, index) = self.longest_notarized_chain_last_hash().unwrap();
|
||||
let unproposed_txs = self.unproposed_txs(index);
|
||||
|
||||
let metadata = Metadata::new(
|
||||
Timestamp::current_time(),
|
||||
@@ -186,15 +186,24 @@ impl ValidatorState {
|
||||
)))
|
||||
}
|
||||
|
||||
/// Retrieve all unconfirmed transactions not proposed in previous blocks.
|
||||
pub fn unproposed_txs(&self) -> Vec<Tx> {
|
||||
/// Retrieve all unconfirmed transactions not proposed in previous blocks
|
||||
/// of provided index chain.
|
||||
pub fn unproposed_txs(&self, index: i64) -> Vec<Tx> {
|
||||
let mut unproposed_txs = self.unconfirmed_txs.clone();
|
||||
for chain in &self.consensus.proposals {
|
||||
for proposal in &chain.proposals {
|
||||
for tx in &proposal.block.txs {
|
||||
if let Some(pos) = unproposed_txs.iter().position(|txs| *txs == *tx) {
|
||||
unproposed_txs.remove(pos);
|
||||
}
|
||||
|
||||
// If index is -1 (canonical blockchain) a new fork will be generated,
|
||||
// therefore all unproposed transactions can be included in the proposal.
|
||||
if index == -1 {
|
||||
return unproposed_txs
|
||||
}
|
||||
|
||||
// We iterate over the fork chain proposals to find already proposed
|
||||
// transactions and remove them from the local unproposed_txs vector.
|
||||
let chain = &self.consensus.proposals[index as usize];
|
||||
for proposal in &chain.proposals {
|
||||
for tx in &proposal.block.txs {
|
||||
if let Some(pos) = unproposed_txs.iter().position(|txs| *txs == *tx) {
|
||||
unproposed_txs.remove(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -203,16 +212,19 @@ impl ValidatorState {
|
||||
}
|
||||
|
||||
/// Finds the longest fully notarized blockchain the node holds and
|
||||
/// returns the last block hash.
|
||||
pub fn longest_notarized_chain_last_hash(&self) -> Result<blake3::Hash> {
|
||||
/// returns the last block hash and the chain index.
|
||||
pub fn longest_notarized_chain_last_hash(&self) -> Result<(blake3::Hash, i64)> {
|
||||
let mut longest_notarized_chain = &self.consensus.proposals[0];
|
||||
let mut length = longest_notarized_chain.proposals.len();
|
||||
let mut index = -1;
|
||||
|
||||
let hash = if !self.consensus.proposals.is_empty() {
|
||||
let mut longest_notarized_chain = &self.consensus.proposals[0];
|
||||
let mut length = longest_notarized_chain.proposals.len();
|
||||
if self.consensus.proposals.len() > 1 {
|
||||
for chain in &self.consensus.proposals[1..] {
|
||||
for (i, chain) in self.consensus.proposals.iter().enumerate() {
|
||||
if chain.notarized() && chain.proposals.len() > length {
|
||||
length = chain.proposals.len();
|
||||
longest_notarized_chain = chain;
|
||||
index = i as i64;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -222,7 +234,7 @@ impl ValidatorState {
|
||||
self.blockchain.last()?.unwrap().1
|
||||
};
|
||||
|
||||
Ok(hash)
|
||||
Ok((hash, index))
|
||||
}
|
||||
|
||||
/// Receive the proposed block, verify its sender (epoch leader),
|
||||
|
||||
Reference in New Issue
Block a user