Merge branch 'chartImprovementFirstSeen' into 'master'

Use first time seen for phe same as transactions to make the live price chart sensible.

See merge request riftenlabs/riftenlabs-indexer!85
This commit is contained in:
jakobsn 2026-05-08 14:20:05 +00:00
commit 3e1895c2f0
8 changed files with 51 additions and 73 deletions

View file

@ -904,7 +904,7 @@ mod tests {
let mut conn = pool.acquire().await.unwrap();
insert_new_pool(&mut conn, &contract0).await.unwrap();
insert_utxo_funding(&mut conn, &vec![contract0.clone()], &txid0, true)
insert_utxo_funding(&mut conn, &vec![contract0.clone()], &txid0)
.await
.unwrap();
insert_block_tx(&mut conn, &txid0, &BlockHash::all_zeros(), t0)
@ -939,7 +939,7 @@ mod tests {
token_amount: Some(token_amount - 10),
};
insert_utxo_funding(&mut conn, &vec![contract1.clone()], &txid1, true)
insert_utxo_funding(&mut conn, &vec![contract1.clone()], &txid1)
.await
.unwrap();
insert_block_tx(&mut conn, &txid1, &BlockHash::all_zeros(), t1)

View file

@ -64,15 +64,20 @@ mod tests {
sats1: u64,
toks1: i64,
) {
// Derive a tiny salt from the token's hex so this helper never collides across tokens
let hex = token.to_hex();
let seed = u8::from_str_radix(&hex[hex.len() - 2..], 16).unwrap_or(0);
// Derive unique hashes per-token by embedding the token's own bytes.
// Single-byte seeds like 0xA0+seed collide when different tokens yield the same
// wrapping result, so use the full 32-byte token identity instead.
let token_bytes = token.into_inner();
let make_hash = |prefix: u8| {
let mut h = token_bytes;
h[0] = h[0].wrapping_add(prefix);
h
};
// Make everything unique per token
let pool_utxo_0 = OutPointHash::from_inner([0xA0u8.wrapping_add(seed); 32]);
let pool_utxo_1 = OutPointHash::from_inner([0xB0u8.wrapping_add(seed); 32]);
let txid0 = Txid::from_inner([0xF0u8.wrapping_add(seed); 32]);
let txid1 = Txid::from_inner([0xF1u8.wrapping_add(seed); 32]);
let pool_utxo_0 = OutPointHash::from_inner(make_hash(0xA0));
let pool_utxo_1 = OutPointHash::from_inner(make_hash(0xB0));
let txid0 = Txid::from_inner(make_hash(0xF0));
let txid1 = Txid::from_inner(make_hash(0xF1));
let owner = PubkeyHash::all_zeros();
@ -91,7 +96,7 @@ mod tests {
token_amount: Some(toks0),
};
insert_new_pool(&mut *conn, &c0).await.unwrap();
insert_utxo_funding(&mut *conn, &vec![c0.clone()], &txid0, true)
insert_utxo_funding(&mut *conn, &vec![c0.clone()], &txid0)
.await
.unwrap();
insert_block_tx(&mut *conn, &txid0, &BlockHash::all_zeros(), t0)
@ -124,7 +129,7 @@ mod tests {
sats: Some(sats1),
token_amount: Some(toks1),
};
insert_utxo_funding(&mut *conn, &vec![c1.clone()], &txid1, true)
insert_utxo_funding(&mut *conn, &vec![c1.clone()], &txid1)
.await
.unwrap();
insert_new_pool(&mut *conn, &c1).await.unwrap();
@ -890,7 +895,7 @@ mod tests {
token_amount: Some(100),
};
insert_new_pool(&mut *conn, &c0).await.unwrap();
insert_utxo_funding(&mut *conn, &vec![c0.clone()], &txid0, true)
insert_utxo_funding(&mut *conn, &vec![c0.clone()], &txid0)
.await
.unwrap();
insert_block_tx(&mut *conn, &txid0, &BlockHash::all_zeros(), t0)
@ -943,7 +948,7 @@ mod tests {
token_amount: Some(200),
};
insert_new_pool(&mut *conn, &c1).await.unwrap();
insert_utxo_funding(&mut *conn, &vec![c1.clone()], &txid1, true)
insert_utxo_funding(&mut *conn, &vec![c1.clone()], &txid1)
.await
.unwrap();
insert_block_tx(&mut *conn, &txid1, &BlockHash::all_zeros(), t1)

View file

@ -39,18 +39,14 @@ pub async fn insert_utxo_funding(
conn: &mut SqliteConnection,
cauldrons: &Vec<ParsedContract>,
txid: &Txid,
replace: bool,
) -> Result<()> {
let sql = format!(
"INSERT OR {} INTO utxo_funding (new_utxo_hash, txid, spent_utxo_hash, new_utxo_txid, new_utxo_n, sats, token_amount, token_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
if replace { "REPLACE" } else { "IGNORE" }
);
let sql = "INSERT OR IGNORE INTO utxo_funding (new_utxo_hash, txid, spent_utxo_hash, new_utxo_txid, new_utxo_n, sats, token_amount, token_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
for c in cauldrons {
if c.new_utxo_hash.is_none() {
continue;
}
sqlx::query(&sql)
sqlx::query(sql)
.bind(c.new_utxo_hash.unwrap().to_blob())
.bind(txid.to_blob())
.bind(c.spent_utxo_hash.to_blob())

View file

@ -614,7 +614,7 @@ mod tests {
)
.await?;
insert_utxo_funding(&mut *conn, &vec![cauldron1.clone()], &txid1, true).await?;
insert_utxo_funding(&mut *conn, &vec![cauldron1.clone()], &txid1).await?;
insert_block_tx(&mut *conn, &txid1, &block_zero, thirty_days_ago).await?;
insert_mempool_tx(&mut *conn, &txid1, thirty_days_ago as u64).await?;
@ -633,13 +633,7 @@ mod tests {
token_amount: Some(1000),
};
insert_utxo_funding(
&mut *conn,
&vec![cauldron1_spent.clone()],
&txid1_spend,
true,
)
.await?;
insert_utxo_funding(&mut *conn, &vec![cauldron1_spent.clone()], &txid1_spend).await?;
insert_block_tx(&mut *conn, &txid1_spend, &block_zero, current_timestamp).await?;
insert_mempool_tx(&mut *conn, &txid1_spend, current_timestamp as u64).await?;
@ -709,7 +703,7 @@ mod tests {
)
.await?;
insert_utxo_funding(&mut *conn, &vec![cauldron2.clone()], &txid2_init, true).await?;
insert_utxo_funding(&mut *conn, &vec![cauldron2.clone()], &txid2_init).await?;
insert_block_tx(&mut *conn, &txid2_init, &block_zero, thirty_days_ago).await?;
insert_mempool_tx(&mut *conn, &txid2_init, thirty_days_ago as u64).await?;
@ -727,13 +721,7 @@ mod tests {
token_amount: Some(1500),
};
insert_utxo_funding(
&mut *conn,
&vec![cauldron2_spent.clone()],
&txid2_spend,
true,
)
.await?;
insert_utxo_funding(&mut *conn, &vec![cauldron2_spent.clone()], &txid2_spend).await?;
insert_block_tx(&mut *conn, &txid2_spend, &block_zero, current_timestamp).await?;
insert_mempool_tx(&mut *conn, &txid2_spend, current_timestamp as u64).await?;
@ -803,7 +791,7 @@ mod tests {
)
.await?;
insert_utxo_funding(&mut *conn, &vec![cauldron3_init.clone()], &txid3_init, true).await?;
insert_utxo_funding(&mut *conn, &vec![cauldron3_init.clone()], &txid3_init).await?;
insert_block_tx(&mut *conn, &txid3_init, &block_zero, thirty_days_ago).await?;
insert_mempool_tx(&mut *conn, &txid3_init, thirty_days_ago as u64).await?;
@ -843,7 +831,7 @@ mod tests {
);
insert_new_pool(&mut *conn, &cauldron4_init).await?;
insert_utxo_funding(&mut *conn, &vec![cauldron4_init.clone()], &txid4_init, true).await?;
insert_utxo_funding(&mut *conn, &vec![cauldron4_init.clone()], &txid4_init).await?;
insert_block_tx(&mut *conn, &txid4_init, &block_zero, thirty_days_ago).await?;
insert_mempool_tx(&mut *conn, &txid4_init, thirty_days_ago as u64).await?;
@ -861,13 +849,7 @@ mod tests {
token_amount: Some(1500),
};
insert_utxo_funding(
&mut *conn,
&vec![cauldron4_spent.clone()],
&txid4_spend,
true,
)
.await?;
insert_utxo_funding(&mut *conn, &vec![cauldron4_spent.clone()], &txid4_spend).await?;
insert_block_tx(&mut *conn, &txid4_spend, &block_zero, current_timestamp).await?;
insert_mempool_tx(&mut *conn, &txid4_spend, current_timestamp as u64).await?;

View file

@ -128,7 +128,7 @@ pub async fn update_mempool(db: &DB, electrum: Arc<Mutex<Client>>) -> Result<()>
cauldrons.len()
);
insert_utxo_funding(&mut db_tx, &cauldrons, &txid, false).await?;
insert_utxo_funding(&mut db_tx, &cauldrons, &txid).await?;
insert_utxo_spending(&mut db_tx, &cauldrons, &txid, false).await?;
insert_user_action(&mut db_tx, &cauldrons, &btx, true).await?;
@ -386,7 +386,7 @@ pub async fn index_blocks(
insert_block_tx(&mut db_tx, &txid, &blockhash, mtp as i64)
.await
.context("inserting block tx")?;
insert_utxo_funding(&mut db_tx, &cauldrons, &txid, true)
insert_utxo_funding(&mut db_tx, &cauldrons, &txid)
.await
.context("inserting funding utxos")?;
insert_utxo_spending(&mut db_tx, &cauldrons, &txid, true)

View file

@ -565,16 +565,16 @@ mod tests {
let cauldron3 = dummy_cauldron(&txid3, &utxo3, &token_zero, 160_000, 2_000, &pkh_zero);
let cauldron4 = dummy_cauldron(&txid4, &utxo4, &token_zero, 200_000, 2_000, &pkh_zero);
insert_utxo_funding(&mut *conn, &vec![cauldron1.clone()], &txid1, true)
insert_utxo_funding(&mut *conn, &vec![cauldron1.clone()], &txid1)
.await
.unwrap();
insert_utxo_funding(&mut *conn, &vec![cauldron2.clone()], &txid2, true)
insert_utxo_funding(&mut *conn, &vec![cauldron2.clone()], &txid2)
.await
.unwrap();
insert_utxo_funding(&mut *conn, &vec![cauldron3.clone()], &txid3, true)
insert_utxo_funding(&mut *conn, &vec![cauldron3.clone()], &txid3)
.await
.unwrap();
insert_utxo_funding(&mut *conn, &vec![cauldron4.clone()], &txid4, true)
insert_utxo_funding(&mut *conn, &vec![cauldron4.clone()], &txid4)
.await
.unwrap();
@ -842,7 +842,7 @@ mod tests {
);
pools.push(pool_hash);
insert_utxo_funding(&mut *conn, &vec![cauldron.clone()], &txid_multi, true)
insert_utxo_funding(&mut *conn, &vec![cauldron.clone()], &txid_multi)
.await
.unwrap();
@ -999,7 +999,7 @@ mod tests {
sats: Some(0),
token_amount: Some(0),
};
insert_utxo_funding(&mut *conn, &vec![cauldron_p.clone()], &txid_price, true)
insert_utxo_funding(&mut *conn, &vec![cauldron_p.clone()], &txid_price)
.await
.unwrap();
insert_block_tx(&mut *conn, &txid_price, &block_zero, t0 as i64)
@ -1043,10 +1043,10 @@ mod tests {
..ca_a1
};
insert_utxo_funding(&mut *conn, &vec![ca_a1.clone()], &txid_net0, true)
insert_utxo_funding(&mut *conn, &vec![ca_a1.clone()], &txid_net0)
.await
.unwrap();
insert_utxo_funding(&mut *conn, &vec![ca_b1.clone()], &txid_net0, true)
insert_utxo_funding(&mut *conn, &vec![ca_b1.clone()], &txid_net0)
.await
.unwrap();

View file

@ -551,13 +551,13 @@ mod tests {
&pkh_zero,
&OutPointHash::all_zeros(),
);
insert_utxo_funding(&mut *conn, &vec![cauldron1.clone()], &txid1, true)
insert_utxo_funding(&mut *conn, &vec![cauldron1.clone()], &txid1)
.await
.unwrap();
insert_utxo_funding(&mut *conn, &vec![cauldron2.clone()], &txid2, true)
insert_utxo_funding(&mut *conn, &vec![cauldron2.clone()], &txid2)
.await
.unwrap();
insert_utxo_funding(&mut *conn, &vec![cauldron3.clone()], &txid3, true)
insert_utxo_funding(&mut *conn, &vec![cauldron3.clone()], &txid3)
.await
.unwrap();
@ -646,14 +646,9 @@ mod tests {
insert_new_pool(&mut *conn, &inactive_cauldron)
.await
.unwrap();
insert_utxo_funding(
&mut *conn,
&vec![inactive_cauldron.clone()],
&inactive_txid,
true,
)
.await
.unwrap();
insert_utxo_funding(&mut *conn, &vec![inactive_cauldron.clone()], &inactive_txid)
.await
.unwrap();
insert_pool_history_entry(
&mut *conn,
&inactive_pool,
@ -1033,7 +1028,7 @@ mod tests {
};
insert_new_pool(&mut *conn, &cauldron).await.unwrap();
insert_utxo_funding(&mut *conn, &vec![cauldron.clone()], &creation_txid, true)
insert_utxo_funding(&mut *conn, &vec![cauldron.clone()], &creation_txid)
.await
.unwrap();
insert_block_tx(&mut *conn, &creation_txid, &block, TIME_1 as i64)
@ -1197,7 +1192,7 @@ mod tests {
&OutPointHash::all_zeros(),
);
insert_new_pool(&mut *conn, &cauldron_a).await.unwrap();
insert_utxo_funding(&mut *conn, &vec![cauldron_a.clone()], &txid_a, true)
insert_utxo_funding(&mut *conn, &vec![cauldron_a.clone()], &txid_a)
.await
.unwrap();
insert_block_tx(&mut *conn, &txid_a, &block, TIME_1 as i64)
@ -1232,7 +1227,7 @@ mod tests {
token_amount: None,
};
insert_new_pool(&mut *conn, &cauldron_b).await.unwrap();
insert_utxo_funding(&mut *conn, &vec![cauldron_b.clone()], &txid_b, true)
insert_utxo_funding(&mut *conn, &vec![cauldron_b.clone()], &txid_b)
.await
.unwrap();
insert_block_tx(&mut *conn, &txid_b, &block, TIME_1 as i64)
@ -1367,7 +1362,7 @@ mod tests {
&PubkeyHash::all_zeros(),
&OutPointHash::all_zeros(),
);
insert_utxo_funding(&mut *conn, &vec![cauldron.clone()], &txid, true)
insert_utxo_funding(&mut *conn, &vec![cauldron.clone()], &txid)
.await
.unwrap();
insert_pool_history_entry(

View file

@ -319,13 +319,13 @@ pub mod tests {
let cauldron3 = dummy_cauldron(&txid3, &utxo3, &token_zero, 300_000, 3_000, &pkh_zero);
// Insert utxo funding data
utxo_funding::insert_utxo_funding(&mut *conn, &vec![cauldron1.clone()], &txid1, true)
utxo_funding::insert_utxo_funding(&mut *conn, &vec![cauldron1.clone()], &txid1)
.await
.unwrap();
utxo_funding::insert_utxo_funding(&mut *conn, &vec![cauldron2.clone()], &txid2, true)
utxo_funding::insert_utxo_funding(&mut *conn, &vec![cauldron2.clone()], &txid2)
.await
.unwrap();
utxo_funding::insert_utxo_funding(&mut *conn, &vec![cauldron3.clone()], &txid3, true)
utxo_funding::insert_utxo_funding(&mut *conn, &vec![cauldron3.clone()], &txid3)
.await
.unwrap();