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

chore(katana-rpc): test cleanup #2363

Merged
merged 1 commit into from
Aug 29, 2024
Merged
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
172 changes: 61 additions & 111 deletions crates/katana/rpc/rpc/tests/starknet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
use std::fs::{self};
use std::path::PathBuf;
use std::sync::Arc;
use std::time::Duration;

use anyhow::Result;
use assert_matches::assert_matches;
Expand All @@ -12,9 +11,8 @@ use dojo_test_utils::sequencer::{get_default_test_starknet_config, TestSequencer
use indexmap::IndexSet;
use katana_core::sequencer::SequencerConfig;
use katana_primitives::genesis::constant::{
DEFAULT_FEE_TOKEN_ADDRESS, DEFAULT_PREFUNDED_ACCOUNT_BALANCE,
DEFAULT_FEE_TOKEN_ADDRESS, DEFAULT_PREFUNDED_ACCOUNT_BALANCE, DEFAULT_UDC_ADDRESS,
};
use katana_rpc_types::receipt::ReceiptBlock;
use starknet::accounts::{
Account, AccountError, Call, ConnectedAccount, ExecutionEncoding, SingleOwnerAccount,
};
Expand All @@ -23,169 +21,121 @@ use starknet::core::types::{
BlockId, BlockTag, DeclareTransactionReceipt, ExecutionResult, Felt, StarknetError,
TransactionFinalityStatus, TransactionReceipt,
};
use starknet::core::utils::{get_contract_address, get_selector_from_name};
use starknet::macros::felt;
use starknet::core::utils::get_contract_address;
use starknet::macros::{felt, selector};
use starknet::providers::{Provider, ProviderError};
use starknet::signers::{LocalWallet, SigningKey};
use tokio::sync::Mutex;

mod common;

const WAIT_TX_DELAY_MILLIS: u64 = 1000;

#[tokio::test(flavor = "multi_thread")]
async fn test_send_declare_and_deploy_contract() {
#[tokio::test]
async fn test_send_declare_and_deploy_contract() -> Result<()> {
let sequencer =
TestSequencer::start(SequencerConfig::default(), get_default_test_starknet_config()).await;

let account = sequencer.account();
let provider = sequencer.provider();

let path: PathBuf = PathBuf::from("tests/test_data/cairo1_contract.json");
let (contract, compiled_class_hash) =
common::prepare_contract_declaration_params(&path).unwrap();
let (contract, compiled_class_hash) = common::prepare_contract_declaration_params(&path)?;

let class_hash = contract.class_hash();
let res = account.declare_v2(Arc::new(contract), compiled_class_hash).send().await.unwrap();

// wait for the tx to be mined
tokio::time::sleep(Duration::from_millis(WAIT_TX_DELAY_MILLIS)).await;

let receipt = account.provider().get_transaction_receipt(res.transaction_hash).await.unwrap();
let res = account.declare_v2(contract.into(), compiled_class_hash).send().await?;

match receipt.block {
ReceiptBlock::Block { .. } => {
let TransactionReceipt::Declare(DeclareTransactionReceipt { finality_status, .. }) =
receipt.receipt
else {
panic!("invalid tx receipt")
};
// check that the tx is executed successfully and return the correct receipt
let receipt = dojo_utils::TransactionWaiter::new(res.transaction_hash, &provider).await?;
assert_matches!(receipt.receipt, TransactionReceipt::Declare(DeclareTransactionReceipt { .. }));

assert_eq!(finality_status, TransactionFinalityStatus::AcceptedOnL2);
}

_ => panic!("invalid tx receipt"),
}

assert!(account.provider().get_class(BlockId::Tag(BlockTag::Latest), class_hash).await.is_ok());

let constructor_calldata = vec![Felt::from(1_u32), Felt::from(2_u32)];
// check that the class is actually declared
assert!(provider.get_class(BlockId::Tag(BlockTag::Pending), class_hash).await.is_ok());

let ctor_args = vec![Felt::ONE, Felt::TWO];
let calldata = [
vec![
res.class_hash, // class hash
Felt::ZERO, // salt
Felt::ZERO, // unique
Felt::from(constructor_calldata.len()), // constructor calldata len
res.class_hash, // class hash
Felt::ZERO, // salt
Felt::ZERO, // unique
Felt::from(ctor_args.len()), // constructor calldata len
],
constructor_calldata.clone(),
ctor_args.clone(),
]
.concat();

let contract_address =
get_contract_address(Felt::ZERO, res.class_hash, &constructor_calldata, Felt::ZERO);
// pre-compute the contract address of the would-be deployed contract
let address = get_contract_address(Felt::ZERO, res.class_hash, &ctor_args, Felt::ZERO);

account
let res = account
.execute_v1(vec![Call {
calldata,
// devnet UDC address
to: Felt::from_hex("0x41a78e741e5af2fec34b695679bc6891742439f7afb8484ecd7766661ad02bf")
.unwrap(),
selector: get_selector_from_name("deployContract").unwrap(),
to: DEFAULT_UDC_ADDRESS.into(),
selector: selector!("deployContract"),
}])
.send()
.await
.unwrap();
.await?;

// wait for the tx to be mined
tokio::time::sleep(Duration::from_millis(WAIT_TX_DELAY_MILLIS)).await;

assert_eq!(
account
.provider()
.get_class_hash_at(BlockId::Tag(BlockTag::Latest), contract_address)
.await
.unwrap(),
class_hash
);
dojo_utils::TransactionWaiter::new(res.transaction_hash, &provider).await?;

sequencer.stop().expect("failed to stop sequencer");
// make sure the contract is deployed
let res = provider.get_class_hash_at(BlockId::Tag(BlockTag::Pending), address).await?;
assert_eq!(res, class_hash);

Ok(())
}

#[tokio::test(flavor = "multi_thread")]
async fn test_send_declare_and_deploy_legacy_contract() {
#[tokio::test]
async fn test_send_declare_and_deploy_legacy_contract() -> Result<()> {
let sequencer =
TestSequencer::start(SequencerConfig::default(), get_default_test_starknet_config()).await;

let account = sequencer.account();
let provider = sequencer.provider();

let path = PathBuf::from("tests/test_data/cairo0_contract.json");
let contract: LegacyContractClass = serde_json::from_reader(fs::File::open(path)?)?;

let legacy_contract: LegacyContractClass =
serde_json::from_reader(fs::File::open(path).unwrap()).unwrap();
let contract_class = Arc::new(legacy_contract);
let class_hash = contract.class_hash()?;
let res = account.declare_legacy(contract.into()).send().await?;

let class_hash = contract_class.class_hash().unwrap();
let res = account.declare_legacy(contract_class).send().await.unwrap();
// wait for the tx to be mined
tokio::time::sleep(Duration::from_millis(WAIT_TX_DELAY_MILLIS)).await;

let receipt = account.provider().get_transaction_receipt(res.transaction_hash).await.unwrap();
let receipt = dojo_utils::TransactionWaiter::new(res.transaction_hash, &provider).await?;
assert_matches!(receipt.receipt, TransactionReceipt::Declare(DeclareTransactionReceipt { .. }));

match receipt.block {
ReceiptBlock::Block { .. } => {
let TransactionReceipt::Declare(DeclareTransactionReceipt { finality_status, .. }) =
receipt.receipt
else {
panic!("invalid tx receipt")
};

assert_eq!(finality_status, TransactionFinalityStatus::AcceptedOnL2);
}

_ => panic!("invalid tx receipt"),
}

assert!(account.provider().get_class(BlockId::Tag(BlockTag::Latest), class_hash).await.is_ok());

let constructor_calldata = vec![Felt::ONE];
// check that the class is actually declared
assert!(provider.get_class(BlockId::Tag(BlockTag::Pending), class_hash).await.is_ok());

let ctor_args = vec![Felt::ONE];
let calldata = [
vec![
res.class_hash, // class hash
Felt::ZERO, // salt
Felt::ZERO, // unique
Felt::from(constructor_calldata.len()), // constructor calldata len
res.class_hash, // class hash
Felt::ZERO, // salt
Felt::ZERO, // unique
Felt::from(ctor_args.len()), // constructor calldata len
],
constructor_calldata.clone(),
ctor_args.clone(),
]
.concat();

let contract_address =
get_contract_address(Felt::ZERO, res.class_hash, &constructor_calldata.clone(), Felt::ZERO);
// pre-compute the contract address of the would-be deployed contract
let address = get_contract_address(Felt::ZERO, res.class_hash, &ctor_args.clone(), Felt::ZERO);

account
let res = account
.execute_v1(vec![Call {
calldata,
// devnet UDC address
to: Felt::from_hex("0x41a78e741e5af2fec34b695679bc6891742439f7afb8484ecd7766661ad02bf")
.unwrap(),
selector: get_selector_from_name("deployContract").unwrap(),
to: DEFAULT_UDC_ADDRESS.into(),
selector: selector!("deployContract"),
}])
.send()
.await
.unwrap();
.await?;

// wait for the tx to be mined
tokio::time::sleep(Duration::from_millis(WAIT_TX_DELAY_MILLIS)).await;

assert_eq!(
account
.provider()
.get_class_hash_at(BlockId::Tag(BlockTag::Latest), contract_address)
.await
.unwrap(),
class_hash
);
dojo_utils::TransactionWaiter::new(res.transaction_hash, &provider).await?;

// make sure the contract is deployed
let res = provider.get_class_hash_at(BlockId::Tag(BlockTag::Pending), address).await?;
assert_eq!(res, class_hash);

sequencer.stop().expect("failed to stop sequencer");
Ok(())
}

#[tokio::test]
Expand Down
Loading