Skip to content

Commit

Permalink
feat(consensus): add central invoke transaction
Browse files Browse the repository at this point in the history
  • Loading branch information
Yael-Starkware committed Dec 25, 2024
1 parent 332004a commit 2fc1955
Show file tree
Hide file tree
Showing 5 changed files with 200 additions and 6 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions crates/sequencing/papyrus_consensus_orchestrator/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ license-file.workspace = true
description = "Implements the consensus context and orchestrates the node's components accordingly"

[dependencies]
assert_matches.workspace = true
async-trait.workspace = true
blockifier.workspace = true
chrono.workspace = true
Expand All @@ -31,6 +32,7 @@ mockall.workspace = true
papyrus_network = { workspace = true, features = ["testing"] }
papyrus_storage = { workspace = true, features = ["testing"] }
papyrus_test_utils.workspace = true
rstest.workspace = true
serde_json.workspace = true
starknet_batcher_types = { workspace = true, features = ["testing"] }
test-case.workspace = true
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"tx": {
"hash_value": "0x6efd067c859e6469d0f6d158e9ae408a9552eb8cc11f618ab3aef3e52450666",
"version": "0x3",
"signature": [],
"nonce": "0x0",
"sender_address": "0x14abfd58671a1a9b30de2fcd2a42e8bff2ce1096a7c70bc7995904965f277e",
"nonce_data_availability_mode": 0,
"fee_data_availability_mode": 0,
"resource_bounds": {
"L1_GAS": {
"max_amount": "0x1",
"max_price_per_unit": "0x1"
},
"L2_GAS": {
"max_amount": "0x0",
"max_price_per_unit": "0x0"
},
"L1_DATA": {
"max_amount": "0x0",
"max_price_per_unit": "0x0"
}
},
"tip": "0x0",
"paymaster_data": [],
"calldata": [
"0x0",
"0x1"
],
"account_deployment_data": [],
"type": "INVOKE_FUNCTION"
},
"time_created": 1734601615
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use assert_matches::assert_matches;
use blockifier::state::cached_state::CommitmentStateDiff;
use indexmap::{indexmap, IndexMap};
use serde::{Deserialize, Serialize};
Expand All @@ -10,7 +11,17 @@ use starknet_api::block::{
};
use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce};
use starknet_api::data_availability::DataAvailabilityMode;
use starknet_api::executable_transaction::{AccountTransaction, InvokeTransaction, Transaction};
use starknet_api::state::StorageKey;
use starknet_api::transaction::fields::{
AccountDeploymentData,
Calldata,
PaymasterData,
Tip,
TransactionSignature,
ValidResourceBounds,
};
use starknet_api::transaction::TransactionHash;
use starknet_types_core::felt::Felt;

/// Central objects are required in order to continue processing the block by the centralized
Expand Down Expand Up @@ -89,3 +100,90 @@ impl From<(CommitmentStateDiff, BlockInfo, StarknetVersion)> for CentralStateDif
}
}
}

#[derive(Debug, PartialEq, Deserialize, Serialize)]
pub struct CentralInvokeTransactionV3 {
pub sender_address: ContractAddress,
pub calldata: Calldata,
pub signature: TransactionSignature,
pub nonce: Nonce,
// TODO(yael): Consider defining a type for resource_bounds that matches the python object.
pub resource_bounds: ValidResourceBounds,
pub tip: Tip,
pub paymaster_data: PaymasterData,
pub account_deployment_data: AccountDeploymentData,
pub nonce_data_availability_mode: u8,
pub fee_data_availability_mode: u8,
pub hash_value: TransactionHash,
}

impl From<InvokeTransaction> for CentralInvokeTransactionV3 {
fn from(tx: InvokeTransaction) -> CentralInvokeTransactionV3 {
assert_matches!(tx.tx, starknet_api::transaction::InvokeTransaction::V3(_));
CentralInvokeTransactionV3 {
sender_address: tx.sender_address(),
calldata: tx.calldata(),
signature: tx.signature(),
nonce: tx.nonce(),
resource_bounds: tx.resource_bounds(),
tip: tx.tip(),
paymaster_data: tx.paymaster_data(),
account_deployment_data: tx.account_deployment_data(),
nonce_data_availability_mode: into_u8(tx.nonce_data_availability_mode()),
fee_data_availability_mode: into_u8(tx.fee_data_availability_mode()),
hash_value: tx.tx_hash(),
}
}
}

fn into_u8(data_availability_mode: DataAvailabilityMode) -> u8 {
match data_availability_mode {
DataAvailabilityMode::L1 => 0,
DataAvailabilityMode::L2 => 1,
}
}

#[derive(Debug, PartialEq, Deserialize, Serialize)]
#[serde(tag = "version")]
pub enum CentralInvokeTransaction {
#[serde(rename = "0x3")]
V3(CentralInvokeTransactionV3),
}

#[derive(Debug, PartialEq, Deserialize, Serialize)]
#[serde(tag = "type")]
pub enum CentralTransaction {
#[serde(rename = "INVOKE_FUNCTION")]
Invoke(CentralInvokeTransaction),
}

impl From<Transaction> for CentralTransaction {
fn from(tx: Transaction) -> CentralTransaction {
match tx {
Transaction::Account(AccountTransaction::Invoke(invoke_tx)) => {
CentralTransaction::Invoke(CentralInvokeTransaction::V3(
CentralInvokeTransactionV3::from(invoke_tx),
))
}
Transaction::Account(_) => unimplemented!(),
Transaction::L1Handler(_) => unimplemented!(),
}
}
}

#[derive(Debug, PartialEq, Deserialize, Serialize)]
pub struct CentralTransactionWritten {
pub tx: CentralTransaction,
pub time_created: u64,
}

impl From<(Transaction, u64)> for CentralTransactionWritten {
fn from((tx, timestamp): (Transaction, u64)) -> CentralTransactionWritten {
CentralTransactionWritten {
tx: CentralTransaction::from(tx),
// This timestamp is required for metrics data. Yoni and Noa approved that it is
// sufficient to take the time during the batcher run.
time_created: timestamp,
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
use std::sync::Arc;

use indexmap::indexmap;
use rstest::rstest;
use serde_json::Value;
use starknet_api::block::{
BlockNumber,
BlockTimestamp,
Expand All @@ -8,14 +12,32 @@ use starknet_api::block::{
};
use starknet_api::core::{ClassHash, CompiledClassHash, Nonce};
use starknet_api::data_availability::DataAvailabilityMode;
use starknet_api::executable_transaction::InvokeTransaction;
use starknet_api::execution_resources::GasAmount;
use starknet_api::test_utils::read_json_file;
use starknet_api::transaction::fields::{
AllResourceBounds,
Calldata,
ResourceBounds,
ValidResourceBounds,
};
use starknet_api::transaction::{InvokeTransactionV3, TransactionHash};
use starknet_api::{contract_address, felt, storage_key};

use super::{CentralBlockInfo, CentralResourcePrice, CentralStateDiff};
use super::{
CentralBlockInfo,
CentralInvokeTransaction,
CentralResourcePrice,
CentralStateDiff,
CentralTransaction,
CentralTransactionWritten,
};

pub const CENTRAL_STATE_DIFF_JSON_PATH: &str = "central_state_diff.json";
pub const CENTRAL_INVOKE_TX_JSON_PATH: &str = "central_invoke_tx.json";

fn central_state_diff() -> CentralStateDiff {
// TODO(yael): compute the CentralStateDiff with into().
CentralStateDiff {
address_to_class_hash: indexmap! {
contract_address!(1_u8) =>
Expand Down Expand Up @@ -52,12 +74,48 @@ fn central_state_diff() -> CentralStateDiff {
}
}

#[test]
fn serialize_central_state_diff() {
let rust_central_state_diff = central_state_diff();
let rust_json = serde_json::to_value(&rust_central_state_diff).unwrap();
fn central_invoke_transaction_json() -> Value {
let invoke_tx = InvokeTransaction {
tx: starknet_api::transaction::InvokeTransaction::V3(InvokeTransactionV3 {
resource_bounds: ValidResourceBounds::AllResources(AllResourceBounds {
l1_gas: ResourceBounds {
max_amount: GasAmount(1),
max_price_per_unit: GasPrice(1),
},
l2_gas: ResourceBounds::default(),
l1_data_gas: ResourceBounds::default(),
}),
// TODO(yael): consider testing these fields with non-default values
tip: Default::default(),
signature: Default::default(),
nonce: Default::default(),
sender_address: contract_address!(
"0x14abfd58671a1a9b30de2fcd2a42e8bff2ce1096a7c70bc7995904965f277e"
),
calldata: Calldata(Arc::new(vec![felt!(0_u8), felt!(1_u8)])),
nonce_data_availability_mode: DataAvailabilityMode::L1,
fee_data_availability_mode: DataAvailabilityMode::L1,
paymaster_data: Default::default(),
account_deployment_data: Default::default(),
}),
tx_hash: TransactionHash(felt!(
"0x6efd067c859e6469d0f6d158e9ae408a9552eb8cc11f618ab3aef3e52450666"
)),
};

let central_transaction_written = CentralTransactionWritten {
tx: CentralTransaction::Invoke(CentralInvokeTransaction::V3(invoke_tx.into())),
time_created: 1734601615,
};

serde_json::to_value(central_transaction_written).unwrap()
}

let python_json = read_json_file(CENTRAL_STATE_DIFF_JSON_PATH);
#[rstest]
#[case::state_diff(serde_json::to_value(central_state_diff()).unwrap(), CENTRAL_STATE_DIFF_JSON_PATH)]
#[case::invoke_tx(central_invoke_transaction_json(), CENTRAL_INVOKE_TX_JSON_PATH)]
fn serialize_central_objects(#[case] rust_json: Value, #[case] python_json_path: &str) {
let python_json = read_json_file(python_json_path);

assert_eq!(rust_json, python_json,);
}

0 comments on commit 2fc1955

Please sign in to comment.