v0.2.3-pre.005
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-onchain-transport-lib/unit_tests/rpc_transactions.rs
|
||||
// version: 4
|
||||
// version: 5
|
||||
|
||||
#[test]
|
||||
fn transaction_encoding_strings_match_current_and_legacy_wire_labels() {
|
||||
@@ -686,3 +686,191 @@ async fn typed_get_signature_statuses_rejects_response_count_mismatch() {
|
||||
assert_eq!(error.context()[2].value(), "1");
|
||||
handle.join().expect("fixture server must join");
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "current_thread")]
|
||||
async fn typed_get_transaction_modern_supports_omitted_and_explicit_empty_config() {
|
||||
let (url, handle) = serve_transaction_once(include_str!("../fixtures/http/get_transaction.null.json"));
|
||||
let pool = transaction_pool_for_url(url.as_str());
|
||||
let result = pool
|
||||
.get_transaction(&crate::HttpRoleName::new("default"), "fixture-signature", std::option::Option::None)
|
||||
.await
|
||||
.expect("getTransaction without config must succeed");
|
||||
assert!(result.is_none());
|
||||
let request = handle.join().expect("fixture server must join");
|
||||
assert_eq!(transaction_request_body(request.as_str())["params"], serde_json::json!(["fixture-signature"]));
|
||||
|
||||
let (url, handle) = serve_transaction_once(include_str!("../fixtures/http/get_transaction.null.json"));
|
||||
let pool = transaction_pool_for_url(url.as_str());
|
||||
let config = crate::SolanaGetTransactionConfig::default();
|
||||
let result = pool
|
||||
.get_transaction(&crate::HttpRoleName::new("default"), "fixture-signature", std::option::Option::Some(&config))
|
||||
.await
|
||||
.expect("getTransaction with explicit empty modern config must succeed");
|
||||
assert!(result.is_none());
|
||||
let request = handle.join().expect("fixture server must join");
|
||||
assert_eq!(transaction_request_body(request.as_str())["params"], serde_json::json!(["fixture-signature", {}]));
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "current_thread")]
|
||||
async fn typed_get_transaction_modern_serializes_full_config_and_preserves_rich_json_parsed_wire() {
|
||||
let (url, handle) = serve_transaction_once(include_str!("../fixtures/http/get_transaction.json_parsed.json"));
|
||||
let pool = transaction_pool_for_url(url.as_str());
|
||||
let config = crate::SolanaGetTransactionConfig::new(
|
||||
std::option::Option::Some(crate::SolanaCommitment::Confirmed),
|
||||
std::option::Option::Some(crate::SolanaTransactionEncoding::JsonParsed),
|
||||
std::option::Option::Some(0),
|
||||
);
|
||||
let result = pool
|
||||
.get_transaction(&crate::HttpRoleName::new("default"), "fixture-signature", std::option::Option::Some(&config))
|
||||
.await
|
||||
.expect("modern getTransaction fixture must succeed")
|
||||
.expect("modern getTransaction fixture must contain a transaction");
|
||||
assert_eq!(result.slot(), 431_000_064);
|
||||
assert_eq!(result.block_time(), std::option::Option::Some(1_787_000_204));
|
||||
assert_eq!(result.version().value(), std::option::Option::Some(&crate::SolanaTransactionVersion::Legacy));
|
||||
assert!(result.transaction_index().is_null());
|
||||
let transaction = match result.transaction() {
|
||||
crate::SolanaEncodedTransaction::Json(value) => value,
|
||||
_ => panic!("jsonParsed response must remain a JSON object"),
|
||||
};
|
||||
assert_eq!(transaction["message"]["accountKeys"][0]["source"], serde_json::json!("transaction"));
|
||||
assert_eq!(transaction["message"]["instructions"][0]["parsed"]["type"], serde_json::json!("transfer"));
|
||||
let meta = result.meta().value().expect("metadata must be present");
|
||||
assert_eq!(meta["computeUnitsConsumed"], serde_json::json!(150));
|
||||
assert_eq!(meta["costUnits"], serde_json::json!(190));
|
||||
assert!(meta["loadedAddresses"].is_null());
|
||||
let request = handle.join().expect("fixture server must join");
|
||||
let body = transaction_request_body(request.as_str());
|
||||
assert_eq!(body["method"], serde_json::json!("getTransaction"));
|
||||
assert_eq!(
|
||||
body["params"],
|
||||
serde_json::json!([
|
||||
"fixture-signature",
|
||||
{"commitment":"confirmed","encoding":"jsonParsed","maxSupportedTransactionVersion":0}
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "current_thread")]
|
||||
async fn typed_get_transaction_modern_covers_all_agave_v4_2_1_encoding_labels_and_response_shapes() {
|
||||
let cases = [
|
||||
(crate::SolanaTransactionEncoding::Binary, include_str!("../fixtures/http/get_transaction.binary_legacy.json")),
|
||||
(crate::SolanaTransactionEncoding::Base58, include_str!("../fixtures/http/get_transaction.base58.json")),
|
||||
(crate::SolanaTransactionEncoding::Base64, include_str!("../fixtures/http/get_transaction.base64.json")),
|
||||
(crate::SolanaTransactionEncoding::Json, include_str!("../fixtures/http/get_transaction.json.json")),
|
||||
(crate::SolanaTransactionEncoding::JsonParsed, include_str!("../fixtures/http/get_transaction.json_parsed.json")),
|
||||
];
|
||||
for (encoding, fixture) in cases {
|
||||
let (url, handle) = serve_transaction_once(fixture);
|
||||
let pool = transaction_pool_for_url(url.as_str());
|
||||
let config = crate::SolanaGetTransactionConfig::new(std::option::Option::None, std::option::Option::Some(encoding), std::option::Option::None);
|
||||
let result = pool
|
||||
.get_transaction(&crate::HttpRoleName::new("default"), "fixture-signature", std::option::Option::Some(&config))
|
||||
.await
|
||||
.expect("encoding-specific modern getTransaction must succeed")
|
||||
.expect("encoding-specific modern getTransaction must contain a transaction");
|
||||
match encoding {
|
||||
crate::SolanaTransactionEncoding::Binary => assert!(matches!(result.transaction(), crate::SolanaEncodedTransaction::LegacyBinary(_))),
|
||||
crate::SolanaTransactionEncoding::Base58 => assert!(matches!(
|
||||
result.transaction(),
|
||||
crate::SolanaEncodedTransaction::Binary { encoding: crate::SolanaTransactionBinaryEncoding::Base58, .. }
|
||||
)),
|
||||
crate::SolanaTransactionEncoding::Base64 => assert!(matches!(
|
||||
result.transaction(),
|
||||
crate::SolanaEncodedTransaction::Binary { encoding: crate::SolanaTransactionBinaryEncoding::Base64, .. }
|
||||
)),
|
||||
crate::SolanaTransactionEncoding::Json | crate::SolanaTransactionEncoding::JsonParsed => {
|
||||
assert!(matches!(result.transaction(), crate::SolanaEncodedTransaction::Json(_)));
|
||||
},
|
||||
}
|
||||
let request = handle.join().expect("fixture server must join");
|
||||
let body = transaction_request_body(request.as_str());
|
||||
assert_eq!(body["params"], serde_json::json!(["fixture-signature", {"encoding":encoding.as_str()}]));
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
#[tokio::test(flavor = "current_thread")]
|
||||
async fn typed_get_transaction_legacy_covers_all_bare_encoding_labels() {
|
||||
let cases = [
|
||||
(crate::SolanaTransactionEncoding::Binary, include_str!("../fixtures/http/get_transaction.binary_legacy.json")),
|
||||
(crate::SolanaTransactionEncoding::Base58, include_str!("../fixtures/http/get_transaction.base58.json")),
|
||||
(crate::SolanaTransactionEncoding::Base64, include_str!("../fixtures/http/get_transaction.base64.json")),
|
||||
(crate::SolanaTransactionEncoding::Json, include_str!("../fixtures/http/get_transaction.json.json")),
|
||||
(crate::SolanaTransactionEncoding::JsonParsed, include_str!("../fixtures/http/get_transaction.json_parsed.json")),
|
||||
];
|
||||
for (encoding, fixture) in cases {
|
||||
let (url, handle) = serve_transaction_once(fixture);
|
||||
let pool = transaction_pool_for_url(url.as_str());
|
||||
let result = pool
|
||||
.get_transaction_legacy(&crate::HttpRoleName::new("default"), "fixture-signature", encoding)
|
||||
.await
|
||||
.expect("legacy bare-encoding getTransaction must succeed");
|
||||
assert!(result.is_some());
|
||||
let request = handle.join().expect("fixture server must join");
|
||||
let body = transaction_request_body(request.as_str());
|
||||
assert_eq!(body["method"], serde_json::json!("getTransaction"));
|
||||
assert_eq!(body["params"], serde_json::json!(["fixture-signature", encoding.as_str()]));
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "current_thread")]
|
||||
async fn typed_get_transaction_preserves_raw_json_meta_version_and_transaction_index() {
|
||||
let (url, handle) = serve_transaction_once(include_str!("../fixtures/http/get_transaction.json.json"));
|
||||
let pool = transaction_pool_for_url(url.as_str());
|
||||
let config = crate::SolanaGetTransactionConfig::new(
|
||||
std::option::Option::Some(crate::SolanaCommitment::Finalized),
|
||||
std::option::Option::Some(crate::SolanaTransactionEncoding::Json),
|
||||
std::option::Option::Some(0),
|
||||
);
|
||||
let result = pool
|
||||
.get_transaction(&crate::HttpRoleName::new("default"), "fixture-signature", std::option::Option::Some(&config))
|
||||
.await
|
||||
.expect("raw JSON getTransaction must succeed")
|
||||
.expect("raw JSON getTransaction must contain a transaction");
|
||||
assert_eq!(result.version().value(), std::option::Option::Some(&crate::SolanaTransactionVersion::Number(0)));
|
||||
assert_eq!(result.transaction_index().value(), std::option::Option::Some(&7));
|
||||
let meta = result.meta().value().expect("metadata must be present");
|
||||
assert_eq!(meta["status"], serde_json::json!({"Ok":null}));
|
||||
assert_eq!(meta["loadedAddresses"]["writable"], serde_json::json!([]));
|
||||
assert_eq!(meta["returnData"]["data"], serde_json::json!(["AQID", "base64"]));
|
||||
assert_eq!(meta["costUnits"], serde_json::json!(190));
|
||||
let request = handle.join().expect("fixture server must join");
|
||||
assert_eq!(
|
||||
transaction_request_body(request.as_str())["params"],
|
||||
serde_json::json!([
|
||||
"fixture-signature",
|
||||
{"commitment":"finalized","encoding":"json","maxSupportedTransactionVersion":0}
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "current_thread")]
|
||||
async fn typed_get_transaction_preserves_unsupported_version_rpc_error() {
|
||||
let (url, handle) = serve_transaction_once(include_str!("../fixtures/http/get_transaction.error_unsupported_version.json"));
|
||||
let pool = transaction_pool_for_url(url.as_str());
|
||||
let config = crate::SolanaGetTransactionConfig::new(
|
||||
std::option::Option::None,
|
||||
std::option::Option::Some(crate::SolanaTransactionEncoding::Base64),
|
||||
std::option::Option::Some(0),
|
||||
);
|
||||
let result = pool.get_transaction(&crate::HttpRoleName::new("default"), "fixture-signature", std::option::Option::Some(&config)).await;
|
||||
let error = result.expect_err("unsupported transaction version must remain an RPC application error");
|
||||
assert_eq!(error.code(), crate::ERROR_CODE_RPC_APPLICATION_ERROR);
|
||||
handle.join().expect("fixture server must join");
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "current_thread")]
|
||||
async fn typed_get_transaction_rejects_processed_commitment_before_io() {
|
||||
let pool = transaction_pool_for_url("http://127.0.0.1:9");
|
||||
let config = crate::SolanaGetTransactionConfig::new(
|
||||
std::option::Option::Some(crate::SolanaCommitment::Processed),
|
||||
std::option::Option::Some(crate::SolanaTransactionEncoding::Json),
|
||||
std::option::Option::None,
|
||||
);
|
||||
let result = pool.get_transaction(&crate::HttpRoleName::new("default"), "fixture-signature", std::option::Option::Some(&config)).await;
|
||||
let error = result.expect_err("processed getTransaction commitment must reject before I/O");
|
||||
assert_eq!(error.code(), crate::ERROR_CODE_INVALID_RPC_PARAMETERS);
|
||||
assert_eq!(error.context()[1].key(), "commitment");
|
||||
assert_eq!(error.context()[1].value(), "processed");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user