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(consensus): calculate the executable_transaction in consensus_context #2458

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ use starknet_api::block::{
GasPrices,
NonzeroGasPrice,
};
use starknet_api::core::ChainId;
use starknet_api::executable_transaction::Transaction as ExecutableTransaction;
use starknet_batcher_types::batcher_types::{
DecisionReachedInput,
Expand Down Expand Up @@ -104,6 +105,8 @@ pub struct SequencerConsensusContext {
outbound_proposal_sender: mpsc::Sender<(u64, mpsc::Receiver<ProposalPart>)>,
// Used to broadcast votes to other consensus nodes.
vote_broadcast_client: BroadcastTopicClient<ConsensusMessage>,
// Used to convert Transaction to ExecutableTransaction.
chain_id: ChainId,
}

impl SequencerConsensusContext {
Expand All @@ -112,6 +115,7 @@ impl SequencerConsensusContext {
outbound_proposal_sender: mpsc::Sender<(u64, mpsc::Receiver<ProposalPart>)>,
vote_broadcast_client: BroadcastTopicClient<ConsensusMessage>,
num_validators: u64,
chain_id: ChainId,
) -> Self {
Self {
batcher,
Expand All @@ -127,6 +131,7 @@ impl SequencerConsensusContext {
current_round: 0,
active_proposal: None,
queued_proposals: BTreeMap::new(),
chain_id,
}
}
}
Expand Down Expand Up @@ -390,6 +395,7 @@ impl SequencerConsensusContext {

let notify = Arc::new(Notify::new());
let notify_clone = Arc::clone(&notify);
let chain_id = self.chain_id.clone();

let handle = tokio::spawn(
async move {
Expand All @@ -400,6 +406,7 @@ impl SequencerConsensusContext {
valid_proposals,
content_receiver,
fin_sender,
chain_id,
);
tokio::select! {
_ = notify_clone.notified() => {}
Expand Down Expand Up @@ -513,6 +520,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 @@ -522,11 +530,15 @@ async fn stream_validate_proposal(
return;
};
match prop_part {
ProposalPart::Transactions(TransactionBatch { transactions: txs, tx_hashes }) => {
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| {
// An error means we have an invalid chain_id.
(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 @@ -22,10 +22,11 @@ use papyrus_protobuf::consensus::{
TransactionBatch,
};
use starknet_api::block::{BlockHash, BlockNumber};
use starknet_api::core::StateDiffCommitment;
use starknet_api::core::{ChainId, Nonce, StateDiffCommitment};
use starknet_api::executable_transaction::Transaction as ExecutableTransaction;
use starknet_api::felt;
use starknet_api::hash::PoseidonHash;
use starknet_api::test_utils::invoke::{executable_invoke_tx, invoke_tx, InvokeTxArgs};
use starknet_api::test_utils::invoke::{invoke_tx, InvokeTxArgs};
use starknet_api::transaction::{Transaction, TransactionHash};
use starknet_batcher_types::batcher_types::{
GetProposalContent,
Expand All @@ -48,21 +49,19 @@ 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> =
vec![generate_executable_invoke_tx(Felt::THREE)];
static ref TX_BATCH: Vec<ExecutableTransaction> = vec![generate_executable_invoke_tx()];
}

fn generate_invoke_tx() -> Transaction {
Transaction::Invoke(invoke_tx(InvokeTxArgs::default()))
Transaction::Invoke(invoke_tx(InvokeTxArgs { nonce: Nonce(felt!(3_u8)), ..Default::default() }))
Yael-Starkware marked this conversation as resolved.
Show resolved Hide resolved
}

fn generate_executable_invoke_tx(tx_hash: Felt) -> ExecutableTransaction {
ExecutableTransaction::Account(executable_invoke_tx(InvokeTxArgs {
tx_hash: TransactionHash(tx_hash),
..Default::default()
}))
fn generate_executable_invoke_tx() -> ExecutableTransaction {
let tx = generate_invoke_tx();
(tx, &CHAIN_ID).try_into().unwrap()
}

// Structs which aren't utilized but should not be dropped.
Expand Down Expand Up @@ -91,6 +90,7 @@ fn setup(batcher: MockBatcherClient) -> (SequencerConsensusContext, NetworkDepen
outbound_proposal_stream_sender,
votes_topic_client,
NUM_VALIDATORS,
CHAIN_ID,
);

let network_dependencies = NetworkDependencies {
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
57 changes: 36 additions & 21 deletions crates/starknet_api/src/transaction_test.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,34 @@
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;

const CHAIN_ID: ChainId = ChainId::Mainnet;

#[fixture]
fn transactions_data() -> Vec<TransactionTestData> {
// The details were taken from Starknet Mainnet. You can find the transactions by hash in:
// https://alpha-mainnet.starknet.io/feeder_gateway/get_transaction?transactionHash=<transaction_hash>
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(), &CHAIN_ID).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 +59,17 @@ 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),
"Transaction_hash.json is expected to have Invoke as the first transaction."
);
let tx_hash = transaction_data.transaction_hash;
let Transaction::Invoke(invoke_tx) = transaction_data.transaction.clone() else {
panic!("Transaction_hash.json is expected to have Invoke as the first transaction.")
};

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

verify_transaction_conversion(tx, tx_hash);
verify_transaction_conversion(&transaction_data.transaction, expected_executable_tx);
}

#[rstest]
Expand All @@ -66,12 +78,15 @@ 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),
"Transaction_hash.json is expected to have L1 handler as the 11th transaction."
);
let tx_hash = transaction_data.transaction_hash;
let Transaction::L1Handler(l1_handler_tx) = transaction_data.transaction.clone() else {
panic!("Transaction_hash.json is expected to have L1 Handler as the 11th transaction.")
};

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, tx_hash);
verify_transaction_conversion(&transaction_data.transaction, 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 @@ -68,6 +68,7 @@ impl ConsensusManager {
outbound_internal_sender,
votes_broadcast_channels.broadcast_topic_client.clone(),
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
Loading