quantum_migration.rs (2681B)
1 use axum::{Form, Json, extract::State}; 2 use serde::Deserialize; 3 use serde_json::{Value, json}; 4 5 use super::HttpState; 6 use crate::domain::Amount; 7 8 #[derive(Deserialize)] 9 pub(super) struct PreviewForm { 10 fee_per_byte: Amount, 11 } 12 13 #[derive(Deserialize)] 14 pub(super) struct SubmitForm { 15 fee_per_byte: Amount, 16 max_fee: Amount, 17 transaction_id: String, 18 } 19 20 pub(super) async fn preview( 21 State(state): State<HttpState>, 22 Form(form): Form<PreviewForm>, 23 ) -> Json<Value> { 24 let node = state.node.lock().await; 25 match node.preview_quantum_migration(form.fee_per_byte) { 26 Ok(preview) => Json(json!({ "ok": true, "preview": preview })), 27 Err(error) => Json(json!({ "ok": false, "error": error.to_string() })), 28 } 29 } 30 31 pub(super) async fn submit( 32 State(state): State<HttpState>, 33 Form(form): Form<SubmitForm>, 34 ) -> Json<Value> { 35 let (result, outbox, pending_envelope) = { 36 let mut node = state.node.lock().await; 37 let result = 38 node.submit_quantum_migration(form.fee_per_byte, form.max_fee, &form.transaction_id); 39 let pending_envelope = result.as_ref().ok().and_then(|preview| { 40 node.pending_transaction_v2_envelopes() 41 .ok()? 42 .into_iter() 43 .find(|(transaction_id, _)| transaction_id == &preview.transaction_id) 44 }); 45 (result, node.drain_outbox(), pending_envelope) 46 }; 47 match result { 48 Ok(preview) => { 49 let persistence_error = if let Some((transaction_id, envelope)) = pending_envelope { 50 let store = state.chain_store.clone(); 51 tokio::task::spawn_blocking(move || { 52 store.save_pending_transaction_v2(&transaction_id, &envelope) 53 }) 54 .await 55 .map_err(|error| anyhow::anyhow!("migration persistence worker failed: {error}")) 56 .and_then(|result| result) 57 .err() 58 .map(|error| error.to_string()) 59 } else { 60 Some( 61 "queued migration is missing from the local transaction-v2 mempool".to_string(), 62 ) 63 }; 64 let broadcast = state.gossip.broadcast(outbox).await; 65 Json(json!({ 66 "ok": true, 67 "transaction_id": preview.transaction_id, 68 "remaining_legacy_utxos": preview.remaining_legacy_utxos, 69 "persistence_error": persistence_error, 70 "broadcast_error": broadcast.err().map(|error| error.to_string()), 71 })) 72 } 73 Err(error) => Json(json!({ "ok": false, "error": error.to_string() })), 74 } 75 }