removed unused params
This commit is contained in:
parent
ef3f4ed3c4
commit
bdca5ed1ff
|
|
@ -18,7 +18,8 @@ use anyhow::{anyhow, Result};
|
|||
use once_cell::sync::OnceCell;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use tokio_postgres::Client;
|
||||
use tokio_postgres::types::ToSql;
|
||||
use tokio_postgres::{Client, Row};
|
||||
|
||||
lazy_static! {
|
||||
pub static ref BASECOIN: String = {
|
||||
|
|
@ -215,7 +216,9 @@ pub use processing::{
|
|||
restore_processed_by_signatures, restore_selected_transactions_processed,
|
||||
spawn_processed_cleanup,
|
||||
};
|
||||
pub use schema::{clear_mempool, db_client, ensure_db_connection, init_db, setup_mempool};
|
||||
pub use schema::{
|
||||
clear_mempool, db_client, ensure_db_connection, init_db, pg_execute, pg_query, setup_mempool,
|
||||
};
|
||||
pub use selection::{
|
||||
apply_selected_transaction_math, clear_selected_transaction_sql, delete_selected_transactions,
|
||||
select_transactions_for_block, stream_selected_transaction_originals,
|
||||
|
|
@ -308,23 +311,19 @@ fn ids_for_table(batch: &SelectedMempoolBatch, table: &str) -> Vec<i64> {
|
|||
.collect()
|
||||
}
|
||||
|
||||
async fn mark_rows_by_ids(
|
||||
client: &Client,
|
||||
table: &str,
|
||||
ids: &[i64],
|
||||
block_number: i32,
|
||||
) -> Result<()> {
|
||||
async fn mark_rows_by_ids(table: &str, ids: &[i64], block_number: i32) -> Result<()> {
|
||||
if ids.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let statement =
|
||||
format!("UPDATE {table} SET processed=true, processed_block_number=$1 WHERE id = ANY($2)");
|
||||
client.execute(&statement, &[&block_number, &ids]).await?;
|
||||
let params: [&(dyn ToSql + Sync); 2] = [&block_number, &ids];
|
||||
pg_execute(&statement, ¶ms).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn unmark_rows_by_ids(client: &Client, table: &str, ids: &[i64]) -> Result<()> {
|
||||
async fn unmark_rows_by_ids(table: &str, ids: &[i64]) -> Result<()> {
|
||||
if ids.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
|
|
@ -332,22 +331,23 @@ async fn unmark_rows_by_ids(client: &Client, table: &str, ids: &[i64]) -> Result
|
|||
let statement = format!(
|
||||
"UPDATE {table} SET processed=false, processed_block_number=NULL WHERE id = ANY($1)"
|
||||
);
|
||||
client.execute(&statement, &[&ids]).await?;
|
||||
let params: [&(dyn ToSql + Sync); 1] = [&ids];
|
||||
pg_execute(&statement, ¶ms).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn delete_rows(client: &Client, table: &str, ids: &[i64]) -> Result<()> {
|
||||
async fn delete_rows(table: &str, ids: &[i64]) -> Result<()> {
|
||||
if ids.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let statement = format!("DELETE FROM {table} WHERE id = ANY($1)");
|
||||
client.execute(&statement, &[&ids]).await?;
|
||||
let params: [&(dyn ToSql + Sync); 1] = [&ids];
|
||||
pg_execute(&statement, ¶ms).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn unmark_by_signatures(
|
||||
client: &Client,
|
||||
table: &str,
|
||||
signature_column: &str,
|
||||
signatures: &[String],
|
||||
|
|
@ -355,33 +355,31 @@ async fn unmark_by_signatures(
|
|||
let statement = format!(
|
||||
"UPDATE {table} SET processed=false, processed_block_number=NULL WHERE {signature_column} = ANY($1) AND processed = true"
|
||||
);
|
||||
Ok(client.execute(&statement, &[&signatures]).await?)
|
||||
let params: [&(dyn ToSql + Sync); 1] = [&signatures];
|
||||
pg_execute(&statement, ¶ms).await
|
||||
}
|
||||
|
||||
async fn delete_processed_before_or_at(block_number: u32, limit: i64) -> Result<()> {
|
||||
// Periodic cleanup deletes processed mempool rows in bounded batches
|
||||
// so long-lived nodes do not accumulate infinite processed history.
|
||||
let client_handle = db_client().await?;
|
||||
let client = client_handle.as_ref();
|
||||
let bn = block_number as i32;
|
||||
|
||||
delete_processed_rows_limited(client, "transfer", bn, limit).await?;
|
||||
delete_processed_rows_limited(client, "token", bn, limit).await?;
|
||||
delete_processed_rows_limited(client, "issue_token", bn, limit).await?;
|
||||
delete_processed_rows_limited(client, "burn", bn, limit).await?;
|
||||
delete_processed_rows_limited(client, "nft", bn, limit).await?;
|
||||
delete_processed_rows_limited(client, "marketing", bn, limit).await?;
|
||||
delete_processed_rows_limited(client, "vanity_address", bn, limit).await?;
|
||||
delete_processed_rows_limited(client, "swap", bn, limit).await?;
|
||||
delete_processed_rows_limited(client, "loan_contract", bn, limit).await?;
|
||||
delete_processed_rows_limited(client, "loan_payment", bn, limit).await?;
|
||||
delete_processed_rows_limited(client, "collateral_claim", bn, limit).await?;
|
||||
delete_processed_rows_limited("transfer", bn, limit).await?;
|
||||
delete_processed_rows_limited("token", bn, limit).await?;
|
||||
delete_processed_rows_limited("issue_token", bn, limit).await?;
|
||||
delete_processed_rows_limited("burn", bn, limit).await?;
|
||||
delete_processed_rows_limited("nft", bn, limit).await?;
|
||||
delete_processed_rows_limited("marketing", bn, limit).await?;
|
||||
delete_processed_rows_limited("vanity_address", bn, limit).await?;
|
||||
delete_processed_rows_limited("swap", bn, limit).await?;
|
||||
delete_processed_rows_limited("loan_contract", bn, limit).await?;
|
||||
delete_processed_rows_limited("loan_payment", bn, limit).await?;
|
||||
delete_processed_rows_limited("collateral_claim", bn, limit).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn delete_processed_rows_limited(
|
||||
client: &Client,
|
||||
table: &str,
|
||||
block_number: i32,
|
||||
limit: i64,
|
||||
|
|
@ -401,5 +399,6 @@ async fn delete_processed_rows_limited(
|
|||
"#
|
||||
);
|
||||
|
||||
Ok(client.execute(&statement, &[&block_number, &limit]).await?)
|
||||
let params: [&(dyn ToSql + Sync); 2] = [&block_number, &limit];
|
||||
pg_execute(&statement, ¶ms).await
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,19 @@
|
|||
use super::*;
|
||||
use tokio_postgres::types::ToSql;
|
||||
|
||||
async fn pg_execute_block_signatures(
|
||||
statement: &str,
|
||||
block_number: i32,
|
||||
signatures: &[String],
|
||||
) -> Result<u64> {
|
||||
let params: [&(dyn ToSql + Sync); 2] = [&block_number, &signatures];
|
||||
pg_execute(statement, ¶ms).await
|
||||
}
|
||||
|
||||
async fn pg_execute_signatures(statement: &str, signatures: &[String]) -> Result<u64> {
|
||||
let params: [&(dyn ToSql + Sync); 1] = [&signatures];
|
||||
pg_execute(statement, ¶ms).await
|
||||
}
|
||||
|
||||
pub async fn mark_selected_transactions_processed(
|
||||
batch: &SelectedMempoolBatch,
|
||||
|
|
@ -6,48 +21,26 @@ pub async fn mark_selected_transactions_processed(
|
|||
) -> Result<()> {
|
||||
// Mark each selected mempool row as processed under the saved block
|
||||
// number so it can be cleaned up or restored later if needed.
|
||||
let client_handle = db_client().await?;
|
||||
let client = client_handle.as_ref();
|
||||
let bn = block_number as i32;
|
||||
|
||||
// Selected batches are grouped by table, then marked with one UPDATE per
|
||||
// table instead of touching rows one at a time.
|
||||
mark_rows_by_ids(client, "transfer", &ids_for_table(batch, "transfer"), bn).await?;
|
||||
mark_rows_by_ids(client, "token", &ids_for_table(batch, "token"), bn).await?;
|
||||
mark_rows_by_ids("transfer", &ids_for_table(batch, "transfer"), bn).await?;
|
||||
mark_rows_by_ids("token", &ids_for_table(batch, "token"), bn).await?;
|
||||
mark_rows_by_ids("issue_token", &ids_for_table(batch, "issue_token"), bn).await?;
|
||||
mark_rows_by_ids("burn", &ids_for_table(batch, "burn"), bn).await?;
|
||||
mark_rows_by_ids("nft", &ids_for_table(batch, "nft"), bn).await?;
|
||||
mark_rows_by_ids("marketing", &ids_for_table(batch, "marketing"), bn).await?;
|
||||
mark_rows_by_ids(
|
||||
&client,
|
||||
"issue_token",
|
||||
&ids_for_table(batch, "issue_token"),
|
||||
bn,
|
||||
)
|
||||
.await?;
|
||||
mark_rows_by_ids(client, "burn", &ids_for_table(batch, "burn"), bn).await?;
|
||||
mark_rows_by_ids(client, "nft", &ids_for_table(batch, "nft"), bn).await?;
|
||||
mark_rows_by_ids(client, "marketing", &ids_for_table(batch, "marketing"), bn).await?;
|
||||
mark_rows_by_ids(
|
||||
&client,
|
||||
"vanity_address",
|
||||
&ids_for_table(batch, "vanity_address"),
|
||||
bn,
|
||||
)
|
||||
.await?;
|
||||
mark_rows_by_ids(client, "swap", &ids_for_table(batch, "swap"), bn).await?;
|
||||
mark_rows_by_ids("swap", &ids_for_table(batch, "swap"), bn).await?;
|
||||
mark_rows_by_ids("loan_contract", &ids_for_table(batch, "loan_contract"), bn).await?;
|
||||
mark_rows_by_ids("loan_payment", &ids_for_table(batch, "loan_payment"), bn).await?;
|
||||
mark_rows_by_ids(
|
||||
&client,
|
||||
"loan_contract",
|
||||
&ids_for_table(batch, "loan_contract"),
|
||||
bn,
|
||||
)
|
||||
.await?;
|
||||
mark_rows_by_ids(
|
||||
&client,
|
||||
"loan_payment",
|
||||
&ids_for_table(batch, "loan_payment"),
|
||||
bn,
|
||||
)
|
||||
.await?;
|
||||
mark_rows_by_ids(
|
||||
&client,
|
||||
"collateral_claim",
|
||||
&ids_for_table(batch, "collateral_claim"),
|
||||
bn,
|
||||
|
|
@ -60,36 +53,29 @@ pub async fn mark_selected_transactions_processed(
|
|||
pub async fn restore_selected_transactions_processed(batch: &SelectedMempoolBatch) -> Result<()> {
|
||||
// If block commit fails after selected rows were marked processed,
|
||||
// restore them before the chain height can acknowledge the block.
|
||||
let client_handle = db_client().await?;
|
||||
let client = client_handle.as_ref();
|
||||
|
||||
unmark_rows_by_ids(client, "transfer", &ids_for_table(batch, "transfer")).await?;
|
||||
unmark_rows_by_ids(client, "token", &ids_for_table(batch, "token")).await?;
|
||||
unmark_rows_by_ids(client, "issue_token", &ids_for_table(batch, "issue_token")).await?;
|
||||
unmark_rows_by_ids(client, "burn", &ids_for_table(batch, "burn")).await?;
|
||||
unmark_rows_by_ids(client, "nft", &ids_for_table(batch, "nft")).await?;
|
||||
unmark_rows_by_ids(client, "marketing", &ids_for_table(batch, "marketing")).await?;
|
||||
unmark_rows_by_ids("transfer", &ids_for_table(batch, "transfer")).await?;
|
||||
unmark_rows_by_ids("token", &ids_for_table(batch, "token")).await?;
|
||||
unmark_rows_by_ids("issue_token", &ids_for_table(batch, "issue_token")).await?;
|
||||
unmark_rows_by_ids("burn", &ids_for_table(batch, "burn")).await?;
|
||||
unmark_rows_by_ids("nft", &ids_for_table(batch, "nft")).await?;
|
||||
unmark_rows_by_ids("marketing", &ids_for_table(batch, "marketing")).await?;
|
||||
unmark_rows_by_ids(
|
||||
&client,
|
||||
"vanity_address",
|
||||
&ids_for_table(batch, "vanity_address"),
|
||||
)
|
||||
.await?;
|
||||
unmark_rows_by_ids(client, "swap", &ids_for_table(batch, "swap")).await?;
|
||||
unmark_rows_by_ids("swap", &ids_for_table(batch, "swap")).await?;
|
||||
unmark_rows_by_ids(
|
||||
&client,
|
||||
"loan_contract",
|
||||
&ids_for_table(batch, "loan_contract"),
|
||||
)
|
||||
.await?;
|
||||
unmark_rows_by_ids(
|
||||
&client,
|
||||
"loan_payment",
|
||||
&ids_for_table(batch, "loan_payment"),
|
||||
)
|
||||
.await?;
|
||||
unmark_rows_by_ids(
|
||||
&client,
|
||||
"collateral_claim",
|
||||
&ids_for_table(batch, "collateral_claim"),
|
||||
)
|
||||
|
|
@ -105,25 +91,23 @@ pub async fn restore_processed_by_signatures(signatures: &[String]) -> Result<bo
|
|||
return Ok(false);
|
||||
}
|
||||
|
||||
let client_handle = db_client().await?;
|
||||
let client = client_handle.as_ref();
|
||||
let mut restored = 0_u64;
|
||||
|
||||
// Each table keeps its own signature columns, so rollback unmarks every
|
||||
// column that could contain one of the rolled-back signatures.
|
||||
restored += unmark_by_signatures(client, "transfer", "signature", signatures).await?;
|
||||
restored += unmark_by_signatures(client, "token", "signature", signatures).await?;
|
||||
restored += unmark_by_signatures(client, "issue_token", "signature", signatures).await?;
|
||||
restored += unmark_by_signatures(client, "burn", "signature", signatures).await?;
|
||||
restored += unmark_by_signatures(client, "nft", "signature", signatures).await?;
|
||||
restored += unmark_by_signatures(client, "marketing", "signature", signatures).await?;
|
||||
restored += unmark_by_signatures(client, "vanity_address", "signature", signatures).await?;
|
||||
restored += unmark_by_signatures(client, "swap", "signature1", signatures).await?;
|
||||
restored += unmark_by_signatures(client, "swap", "signature2", signatures).await?;
|
||||
restored += unmark_by_signatures(client, "loan_contract", "signature1", signatures).await?;
|
||||
restored += unmark_by_signatures(client, "loan_contract", "signature2", signatures).await?;
|
||||
restored += unmark_by_signatures(client, "loan_payment", "signature", signatures).await?;
|
||||
restored += unmark_by_signatures(client, "collateral_claim", "signature", signatures).await?;
|
||||
restored += unmark_by_signatures("transfer", "signature", signatures).await?;
|
||||
restored += unmark_by_signatures("token", "signature", signatures).await?;
|
||||
restored += unmark_by_signatures("issue_token", "signature", signatures).await?;
|
||||
restored += unmark_by_signatures("burn", "signature", signatures).await?;
|
||||
restored += unmark_by_signatures("nft", "signature", signatures).await?;
|
||||
restored += unmark_by_signatures("marketing", "signature", signatures).await?;
|
||||
restored += unmark_by_signatures("vanity_address", "signature", signatures).await?;
|
||||
restored += unmark_by_signatures("swap", "signature1", signatures).await?;
|
||||
restored += unmark_by_signatures("swap", "signature2", signatures).await?;
|
||||
restored += unmark_by_signatures("loan_contract", "signature1", signatures).await?;
|
||||
restored += unmark_by_signatures("loan_contract", "signature2", signatures).await?;
|
||||
restored += unmark_by_signatures("loan_payment", "signature", signatures).await?;
|
||||
restored += unmark_by_signatures("collateral_claim", "signature", signatures).await?;
|
||||
|
||||
Ok(restored > 0)
|
||||
}
|
||||
|
|
@ -167,88 +151,86 @@ pub async fn mark_processed_by_signatures(signatures: &[String], block_number: u
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
let client_handle = db_client().await?;
|
||||
let client = client_handle.as_ref();
|
||||
let bn = block_number as i32;
|
||||
|
||||
// Remote/synced blocks do not know local row IDs, so they mark by
|
||||
// transaction signatures instead.
|
||||
client
|
||||
.execute(
|
||||
pg_execute_block_signatures(
|
||||
"UPDATE transfer SET processed=true, processed_block_number=$1 WHERE signature = ANY($2)",
|
||||
&[&bn, &signatures],
|
||||
bn,
|
||||
signatures,
|
||||
)
|
||||
.await?;
|
||||
client
|
||||
.execute(
|
||||
pg_execute_block_signatures(
|
||||
"UPDATE token SET processed=true, processed_block_number=$1 WHERE signature = ANY($2)",
|
||||
&[&bn, &signatures],
|
||||
bn,
|
||||
signatures,
|
||||
)
|
||||
.await?;
|
||||
client
|
||||
.execute(
|
||||
pg_execute_block_signatures(
|
||||
"UPDATE issue_token SET processed=true, processed_block_number=$1 WHERE signature = ANY($2)",
|
||||
&[&bn, &signatures],
|
||||
bn,
|
||||
signatures,
|
||||
)
|
||||
.await?;
|
||||
client
|
||||
.execute(
|
||||
pg_execute_block_signatures(
|
||||
"UPDATE burn SET processed=true, processed_block_number=$1 WHERE signature = ANY($2)",
|
||||
&[&bn, &signatures],
|
||||
bn,
|
||||
signatures,
|
||||
)
|
||||
.await?;
|
||||
client
|
||||
.execute(
|
||||
pg_execute_block_signatures(
|
||||
"UPDATE nft SET processed=true, processed_block_number=$1 WHERE signature = ANY($2)",
|
||||
&[&bn, &signatures],
|
||||
bn,
|
||||
signatures,
|
||||
)
|
||||
.await?;
|
||||
client
|
||||
.execute(
|
||||
pg_execute_block_signatures(
|
||||
"UPDATE marketing SET processed=true, processed_block_number=$1 WHERE signature = ANY($2)",
|
||||
&[&bn, &signatures],
|
||||
bn,
|
||||
signatures,
|
||||
)
|
||||
.await?;
|
||||
client
|
||||
.execute(
|
||||
pg_execute_block_signatures(
|
||||
"UPDATE vanity_address SET processed=true, processed_block_number=$1 WHERE signature = ANY($2)",
|
||||
&[&bn, &signatures],
|
||||
bn,
|
||||
signatures,
|
||||
)
|
||||
.await?;
|
||||
client
|
||||
.execute(
|
||||
pg_execute_block_signatures(
|
||||
"UPDATE swap SET processed=true, processed_block_number=$1 WHERE signature1 = ANY($2)",
|
||||
&[&bn, &signatures],
|
||||
bn,
|
||||
signatures,
|
||||
)
|
||||
.await?;
|
||||
client
|
||||
.execute(
|
||||
pg_execute_block_signatures(
|
||||
"UPDATE swap SET processed=true, processed_block_number=$1 WHERE signature2 = ANY($2)",
|
||||
&[&bn, &signatures],
|
||||
bn,
|
||||
signatures,
|
||||
)
|
||||
.await?;
|
||||
client
|
||||
.execute(
|
||||
pg_execute_block_signatures(
|
||||
"UPDATE loan_contract SET processed=true, processed_block_number=$1 WHERE signature1 = ANY($2)",
|
||||
&[&bn, &signatures],
|
||||
bn,
|
||||
signatures,
|
||||
)
|
||||
.await?;
|
||||
client
|
||||
.execute(
|
||||
pg_execute_block_signatures(
|
||||
"UPDATE loan_contract SET processed=true, processed_block_number=$1 WHERE signature2 = ANY($2)",
|
||||
&[&bn, &signatures],
|
||||
bn,
|
||||
signatures,
|
||||
)
|
||||
.await?;
|
||||
client
|
||||
.execute(
|
||||
pg_execute_block_signatures(
|
||||
"UPDATE loan_payment SET processed=true, processed_block_number=$1 WHERE signature = ANY($2)",
|
||||
&[&bn, &signatures],
|
||||
bn,
|
||||
signatures,
|
||||
)
|
||||
.await?;
|
||||
client
|
||||
.execute(
|
||||
pg_execute_block_signatures(
|
||||
"UPDATE collateral_claim SET processed=true, processed_block_number=$1 WHERE signature = ANY($2)",
|
||||
&[&bn, &signatures],
|
||||
bn,
|
||||
signatures,
|
||||
)
|
||||
.await?;
|
||||
|
||||
|
|
@ -262,69 +244,45 @@ pub async fn delete_by_signatures(signatures: &[String]) -> Result<()> {
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
let client_handle = db_client().await?;
|
||||
let client = client_handle.as_ref();
|
||||
|
||||
// Failed validation removes every matching pending row no matter which
|
||||
// transaction table currently owns the signature.
|
||||
client
|
||||
.execute(
|
||||
"DELETE FROM transfer WHERE signature = ANY($1)",
|
||||
&[&signatures],
|
||||
)
|
||||
.await?;
|
||||
client
|
||||
.execute(
|
||||
"DELETE FROM token WHERE signature = ANY($1)",
|
||||
&[&signatures],
|
||||
)
|
||||
.await?;
|
||||
client
|
||||
.execute(
|
||||
pg_execute_signatures("DELETE FROM transfer WHERE signature = ANY($1)", signatures).await?;
|
||||
pg_execute_signatures("DELETE FROM token WHERE signature = ANY($1)", signatures).await?;
|
||||
pg_execute_signatures(
|
||||
"DELETE FROM issue_token WHERE signature = ANY($1)",
|
||||
&[&signatures],
|
||||
signatures,
|
||||
)
|
||||
.await?;
|
||||
client
|
||||
.execute("DELETE FROM burn WHERE signature = ANY($1)", &[&signatures])
|
||||
.await?;
|
||||
client
|
||||
.execute("DELETE FROM nft WHERE signature = ANY($1)", &[&signatures])
|
||||
.await?;
|
||||
client
|
||||
.execute(
|
||||
pg_execute_signatures("DELETE FROM burn WHERE signature = ANY($1)", signatures).await?;
|
||||
pg_execute_signatures("DELETE FROM nft WHERE signature = ANY($1)", signatures).await?;
|
||||
pg_execute_signatures(
|
||||
"DELETE FROM marketing WHERE signature = ANY($1)",
|
||||
&[&signatures],
|
||||
signatures,
|
||||
)
|
||||
.await?;
|
||||
client
|
||||
.execute(
|
||||
pg_execute_signatures(
|
||||
"DELETE FROM vanity_address WHERE signature = ANY($1)",
|
||||
&[&signatures],
|
||||
signatures,
|
||||
)
|
||||
.await?;
|
||||
client
|
||||
.execute(
|
||||
pg_execute_signatures(
|
||||
"DELETE FROM swap WHERE signature1 = ANY($1) OR signature2 = ANY($1)",
|
||||
&[&signatures],
|
||||
signatures,
|
||||
)
|
||||
.await?;
|
||||
client
|
||||
.execute(
|
||||
pg_execute_signatures(
|
||||
"DELETE FROM loan_contract WHERE signature1 = ANY($1) OR signature2 = ANY($1)",
|
||||
&[&signatures],
|
||||
signatures,
|
||||
)
|
||||
.await?;
|
||||
client
|
||||
.execute(
|
||||
pg_execute_signatures(
|
||||
"DELETE FROM loan_payment WHERE signature = ANY($1)",
|
||||
&[&signatures],
|
||||
signatures,
|
||||
)
|
||||
.await?;
|
||||
client
|
||||
.execute(
|
||||
pg_execute_signatures(
|
||||
"DELETE FROM collateral_claim WHERE signature = ANY($1)",
|
||||
&[&signatures],
|
||||
signatures,
|
||||
)
|
||||
.await?;
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,17 @@ pub async fn db_client() -> Result<Arc<Client>> {
|
|||
Ok(slot.read().await.clone())
|
||||
}
|
||||
|
||||
fn is_closed_postgres_connection(err: &tokio_postgres::Error) -> bool {
|
||||
if err.is_closed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
let message = err.to_string().to_ascii_lowercase();
|
||||
message.contains("connection closed")
|
||||
|| message.contains("connection reset")
|
||||
|| message.contains("broken pipe")
|
||||
}
|
||||
|
||||
pub async fn reconnect_db() -> Result<()> {
|
||||
let client = connect_client().await?;
|
||||
|
||||
|
|
@ -55,6 +66,32 @@ pub async fn ensure_db_connection() -> Result<()> {
|
|||
reconnect_db().await
|
||||
}
|
||||
|
||||
pub async fn pg_execute(statement: &str, params: &[&(dyn ToSql + Sync)]) -> Result<u64> {
|
||||
let client_handle = db_client().await?;
|
||||
match client_handle.execute(statement, params).await {
|
||||
Ok(count) => Ok(count),
|
||||
Err(err) if is_closed_postgres_connection(&err) => {
|
||||
reconnect_db().await?;
|
||||
let client_handle = db_client().await?;
|
||||
Ok(client_handle.execute(statement, params).await?)
|
||||
}
|
||||
Err(err) => Err(err.into()),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn pg_query(statement: &str, params: &[&(dyn ToSql + Sync)]) -> Result<Vec<Row>> {
|
||||
let client_handle = db_client().await?;
|
||||
match client_handle.query(statement, params).await {
|
||||
Ok(rows) => Ok(rows),
|
||||
Err(err) if is_closed_postgres_connection(&err) => {
|
||||
reconnect_db().await?;
|
||||
let client_handle = db_client().await?;
|
||||
Ok(client_handle.query(statement, params).await?)
|
||||
}
|
||||
Err(err) => Err(err.into()),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn init_db() -> Result<()> {
|
||||
// Initialize the shared Postgres client used by the mempool tables.
|
||||
if DB.get().is_some() {
|
||||
|
|
|
|||
|
|
@ -18,10 +18,8 @@ fn index_selected_wallet_transaction(
|
|||
pub async fn select_transactions_for_block(limit: i64) -> Result<SelectedMempoolBatch> {
|
||||
// Pull the highest-priority unprocessed rows across all mempool
|
||||
// tables, keeping the original bytes for block-file streaming later.
|
||||
let client_handle = db_client().await?;
|
||||
let client = client_handle.as_ref();
|
||||
let rows = client
|
||||
.query(
|
||||
let rows =
|
||||
pg_query(
|
||||
r#"
|
||||
SELECT * FROM (
|
||||
SELECT
|
||||
|
|
@ -1016,9 +1014,6 @@ pub async fn stream_selected_transaction_originals(
|
|||
}
|
||||
|
||||
pub async fn delete_selected_transactions(batch: &SelectedMempoolBatch) -> Result<()> {
|
||||
let client_handle = db_client().await?;
|
||||
let client = client_handle.as_ref();
|
||||
|
||||
// Each transaction kind still lives in a separate SQL table, so deletion
|
||||
// groups the selected IDs by table after the block has been written.
|
||||
let transfer_ids = ids_for_table(batch, "transfer");
|
||||
|
|
@ -1033,17 +1028,17 @@ pub async fn delete_selected_transactions(batch: &SelectedMempoolBatch) -> Resul
|
|||
let borrower_ids = ids_for_table(batch, "loan_payment");
|
||||
let collateral_ids = ids_for_table(batch, "collateral_claim");
|
||||
|
||||
delete_rows(client, "transfer", &transfer_ids).await?;
|
||||
delete_rows(client, "token", &token_ids).await?;
|
||||
delete_rows(client, "issue_token", &issue_token_ids).await?;
|
||||
delete_rows(client, "burn", &burn_ids).await?;
|
||||
delete_rows(client, "nft", &nft_ids).await?;
|
||||
delete_rows(client, "marketing", &marketing_ids).await?;
|
||||
delete_rows(client, "vanity_address", &vanity_ids).await?;
|
||||
delete_rows(client, "swap", &swap_ids).await?;
|
||||
delete_rows(client, "loan_contract", &lender_ids).await?;
|
||||
delete_rows(client, "loan_payment", &borrower_ids).await?;
|
||||
delete_rows(client, "collateral_claim", &collateral_ids).await?;
|
||||
delete_rows("transfer", &transfer_ids).await?;
|
||||
delete_rows("token", &token_ids).await?;
|
||||
delete_rows("issue_token", &issue_token_ids).await?;
|
||||
delete_rows("burn", &burn_ids).await?;
|
||||
delete_rows("nft", &nft_ids).await?;
|
||||
delete_rows("marketing", &marketing_ids).await?;
|
||||
delete_rows("vanity_address", &vanity_ids).await?;
|
||||
delete_rows("swap", &swap_ids).await?;
|
||||
delete_rows("loan_contract", &lender_ids).await?;
|
||||
delete_rows("loan_payment", &borrower_ids).await?;
|
||||
delete_rows("collateral_claim", &collateral_ids).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -256,7 +256,7 @@ pub async fn torrent_submission(
|
|||
}
|
||||
};
|
||||
let torrent_hash = skein_128_hash_bytes(&torrent_bytes);
|
||||
if has_recent_torrent(&torrent_hash, height).await {
|
||||
if has_recent_torrent(&torrent_hash).await {
|
||||
// Recent-torrent cache prevents rebroadcast loops from repeatedly
|
||||
// staging and verifying the same metadata.
|
||||
let msg = "Torrent already seen.".to_string().as_bytes().to_vec();
|
||||
|
|
|
|||
|
|
@ -233,7 +233,7 @@ pub fn handle_control_command() -> Result<bool, Box<dyn std::error::Error>> {
|
|||
}
|
||||
|
||||
#[cfg(not(unix))]
|
||||
pub fn install_shutdown_cleanup(_db: crate::sled::Db) {}
|
||||
pub fn install_shutdown_cleanup() {}
|
||||
|
||||
#[cfg(not(unix))]
|
||||
pub fn remove_registered_pid_file() {}
|
||||
|
|
|
|||
|
|
@ -119,7 +119,10 @@ pub async fn run_unlocked_node(wallet: Arc<Wallet>, install_shutdown: bool) -> R
|
|||
|
||||
if install_shutdown {
|
||||
// Console/daemon mode owns signal cleanup; Windows service shutdown is handled separately.
|
||||
#[cfg(unix)]
|
||||
install_shutdown_cleanup(db.clone());
|
||||
#[cfg(not(unix))]
|
||||
install_shutdown_cleanup();
|
||||
}
|
||||
|
||||
if let Err(e) = clear_ip_scores(&db) {
|
||||
|
|
|
|||
|
|
@ -419,7 +419,9 @@ fn stop_service_if_running(
|
|||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn contractless_service_main(_arguments: Vec<OsString>) {
|
||||
fn contractless_service_main(arguments: Vec<OsString>) {
|
||||
drop(arguments);
|
||||
|
||||
// SCM enters here instead of the normal console main path.
|
||||
if let Err(err) = run_service() {
|
||||
eprintln!("Windows service error: {err}");
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ lazy_static! {
|
|||
Mutex::new(HashMap::new());
|
||||
}
|
||||
|
||||
pub async fn has_recent_torrent(hash: &str, _block_height: u32) -> bool {
|
||||
pub async fn has_recent_torrent(hash: &str) -> bool {
|
||||
// The hash alone identifies duplicate torrent bytes in the recent in-memory cache.
|
||||
let map = RECENT_TORRENTS.lock().await;
|
||||
map.contains_key(hash)
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ async fn verify_transaction(
|
|||
balance_tracker: Arc<Mutex<BlockBalanceTracker>>,
|
||||
) -> Result<String, String> {
|
||||
if let Transaction::Genesis(genesis_tx) = &transaction {
|
||||
match genesis_tx.verify(miner, db).await {
|
||||
match genesis_tx.verify().await {
|
||||
Ok(value) => {
|
||||
reserve_verified_transaction(db, &transaction, balance_tracker).await?;
|
||||
return Ok(value);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
use crate::blocks::genesis::GenesisTransaction;
|
||||
use crate::common::check_genesis::genesis_checkup;
|
||||
use crate::sled::Db;
|
||||
|
||||
impl GenesisTransaction {
|
||||
pub async fn verify(&self, _miner: String, db: &Db) -> Result<String, String> {
|
||||
pub async fn verify(&self) -> Result<String, String> {
|
||||
// Genesis is pinned to a fixed message and only valid before the
|
||||
// chain already has a committed genesis block.
|
||||
let msg = &self.unsigned.message;
|
||||
|
|
@ -11,7 +10,6 @@ impl GenesisTransaction {
|
|||
return Err("Not a valid Genesis block").map_err(|s| s.to_string())?;
|
||||
}
|
||||
|
||||
let _ = db;
|
||||
if genesis_checkup().await {
|
||||
return Err("Genesis block already exists.".to_string());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use crate::FnDsaKeyPair;
|
|||
use crate::{decode, encode};
|
||||
|
||||
impl Wallet {
|
||||
pub fn generate_keypair(_network_byte: u8) -> (Vec<u8>, String) {
|
||||
pub fn generate_keypair() -> (Vec<u8>, String) {
|
||||
loop {
|
||||
// Generate a new FN-DSA key pair using the wallet security parameter.
|
||||
let keypair = FnDsaKeyPair::generate(Self::FN_DSA_LOGN)
|
||||
|
|
@ -25,9 +25,6 @@ impl Wallet {
|
|||
}
|
||||
|
||||
pub fn regenerate_public_key(private_key_hex: &str) -> Result<Vec<u8>, String> {
|
||||
// Regenerated public keys always use the network selected at compile time.
|
||||
let network_byte = Self::current_network_byte();
|
||||
|
||||
// Decode the stored private key from its wallet hex representation.
|
||||
let private_key_bytes = match decode(private_key_hex) {
|
||||
Ok(bytes) => bytes,
|
||||
|
|
@ -47,7 +44,6 @@ impl Wallet {
|
|||
let keypair = FnDsaKeyPair::from_private_key(&private_key_bytes)
|
||||
.map_err(|e| format!("Failed to decode the provided FN-DSA private key: {e}"))?;
|
||||
|
||||
let _ = network_byte;
|
||||
let public_key_bytes = keypair.public_key().to_vec();
|
||||
if !Self::has_valid_public_key_bytes(&public_key_bytes) {
|
||||
return Err("FN-DSA public key does not satisfy this network's wallet key rule."
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@ use crate::Path;
|
|||
use crate::{create_img, encrypts};
|
||||
|
||||
impl Wallet {
|
||||
pub fn create_wallet(&self, network_byte: u8) -> Wallet {
|
||||
pub fn create_wallet(&self) -> Wallet {
|
||||
// Generate a fresh FN-DSA key pair for the selected network.
|
||||
let (public_key, private_key) = Self::generate_keypair(network_byte);
|
||||
let (public_key, private_key) = Self::generate_keypair();
|
||||
|
||||
// Hash the public key body into the fixed 22-byte short-address format.
|
||||
let short_address_bytes = Self::public_key_bytes_to_short_address_bytes(&public_key)
|
||||
|
|
@ -77,7 +77,7 @@ impl Wallet {
|
|||
};
|
||||
|
||||
// Generate the wallet for the active network.
|
||||
let wallet = Wallet::create_wallet(&wallet, Self::current_network_byte());
|
||||
let wallet = Wallet::create_wallet(&wallet);
|
||||
|
||||
// Save the generated wallet file before loading and decrypting it through the normal path.
|
||||
wallet.saved.save_the_wallet(wallet_path).await;
|
||||
|
|
|
|||
Loading…
Reference in New Issue