From 0ca35044fbab7daf12f2b6d5a0323283ae5dbce3 Mon Sep 17 00:00:00 2001 From: Stan Bondi Date: Thu, 5 Sep 2024 16:18:31 +0400 Subject: [PATCH] fix(consensus)!: fix block and leader fee proposals (#1133) Description --- Fixes leader and block fee proposals Motivation and Context --- total_leader_fee was always 0 in blocks. How Has This Been Tested? --- Manually What process can a PR reviewer use to test or verify this change? --- Check the total_leader fee > 0 in blocks with LocalOnly/AllAccept Breaking Changes --- - [ ] None - [x] Requires data directory to be deleted - [ ] Other - Please specify --- .../consensus/src/hotstuff/on_propose.rs | 64 ++++++------- .../on_ready_to_vote_on_local_block.rs | 91 +++++++++++++++++-- dan_layer/consensus_tests/src/consensus.rs | 2 - dan_layer/engine_types/src/substate.rs | 4 + .../up.sql | 37 ++++---- dan_layer/state_store_sqlite/src/reader.rs | 2 + dan_layer/state_store_sqlite/src/schema.rs | 7 +- .../src/sql_models/transaction_pool.rs | 33 +++---- dan_layer/state_store_sqlite/src/writer.rs | 8 ++ .../src/consensus_models/transaction_pool.rs | 4 +- .../transaction_pool_status_update.rs | 10 +- .../templates/tariswap/src/lib.rs | 2 +- 12 files changed, 172 insertions(+), 92 deletions(-) diff --git a/dan_layer/consensus/src/hotstuff/on_propose.rs b/dan_layer/consensus/src/hotstuff/on_propose.rs index ce3185f0b..0bd6e32c9 100644 --- a/dan_layer/consensus/src/hotstuff/on_propose.rs +++ b/dan_layer/consensus/src/hotstuff/on_propose.rs @@ -281,11 +281,11 @@ where TConsensusSpec: ConsensusSpec // Leader thinks that all local nodes agree that all shard groups have prepared, we are ready to accept // locally - TransactionPoolStage::AllPrepared => self.local_accept_transaction(local_committee_info, &mut tx_rec), - // Leader thinks local nodes are ready to accept an ABORT - TransactionPoolStage::SomePrepared => Ok(Some(Command::LocalAccept( - self.get_current_transaction_atom(local_committee_info, &mut tx_rec)?, + TransactionPoolStage::AllPrepared => Ok(Some(Command::LocalAccept( + self.get_transaction_atom_with_leader_fee(local_committee_info, &mut tx_rec)?, ))), + // Leader thinks local nodes are ready to accept an ABORT + TransactionPoolStage::SomePrepared => Ok(Some(Command::LocalAccept(tx_rec.get_current_transaction_atom()))), // Leader thinks that all foreign ACCEPT pledges have been received and, we are ready to accept the result // (COMMIT/ABORT) TransactionPoolStage::LocalAccepted => { @@ -641,11 +641,11 @@ where TConsensusSpec: ConsensusSpec "🏠️ Transaction {} is local only, proposing LocalOnly", tx_rec.transaction_id(), ); - let involved = NonZeroU64::new(1).expect("1 > 0"); - let leader_fee = tx_rec.calculate_leader_fee(involved, EXHAUST_DIVISOR); - tx_rec.set_leader_fee(leader_fee); - let atom = tx_rec.get_current_transaction_atom(); - if atom.decision.is_commit() { + + if tx_rec.current_decision().is_commit() { + let involved = NonZeroU64::new(1).expect("1 > 0"); + let leader_fee = tx_rec.calculate_leader_fee(involved, EXHAUST_DIVISOR); + tx_rec.set_leader_fee(leader_fee); let diff = execution.result().finalize.result.accept().ok_or_else(|| { HotStuffError::InvariantError(format!( "prepare_transaction: Transaction {} has COMMIT decision but execution failed when \ @@ -668,6 +668,7 @@ where TConsensusSpec: ConsensusSpec executed_transactions.insert(*tx_rec.transaction_id(), execution); + let atom = tx_rec.get_current_transaction_atom(); Command::LocalOnly(atom) }, PreparedTransaction::LocalOnly(LocalPreparedTransaction::EarlyAbort { transaction, .. }) => { @@ -743,7 +744,7 @@ where TConsensusSpec: ConsensusSpec ) -> Result, HotStuffError> { // Only set to abort if either the local or one or more foreign shards decided to ABORT if tx_rec.current_decision().is_abort() { - return Ok(Some(Command::SomePrepare(tx_rec.get_local_transaction_atom()))); + return Ok(Some(Command::SomePrepare(tx_rec.get_current_transaction_atom()))); } let mut execution = @@ -771,27 +772,15 @@ where TConsensusSpec: ConsensusSpec tx_rec.update_from_execution(&execution); executed_transactions.insert(*tx_rec.transaction_id(), execution); - return Ok(Some(Command::AllPrepare( - self.get_current_transaction_atom(local_committee_info, tx_rec)?, - ))); + return Ok(Some(Command::AllPrepare(tx_rec.get_current_transaction_atom()))); } tx_rec.update_from_execution(&execution); - let atom = self.get_current_transaction_atom(local_committee_info, tx_rec)?; executed_transactions.insert(*tx_rec.transaction_id(), execution); // If we locally decided to ABORT, we are still saying that we think all prepared. When we enter the acceptance // phase, we will propose SomeAccept for this case. - Ok(Some(Command::AllPrepare(atom))) - } - - fn local_accept_transaction( - &self, - local_committee_info: &CommitteeInfo, - tx_rec: &mut TransactionPoolRecord, - ) -> Result, HotStuffError> { - let atom = self.get_current_transaction_atom(local_committee_info, tx_rec)?; - Ok(Some(Command::LocalAccept(atom))) + Ok(Some(Command::AllPrepare(tx_rec.get_current_transaction_atom()))) } fn accept_transaction( @@ -825,24 +814,27 @@ where TConsensusSpec: ConsensusSpec *tx_rec.transaction_id(), &filter_diff_for_committee(local_committee_info, diff), )?; - Ok(Some(Command::AllAccept(tx_rec.get_current_transaction_atom()))) + let atom = self.get_transaction_atom_with_leader_fee(local_committee_info, tx_rec)?; + Ok(Some(Command::AllAccept(atom))) } - fn get_current_transaction_atom( + fn get_transaction_atom_with_leader_fee( &self, local_committee_info: &CommitteeInfo, tx_rec: &mut TransactionPoolRecord, ) -> Result { - let num_involved_shard_groups = - local_committee_info.count_distinct_shard_groups(tx_rec.evidence().substate_addresses_iter()); - let involved = NonZeroU64::new(num_involved_shard_groups as u64).ok_or_else(|| { - HotStuffError::InvariantError(format!( - "PROPOSE: Transaction {} involves zero shard groups", - tx_rec.transaction_id(), - )) - })?; - let leader_fee = tx_rec.calculate_leader_fee(involved, EXHAUST_DIVISOR); - tx_rec.set_leader_fee(leader_fee); + if tx_rec.current_decision().is_commit() { + let num_involved_shard_groups = + local_committee_info.count_distinct_shard_groups(tx_rec.evidence().substate_addresses_iter()); + let involved = NonZeroU64::new(num_involved_shard_groups as u64).ok_or_else(|| { + HotStuffError::InvariantError(format!( + "PROPOSE: Transaction {} involves zero shard groups", + tx_rec.transaction_id(), + )) + })?; + let leader_fee = tx_rec.calculate_leader_fee(involved, EXHAUST_DIVISOR); + tx_rec.set_leader_fee(leader_fee); + } let atom = tx_rec.get_current_transaction_atom(); Ok(atom) } diff --git a/dan_layer/consensus/src/hotstuff/on_ready_to_vote_on_local_block.rs b/dan_layer/consensus/src/hotstuff/on_ready_to_vote_on_local_block.rs index 6844a2dc4..406ecdeaf 100644 --- a/dan_layer/consensus/src/hotstuff/on_ready_to_vote_on_local_block.rs +++ b/dan_layer/consensus/src/hotstuff/on_ready_to_vote_on_local_block.rs @@ -360,7 +360,14 @@ where TConsensusSpec: ConsensusSpec } }, Command::LocalAccept(atom) => { - if !self.evaluate_local_accept_command(tx, block, &locked_block, atom, proposed_block_change_set)? { + if !self.evaluate_local_accept_command( + tx, + block, + &locked_block, + atom, + local_committee_info, + proposed_block_change_set, + )? { proposed_block_change_set.no_vote(); return Ok(()); } @@ -374,6 +381,7 @@ where TConsensusSpec: ConsensusSpec local_committee_info, &mut substate_store, proposed_block_change_set, + &mut total_leader_fee, )? { proposed_block_change_set.no_vote(); return Ok(()); @@ -919,10 +927,12 @@ where TConsensusSpec: ConsensusSpec err ); - tx_rec.set_local_decision(Decision::Abort); execution.set_abort_reason(RejectReason::FailedToLockOutputs(err.to_string())); + tx_rec.set_local_decision(Decision::Abort); + tx_rec.set_transaction_fee(0); tx_rec.set_next_stage(TransactionPoolStage::AllPrepared, true)?; + proposed_block_change_set .set_next_transaction_update(tx_rec)? .add_transaction_execution(execution)?; @@ -1062,6 +1072,7 @@ where TConsensusSpec: ConsensusSpec block: &Block, locked_block: &LockedBlock, atom: &TransactionAtom, + local_committee_info: &CommitteeInfo, proposed_block_change_set: &mut ProposedBlockChangeSet, ) -> Result { let Some(mut tx_rec) = @@ -1115,6 +1126,39 @@ where TConsensusSpec: ConsensusSpec return Ok(false); } + if atom.decision.is_commit() { + let Some(ref leader_fee) = atom.leader_fee else { + warn!( + target: LOG_TARGET, + "❌ NO VOTE: Leader fee in tx {} not set for AllAccept command in block {}", + atom.id, + block, + ); + return Ok(false); + }; + + // Check the leader fee in the local accept phase. The fee only applied (is added to the block fee) for + // AllAccept + let num_involved_shard_groups = + local_committee_info.count_distinct_shard_groups(tx_rec.evidence().substate_addresses_iter()); + let involved = NonZeroU64::new(num_involved_shard_groups as u64) + .ok_or_else(|| HotStuffError::InvariantError("Number of involved shard groups is 0".to_string()))?; + let calculated_leader_fee = tx_rec.calculate_leader_fee(involved, EXHAUST_DIVISOR); + if calculated_leader_fee != *leader_fee { + warn!( + target: LOG_TARGET, + "❌ NO VOTE: LocalAccept leader fee disagreement for block {}. Leader proposed {}, we calculated {}", + block, + atom.leader_fee.as_ref().expect("None already checked"), + calculated_leader_fee + ); + + return Ok(false); + } + + tx_rec.set_leader_fee(calculated_leader_fee); + } + tx_rec.set_next_stage( TransactionPoolStage::LocalAccepted, tx_rec.evidence().all_addresses_justified(), @@ -1133,11 +1177,12 @@ where TConsensusSpec: ConsensusSpec local_committee_info: &CommitteeInfo, substate_store: &mut PendingSubstateStore, proposed_block_change_set: &mut ProposedBlockChangeSet, + total_leader_fee: &mut u64, ) -> Result { if atom.decision.is_abort() { warn!( target: LOG_TARGET, - "❌ AllAccept command received for block {} but requires that the transaction is COMMIT", + "❌ NO VOTE: AllAccept command received for block {} but requires that the transaction is COMMIT", block.id(), ); return Ok(false); @@ -1148,7 +1193,7 @@ where TConsensusSpec: ConsensusSpec else { warn!( target: LOG_TARGET, - "⚠️ Local proposal received ({}) for transaction {} which is not in the pool. This is likely a previous transaction that has been re-proposed. Not voting on block.", + "⚠️ NO VOTE: Local proposal received ({}) for transaction {} which is not in the pool. This is likely a previous transaction that has been re-proposed. Not voting on block.", block, atom.id(), ); @@ -1158,7 +1203,7 @@ where TConsensusSpec: ConsensusSpec if !tx_rec.current_stage().is_local_accepted() { warn!( target: LOG_TARGET, - "{} ❌ AllAccept Stage disagreement in block {} for transaction {}. Leader proposed AllAccept, but local stage is {}", + "{} ❌ NO VOTE: AllAccept Stage disagreement in block {} for transaction {}. Leader proposed AllAccept, but local stage is {}", self.local_validator_pk, block, tx_rec.transaction_id(), @@ -1170,7 +1215,7 @@ where TConsensusSpec: ConsensusSpec if tx_rec.current_decision().is_abort() { warn!( target: LOG_TARGET, - "❌ AllAccept decision disagreement for transaction {} in block {}. Leader proposed COMMIT, we decided ABORT", + "❌ NO VOTE: AllAccept decision disagreement for transaction {} in block {}. Leader proposed COMMIT, we decided ABORT", tx_rec.transaction_id(), block, ); @@ -1180,7 +1225,7 @@ where TConsensusSpec: ConsensusSpec if tx_rec.transaction_fee() != atom.transaction_fee { warn!( target: LOG_TARGET, - "❌ AllAccept transaction fee disagreement tx {} in block {}. Leader proposed {}, we calculated {}", + "❌ NO VOTE: AllAccept transaction fee disagreement tx {} in block {}. Leader proposed {}, we calculated {}", tx_rec.transaction_id(), block, atom.transaction_fee, @@ -1189,6 +1234,36 @@ where TConsensusSpec: ConsensusSpec return Ok(false); } + let Some(ref leader_fee) = atom.leader_fee else { + warn!( + target: LOG_TARGET, + "❌ NO VOTE: Leader fee in tx {} not set for AllAccept command in block {}", + atom.id, + block, + ); + return Ok(false); + }; + + let local_leader_fee = tx_rec.leader_fee().ok_or_else(|| { + HotStuffError::InvariantError(format!( + "evaluate_all_accept_command: Transaction {} has COMMIT decision and is at LocalAccepted stage but \ + leader fee is missing", + tx_rec.transaction_id() + )) + })?; + + if local_leader_fee != leader_fee { + warn!( + target: LOG_TARGET, + "❌ NO VOTE: Leader fee disagreement for tx {} in block {}. Leader proposed {}, we calculated {}", + atom.id, + block, + leader_fee, + local_leader_fee + ); + return Ok(false); + } + let execution = BlockTransactionExecution::get_pending_for_block(tx, tx_rec.transaction_id(), block.parent()) .optional()? .ok_or_else(|| { @@ -1205,6 +1280,8 @@ where TConsensusSpec: ConsensusSpec )) })?; + *total_leader_fee += leader_fee.fee(); + substate_store.put_diff( *tx_rec.transaction_id(), &filter_diff_for_committee(local_committee_info, diff), diff --git a/dan_layer/consensus_tests/src/consensus.rs b/dan_layer/consensus_tests/src/consensus.rs index af1407220..ee6a665c6 100644 --- a/dan_layer/consensus_tests/src/consensus.rs +++ b/dan_layer/consensus_tests/src/consensus.rs @@ -382,8 +382,6 @@ async fn foreign_shard_group_decides_to_abort() { async fn multishard_local_inputs_foreign_outputs() { setup_logger(); let mut test = Test::builder() - // Test can take 11s, this could cut it a little fine - may indicate that we need to optimise - .with_test_timeout(Duration::from_secs(60)) .add_committee(0, vec!["1", "2"]) .add_committee(1, vec!["3", "4"]) .start() diff --git a/dan_layer/engine_types/src/substate.rs b/dan_layer/engine_types/src/substate.rs index fc3cef8bd..b1efd0ff0 100644 --- a/dan_layer/engine_types/src/substate.rs +++ b/dan_layer/engine_types/src/substate.rs @@ -261,6 +261,10 @@ impl SubstateId { pub fn is_transaction_receipt(&self) -> bool { matches!(self, Self::TransactionReceipt(_)) } + + pub fn is_read_only(&self) -> bool { + matches!(self, Self::TransactionReceipt(_) | Self::Resource(_)) + } } impl From for SubstateId { diff --git a/dan_layer/state_store_sqlite/migrations/2023-06-08-091819_create_state_store/up.sql b/dan_layer/state_store_sqlite/migrations/2023-06-08-091819_create_state_store/up.sql index a316065c6..d905ef783 100644 --- a/dan_layer/state_store_sqlite/migrations/2023-06-08-091819_create_state_store/up.sql +++ b/dan_layer/state_store_sqlite/migrations/2023-06-08-091819_create_state_store/up.sql @@ -300,21 +300,20 @@ create unique index transaction_executions_uniq_block_id_transaction_id on trans create table transaction_pool ( - id integer not null primary key AUTOINCREMENT, - transaction_id text not null, - original_decision text not null, - local_decision text null, - remote_decision text null, - evidence text null, - transaction_fee bigint null, - leader_fee bigint null, - global_exhaust_burn bigint null, - stage text not null, - pending_stage text null, - is_ready boolean not null, - confirm_stage text null, - updated_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + id integer not null primary key AUTOINCREMENT, + transaction_id text not null, + original_decision text not null, + local_decision text null, + remote_decision text null, + evidence text null, + transaction_fee bigint not null DEFAULT 0, + leader_fee text null, + stage text not null, + pending_stage text null, + is_ready boolean not null, + confirm_stage text null, + updated_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (transaction_id) REFERENCES transactions (transaction_id) ); create unique index transaction_pool_uniq_idx_transaction_id on transaction_pool (transaction_id); @@ -330,6 +329,8 @@ create table transaction_pool_state_updates evidence text not null, is_ready boolean not null, local_decision text not null, + transaction_fee bigint not null, + leader_fee text null, remote_decision text null, is_applied boolean not null DEFAULT '0', created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, @@ -521,7 +522,6 @@ BEGIN new_evidence, transaction_fee, leader_fee, - global_exhaust_burn, stage, new_stage, pending_stage, @@ -539,9 +539,8 @@ BEGIN OLD.remote_decision, OLD.evidence, NEW.evidence, - OLD.transaction_fee, - OLD.leader_fee, - OLD.global_exhaust_burn, + NEW.transaction_fee, + NEW.leader_fee, OLD.stage, NEW.stage, OLD.pending_stage, diff --git a/dan_layer/state_store_sqlite/src/reader.rs b/dan_layer/state_store_sqlite/src/reader.rs index 43bc607fa..89b3f7621 100644 --- a/dan_layer/state_store_sqlite/src/reader.rs +++ b/dan_layer/state_store_sqlite/src/reader.rs @@ -212,6 +212,8 @@ impl<'a, TAddr: NodeAddressable + Serialize + DeserializeOwned + 'a> SqliteState evidence, is_ready, local_decision, + transaction_fee, + leader_fee, remote_decision, is_applied, created_at diff --git a/dan_layer/state_store_sqlite/src/schema.rs b/dan_layer/state_store_sqlite/src/schema.rs index 0c93c7306..d800e9eaf 100644 --- a/dan_layer/state_store_sqlite/src/schema.rs +++ b/dan_layer/state_store_sqlite/src/schema.rs @@ -371,9 +371,8 @@ diesel::table! { local_decision -> Nullable, remote_decision -> Nullable, evidence -> Nullable, - transaction_fee -> Nullable, - leader_fee -> Nullable, - global_exhaust_burn -> Nullable, + transaction_fee -> BigInt, + leader_fee -> Nullable, stage -> Text, pending_stage -> Nullable, is_ready -> Bool, @@ -420,6 +419,8 @@ diesel::table! { evidence -> Text, is_ready -> Bool, local_decision -> Text, + transaction_fee -> BigInt, + leader_fee -> Nullable, remote_decision -> Nullable, is_applied -> Bool, created_at -> Timestamp, diff --git a/dan_layer/state_store_sqlite/src/sql_models/transaction_pool.rs b/dan_layer/state_store_sqlite/src/sql_models/transaction_pool.rs index a47afda4b..24893274b 100644 --- a/dan_layer/state_store_sqlite/src/sql_models/transaction_pool.rs +++ b/dan_layer/state_store_sqlite/src/sql_models/transaction_pool.rs @@ -19,9 +19,8 @@ pub struct TransactionPoolRecord { pub local_decision: Option, pub remote_decision: Option, pub evidence: Option, - pub transaction_fee: Option, - pub leader_fee: Option, - pub global_exhaust_burn: Option, + pub transaction_fee: i64, + pub leader_fee: Option, pub stage: String, // TODO: This is the last stage update, but does not reflect the actual stage (which comes from the // transaction_pool_state_updates table). This is kind of a hack to make transaction_pool_count work @@ -48,6 +47,8 @@ impl TransactionPoolRecord { let mut local_decision = self.local_decision; let mut is_ready = self.is_ready; let mut remote_decision = self.remote_decision; + let mut leader_fee = self.leader_fee; + let mut transaction_fee = self.transaction_fee; if let Some(update) = update { evidence.merge(deserialize_json(&update.evidence)?); @@ -55,32 +56,18 @@ impl TransactionPoolRecord { pending_stage = Some(parse_from_string(&update.stage)?); local_decision = Some(update.local_decision); remote_decision = update.remote_decision; + leader_fee = update.leader_fee; + transaction_fee = update.transaction_fee; } let remote_decision = remote_decision.as_deref().map(parse_from_string).transpose()?; - - let leader_fee = self - .leader_fee - .map(|leader_fee| -> Result { - Ok(LeaderFee { - fee: leader_fee as u64, - global_exhaust_burn: self.global_exhaust_burn.map(|burn| burn as u64).ok_or_else(|| { - StorageError::DataInconsistency { - details: format!( - "TransactionPoolRecord {} has a leader_fee but no global_exhaust_burn", - self.id - ), - } - })?, - }) - }) - .transpose()?; + let leader_fee = leader_fee.as_deref().map(deserialize_json::).transpose()?; let original_decision = parse_from_string(&self.original_decision)?; Ok(consensus_models::TransactionPoolRecord::load( deserialize_hex_try_from(&self.transaction_id)?, evidence, - self.transaction_fee.map(|f| f as u64), + transaction_fee as u64, leader_fee, parse_from_string(&self.stage)?, pending_stage, @@ -111,6 +98,10 @@ pub struct TransactionPoolStateUpdate { pub is_ready: bool, #[diesel(sql_type = diesel::sql_types::Text)] pub local_decision: String, + #[diesel(sql_type = diesel::sql_types::BigInt)] + pub transaction_fee: i64, + #[diesel(sql_type = diesel::sql_types::Nullable < diesel::sql_types::Text >)] + pub leader_fee: Option, #[diesel(sql_type = diesel::sql_types::Nullable < diesel::sql_types::Text >)] pub remote_decision: Option, #[diesel(sql_type = diesel::sql_types::Bool)] diff --git a/dan_layer/state_store_sqlite/src/writer.rs b/dan_layer/state_store_sqlite/src/writer.rs index 0a044de5f..d8b0d6604 100644 --- a/dan_layer/state_store_sqlite/src/writer.rs +++ b/dan_layer/state_store_sqlite/src/writer.rs @@ -950,6 +950,8 @@ impl<'tx, TAddr: NodeAddressable + 'tx> StateStoreWriteTransaction for SqliteSta transaction_pool_state_updates::stage.eq(update.stage().to_string()), transaction_pool_state_updates::local_decision.eq(update.decision().to_string()), transaction_pool_state_updates::remote_decision.eq(update.remote_decision().map(|d| d.to_string())), + transaction_pool_state_updates::transaction_fee.eq(update.transaction_fee() as i64), + transaction_pool_state_updates::leader_fee.eq(update.leader_fee().map(serialize_json).transpose()?), transaction_pool_state_updates::is_ready.eq(update.is_ready()), ); @@ -1080,6 +1082,8 @@ impl<'tx, TAddr: NodeAddressable + 'tx> StateStoreWriteTransaction for SqliteSta struct TransactionPoolChangeSet { stage: Option, local_decision: Option, + transaction_fee: Option, + leader_fee: Option>, evidence: Option>, is_ready: Option, confirm_stage: Option>, @@ -1096,6 +1100,10 @@ impl<'tx, TAddr: NodeAddressable + 'tx> StateStoreWriteTransaction for SqliteSta let changeset = TransactionPoolChangeSet { stage: Some(update.stage), local_decision: Some(update.local_decision), + transaction_fee: Some(update.transaction_fee), + // Only update if Some. This isn't technically necessary since leader fee should be in every update, but + // it does shorten the update query FWIW. + leader_fee: update.leader_fee.map(Some), evidence: Some(Some(update.evidence)), is_ready: Some(update.is_ready), confirm_stage, diff --git a/dan_layer/storage/src/consensus_models/transaction_pool.rs b/dan_layer/storage/src/consensus_models/transaction_pool.rs index c66a68641..0f24d998b 100644 --- a/dan_layer/storage/src/consensus_models/transaction_pool.rs +++ b/dan_layer/storage/src/consensus_models/transaction_pool.rs @@ -332,7 +332,7 @@ impl TransactionPoolRecord { pub fn load( id: TransactionId, evidence: Evidence, - transaction_fee: Option, + transaction_fee: u64, leader_fee: Option, stage: TransactionPoolStage, pending_stage: Option, @@ -344,7 +344,7 @@ impl TransactionPoolRecord { Self { transaction_id: id, evidence, - transaction_fee: transaction_fee.unwrap_or(0), + transaction_fee, leader_fee, stage, pending_stage, diff --git a/dan_layer/storage/src/consensus_models/transaction_pool_status_update.rs b/dan_layer/storage/src/consensus_models/transaction_pool_status_update.rs index 8dcfafbd1..1c2e76746 100644 --- a/dan_layer/storage/src/consensus_models/transaction_pool_status_update.rs +++ b/dan_layer/storage/src/consensus_models/transaction_pool_status_update.rs @@ -4,7 +4,7 @@ use tari_transaction::TransactionId; use crate::{ - consensus_models::{BlockId, Decision, Evidence, TransactionPoolRecord, TransactionPoolStage}, + consensus_models::{BlockId, Decision, Evidence, LeaderFee, TransactionPoolRecord, TransactionPoolStage}, StateStoreWriteTransaction, }; @@ -42,6 +42,14 @@ impl TransactionPoolStatusUpdate { self.transaction.remote_decision() } + pub fn transaction_fee(&self) -> u64 { + self.transaction.transaction_fee() + } + + pub fn leader_fee(&self) -> Option<&LeaderFee> { + self.transaction.leader_fee() + } + pub fn apply_evidence(&self, tx_rec_mut: &mut TransactionPoolRecord) { tx_rec_mut.set_evidence(self.evidence().clone()); } diff --git a/utilities/tariswap_test_bench/templates/tariswap/src/lib.rs b/utilities/tariswap_test_bench/templates/tariswap/src/lib.rs index 3054ffb72..4cd4a52c7 100644 --- a/utilities/tariswap_test_bench/templates/tariswap/src/lib.rs +++ b/utilities/tariswap_test_bench/templates/tariswap/src/lib.rs @@ -137,7 +137,7 @@ mod tariswap { ResourceManager::get(self.lp_resource).mint_fungible(new_lp_amount) } - pub fn remove_liquidity(&mut self, mut lp_bucket: Bucket) -> (Bucket, Bucket) { + pub fn remove_liquidity(&mut self, lp_bucket: Bucket) -> (Bucket, Bucket) { assert!(lp_bucket.resource_address() == self.lp_resource, "Invalid LP resource"); // get the pool information