Skip to content

Commit 252ada0

Browse files
committed
chore: more tests
1 parent ad594e5 commit 252ada0

File tree

2 files changed

+143
-16
lines changed

2 files changed

+143
-16
lines changed

crates/tx-cache/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,5 @@ uuid = { workspace = true, features = ["serde"] }
2525

2626
[dev-dependencies]
2727
serde_urlencoded = "0.7.1"
28-
uuid = { workspace = true, features = ["serde", "v4"] }
28+
uuid = { workspace = true, features = ["serde", "v4"] }
29+
serde_json.workspace = true

crates/tx-cache/src/types.rs

Lines changed: 141 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,16 @@ pub trait CacheObject {
1515
}
1616

1717
/// A response from the transaction cache, containing an item.
18-
#[derive(Debug, Clone, Serialize, Deserialize)]
19-
#[serde(untagged)]
18+
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
19+
#[serde(untagged, rename_all_fields = "camelCase")]
2020
pub enum CacheResponse<T: CacheObject> {
2121
/// A paginated response, containing the inner item and a next cursor.
2222
Paginated {
2323
/// The actual item.
2424
#[serde(flatten)]
2525
inner: T,
2626
/// The next cursor for pagination, if any.
27-
next_cursor: Option<T::Key>,
27+
next_cursor: T::Key,
2828
},
2929
/// An unpaginated response, containing the actual item.
3030
Unpaginated {
@@ -41,7 +41,7 @@ impl<T: CacheObject> CacheObject for CacheResponse<T> {
4141
impl<T: CacheObject> CacheResponse<T> {
4242
/// Create a new paginated response from a list of items and a pagination info.
4343
pub const fn paginated(inner: T, pagination: T::Key) -> Self {
44-
Self::Paginated { inner, next_cursor: Some(pagination) }
44+
Self::Paginated { inner, next_cursor: pagination }
4545
}
4646

4747
/// Create a new unpaginated response from a list of items.
@@ -68,7 +68,7 @@ impl<T: CacheObject> CacheResponse<T> {
6868
/// Return the next cursor for pagination, if any.
6969
pub const fn next_cursor(&self) -> Option<&T::Key> {
7070
match self {
71-
Self::Paginated { next_cursor, .. } => next_cursor.as_ref(),
71+
Self::Paginated { next_cursor, .. } => Some(next_cursor),
7272
Self::Unpaginated { .. } => None,
7373
}
7474
}
@@ -99,7 +99,7 @@ impl<T: CacheObject> CacheResponse<T> {
9999
/// Consume the response and return the parts.
100100
pub fn into_parts(self) -> (T, Option<T::Key>) {
101101
match self {
102-
Self::Paginated { inner, next_cursor } => (inner, next_cursor),
102+
Self::Paginated { inner, next_cursor } => (inner, Some(next_cursor)),
103103
Self::Unpaginated { inner } => (inner, None),
104104
}
105105
}
@@ -112,7 +112,7 @@ impl<T: CacheObject> CacheResponse<T> {
112112

113113
/// A bundle response from the transaction cache, containing a UUID and a
114114
/// [`SignetEthBundle`].
115-
#[derive(Debug, Clone, Serialize, Deserialize)]
115+
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
116116
pub struct TxCacheBundle {
117117
/// The bundle id (a UUID)
118118
pub id: uuid::Uuid,
@@ -154,7 +154,7 @@ impl TxCacheBundle {
154154
}
155155

156156
/// A response from the transaction cache, containing a single bundle.
157-
#[derive(Debug, Clone, Serialize, Deserialize)]
157+
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
158158
pub struct TxCacheBundleResponse {
159159
/// The bundle.
160160
pub bundle: TxCacheBundle,
@@ -196,7 +196,7 @@ impl TxCacheBundleResponse {
196196
}
197197

198198
/// Response from the transaction cache `bundles` endpoint, containing a list of bundles.
199-
#[derive(Debug, Clone, Serialize, Deserialize)]
199+
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
200200
pub struct TxCacheBundlesResponse {
201201
/// the list of bundles
202202
pub bundles: Vec<TxCacheBundle>,
@@ -243,7 +243,7 @@ impl TxCacheBundlesResponse {
243243
}
244244

245245
/// Represents a response to successfully adding or updating a bundle in the transaction cache.
246-
#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
246+
#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq, Eq)]
247247
pub struct TxCacheSendBundleResponse {
248248
/// The bundle id (a UUID)
249249
pub id: uuid::Uuid,
@@ -273,7 +273,7 @@ impl CacheObject for TxCacheSendBundleResponse {
273273
}
274274

275275
/// Response from the transaction cache `transactions` endpoint, containing a list of transactions.
276-
#[derive(Debug, Clone, Serialize, Deserialize)]
276+
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
277277
pub struct TxCacheTransactionsResponse {
278278
/// The list of transactions.
279279
pub transactions: Vec<TxEnvelope>,
@@ -320,7 +320,7 @@ impl TxCacheTransactionsResponse {
320320
}
321321

322322
/// Response from the transaction cache to successfully adding a transaction.
323-
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
323+
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
324324
pub struct TxCacheSendTransactionResponse {
325325
/// The transaction hash
326326
pub tx_hash: B256,
@@ -362,7 +362,7 @@ impl TxCacheSendTransactionResponse {
362362
}
363363

364364
/// Response from the transaction cache `orders` endpoint, containing a list of signed orders.
365-
#[derive(Debug, Clone, Serialize, Deserialize)]
365+
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
366366
pub struct TxCacheOrdersResponse {
367367
/// The list of signed orders.
368368
pub orders: Vec<SignedOrder>,
@@ -404,7 +404,7 @@ impl TxCacheOrdersResponse {
404404
}
405405

406406
/// Response from the transaction cache to successfully adding an order.
407-
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
407+
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
408408
pub struct TxCacheSendOrderResponse {
409409
/// The order id
410410
pub id: B256,
@@ -861,9 +861,135 @@ impl<'de> Deserialize<'de> for CursorPayload<OrderKey> {
861861

862862
#[cfg(test)]
863863
mod tests {
864+
use super::*;
864865
use std::str::FromStr;
865866

866-
use super::*;
867+
fn dummy_bundle_with_id(id: Uuid) -> TxCacheBundle {
868+
TxCacheBundle {
869+
id,
870+
bundle: SignetEthBundle {
871+
bundle: alloy::rpc::types::mev::EthSendBundle {
872+
txs: vec![],
873+
block_number: 0,
874+
min_timestamp: None,
875+
max_timestamp: None,
876+
reverting_tx_hashes: vec![],
877+
replacement_uuid: Some(id.to_string()),
878+
dropping_tx_hashes: vec![],
879+
refund_percent: None,
880+
refund_recipient: None,
881+
refund_tx_hashes: vec![],
882+
extra_fields: Default::default(),
883+
},
884+
host_fills: None,
885+
host_txs: vec![],
886+
},
887+
}
888+
}
889+
890+
#[test]
891+
fn test_unpaginated_cache_response_deser() {
892+
let cache_response = CacheResponse::Unpaginated {
893+
inner: TxCacheTransactionsResponse { transactions: vec![] },
894+
};
895+
let expected_json = r#"{"transactions":[]}"#;
896+
let serialized = serde_json::to_string(&cache_response).unwrap();
897+
assert_eq!(serialized, expected_json);
898+
let deserialized =
899+
serde_json::from_str::<CacheResponse<TxCacheTransactionsResponse>>(&serialized)
900+
.unwrap();
901+
assert_eq!(deserialized, cache_response);
902+
}
903+
904+
#[test]
905+
fn test_paginated_cache_response_deser() {
906+
let cache_response = CacheResponse::Paginated {
907+
inner: TxCacheTransactionsResponse { transactions: vec![] },
908+
next_cursor: TxKey {
909+
txn_hash: B256::repeat_byte(0xaa),
910+
score: 100,
911+
global_transaction_score_key: "gtsk".to_string(),
912+
},
913+
};
914+
let expected_json = r#"{"transactions":[],"nextCursor":{"txnHash":"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","score":100,"globalTransactionScoreKey":"gtsk"}}"#;
915+
let serialized = serde_json::to_string(&cache_response).unwrap();
916+
assert_eq!(serialized, expected_json);
917+
let deserialized =
918+
serde_json::from_str::<CacheResponse<TxCacheTransactionsResponse>>(&expected_json)
919+
.unwrap();
920+
assert_eq!(deserialized, cache_response);
921+
}
922+
923+
// `serde_json` should be able to deserialize the old format, regardless if there's pagination information on the response.
924+
// This mimics the behavior of the types pre-pagination.
925+
#[test]
926+
fn test_backwards_compatibility_cache_response_deser() {
927+
let expected_json = r#"{"transactions":[],"nextCursor":{"txnHash":"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","score":100,"globalTransactionScoreKey":"gtsk"}}"#;
928+
let deserialized =
929+
serde_json::from_str::<TxCacheTransactionsResponse>(&expected_json).unwrap();
930+
assert_eq!(deserialized, TxCacheTransactionsResponse { transactions: vec![] });
931+
}
932+
933+
// `serde_json` should be able to deserialize the old format, regardless if there's pagination information on the response.
934+
// This mimics the behavior of the types pre-pagination.
935+
#[test]
936+
fn test_backwards_compatibility_cache_bundle_response_deser() {
937+
let expected_json = r#"{"bundles":[{"id":"5932d4bb-58d9-41a9-851d-8dd7f04ccc33","bundle":{"txs":[],"blockNumber":"0x0","replacementUuid":"5932d4bb-58d9-41a9-851d-8dd7f04ccc33"}}]}"#;
938+
let uuid = Uuid::from_str("5932d4bb-58d9-41a9-851d-8dd7f04ccc33").unwrap();
939+
940+
let deserialized = serde_json::from_str::<TxCacheBundlesResponse>(&expected_json).unwrap();
941+
942+
assert_eq!(
943+
deserialized,
944+
TxCacheBundlesResponse { bundles: vec![dummy_bundle_with_id(uuid)] }
945+
);
946+
}
947+
948+
// `serde_json` should be able to deserialize the old format, regardless if there's pagination information on the response.
949+
// This mimics the behavior of the types pre-pagination.
950+
#[test]
951+
fn test_backwards_compatibility_cache_order_response_deser() {
952+
let expected_json = r#"{"orders":[{"permit":{"permitted":[{"token":"0x0b8bc5e60ee10957e0d1a0d95598fa63e65605e2","amount":"0xf4240"}],"nonce":"0x637253c1eb651","deadline":"0x6846fde6"},"owner":"0x492e9c316f073fe4de9d665221568cdad1a7e95b","signature":"0x73e31a7c80f02840c4e0671230c408a5cbc7cddefc780db4dd102eed8e87c5740fc89944eb8e5756edd368ed755415ed090b043d1740ee6869c20cb1676329621c","outputs":[{"token":"0x885f8db528dc8a38aa3ddad9d3f619746b4a6a81","amount":"0xf4240","recipient":"0x492e9c316f073fe4de9d665221568cdad1a7e95b","chainId":3151908}]}], "id":"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}"#;
953+
let _ = serde_json::from_str::<TxCacheOrdersResponse>(&expected_json).unwrap();
954+
}
955+
956+
#[test]
957+
fn test_unpaginated_cache_bundle_response_deser() {
958+
let cache_response = CacheResponse::Unpaginated {
959+
inner: TxCacheBundlesResponse {
960+
bundles: vec![dummy_bundle_with_id(
961+
Uuid::from_str("5932d4bb-58d9-41a9-851d-8dd7f04ccc33").unwrap(),
962+
)],
963+
},
964+
};
965+
let expected_json = r#"{"bundles":[{"id":"5932d4bb-58d9-41a9-851d-8dd7f04ccc33","bundle":{"txs":[],"blockNumber":"0x0","replacementUuid":"5932d4bb-58d9-41a9-851d-8dd7f04ccc33"}}]}"#;
966+
let serialized = serde_json::to_string(&cache_response).unwrap();
967+
assert_eq!(serialized, expected_json);
968+
let deserialized =
969+
serde_json::from_str::<CacheResponse<TxCacheBundlesResponse>>(&expected_json).unwrap();
970+
assert_eq!(deserialized, cache_response);
971+
}
972+
973+
#[test]
974+
fn test_paginated_cache_bundle_response_deser() {
975+
let uuid = Uuid::from_str("5932d4bb-58d9-41a9-851d-8dd7f04ccc33").unwrap();
976+
977+
let cache_response = CacheResponse::Paginated {
978+
inner: TxCacheBundlesResponse { bundles: vec![dummy_bundle_with_id(uuid)] },
979+
next_cursor: BundleKey {
980+
id: uuid,
981+
score: 100,
982+
global_bundle_score_key: "gbsk".to_string(),
983+
},
984+
};
985+
let expected_json = r#"{"bundles":[{"id":"5932d4bb-58d9-41a9-851d-8dd7f04ccc33","bundle":{"txs":[],"blockNumber":"0x0","replacementUuid":"5932d4bb-58d9-41a9-851d-8dd7f04ccc33"}}],"nextCursor":{"id":"5932d4bb-58d9-41a9-851d-8dd7f04ccc33","score":100,"globalBundleScoreKey":"gbsk"}}"#;
986+
let serialized = serde_json::to_string(&cache_response).unwrap();
987+
dbg!(&serialized);
988+
assert_eq!(serialized, expected_json);
989+
let deserialized =
990+
serde_json::from_str::<CacheResponse<TxCacheBundlesResponse>>(&expected_json).unwrap();
991+
assert_eq!(deserialized, cache_response);
992+
}
867993

868994
#[test]
869995
fn test_pagination_params_simple_deser() {

0 commit comments

Comments
 (0)