Skip to content

Commit c0a9617

Browse files
committed
Cancel bundle
1 parent 489fa99 commit c0a9617

File tree

2 files changed

+113
-68
lines changed

2 files changed

+113
-68
lines changed

crates/datastore/src/postgres.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,8 +242,12 @@ impl BundleDatastore for PostgresDatastore {
242242
}
243243
}
244244

245-
async fn cancel_bundle(&self, _id: Uuid) -> Result<()> {
246-
todo!()
245+
async fn cancel_bundle(&self, id: Uuid) -> Result<()> {
246+
sqlx::query("DELETE FROM bundles WHERE id = $1")
247+
.bind(id)
248+
.execute(&self.pool)
249+
.await?;
250+
Ok(())
247251
}
248252

249253
async fn select_bundles(&self, filter: BundleFilter) -> Result<Vec<BundleWithMetadata>> {

crates/datastore/tests/datastore.rs

Lines changed: 107 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -30,26 +30,53 @@ async fn setup_datastore() -> eyre::Result<TestHarness> {
3030
})
3131
}
3232

33-
#[tokio::test]
34-
async fn insert_and_get() -> eyre::Result<()> {
35-
let harness = setup_datastore().await?;
36-
let test_bundle = EthSendBundle {
37-
txs: vec![
38-
"0x02f8bf8221058304f8c782038c83d2a76b833d0900942e85c218afcdeb3d3b3f0f72941b4861f915bbcf80b85102000e0000000bb800001010c78c430a094eb7ae67d41a7cca25cdb9315e63baceb03bf4529e57a6b1b900010001f4000a101010110111101111011011faa7efc8e6aa13b029547eecbf5d370b4e1e52eec080a009fc02a6612877cec7e1223f0a14f9a9507b82ef03af41fcf14bf5018ccf2242a0338b46da29a62d28745c828077327588dc82c03a4b0210e3ee1fd62c608f8fcd".parse::<Bytes>()?,
39-
],
33+
fn get_test_tx() -> eyre::Result<Bytes> {
34+
"0x02f8bf8221058304f8c782038c83d2a76b833d0900942e85c218afcdeb3d3b3f0f72941b4861f915bbcf80b85102000e0000000bb800001010c78c430a094eb7ae67d41a7cca25cdb9315e63baceb03bf4529e57a6b1b900010001f4000a101010110111101111011011faa7efc8e6aa13b029547eecbf5d370b4e1e52eec080a009fc02a6612877cec7e1223f0a14f9a9507b82ef03af41fcf14bf5018ccf2242a0338b46da29a62d28745c828077327588dc82c03a4b0210e3ee1fd62c608f8fcd".parse::<Bytes>().map_err(|e| e.into())
35+
}
36+
37+
fn create_test_bundle_with_reverting_tx() -> eyre::Result<EthSendBundle> {
38+
Ok(EthSendBundle {
39+
txs: vec![get_test_tx()?],
4040
block_number: 12345,
4141
min_timestamp: Some(1640995200),
4242
max_timestamp: Some(1640995260),
4343
reverting_tx_hashes: vec![
44-
"0x3ea7e1482485387e61150ee8e5c8cad48a14591789ac02cc2504046d96d0a5f4".parse::<TxHash>()?,
44+
"0x3ea7e1482485387e61150ee8e5c8cad48a14591789ac02cc2504046d96d0a5f4"
45+
.parse::<TxHash>()?,
4546
],
4647
replacement_uuid: None,
4748
dropping_tx_hashes: vec![],
4849
refund_percent: None,
4950
refund_recipient: None,
5051
refund_tx_hashes: vec![],
5152
extra_fields: Default::default(),
52-
};
53+
})
54+
}
55+
56+
fn create_test_bundle(
57+
block_number: u64,
58+
min_timestamp: Option<u64>,
59+
max_timestamp: Option<u64>,
60+
) -> eyre::Result<EthSendBundle> {
61+
Ok(EthSendBundle {
62+
txs: vec![get_test_tx()?],
63+
block_number,
64+
min_timestamp,
65+
max_timestamp,
66+
reverting_tx_hashes: vec![],
67+
replacement_uuid: None,
68+
dropping_tx_hashes: vec![],
69+
refund_percent: None,
70+
refund_recipient: None,
71+
refund_tx_hashes: vec![],
72+
extra_fields: Default::default(),
73+
})
74+
}
75+
76+
#[tokio::test]
77+
async fn insert_and_get() -> eyre::Result<()> {
78+
let harness = setup_datastore().await?;
79+
let test_bundle = create_test_bundle_with_reverting_tx()?;
5380

5481
let insert_result = harness.data_store.insert_bundle(test_bundle.clone()).await;
5582
if let Err(ref err) = insert_result {
@@ -115,63 +142,10 @@ async fn insert_and_get() -> eyre::Result<()> {
115142
async fn select_bundles_comprehensive() -> eyre::Result<()> {
116143
let harness = setup_datastore().await?;
117144

118-
let test_tx = "0x02f8bf8221058304f8c782038c83d2a76b833d0900942e85c218afcdeb3d3b3f0f72941b4861f915bbcf80b85102000e0000000bb800001010c78c430a094eb7ae67d41a7cca25cdb9315e63baceb03bf4529e57a6b1b900010001f4000a101010110111101111011011faa7efc8e6aa13b029547eecbf5d370b4e1e52eec080a009fc02a6612877cec7e1223f0a14f9a9507b82ef03af41fcf14bf5018ccf2242a0338b46da29a62d28745c828077327588dc82c03a4b0210e3ee1fd62c608f8fcd".parse::<Bytes>()?;
119-
120-
let bundle1 = EthSendBundle {
121-
txs: vec![test_tx.clone()],
122-
block_number: 100,
123-
min_timestamp: Some(1000),
124-
max_timestamp: Some(2000),
125-
reverting_tx_hashes: vec![],
126-
replacement_uuid: None,
127-
dropping_tx_hashes: vec![],
128-
refund_percent: None,
129-
refund_recipient: None,
130-
refund_tx_hashes: vec![],
131-
extra_fields: Default::default(),
132-
};
133-
134-
let bundle2 = EthSendBundle {
135-
txs: vec![test_tx.clone()],
136-
block_number: 200,
137-
min_timestamp: Some(1500),
138-
max_timestamp: Some(2500),
139-
reverting_tx_hashes: vec![],
140-
replacement_uuid: None,
141-
dropping_tx_hashes: vec![],
142-
refund_percent: None,
143-
refund_recipient: None,
144-
refund_tx_hashes: vec![],
145-
extra_fields: Default::default(),
146-
};
147-
148-
let bundle3 = EthSendBundle {
149-
txs: vec![test_tx.clone()],
150-
block_number: 300,
151-
min_timestamp: None, // valid for all times
152-
max_timestamp: None,
153-
reverting_tx_hashes: vec![],
154-
replacement_uuid: None,
155-
dropping_tx_hashes: vec![],
156-
refund_percent: None,
157-
refund_recipient: None,
158-
refund_tx_hashes: vec![],
159-
extra_fields: Default::default(),
160-
};
161-
162-
let bundle4 = EthSendBundle {
163-
txs: vec![test_tx.clone()],
164-
block_number: 0, // valid for all blocks
165-
min_timestamp: Some(500),
166-
max_timestamp: Some(3000),
167-
reverting_tx_hashes: vec![],
168-
replacement_uuid: None,
169-
dropping_tx_hashes: vec![],
170-
refund_percent: None,
171-
refund_recipient: None,
172-
refund_tx_hashes: vec![],
173-
extra_fields: Default::default(),
174-
};
145+
let bundle1 = create_test_bundle(100, Some(1000), Some(2000))?;
146+
let bundle2 = create_test_bundle(200, Some(1500), Some(2500))?;
147+
let bundle3 = create_test_bundle(300, None, None)?; // valid for all times
148+
let bundle4 = create_test_bundle(0, Some(500), Some(3000))?; // valid for all blocks
175149

176150
harness
177151
.data_store
@@ -260,3 +234,70 @@ async fn select_bundles_comprehensive() -> eyre::Result<()> {
260234

261235
Ok(())
262236
}
237+
238+
#[tokio::test]
239+
async fn cancel_bundle_workflow() -> eyre::Result<()> {
240+
let harness = setup_datastore().await?;
241+
242+
let bundle1 = create_test_bundle(100, Some(1000), Some(2000))?;
243+
let bundle2 = create_test_bundle(200, Some(1500), Some(2500))?;
244+
245+
let bundle1_id = harness
246+
.data_store
247+
.insert_bundle(bundle1)
248+
.await
249+
.expect("Failed to insert bundle1");
250+
let bundle2_id = harness
251+
.data_store
252+
.insert_bundle(bundle2)
253+
.await
254+
.expect("Failed to insert bundle2");
255+
256+
let retrieved_bundle1 = harness
257+
.data_store
258+
.get_bundle(bundle1_id)
259+
.await
260+
.expect("Failed to get bundle1");
261+
assert!(
262+
retrieved_bundle1.is_some(),
263+
"Bundle1 should exist before cancellation"
264+
);
265+
266+
let retrieved_bundle2 = harness
267+
.data_store
268+
.get_bundle(bundle2_id)
269+
.await
270+
.expect("Failed to get bundle2");
271+
assert!(
272+
retrieved_bundle2.is_some(),
273+
"Bundle2 should exist before cancellation"
274+
);
275+
276+
harness
277+
.data_store
278+
.cancel_bundle(bundle1_id)
279+
.await
280+
.expect("Failed to cancel bundle1");
281+
282+
let cancelled_bundle1 = harness
283+
.data_store
284+
.get_bundle(bundle1_id)
285+
.await
286+
.expect("Failed to get bundle1 after cancellation");
287+
assert!(
288+
cancelled_bundle1.is_none(),
289+
"Bundle1 should not exist after cancellation"
290+
);
291+
292+
let still_exists_bundle2 = harness
293+
.data_store
294+
.get_bundle(bundle2_id)
295+
.await
296+
.expect("Failed to get bundle2 after bundle1 cancellation");
297+
assert!(
298+
still_exists_bundle2.is_some(),
299+
"Bundle2 should still exist after bundle1 cancellation"
300+
);
301+
302+
Ok(())
303+
}

0 commit comments

Comments
 (0)