-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #49 from Tbelleng/feat/release_ditto
✨ Adding add_invoke_transaction and deploy_account_transaction RPC test
- Loading branch information
Showing
5 changed files
with
382 additions
and
0 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
#![feature(assert_matches)] | ||
|
||
mod common; | ||
use common::*; | ||
use starknet_core::types::{ | ||
BroadcastedInvokeTransaction, FieldElement, StarknetError, TransactionStatus, | ||
}; | ||
use starknet_providers::{ | ||
jsonrpc::{HttpTransport, JsonRpcClient}, | ||
Provider, ProviderError, | ||
}; | ||
use std::assert_matches::assert_matches; | ||
use std::thread; | ||
use std::time::Duration; | ||
|
||
/// Test for the `add_invoke_transaction` Deoxys RPC method | ||
/// Submit a new transaction to be added to the chain | ||
/// | ||
/// # Arguments | ||
/// * `invoke_transaction` - An invoke transaction, | ||
/// with following fields: | ||
/// * `type` - INVOKE | ||
/// * `sender_address` - The address of the sender | ||
/// * `calldata` - The calldata to send | ||
/// * `max_fee` - The maximum fees sender is willing to pay | ||
/// * `version` - The version of the transaction | ||
/// * `signature` - The transaction signature | ||
/// * `nonce` - The nonce of the transaction | ||
/// | ||
/// # Returns | ||
/// * `result` - The result of the transaction submission, with the transaction hash that has been submitted | ||
/// | ||
/// # Errors | ||
/// * `invalid_transaction_nonce` - If the transaction nonce is invalid | ||
/// * `insufficient_account_balance` - If the account balance is insufficient | ||
/// * `insufficient_max_fee` - If the max fee is insufficient | ||
/// * `invalid_transaction_nonce` - If the transaction nonce is invalid | ||
/// * `validation_failure` - If the transaction validation fails | ||
/// * `non_account` - If the sender address is not a valid account | ||
/// * `duplicate_transaction` - If a transaction with same params already exists | ||
/// * `unsupported_transaction_version` - If the transaction version is not supported | ||
/// * `unexpected_error` - If an unexpected error occurs | ||
|
||
/// Following tests runs using V1 Invoke Transaction (params follow starknet-rs implementation) | ||
#[rstest] | ||
#[tokio::test] | ||
async fn fail_if_param_(deoxys: JsonRpcClient<HttpTransport>) { | ||
let invalid_invoke_transaction = BroadcastedInvokeTransaction { | ||
sender_address: FieldElement::from_hex_be("valid_address").unwrap(), | ||
calldata: vec![FieldElement::from_hex_be("calldata_array").unwrap()], | ||
max_fee: FieldElement::from_hex_be("0x0ffffffff").unwrap(), | ||
signature: vec![FieldElement::from_hex_be("signature_array").unwrap()], | ||
nonce: FieldElement::from_hex_be("0x000000").unwrap(), //here nonce is invalid | ||
is_query: false, | ||
}; | ||
|
||
let response_deoxys = deoxys | ||
.add_invoke_transaction(invalid_invoke_transaction) | ||
.await; | ||
|
||
assert_matches!( | ||
response_deoxys, | ||
Err(ProviderError::StarknetError( | ||
StarknetError::InvalidTransactionNonce | ||
)) | ||
); | ||
} | ||
|
||
#[rstest] | ||
#[tokio::test] | ||
async fn fail_if_insufficient_max_fee(deoxys: JsonRpcClient<HttpTransport>) { | ||
let invalid_invoke_transaction = BroadcastedInvokeTransaction { | ||
sender_address: FieldElement::from_hex_be("valid_address").unwrap(), | ||
calldata: vec![FieldElement::from_hex_be("calldata_array").unwrap()], | ||
max_fee: FieldElement::from_hex_be("0x000000").unwrap(), //here max_fee is insufficient | ||
signature: vec![FieldElement::from_hex_be("signature_array").unwrap()], | ||
nonce: FieldElement::from_hex_be("0x01").unwrap(), | ||
is_query: false, | ||
}; | ||
|
||
let response_deoxys = deoxys | ||
.add_invoke_transaction(invalid_invoke_transaction) | ||
.await; | ||
|
||
assert_matches!( | ||
response_deoxys, | ||
Err(ProviderError::StarknetError( | ||
StarknetError::InsufficientMaxFee | ||
)) | ||
); | ||
} | ||
|
||
#[rstest] | ||
#[tokio::test] | ||
async fn fail_if_bad_calldata(deoxys: JsonRpcClient<HttpTransport>) { | ||
let invalid_invoke_transaction = BroadcastedInvokeTransaction { | ||
sender_address: FieldElement::from_hex_be("valid_address").unwrap(), | ||
calldata: vec![FieldElement::from_hex_be("0x000000").unwrap()], //here calldata is invalid | ||
max_fee: FieldElement::from_hex_be("0x0ffffffff").unwrap(), | ||
signature: vec![FieldElement::from_hex_be("signature_array").unwrap()], | ||
nonce: FieldElement::from_hex_be("0x01").unwrap(), | ||
is_query: false, | ||
}; | ||
|
||
let response_deoxys = deoxys | ||
.add_invoke_transaction(invalid_invoke_transaction) | ||
.await; | ||
|
||
assert_matches!( | ||
response_deoxys, | ||
Err(ProviderError::StarknetError( | ||
StarknetError::ValidationFailure | ||
)) | ||
); | ||
} | ||
|
||
#[rstest] | ||
#[tokio::test] | ||
async fn works_ok_with_valid_params(deoxys: JsonRpcClient<HttpTransport>) { | ||
let valid_invoke_transaction = BroadcastedInvokeTransaction { | ||
sender_address: FieldElement::from_hex_be("valid_address").unwrap(), | ||
calldata: vec![FieldElement::from_hex_be("calldata_array").unwrap()], | ||
max_fee: FieldElement::from_hex_be("0x0ffffffff").unwrap(), | ||
signature: vec![FieldElement::from_hex_be("signature_array").unwrap()], | ||
nonce: FieldElement::from_hex_be("0x01").unwrap(), | ||
is_query: false, | ||
}; | ||
|
||
//Here we added a valid transaction | ||
let response_deoxys = deoxys | ||
.add_invoke_transaction(valid_invoke_transaction) | ||
.await; | ||
|
||
//Now, if the transaction is valid, the rpc call response contain the transaction hash | ||
let transaction_submitted_hash = response_deoxys | ||
.expect("Transaction submition failed") | ||
.transaction_hash; | ||
|
||
//Wait for the transaction to be added to the chain | ||
thread::sleep(Duration::from_secs(15)); | ||
|
||
//Let's check the transaction status | ||
let transaction_status = deoxys | ||
.get_transaction_status(transaction_submitted_hash) | ||
.await; | ||
|
||
assert_matches!(transaction_status.unwrap(), TransactionStatus::Received); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
#![feature(assert_matches)] | ||
|
||
mod common; | ||
use common::*; | ||
use starknet_core::types::{ | ||
BroadcastedDeployAccountTransaction, FieldElement, StarknetError, TransactionStatus, | ||
}; | ||
use starknet_providers::{ | ||
jsonrpc::{HttpTransport, JsonRpcClient}, | ||
Provider, ProviderError, | ||
}; | ||
use std::assert_matches::assert_matches; | ||
use std::thread; | ||
use std::time::Duration; | ||
|
||
/// Test for the `deploy_account_transaction` Deoxys RPC method | ||
/// Submit a new deploy account transaction | ||
/// | ||
/// There is two type of DeployAccountTransaction: V1 and V3 | ||
/// | ||
/// # Arguments | ||
/// * `deploy_account_transaction` - A deploy account transaction | ||
/// with following fields (V1): | ||
/// * `type` - DEPLOY_ACCOUNT | ||
/// * `max_fee` - The maximal fee willing to be paid | ||
/// * `signature` - The transaction signature | ||
/// * `nonce` - The nonce of the transaction | ||
/// * `contract_address_salt` - The salt for the address of the deployed contract | ||
/// * `constructor_calldata` - The parameters passed to the constructor | ||
/// * `class_hash` - The hash of the deployed contract's class | ||
/// * `is_query` - If set to `true`, uses a query-only transaction version that's invalid for execution | ||
/// | ||
/// # Returns | ||
/// * `result` - The result of the transaction submission | ||
/// with following fields: | ||
/// * `transaction_hash` - The hash of the transaction | ||
/// * `contract_address` - The address of the deployed contract | ||
/// | ||
/// # Errors | ||
/// * `invalid_transaction_nonce` - If the transaction nonce is invalid | ||
/// * `insufficient_account_balance` - If the account balance is insufficient | ||
/// * `insufficient_max_fee` - If the max fee is insufficient | ||
/// * `invalid_transaction_nonce` - If the transaction nonce is invalid | ||
/// * `validation_failure` - If the transaction validation fails | ||
/// * `non_account` - If the sender address is not a valid account | ||
/// * `duplicate_transaction` - If a transaction with same params already exists | ||
/// * `unsupported_transaction_version` - If the transaction version is not supported | ||
/// * `unexpected_error` - If an unexpected error occurs | ||
|
||
#[rstest] | ||
#[tokio::test] | ||
async fn fail_if_param_(deoxys: JsonRpcClient<HttpTransport>) { | ||
let invalid_deploy_account_transaction = BroadcastedDeployAccountTransaction { | ||
max_fee: FieldElement::from_hex_be("0x0ffffffff").unwrap(), | ||
signature: vec![FieldElement::from_hex_be("signature_array").unwrap()], | ||
nonce: FieldElement::from_hex_be("0x000000").unwrap(), //here nonce is invalid | ||
contract_address_salt: FieldElement::from_hex_be("0x000000").unwrap(), | ||
constructor_calldata: vec![FieldElement::from_hex_be("constructor_calldata_array").unwrap()], | ||
class_hash: FieldElement::from_hex_be("0x000000").unwrap(), | ||
is_query: false, | ||
}; | ||
|
||
let response_deoxys = deoxys | ||
.add_deploy_account_transaction(invalid_deploy_account_transaction) | ||
.await; | ||
|
||
assert_matches!( | ||
response_deoxys, | ||
Err(ProviderError::StarknetError( | ||
StarknetError::InvalidTransactionNonce | ||
)) | ||
); | ||
} | ||
|
||
#[rstest] | ||
#[tokio::test] | ||
async fn fail_if_insufficient_max_fee(deoxys: JsonRpcClient<HttpTransport>) { | ||
let invalid_deploy_account_transaction = BroadcastedDeployAccountTransaction { | ||
max_fee: FieldElement::from_hex_be("0x000000").unwrap(), //here max_fee is insufficient | ||
signature: vec![FieldElement::from_hex_be("signature_array").unwrap()], | ||
nonce: FieldElement::from_hex_be("0x000000").unwrap(), | ||
contract_address_salt: FieldElement::from_hex_be("0x000000").unwrap(), | ||
constructor_calldata: vec![FieldElement::from_hex_be("constructor_calldata_array").unwrap()], | ||
class_hash: FieldElement::from_hex_be("0x000000").unwrap(), | ||
is_query: false, | ||
}; | ||
|
||
let response_deoxys = deoxys | ||
.add_deploy_account_transaction(invalid_deploy_account_transaction) | ||
.await; | ||
|
||
assert_matches!( | ||
response_deoxys, | ||
Err(ProviderError::StarknetError( | ||
StarknetError::InsufficientMaxFee | ||
)) | ||
); | ||
} | ||
|
||
#[rstest] | ||
#[tokio::test] | ||
async fn fail_if_invalid_transaction_nonce(deoxys: JsonRpcClient<HttpTransport>) { | ||
let invalid_deploy_account_transaction = BroadcastedDeployAccountTransaction { | ||
max_fee: FieldElement::from_hex_be("0x0ffffffff").unwrap(), | ||
signature: vec![FieldElement::from_hex_be("signature_array").unwrap()], | ||
nonce: FieldElement::from_hex_be("0x000000").unwrap(), //here nonce is invalid | ||
contract_address_salt: FieldElement::from_hex_be("0x000000").unwrap(), | ||
constructor_calldata: vec![FieldElement::from_hex_be("constructor_calldata_array").unwrap()], | ||
class_hash: FieldElement::from_hex_be("0x000000").unwrap(), | ||
is_query: false, | ||
}; | ||
|
||
let response_deoxys = deoxys | ||
.add_deploy_account_transaction(invalid_deploy_account_transaction) | ||
.await; | ||
|
||
assert_matches!( | ||
response_deoxys, | ||
Err(ProviderError::StarknetError( | ||
StarknetError::InvalidTransactionNonce | ||
)) | ||
); | ||
} | ||
|
||
#[rstest] | ||
#[tokio::test] | ||
async fn works_ok(deoxys: JsonRpcClient<HttpTransport>) { | ||
let valid_deploy_account_transaction = BroadcastedDeployAccountTransaction { | ||
max_fee: FieldElement::from_hex_be("0x0ffffffff").unwrap(), | ||
signature: vec![FieldElement::from_hex_be("signature_array").unwrap()], | ||
nonce: FieldElement::from_hex_be("0x000000").unwrap(), | ||
contract_address_salt: FieldElement::from_hex_be("0x000000").unwrap(), | ||
constructor_calldata: vec![FieldElement::from_hex_be("constructor_calldata_array").unwrap()], | ||
class_hash: FieldElement::from_hex_be("0x000000").unwrap(), | ||
is_query: false, | ||
}; | ||
|
||
let response_deoxys = deoxys | ||
.add_deploy_account_transaction(valid_deploy_account_transaction) | ||
.await; | ||
|
||
//Here, as response we got the transaction hash and the contract address deployed | ||
let result = response_deoxys.unwrap(); | ||
|
||
//Now, if the transaction is valid, the rpc call response contain the transaction hash | ||
let transaction_submitted_hash = response_deoxys | ||
.expect("Transaction submition failed") | ||
.transaction_hash; | ||
|
||
//Wait for the transaction to be added to the chain | ||
thread::sleep(Duration::from_secs(15)); | ||
|
||
//Let's check the transaction status | ||
let transaction_status = deoxys | ||
.get_transaction_status(transaction_submitted_hash) | ||
.await; | ||
|
||
assert_matches!(transaction_status.unwrap(), TransactionStatus::Received); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
#![feature(assert_matches)] | ||
|
||
mod common; | ||
use common::*; | ||
|
||
use rand::Rng; | ||
use std::assert_matches::assert_matches; | ||
|
||
use starknet_core::types::{BlockId, FieldElement, StarknetError}; | ||
use starknet_providers::{ | ||
jsonrpc::{HttpTransport, JsonRpcClient}, | ||
Provider, ProviderError, | ||
}; | ||
|
||
#[rstest] | ||
#[tokio::test] | ||
async fn fail_non_existing_block(deoxys: JsonRpcClient<HttpTransport>) { | ||
assert_matches!( | ||
deoxys | ||
.trace_block_transactions(BlockId::Hash(FieldElement::ZERO)) | ||
.await, | ||
Err(ProviderError::StarknetError(StarknetError::BlockNotFound)) | ||
); | ||
} | ||
|
||
#[rstest] | ||
#[tokio::test] | ||
async fn works_ok_for_block_10000( | ||
deoxys: JsonRpcClient<HttpTransport>, | ||
pathfinder: JsonRpcClient<HttpTransport>, | ||
) { | ||
let block_number = BlockId::Number(10000); | ||
|
||
let deoxys_trace = deoxys.trace_block_transactions(block_number).await; | ||
let _pathfinder_trace = pathfinder.trace_block_transactions(block_number).await; | ||
|
||
assert_matches!(deoxys_trace, _pathfinder_trace); | ||
} | ||
|
||
#[rstest] | ||
#[tokio::test] | ||
async fn works_ok_for_block_300000( | ||
deoxys: JsonRpcClient<HttpTransport>, | ||
pathfinder: JsonRpcClient<HttpTransport>, | ||
) { | ||
let block_number = BlockId::Number(300000); | ||
|
||
let deoxys_trace = deoxys.trace_block_transactions(block_number).await; | ||
let _pathfinder_trace = pathfinder.trace_block_transactions(block_number).await; | ||
|
||
assert_matches!(deoxys_trace, _pathfinder_trace); | ||
} | ||
|
||
#[rstest] | ||
#[tokio::test] | ||
async fn works_ok_for_random_block( | ||
deoxys: JsonRpcClient<HttpTransport>, | ||
pathfinder: JsonRpcClient<HttpTransport>, | ||
) { | ||
let mut rng = rand::thread_rng(); | ||
let random_block_number = rng.gen_range(100000..602000); | ||
|
||
let block_number = BlockId::Number(random_block_number); | ||
|
||
let deoxys_trace = deoxys.trace_block_transactions(block_number).await; | ||
let _pathfinder_trace = pathfinder.trace_block_transactions(block_number).await; | ||
println!("{:?}", deoxys_trace); | ||
println!("block choose is: {:?}", block_number); | ||
|
||
assert_matches!(deoxys_trace, _pathfinder_trace); | ||
} |