Skip to content

Commit

Permalink
feat(consensus): calculate the executable_transaction in consensus_co…
Browse files Browse the repository at this point in the history
…ntext
  • Loading branch information
Yael-Starkware committed Dec 4, 2024
1 parent bcba5fd commit c461854
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ use papyrus_protobuf::consensus::{
Vote,
};
use starknet_api::block::{BlockHash, BlockHashAndNumber, BlockInfo, BlockNumber, BlockTimestamp};
use starknet_api::core::ChainId;
use starknet_api::executable_transaction::Transaction as ExecutableTransaction;
use starknet_api::transaction::Transaction;
use starknet_batcher_types::batcher_types::{
Expand Down Expand Up @@ -82,6 +83,7 @@ pub struct SequencerConsensusContext {
queued_proposals:
BTreeMap<Round, (ValidationParams, oneshot::Sender<(ProposalContentId, ProposalFin)>)>,
outbound_proposal_sender: mpsc::Sender<(u64, mpsc::Receiver<ProposalPart>)>,
chain_id: ChainId,
}

impl SequencerConsensusContext {
Expand All @@ -90,6 +92,7 @@ impl SequencerConsensusContext {
_proposal_streaming_client: BroadcastTopicClient<ProposalPart>,
outbound_proposal_sender: mpsc::Sender<(u64, mpsc::Receiver<ProposalPart>)>,
num_validators: u64,
chain_id: ChainId,
) -> Self {
Self {
batcher,
Expand All @@ -102,6 +105,7 @@ impl SequencerConsensusContext {
current_round: 0,
active_proposal: None,
queued_proposals: BTreeMap::new(),
chain_id,
}
}
}
Expand Down Expand Up @@ -355,7 +359,8 @@ impl SequencerConsensusContext {
let notify = Arc::new(Notify::new());
let notify_clone = Arc::clone(&notify);

let handle = tokio::spawn(
let handle = tokio::spawn({
let chain_id = self.chain_id.clone();
async move {
let validate_fut = stream_validate_proposal(
height,
Expand All @@ -364,6 +369,7 @@ impl SequencerConsensusContext {
valid_proposals,
content_receiver,
fin_sender,
chain_id,
);
tokio::select! {
_ = notify_clone.notified() => {}
Expand All @@ -374,8 +380,8 @@ impl SequencerConsensusContext {
}
}
}
.instrument(debug_span!("consensus_validate_proposal")),
);
.instrument(debug_span!("consensus_validate_proposal"))
});
self.active_proposal = Some((notify, handle));
}

Expand Down Expand Up @@ -477,6 +483,7 @@ async fn stream_validate_proposal(
valid_proposals: Arc<Mutex<HeightToIdToContent>>,
mut content_receiver: mpsc::Receiver<ProposalPart>,
fin_sender: oneshot::Sender<(ProposalContentId, ProposalFin)>,
chain_id: ChainId,
) {
let mut content = Vec::new();
let network_block_id = loop {
Expand All @@ -488,8 +495,11 @@ async fn stream_validate_proposal(
ProposalPart::Transactions(TransactionBatch { transactions: txs, tx_hashes }) => {
let exe_txs: Vec<ExecutableTransaction> = txs
.into_iter()
.zip(tx_hashes.into_iter())
.map(|tx_tup| tx_tup.into())
.map(|tx| {
(tx, &chain_id)
.try_into()
.expect("Failed to convert transaction to executable_transation.")
})
.collect();
content.extend_from_slice(&exe_txs[..]);
let input = SendProposalContentInput {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use papyrus_protobuf::consensus::{
TransactionBatch,
};
use starknet_api::block::{BlockHash, BlockNumber};
use starknet_api::core::{ContractAddress, StateDiffCommitment};
use starknet_api::core::{ChainId, ContractAddress, StateDiffCommitment};
use starknet_api::executable_transaction::{
AccountTransaction,
Transaction as ExecutableTransaction,
Expand Down Expand Up @@ -50,6 +50,7 @@ const TIMEOUT: Duration = Duration::from_millis(100);
const CHANNEL_SIZE: usize = 5000;
const NUM_VALIDATORS: u64 = 4;
const STATE_DIFF_COMMITMENT: StateDiffCommitment = StateDiffCommitment(PoseidonHash(Felt::ZERO));
const CHAIN_ID: ChainId = ChainId::Mainnet;

lazy_static! {
static ref TX_BATCH: Vec<ExecutableTransaction> =
Expand Down Expand Up @@ -124,6 +125,7 @@ async fn build_proposal() {
broadcast_topic_client,
outbound_internal_sender,
NUM_VALIDATORS,
CHAIN_ID,
);
let init = ProposalInit {
height: BlockNumber(0),
Expand Down Expand Up @@ -186,6 +188,7 @@ async fn validate_proposal_success() {
broadcast_topic_client,
outbound_internal_sender,
NUM_VALIDATORS,
CHAIN_ID,
);
// Initialize the context for a specific height, starting with round 0.
context.set_height_and_round(BlockNumber(0), 0).await;
Expand Down Expand Up @@ -252,6 +255,7 @@ async fn repropose() {
broadcast_topic_client,
outbound_internal_sender,
NUM_VALIDATORS,
CHAIN_ID,
);
// Initialize the context for a specific height, starting with round 0.
context.set_height_and_round(BlockNumber(0), 0).await;
Expand Down Expand Up @@ -330,6 +334,7 @@ async fn proposals_from_different_rounds() {
broadcast_topic_client,
outbound_internal_sender,
NUM_VALIDATORS,
CHAIN_ID,
);
// Initialize the context for a specific height, starting with round 0.
context.set_height_and_round(BlockNumber(0), 0).await;
Expand Down Expand Up @@ -426,6 +431,7 @@ async fn interrupt_active_proposal() {
broadcast_topic_client,
outbound_internal_sender,
NUM_VALIDATORS,
CHAIN_ID,
);
// Initialize the context for a specific height, starting with round 0.
context.set_height_and_round(BlockNumber(0), 0).await;
Expand Down
15 changes: 9 additions & 6 deletions crates/starknet_api/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,22 +135,25 @@ impl From<executable_transaction::Transaction> for Transaction {
}
}

impl From<(Transaction, TransactionHash)> for executable_transaction::Transaction {
fn from((tx, tx_hash): (Transaction, TransactionHash)) -> Self {
impl TryFrom<(Transaction, &ChainId)> for executable_transaction::Transaction {
type Error = StarknetApiError;

fn try_from((tx, chain_id): (Transaction, &ChainId)) -> Result<Self, Self::Error> {
let tx_hash = tx.calculate_transaction_hash(chain_id)?;
match tx {
Transaction::Invoke(tx) => executable_transaction::Transaction::Account(
Transaction::Invoke(tx) => Ok(executable_transaction::Transaction::Account(
executable_transaction::AccountTransaction::Invoke(
executable_transaction::InvokeTransaction { tx, tx_hash },
),
),
Transaction::L1Handler(tx) => executable_transaction::Transaction::L1Handler(
)),
Transaction::L1Handler(tx) => Ok(executable_transaction::Transaction::L1Handler(
executable_transaction::L1HandlerTransaction {
tx,
tx_hash,
// TODO (yael 1/12/2024): The paid fee should be an input from the l1_handler.
paid_fee_on_l1: Fee(1),
},
),
)),
_ => {
unimplemented!(
"Unsupported transaction type. Only Invoke and L1Handler are currently \
Expand Down
52 changes: 36 additions & 16 deletions crates/starknet_api/src/transaction_test.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
use assert_matches::assert_matches;
use rstest::{fixture, rstest};

use super::{Transaction, TransactionHash};
use super::Transaction;
use crate::block::NonzeroGasPrice;
use crate::executable_transaction::Transaction as ExecutableTransaction;
use crate::core::ChainId;
use crate::executable_transaction::{
AccountTransaction,
InvokeTransaction,
L1HandlerTransaction,
Transaction as ExecutableTransaction,
};
use crate::execution_resources::GasAmount;
use crate::test_utils::{read_json_file, TransactionTestData};
use crate::transaction::Fee;
Expand All @@ -15,11 +21,13 @@ fn transactions_data() -> Vec<TransactionTestData> {
serde_json::from_value(read_json_file("transaction_hash.json")).unwrap()
}

fn verify_transaction_conversion(tx: Transaction, tx_hash: TransactionHash) {
let executable_tx: ExecutableTransaction = (tx.clone(), tx_hash).into();
let reconverted_tx = Transaction::from(executable_tx);
fn verify_transaction_conversion(tx: &Transaction, expected_executable_tx: ExecutableTransaction) {
let converted_executable_tx: ExecutableTransaction =
(tx.clone(), &ChainId::Mainnet).try_into().unwrap();
let reconverted_tx = Transaction::from(converted_executable_tx.clone());

assert_eq!(tx, reconverted_tx);
assert_eq!(converted_executable_tx, expected_executable_tx);
assert_eq!(tx, &reconverted_tx);
}

#[test]
Expand Down Expand Up @@ -50,14 +58,20 @@ fn test_fee_div_ceil() {
fn test_invoke_executable_transaction_conversion(mut transactions_data: Vec<TransactionTestData>) {
// Extract Invoke transaction data.
let transaction_data = transactions_data.remove(0);
let tx = assert_matches!(
transaction_data.transaction,
Transaction::Invoke(tx) => Transaction::Invoke(tx),
let tx = transaction_data.transaction;
let invoke_tx = assert_matches!(
tx,
Transaction::Invoke(ref invoke_tx) => invoke_tx.clone(),
"Transaction_hash.json is expected to have Invoke as the first transaction."
);
let tx_hash = transaction_data.transaction_hash;

verify_transaction_conversion(tx, tx_hash);
let expected_executable_tx =
ExecutableTransaction::Account(AccountTransaction::Invoke(InvokeTransaction {
tx: invoke_tx,
tx_hash: transaction_data.transaction_hash,
}));

verify_transaction_conversion(&tx, expected_executable_tx);
}

#[rstest]
Expand All @@ -66,12 +80,18 @@ fn test_l1_handler_executable_transaction_conversion(
) {
// Extract L1 Handler transaction data.
let transaction_data = transactions_data.remove(10);
let tx = assert_matches!(
transaction_data.transaction,
Transaction::L1Handler(tx) => Transaction::L1Handler(tx),
let tx = transaction_data.transaction;
let l1_handler_tx = assert_matches!(
tx,
Transaction::L1Handler(ref l1_handler_tx) => l1_handler_tx.clone(),
"Transaction_hash.json is expected to have L1 handler as the 11th transaction."
);
let tx_hash = transaction_data.transaction_hash;

verify_transaction_conversion(tx, tx_hash);
let expected_executable_tx = ExecutableTransaction::L1Handler(L1HandlerTransaction {
tx: l1_handler_tx,
tx_hash: transaction_data.transaction_hash,
paid_fee_on_l1: Fee(1),
});

verify_transaction_conversion(&tx, expected_executable_tx);
}
1 change: 1 addition & 0 deletions crates/starknet_consensus_manager/src/consensus_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ impl ConsensusManager {
old_proposals_broadcast_channels.broadcast_topic_client.clone(),
outbound_internal_sender,
self.config.consensus_config.num_validators,
self.config.consensus_config.chain_id.clone(),
);

let mut network_handle = tokio::task::spawn(network_manager.run());
Expand Down

0 comments on commit c461854

Please sign in to comment.