Skip to content
This repository has been archived by the owner on Aug 2, 2024. It is now read-only.

Commit

Permalink
Merge branch 'main' into remove-duplicated-polkadot-sdk-repo
Browse files Browse the repository at this point in the history
  • Loading branch information
tdelabro authored Nov 18, 2023
2 parents b0e79f0 + 6cd4fd2 commit a867343
Show file tree
Hide file tree
Showing 10 changed files with 174 additions and 54 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
## Next release

- chore: remove crates that have been copy-pasted from plkdtSDK
- feat(rpc): return deployed contract address and actual fee in transaction
receipt
- fix: Wait for 1 minute for transaction to be processed in
get_transaction_receipt rpc
- ci: Fix starknet foundry sncast not found
Expand Down
74 changes: 56 additions & 18 deletions crates/client/rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -953,18 +953,37 @@ where

let chain_id = self.chain_id()?.0.into();

let (tx_type, events) = self
let fee_disabled =
self.client.runtime_api().is_transaction_fee_disabled(substrate_block_hash).map_err(|e| {
error!("Failed to get check fee disabled. Substrate block hash: {substrate_block_hash}, error: {e}");
StarknetRpcApiError::InternalServerError
})?;

let (tx_index, transaction) = self
.client
.runtime_api()
.get_events_for_tx_hash(substrate_block_hash, block_extrinsics, chain_id, transaction_hash.into())
.get_index_and_tx_for_tx_hash(substrate_block_hash, block_extrinsics, chain_id, transaction_hash.into())
.map_err(|e| {
error!(
"Failed to get events for transaction hash. Substrate block hash: {substrate_block_hash}, \
"Failed to get index for transaction hash. Substrate block hash: {substrate_block_hash}, \
transaction hash: {transaction_hash}, error: {e}"
);
StarknetRpcApiError::InternalServerError
})?
.expect("the transaction should be present in the substrate extrinsics");
.expect("the transaction should be present in the substrate extrinsics"); // not reachable

let events = self
.client
.runtime_api()
.get_events_for_tx_by_index(substrate_block_hash, tx_index)
.map_err(|e| {
error!(
"Failed to get events for transaction index. Substrate block hash: {substrate_block_hash}, \
transaction idx: {tx_index}, error: {e}"
);
StarknetRpcApiError::InternalServerError
})?
.expect("the transaction should be present in the substrate extrinsics"); // not reachable

let execution_result = {
let revert_error = self
Expand Down Expand Up @@ -994,48 +1013,67 @@ where
}
}

let receipt = match tx_type {
mp_transactions::TxType::Declare => TransactionReceipt::Declare(DeclareTransactionReceipt {
let events_converted: Vec<starknet_core::types::Event> =
events.clone().into_iter().map(event_conversion).collect();

let actual_fee = if fee_disabled {
FieldElement::ZERO
} else {
// Event {
// from_address: fee_token_address,
// keys: [selector("Transfer")],
// data: [
// send_from_address, // account_contract_address
// send_to_address, // to (sequencer address)
// expected_fee_value_low, // transfer amount (fee)
// expected_fee_value_high,
// ]},
// fee transfer must be the last event, except enabled disable-transaction-fee feature
events_converted.last().unwrap().data[2]
};

let receipt = match transaction {
mp_transactions::Transaction::Declare(_) => TransactionReceipt::Declare(DeclareTransactionReceipt {
transaction_hash,
actual_fee: Default::default(),
actual_fee,
finality_status: TransactionFinalityStatus::AcceptedOnL2,
block_hash,
block_number,
messages_sent: Default::default(),
events: events.into_iter().map(event_conversion).collect(),
events: events_converted,
execution_result,
}),
mp_transactions::TxType::DeployAccount => {
mp_transactions::Transaction::DeployAccount(tx) => {
TransactionReceipt::DeployAccount(DeployAccountTransactionReceipt {
transaction_hash,
actual_fee: Default::default(),
actual_fee,
finality_status: TransactionFinalityStatus::AcceptedOnL2,
block_hash,
block_number,
messages_sent: Default::default(),
events: events.into_iter().map(event_conversion).collect(),
contract_address: Default::default(), // TODO: we can probably find this in the events
events: events_converted,
contract_address: tx.get_account_address(),
execution_result,
})
}
mp_transactions::TxType::Invoke => TransactionReceipt::Invoke(InvokeTransactionReceipt {
mp_transactions::Transaction::Invoke(_) => TransactionReceipt::Invoke(InvokeTransactionReceipt {
transaction_hash,
actual_fee: Default::default(),
actual_fee,
finality_status: TransactionFinalityStatus::AcceptedOnL2,
block_hash,
block_number,
messages_sent: Default::default(),
events: events.into_iter().map(event_conversion).collect(),
events: events_converted,
execution_result,
}),
mp_transactions::TxType::L1Handler => TransactionReceipt::L1Handler(L1HandlerTransactionReceipt {
mp_transactions::Transaction::L1Handler(_) => TransactionReceipt::L1Handler(L1HandlerTransactionReceipt {
transaction_hash,
actual_fee: Default::default(),
actual_fee,
finality_status: TransactionFinalityStatus::AcceptedOnL2,
block_hash,
block_number,
messages_sent: Default::default(),
events: events.into_iter().map(event_conversion).collect(),
events: events_converted,
execution_result,
}),
};
Expand Down
3 changes: 3 additions & 0 deletions crates/pallets/starknet/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1190,4 +1190,7 @@ impl<T: Config> Pallet<T> {
pub fn chain_id() -> Felt252Wrapper {
T::ChainId::get()
}
pub fn is_transaction_fee_disabled() -> bool {
T::DisableTransactionFee::get()
}
}
8 changes: 6 additions & 2 deletions crates/pallets/starknet/src/runtime_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use alloc::sync::Arc;

use blockifier::execution::contract_class::ContractClass;
use mp_felt::Felt252Wrapper;
use mp_transactions::{Transaction, TxType, UserTransaction};
use mp_transactions::{Transaction, UserTransaction};
use sp_api::BlockT;
pub extern crate alloc;
use alloc::string::String;
Expand Down Expand Up @@ -56,7 +56,9 @@ sp_api::decl_runtime_apis! {
/// the runtime itself, accomplished through the extrinsic_filter method. This enables the
/// client to operate seamlessly while abstracting the extrinsic complexity.
fn extrinsic_filter(xts: Vec<<Block as BlockT>::Extrinsic>) -> Vec<Transaction>;
fn get_events_for_tx_hash(xts: Vec<<Block as BlockT>::Extrinsic>, chain_id: Felt252Wrapper, tx_hash: Felt252Wrapper) -> Option<(TxType, Vec<StarknetEvent>)>;
fn get_index_and_tx_for_tx_hash(xts: Vec<<Block as BlockT>::Extrinsic>, chain_id: Felt252Wrapper, tx_hash: Felt252Wrapper) -> Option<(u32, Transaction)>;
/// Returns events, call with index from get_index_and_tx_for_tx_hash method
fn get_events_for_tx_by_index(tx_index: u32) -> Option<Vec<StarknetEvent>>;

/// Return the list of StarknetEvent evmitted during this block, along with the hash of the starknet transaction they bellong to
///
Expand All @@ -66,6 +68,8 @@ sp_api::decl_runtime_apis! {
fn get_tx_execution_outcome(tx_hash: TransactionHash) -> Option<Vec<u8>>;
/// Return the block context
fn get_block_context() -> BlockContext;
/// Return is fee disabled in state
fn is_transaction_fee_disabled() -> bool;
}

pub trait ConvertTransactionRuntimeApi {
Expand Down
3 changes: 2 additions & 1 deletion crates/pallets/starknet/src/tests/deploy_account_tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use sp_runtime::transaction_validity::{InvalidTransaction, TransactionSource, Tr
use starknet_api::api_core::{ContractAddress, Nonce};
use starknet_api::hash::StarkFelt;
use starknet_api::transaction::{Event as StarknetEvent, EventContent, EventData, EventKey};
use starknet_core::utils::get_selector_from_name;
use starknet_crypto::FieldElement;

use super::mock::default_mock::*;
Expand Down Expand Up @@ -45,7 +46,7 @@ fn given_contract_run_deploy_account_tx_works() {
let expected_fee_transfer_event = Event::StarknetEvent(StarknetEvent {
content: EventContent {
keys: vec![EventKey(
StarkFelt::try_from("0x0099cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9").unwrap(),
StarkFelt::try_from(get_selector_from_name(mp_fee::TRANSFER_SELECTOR_NAME).unwrap()).unwrap(),
)],
data: EventData(vec![
address.0.0, // From
Expand Down
7 changes: 4 additions & 3 deletions crates/pallets/starknet/src/tests/erc20.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use starknet_api::api_core::{ContractAddress, PatriciaKey};
use starknet_api::hash::StarkFelt;
use starknet_api::state::StorageKey;
use starknet_api::transaction::{Event as StarknetEvent, EventContent, EventData, EventKey};
use starknet_core::utils::get_selector_from_name;

use super::mock::default_mock::*;
use super::mock::*;
Expand Down Expand Up @@ -98,7 +99,7 @@ fn given_erc20_transfer_when_invoke_then_it_works() {
let expected_fee_transfer_event = Event::StarknetEvent(StarknetEvent {
content: EventContent {
keys: vec![EventKey(
StarkFelt::try_from("0x0099cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9").unwrap(),
StarkFelt::try_from(get_selector_from_name(mp_fee::TRANSFER_SELECTOR_NAME).unwrap()).unwrap(),
)],
data: EventData(vec![
sender_account.0.0, // From
Expand Down Expand Up @@ -171,7 +172,7 @@ fn given_erc20_transfer_when_invoke_then_it_works() {
let expected_event = Event::StarknetEvent(StarknetEvent {
content: EventContent {
keys: vec![
EventKey(StarkFelt::try_from("0x0099cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9")
EventKey(StarkFelt::try_from(get_selector_from_name(mp_fee::TRANSFER_SELECTOR_NAME).unwrap())
.unwrap()),
],
data: EventData(vec![
Expand All @@ -192,7 +193,7 @@ fn given_erc20_transfer_when_invoke_then_it_works() {
let expected_fee_transfer_event = Event::StarknetEvent(StarknetEvent {
content: EventContent {
keys: vec![
EventKey(StarkFelt::try_from("0x0099cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9")
EventKey(StarkFelt::try_from(get_selector_from_name(mp_fee::TRANSFER_SELECTOR_NAME).unwrap())
.unwrap()),
],
data: EventData(vec![
Expand Down
5 changes: 2 additions & 3 deletions crates/pallets/starknet/src/tests/invoke_tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,13 @@ fn given_hardcoded_contract_run_invoke_tx_then_it_works() {
StarkFelt::try_from("0x02dfd0ded452658d67535279591c1ed9898431e1eafad7896239f0bfa68493d6").unwrap()
)
);

assert!(System::events().into_iter().map(|event_record| event_record.event).any(|e| match e {
RuntimeEvent::Starknet(Event::StarknetEvent(e)) => {
e == StarknetEvent {
from_address: Starknet::fee_token_address(),
content: EventContent {
keys: vec![EventKey(
StarkFelt::try_from("0x0099cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9")
StarkFelt::try_from(get_selector_from_name(mp_fee::TRANSFER_SELECTOR_NAME).unwrap())
.unwrap(),
)],
data: EventData(vec![
Expand Down Expand Up @@ -137,7 +136,7 @@ fn given_hardcoded_contract_run_invoke_tx_then_event_is_emitted() {
from_address: Starknet::fee_token_address(),
content: EventContent {
keys: vec![EventKey(
StarkFelt::try_from("0x0099cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9")
StarkFelt::try_from(get_selector_from_name(mp_fee::TRANSFER_SELECTOR_NAME).unwrap())
.unwrap(),
)],
data: EventData(vec![
Expand Down
18 changes: 9 additions & 9 deletions crates/primitives/fee/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ pub static VM_RESOURCE_FEE_COSTS: [(&str, FixedU128); 7] = [
("ec_op_builtin", FixedU128::from_inner(10_240_000_000_000_000_000)),
];

pub const TRANSFER_SELECTOR_NAME: &str = "Transfer";
pub const TRANSFER_SELECTOR_HASH: [u8; 32] = [
0, 131, 175, 211, 244, 202, 237, 198, 238, 191, 68, 36, 111, 229, 78, 56, 201, 94, 49, 121, 165, 236, 158, 168, 23,
64, 236, 165, 180, 130, 209, 46,
]; // starknet_keccak(TRANSFER_SELECTOR_NAME.as_bytes()).to_le_bytes();

/// Gets the transaction resources.
pub fn compute_transaction_resources<S: State + StateChanges>(
state: &S,
Expand Down Expand Up @@ -115,20 +121,14 @@ fn execute_fee_transfer(
let lsb_amount = StarkFelt::from(actual_fee.0);
// The most significant 128 bits of the amount transferred.
let msb_amount = StarkFelt::from(0_u64);

let storage_address = block_context.fee_token_address;
let fee_transfer_call = CallEntryPoint {
class_hash: None,
code_address: None,
entry_point_type: EntryPointType::External,
entry_point_selector: EntryPointSelector(
// The value is hardcoded and it's the encoding of the "transfer" selector so it cannot fail.
StarkFelt::new([
0, 131, 175, 211, 244, 202, 237, 198, 238, 191, 68, 36, 111, 229, 78, 56, 201, 94, 49, 121, 165, 236,
158, 168, 23, 64, 236, 165, 180, 130, 209, 46,
])
.unwrap(),
),
// The value TRANSFER_SELECTOR_HASH is hardcoded and it's the encoding of the "transfer" selector so it cannot
// fail.
entry_point_selector: EntryPointSelector(StarkFelt::new(TRANSFER_SELECTOR_HASH).unwrap()),
calldata: calldata![
*block_context.sequencer_address.0.key(), // Recipient.
lsb_amount,
Expand Down
33 changes: 20 additions & 13 deletions crates/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub use frame_system::Call as SystemCall;
use frame_system::{EventRecord, Phase};
use mp_felt::Felt252Wrapper;
use mp_transactions::compute_hash::ComputeTransactionHash;
use mp_transactions::{Transaction, TxType, UserTransaction};
use mp_transactions::{Transaction, UserTransaction};
use pallet_grandpa::{fg_primitives, AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList};
/// Import the StarkNet pallet.
pub use pallet_starknet;
Expand Down Expand Up @@ -258,6 +258,10 @@ impl_runtime_apis! {
Starknet::chain_id()
}

fn is_transaction_fee_disabled() -> bool {
Starknet::is_transaction_fee_disabled()
}

fn estimate_fee(transactions: Vec<UserTransaction>) -> Result<Vec<(u64, u64)>, DispatchError> {
Starknet::estimate_fee(transactions)
}
Expand Down Expand Up @@ -297,7 +301,7 @@ impl_runtime_apis! {
}).collect::<Vec<Transaction>>()
}

fn get_events_for_tx_hash(extrinsics: Vec<<Block as BlockT>::Extrinsic>, chain_id: Felt252Wrapper, tx_hash: Felt252Wrapper) -> Option<(TxType, Vec<StarknetEvent>)> {
fn get_index_and_tx_for_tx_hash(extrinsics: Vec<<Block as BlockT>::Extrinsic>, chain_id: Felt252Wrapper, tx_hash: Felt252Wrapper) -> Option<(u32, Transaction)> {
// Find our tx and it's index
let (tx_index, tx) = extrinsics.into_iter().enumerate().find(|(_, xt)| {
let computed_tx_hash = match &xt.function {
Expand All @@ -310,16 +314,19 @@ impl_runtime_apis! {

computed_tx_hash == tx_hash
})?;

// Compute it's tx type
let tx_type = match tx.function {
RuntimeCall::Starknet( invoke { .. }) => TxType::Invoke,
RuntimeCall::Starknet( declare { .. }) => TxType::Declare,
RuntimeCall::Starknet( deploy_account { .. }) => TxType::DeployAccount,
RuntimeCall::Starknet( consume_l1_message { .. }) => TxType::L1Handler,
_ => panic!("The previous match made sure that at this point tx is one of those starknet calls"),
let transaction = match tx.function {
RuntimeCall::Starknet( invoke { transaction }) => Transaction::Invoke(transaction),
RuntimeCall::Starknet( declare { transaction, .. }) => Transaction::Declare(transaction),
RuntimeCall::Starknet( deploy_account { transaction }) => Transaction::DeployAccount(transaction),
RuntimeCall::Starknet( consume_l1_message { transaction, .. }) => Transaction::L1Handler(transaction),
_ => unreachable!("The previous match made sure that at this point tx is one of those starknet calls"),
};

let tx_index = u32::try_from(tx_index).expect("unexpected number of transactions");
Some((tx_index, transaction))
}

fn get_events_for_tx_by_index(tx_index: u32) -> Option<Vec<StarknetEvent>> {

// Skip all the events that are not related to our tx
let event_iter = System::read_events_no_consensus().filter_map(|event| {
Expand All @@ -333,7 +340,7 @@ impl_runtime_apis! {
_ => return true
};

tx_index as u32 != index
tx_index != index
});

// Collect all the events related to our tx
Expand All @@ -345,10 +352,10 @@ impl_runtime_apis! {
_ => panic!("The previous iteration made sure at this point phase is of ApplyExtrinsic variant"),
};

tx_index as u32 == index
tx_index == index
}).map(|(_, event)| event).collect();

Some((tx_type, events))
Some(events)
}

fn get_tx_execution_outcome(tx_hash: TransactionHash) -> Option<Vec<u8>> {
Expand Down
Loading

0 comments on commit a867343

Please sign in to comment.