diff --git a/src/db/cauldron/pool.rs b/src/db/cauldron/pool.rs index 9a5276d..006ae37 100644 --- a/src/db/cauldron/pool.rs +++ b/src/db/cauldron/pool.rs @@ -29,7 +29,9 @@ pub fn create_table(conn: &Connection) { utxo TEXT PRIMARY KEY REFERENCES utxo_funding(new_utxo_hash) ON DELETE CASCADE, pool TEXT REFERENCES pool(creation_utxo) ON DELETE CASCADE, txid TEXT REFERENCES tx(txid) ON DELETE CASCADE, - tx_pos TEXT NOT NULL + tx_pos TEXT NOT NULL, + mtp_timestamp BIGINT, + first_seen_timestamp BIGINT )", [], ) @@ -83,10 +85,18 @@ fn insert_pool_history_entry( conn: &Connection, pool: &OutPointHash, cauldron: &ParsedContract, + mtp_timestamp: Option, + first_seen_timestamp: Option, ) -> Result<()> { - // or replace, as it could have been added in mempool, then block conn.execute( - "INSERT OR REPLACE INTO pool_history_entry (utxo, pool, txid, tx_pos) VALUES (?, ?, ?, ?)", + "INSERT INTO pool_history_entry (utxo, pool, txid, tx_pos, mtp_timestamp, first_seen_timestamp) + VALUES (?, ?, ?, ?, ?, ?) + ON CONFLICT(utxo) DO UPDATE SET + pool = excluded.pool, + txid = excluded.txid, + tx_pos = excluded.tx_pos, + mtp_timestamp = COALESCE(excluded.mtp_timestamp, pool_history_entry.mtp_timestamp), + first_seen_timestamp = COALESCE(excluded.first_seen_timestamp, pool_history_entry.first_seen_timestamp)", params![ cauldron .new_utxo_hash @@ -100,13 +110,20 @@ fn insert_pool_history_entry( cauldron .new_utxo_n .expect("utxo index of new pool history entry"), + mtp_timestamp, + first_seen_timestamp, ], ) .context("inserting pool_history_entry")?; Ok(()) } -pub fn update_pool_history(conn: &Connection, cauldrons: Vec) -> Result<()> { +pub fn update_pool_history( + conn: &Connection, + cauldrons: Vec, + mtp_timestamp: Option, + first_seen_timestamp: Option, +) -> Result<()> { if cauldrons.is_empty() { return Ok(()); } @@ -158,10 +175,22 @@ pub fn update_pool_history(conn: &Connection, cauldrons: Vec) -> .to_hex() ); insert_new_pool(conn, ¤t)?; - insert_pool_history_entry(conn, &pool_utxo, ¤t)?; + insert_pool_history_entry( + conn, + &pool_utxo, + ¤t, + mtp_timestamp, + first_seen_timestamp, + )?; } else { debug!("New entry for pool {}", pool_utxo.to_hex()); - insert_pool_history_entry(conn, &pool_utxo, ¤t)?; + insert_pool_history_entry( + conn, + &pool_utxo, + ¤t, + mtp_timestamp, + first_seen_timestamp, + )?; } } diff --git a/src/db/cauldron/tx.rs b/src/db/cauldron/tx.rs index a79b52a..3816ab0 100644 --- a/src/db/cauldron/tx.rs +++ b/src/db/cauldron/tx.rs @@ -2,7 +2,6 @@ // // This software is licensed under the GNU Affero General Public License (AGPL), version 3.0 or later. // A copy of the license can be found in the LICENSE file or at https://www.gnu.org/licenses/agpl-3.0.html -use std::time::{SystemTime, UNIX_EPOCH}; use anyhow::Result; use bitcoin_hashes::hex::{FromHex, ToHex}; @@ -35,18 +34,17 @@ pub fn insert_block_tx( Ok(()) } -pub fn insert_mempool_tx(conn: &rusqlite::Connection, txid: &Txid) -> Result<()> { +pub fn insert_mempool_tx( + conn: &rusqlite::Connection, + txid: &Txid, + first_seen_timestamp: u64, +) -> Result<()> { let sql = "INSERT INTO tx (txid, first_seen_timestamp) VALUES (?1, ?2) ON CONFLICT(txid) DO UPDATE SET first_seen_timestamp = excluded.first_seen_timestamp"; - let current_timestamp = SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap() - .as_secs() as i64; - - conn.execute(sql, params![&txid.to_hex(), current_timestamp])?; + conn.execute(sql, params![&txid.to_hex(), first_seen_timestamp])?; Ok(()) } diff --git a/src/index.rs b/src/index.rs index 61a87b6..eb003bd 100644 --- a/src/index.rs +++ b/src/index.rs @@ -6,6 +6,7 @@ use std::{ collections::HashSet, sync::{mpsc::sync_channel, Arc, Mutex}, + time::{SystemTime, UNIX_EPOCH}, }; use bitcoin_hashes::hex::{FromHex, ToHex}; @@ -74,10 +75,15 @@ pub fn update_mempool(db: DBPool, electrum: Arc>) -> Result<()> { db::cauldron::mempool::delete_mempool_tx(&db_tx, txid)?; } + let current_timestamp = SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_secs(); + for tx in txs_to_add { let txid = tx.txid(); debug!("mempool add {}", txid.to_hex()); - db::cauldron::tx::insert_mempool_tx(&db_tx, &txid)?; + db::cauldron::tx::insert_mempool_tx(&db_tx, &txid, current_timestamp)?; let cauldrons: Vec = tx .input .iter() @@ -92,7 +98,7 @@ pub fn update_mempool(db: DBPool, electrum: Arc>) -> Result<()> { all_cauldrons.extend(cauldrons); } - db::cauldron::pool::update_pool_history(&db_tx, all_cauldrons) + db::cauldron::pool::update_pool_history(&db_tx, all_cauldrons, None, Some(current_timestamp)) .context("update pool history")?; Ok(db_tx.commit()?) @@ -236,7 +242,7 @@ pub fn index_blocks( } // Figuring out initial utxo needs to be done on all cauldrons in a block. - db::cauldron::pool::update_pool_history(&db_tx, all_cauldrons) + db::cauldron::pool::update_pool_history(&db_tx, all_cauldrons, Some(mtp), None) .context("update pool history")?; config_set(&db_tx, KEY_LAST_INDEXED, &blockhash.to_hex());