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

Commit

Permalink
Merge branch '1613_hashT' of https://github.com/fishseabowl/madara in…
Browse files Browse the repository at this point in the history
…to 1613_hashT
  • Loading branch information
fishseabowl committed Jun 6, 2024
2 parents d5bd4d7 + 65f6462 commit 9b13de1
Show file tree
Hide file tree
Showing 13 changed files with 323 additions and 92 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

- dev: make HasherT methods accept iterator rather than &[Felt] as argument
- test: Adding txv3 tests
- feat: L1 gas price/fix

## v0.8.0

Expand Down
2 changes: 1 addition & 1 deletion crates/client/l1-gas-price/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub struct FeeHistory {
/// of the returned range, because this value can be derived from the newest block. Zeroes
/// are returned for pre-EIP-4844 blocks.
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub base_fee_per_blob_gas: Vec<u128>,
pub base_fee_per_blob_gas: Vec<String>,
/// An array of block blob gas used ratios. These are calculated as the ratio of gasUsed and
/// gasLimit.
#[serde(default, skip_serializing_if = "Vec::is_empty")]
Expand Down
12 changes: 8 additions & 4 deletions crates/client/l1-gas-price/src/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,14 @@ async fn update_gas_price(
// The RPC responds with 301 elements for some reason. It's also just safer to manually
// take the last 300. We choose 300 to get average gas caprice for last one hour (300 * 12 sec block
// time).
let (_, blob_fee_history_one_hour) =
fee_history.result.base_fee_per_blob_gas.split_at(fee_history.result.base_fee_per_blob_gas.len() - 300);

let avg_blob_base_fee = blob_fee_history_one_hour.iter().sum::<u128>() / blob_fee_history_one_hour.len() as u128;
let (_, blob_fee_history_one_hour) = fee_history
.result
.base_fee_per_blob_gas
.split_at(fee_history.result.base_fee_per_blob_gas.len().max(300) - 300);

let avg_blob_base_fee =
blob_fee_history_one_hour.iter().map(|hex_str| u128::from_str_radix(&hex_str[2..], 16).unwrap()).sum::<u128>()
/ blob_fee_history_one_hour.len() as u128;

let eth_gas_price = u128::from_str_radix(
fee_history
Expand Down
32 changes: 20 additions & 12 deletions crates/node/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use mp_starknet_inherent::{
InherentDataProvider as StarknetInherentDataProvider, InherentError as StarknetInherentError, L1GasPrices,
StarknetInherentData, DEFAULT_SEQUENCER_ADDRESS, SEQ_ADDR_STORAGE_KEY,
};
use pallet_starknet_runtime_api::StarknetRuntimeApi;
use prometheus_endpoint::Registry;
use sc_basic_authorship::ProposerFactory;
use sc_client_api::{Backend, BlockBackend, BlockchainEvents, HeaderBackend};
Expand All @@ -33,7 +34,7 @@ use sc_telemetry::{Telemetry, TelemetryWorker};
use sc_transaction_pool::FullPool;
use sc_transaction_pool_api::OffchainTransactionPoolFactory;
use sp_api::offchain::OffchainStorage;
use sp_api::ConstructRuntimeApi;
use sp_api::{ConstructRuntimeApi, ProvideRuntimeApi};
use sp_consensus_aura::sr25519::AuthorityPair as AuraPair;
use sp_offchain::STORAGE_PREFIX;

Expand Down Expand Up @@ -346,18 +347,25 @@ pub fn new_full(
),
);

// Ensuring we've fetched the latest price before we start the node
futures::executor::block_on(mc_l1_gas_price::worker::run_worker(
ethereum_conf.clone(),
l1_gas_price.clone(),
false,
));
let fees_disabled = client
.runtime_api()
.is_transaction_fee_disabled(client.chain_info().best_hash)
.expect("Failed to get fee status");

task_manager.spawn_handle().spawn(
"l1-gas-prices-worker",
Some(MADARA_TASK_GROUP),
mc_l1_gas_price::worker::run_worker(ethereum_conf.clone(), l1_gas_price.clone(), true),
);
if !fees_disabled {
// Ensuring we've fetched the latest price before we start the node
futures::executor::block_on(mc_l1_gas_price::worker::run_worker(
ethereum_conf.clone(),
l1_gas_price.clone(),
false,
));

task_manager.spawn_handle().spawn(
"l1-gas-prices-worker",
Some(MADARA_TASK_GROUP),
mc_l1_gas_price::worker::run_worker(ethereum_conf.clone(), l1_gas_price.clone(), true),
);
}
}
}

Expand Down
70 changes: 67 additions & 3 deletions crates/pallets/starknet/src/tests/declare_tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,60 @@ use sp_runtime::transaction_validity::{
InvalidTransaction, TransactionSource, TransactionValidityError, ValidTransaction,
};
use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce, PatriciaKey};
use starknet_api::data_availability::DataAvailabilityMode;
use starknet_api::hash::StarkFelt;
use starknet_api::transaction::{
DeclareTransaction as StarknetApiDeclareTransaction, DeclareTransactionV0V1, DeclareTransactionV2, Fee,
TransactionSignature,
DeclareTransaction as StarknetApiDeclareTransaction, DeclareTransactionV0V1, DeclareTransactionV2,
DeclareTransactionV3, Fee, TransactionSignature,
};
use starknet_crypto::FieldElement;

use super::mock::default_mock::*;
use super::mock::*;
use super::utils::{get_contract_class, sign_message_hash};
use super::utils::{create_resource_bounds, get_contract_class, sign_message_hash};
use crate::tests::{set_infinite_tokens, set_nonce};
use crate::Error;

fn create_declare_erc20_v3_transaction(
chain_id: Felt252Wrapper,
account_type: AccountType,
sender_address: Option<ContractAddress>,
signature: Option<TransactionSignature>,
nonce: Option<Nonce>,
) -> BlockifierDeclareTransaction {
let sender_address = sender_address.unwrap_or_else(|| get_account_address(None, account_type));
let erc20_class = get_contract_class("erc20.casm.json", 1);
let erc20_class_hash =
ClassHash(StarkFelt::try_from("0x057eca87f4b19852cfd4551cf4706ababc6251a8781733a0a11cf8e94211da95").unwrap());

let compiled_erc20_class_hash = CompiledClassHash(
StarkFelt::try_from("0x00df4d3042eec107abe704619f13d92bbe01a58029311b7a1886b23dcbb4ea87").unwrap(),
);

let mut tx = StarknetApiDeclareTransaction::V3(DeclareTransactionV3 {
resource_bounds: create_resource_bounds(),
tip: starknet_api::transaction::Tip::default(),
signature: TransactionSignature::default(),
nonce: nonce.unwrap_or_default(),
class_hash: erc20_class_hash,
compiled_class_hash: compiled_erc20_class_hash,
sender_address,
nonce_data_availability_mode: DataAvailabilityMode::L1,
fee_data_availability_mode: DataAvailabilityMode::L1,
paymaster_data: starknet_api::transaction::PaymasterData(vec![]),
account_deployment_data: starknet_api::transaction::AccountDeploymentData(vec![]),
});

let tx_hash = tx.compute_hash(chain_id, false);
// Force to do that because ComputeTransactionHash cannot be implemented on DeclareTransactionV0V1
// directly...
if let StarknetApiDeclareTransaction::V3(tx) = &mut tx {
tx.signature = signature.unwrap_or_else(|| sign_message_hash(tx_hash));
}

BlockifierDeclareTransaction::new(tx, tx_hash, ClassInfo::new(&erc20_class, 1, 1).unwrap()).unwrap()
}

fn create_declare_erc20_v1_transaction(
chain_id: Felt252Wrapper,
account_type: AccountType,
Expand Down Expand Up @@ -395,3 +436,26 @@ fn test_declare_using_transaction_v0() {
assert!(Starknet::validate_unsigned(TransactionSource::InBlock, &crate::Call::declare { transaction }).is_ok());
});
}

#[test]
fn given_contract_declare_tx3_than_works() {
new_test_ext::<MockRuntime>().execute_with(|| {
basic_test_setup(2);

let none_origin = RuntimeOrigin::none();
let chain_id = Starknet::chain_id();

let transaction = create_declare_erc20_v3_transaction(
chain_id,
AccountType::V1(AccountTypeV1Inner::NoValidate),
None,
None,
None,
);
let class_hash = transaction.class_hash();
let contract_class = transaction.contract_class();

assert_ok!(Starknet::declare(none_origin.clone(), transaction.clone()));
assert_eq!(Starknet::contract_class_by_class_hash(class_hash.0).unwrap(), contract_class);
});
}
72 changes: 69 additions & 3 deletions crates/pallets/starknet/src/tests/deploy_account_tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,18 @@ use mp_transactions::compute_hash::ComputeTransactionHash;
use sp_runtime::traits::ValidateUnsigned;
use sp_runtime::transaction_validity::{InvalidTransaction, TransactionSource, TransactionValidityError};
use starknet_api::core::{calculate_contract_address, ClassHash, ContractAddress, Nonce};
use starknet_api::data_availability::DataAvailabilityMode;
use starknet_api::hash::StarkFelt;
use starknet_api::transaction::{
Calldata, ContractAddressSalt, DeployAccountTransactionV1, Event as StarknetEvent, EventContent, EventData,
EventKey, Fee, TransactionSignature,
Calldata, ContractAddressSalt, DeployAccountTransactionV1, DeployAccountTransactionV3, Event as StarknetEvent,
EventContent, EventData, EventKey, Fee, TransactionSignature,
};
use starknet_core::utils::get_selector_from_name;
use starknet_crypto::FieldElement;

use super::mock::default_mock::*;
use super::mock::*;
use super::utils::{sign_message_hash, sign_message_hash_braavos};
use super::utils::{create_resource_bounds, sign_message_hash, sign_message_hash_braavos};
use crate::tests::constants::{ACCOUNT_PUBLIC_KEY, SALT, TRANSFER_SELECTOR_NAME};
use crate::tests::{get_deploy_account_dummy, set_infinite_tokens, set_nonce};
use crate::{Error, StorageView};
Expand All @@ -42,6 +43,26 @@ fn deploy_v1_to_blockifier_deploy(
)
}

fn deploy_v3_to_blockifier_deploy(
tx: DeployAccountTransactionV3,
chain_id: Felt252Wrapper,
) -> DeployAccountTransaction {
let tx_hash = tx.compute_hash(chain_id, false);
let contract_address = calculate_contract_address(
tx.contract_address_salt,
tx.class_hash,
&tx.constructor_calldata,
Default::default(),
)
.unwrap();

DeployAccountTransaction::new(
starknet_api::transaction::DeployAccountTransaction::V3(tx),
tx_hash,
contract_address,
)
}

fn helper_create_deploy_account_tx(
chain_id: Felt252Wrapper,
salt: ContractAddressSalt,
Expand All @@ -60,6 +81,28 @@ fn helper_create_deploy_account_tx(
deploy_v1_to_blockifier_deploy(tx, chain_id)
}

fn helper_create_deploy_account_tx3(
chain_id: Felt252Wrapper,
salt: ContractAddressSalt,
calldata: Calldata,
account_class_hash: ClassHash,
) -> DeployAccountTransaction {
let tx = DeployAccountTransactionV3 {
resource_bounds: create_resource_bounds(),
tip: starknet_api::transaction::Tip::default(),
signature: TransactionSignature::default(),
nonce: Nonce(StarkFelt::ZERO),
class_hash: account_class_hash,
contract_address_salt: salt,
constructor_calldata: calldata,
nonce_data_availability_mode: DataAvailabilityMode::L1,
fee_data_availability_mode: DataAvailabilityMode::L1,
paymaster_data: starknet_api::transaction::PaymasterData(vec![]),
};

deploy_v3_to_blockifier_deploy(tx, chain_id)
}

#[test]
fn given_contract_run_deploy_account_tx_works() {
new_test_ext::<MockRuntime>().execute_with(|| {
Expand Down Expand Up @@ -509,3 +552,26 @@ fn test_verify_nonce_in_unsigned_tx() {
);
});
}

#[test]
fn given_contract_run_deploy_account_tx3_works() {
new_test_ext::<MockRuntime>().execute_with(|| {
basic_test_setup(2);
let none_origin = RuntimeOrigin::none();
let chain_id = Starknet::chain_id();
// TEST ACCOUNT CONTRACT
// - ref testnet tx(0x0751b4b5b95652ad71b1721845882c3852af17e2ed0c8d93554b5b292abb9810)
let salt = ContractAddressSalt(
StarkFelt::try_from("0x03b37cbe4e9eac89d54c5f7cc6329a63a63e8c8db2bf936f981041e086752463").unwrap(),
);
let (account_class_hash, calldata) = account_helper(AccountType::V0(AccountTypeV0Inner::NoValidate));

let deploy_tx = helper_create_deploy_account_tx3(chain_id, salt, calldata, account_class_hash);
let contract_address = deploy_tx.contract_address;

set_infinite_tokens::<MockRuntime>(&contract_address);

assert_ok!(Starknet::deploy_account(none_origin, deploy_tx));
assert_eq!(Starknet::contract_class_hash_by_address(contract_address), account_class_hash.0);
});
}
74 changes: 73 additions & 1 deletion crates/pallets/starknet/src/tests/invoke_tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use sp_runtime::transaction_validity::{
InvalidTransaction, TransactionSource, TransactionValidityError, ValidTransaction,
};
use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce, PatriciaKey};
use starknet_api::data_availability::DataAvailabilityMode;
use starknet_api::hash::StarkFelt;
use starknet_api::state::StorageKey;
use starknet_api::transaction::{
Expand All @@ -28,7 +29,8 @@ use super::constants::{
use super::mock::default_mock::*;
use super::mock::*;
use super::utils::{
get_balance_contract_call, get_contract_class, set_account_erc20_balance_to_zero, sign_message_hash,
create_resource_bounds, get_balance_contract_call, get_contract_class, set_account_erc20_balance_to_zero,
sign_message_hash,
};
use crate::tests::constants::{UDC_ADDRESS, UDC_SELECTOR};
use crate::tests::{
Expand Down Expand Up @@ -903,3 +905,73 @@ fn given_hardcoded_contract_set_erc20_balance_to_zero() {
);
});
}

#[test]
fn given_hardcoded_contract_run_invoke_tx_v3_with_inner_call_in_validate_then_it_fails() {
new_test_ext::<MockRuntime>().execute_with(|| {
basic_test_setup(2);
let none_origin = RuntimeOrigin::none();

let sender_address = get_account_address(None, AccountType::V0(AccountTypeV0Inner::InnerCall));
let mut transaction = get_invoke_v3_dummy(Starknet::chain_id(), NONCE_ZERO);
if let starknet_api::transaction::InvokeTransaction::V3(tx) = &mut transaction.tx {
tx.signature = TransactionSignature(vec![StarkFelt::ONE, StarkFelt::ONE]);
tx.sender_address = sender_address;
};

let storage_key = get_storage_var_address("destination", &[]);
let destination = StarkFelt::try_from(TEST_CONTRACT_ADDRESS).unwrap();
StorageView::<MockRuntime>::insert((sender_address, storage_key), destination);

let storage_key = get_storage_var_address("function_selector", &[]);
let selector = get_selector_from_name("without_arg").unwrap();
StorageView::<MockRuntime>::insert(
(sender_address, storage_key),
StarkFelt::from(Felt252Wrapper::from(selector)),
);

assert_err!(Starknet::invoke(none_origin, transaction), Error::<MockRuntime>::TransactionExecutionFailed);
});
}

#[test]
fn given_account_not_deployed_invoke_tx_v3_fails_for_nonce_not_one() {
new_test_ext::<MockRuntime>().execute_with(|| {
basic_test_setup(2);

// Wrong address (not deployed)
let contract_address = ContractAddress(PatriciaKey(StarkFelt::try_from("0x13123131").unwrap()));

let transaction = starknet_api::transaction::InvokeTransactionV3 {
resource_bounds: create_resource_bounds(),
tip: starknet_api::transaction::Tip::default(),
calldata: Calldata::default(),
sender_address: contract_address,
nonce: Nonce(StarkFelt::ZERO),
signature: TransactionSignature::default(),
nonce_data_availability_mode: DataAvailabilityMode::L1,
fee_data_availability_mode: DataAvailabilityMode::L1,
paymaster_data: starknet_api::transaction::PaymasterData(vec![]),
account_deployment_data: starknet_api::transaction::AccountDeploymentData(vec![StarkFelt::ZERO]),
};

assert_eq!(
Starknet::validate_unsigned(
TransactionSource::InBlock,
&crate::Call::invoke { transaction: transaction.into() }
),
Err(TransactionValidityError::Invalid(InvalidTransaction::BadProof))
);
})
}

#[test]
fn given_hardcoded_contract_run_invoke_tx3_then_it_works() {
new_test_ext::<MockRuntime>().execute_with(|| {
basic_test_setup(2);

let transaction = get_invoke_v3_dummy(Starknet::chain_id(), NONCE_ZERO);

assert_ok!(Starknet::invoke(RuntimeOrigin::none(), transaction));
});
}
2 changes: 1 addition & 1 deletion crates/pallets/starknet/src/tests/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ pub fn create_resource_bounds() -> starknet_api::transaction::ResourceBoundsMapp
let mut map = BTreeMap::new();
map.insert(
starknet_api::transaction::Resource::L1Gas,
starknet_api::transaction::ResourceBounds { max_amount: 10000, max_price_per_unit: 12000 },
starknet_api::transaction::ResourceBounds { max_amount: 150000, max_price_per_unit: 12000 },
);
map.insert(
starknet_api::transaction::Resource::L2Gas,
Expand Down
Loading

0 comments on commit 9b13de1

Please sign in to comment.