Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: allow multiple concurrent transactions into the same block #970

Open
wants to merge 12 commits into
base: development
Choose a base branch
from
10 changes: 9 additions & 1 deletion dan_layer/consensus/src/hotstuff/on_propose.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,15 @@ where TConsensusSpec: ConsensusSpec
// prepared. We can now propose to Accept it. We also propose the decision change which everyone
// should agree with if they received the same foreign LocalPrepare.
TransactionPoolStage::LocalPrepared => {
let involved = local_committee_shard.count_distinct_shards(t.transaction().evidence.shards_iter());
// For now we need to treat transactions without versions in a special case
// TODO: update the evidence after execution so all transactions are treated equally here
let db_transaction = t.get_transaction(tx)?;
let involved = if db_transaction.transaction().has_inputs_without_version() {
db_transaction.transaction().all_inputs_iter().count()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The number of inputs is not necessarily (and usually not) the number of involved shards

} else {
local_committee_shard.count_distinct_shards(t.transaction().evidence.shards_iter())
};

let involved = NonZeroU64::new(involved as u64).ok_or_else(|| {
HotStuffError::InvariantError(format!(
"Number of involved shards is zero for transaction {}",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -630,8 +630,15 @@ where TConsensusSpec: ConsensusSpec
return Ok(None);
}

let distinct_shards =
local_committee_shard.count_distinct_shards(tx_rec.transaction().evidence.shards_iter());
// For now we need to treat transactions without versions in a special case
// TODO: update the evidence after execution so all transactions are treated equally here
let executed = self.get_executed_transaction(tx, &t.id, &mut executor)?;
let transaction = executed.transaction();
let distinct_shards = if transaction.has_inputs_without_version() {
transaction.all_inputs_iter().count()
} else {
local_committee_shard.count_distinct_shards(tx_rec.transaction().evidence.shards_iter())
};
let distinct_shards = NonZeroU64::new(distinct_shards as u64).ok_or_else(|| {
HotStuffError::InvariantError(format!(
"Distinct shards is zero for transaction {} in block {}",
Expand Down
60 changes: 40 additions & 20 deletions dan_layer/storage/src/consensus_models/executed_transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,27 +144,47 @@ impl ExecutedTransaction {
}

pub fn to_initial_evidence(&self) -> Evidence {
// Note that we only add evidence for inputs that have specific version numbers
let mut deduped_evidence = HashMap::new();
deduped_evidence.extend(self.transaction.inputs().iter().map(|input| {
(input.to_substate_address(), ShardEvidence {
qc_ids: IndexSet::new(),
lock: LockFlag::Write,
})
}));

deduped_evidence.extend(self.transaction.input_refs().iter().map(|input_ref| {
(input_ref.to_substate_address(), ShardEvidence {
qc_ids: IndexSet::new(),
lock: LockFlag::Read,
})
}));

deduped_evidence.extend(self.transaction.filled_inputs().iter().map(|input_ref| {
(input_ref.to_substate_address(), ShardEvidence {
qc_ids: IndexSet::new(),
lock: LockFlag::Write,
})
}));

deduped_evidence.extend(
self.transaction
.inputs()
.iter()
.filter(|i| i.version().is_some())
.map(|input| {
(input.to_substate_address(), ShardEvidence {
qc_ids: IndexSet::new(),
lock: LockFlag::Write,
})
}),
);

deduped_evidence.extend(
self.transaction
.input_refs()
.iter()
.filter(|i| i.version().is_some())
.map(|input_ref| {
(input_ref.to_substate_address(), ShardEvidence {
qc_ids: IndexSet::new(),
lock: LockFlag::Read,
})
}),
);

deduped_evidence.extend(
self.transaction
.filled_inputs()
.iter()
.filter(|i| i.version().is_some())
.map(|input_ref| {
(input_ref.to_substate_address(), ShardEvidence {
qc_ids: IndexSet::new(),
lock: LockFlag::Write,
})
}),
);

let tx_reciept_address = SubstateAddress::for_transaction_receipt(self.id().into_receipt_address());
deduped_evidence.extend(
Expand Down