Merge branch 'bug-bcmr' into 'master'
Fix bcmr_failure unique constraint for multi-token transactions Closes #17 See merge request riftenlabs/riftenlabs-indexer!50
This commit is contained in:
commit
16ed485711
1 changed files with 63 additions and 8 deletions
|
|
@ -61,7 +61,6 @@ pub fn prepare_tables(conn: &Connection) {
|
|||
)
|
||||
.expect("failed to create bcmr_data table");
|
||||
|
||||
// NOTE: PRIMARY KEY (utxo, txid) is required for ON CONFLICT(utxo, txid)
|
||||
conn.execute(
|
||||
"CREATE TABLE bcmr_failure (
|
||||
token_id TEXT NOT NULL,
|
||||
|
|
@ -133,13 +132,6 @@ pub fn prepare_tables(conn: &Connection) {
|
|||
)
|
||||
.expect("failed to create idx_bcmr_data_utxo");
|
||||
|
||||
// Enforce per-(utxo, txid) backoff and dedupe updates
|
||||
conn.execute(
|
||||
"CREATE UNIQUE INDEX IF NOT EXISTS idx_bcmr_failure_utxo_txid ON bcmr_failure(utxo, txid)",
|
||||
[],
|
||||
)
|
||||
.expect("failed to create idx_bcmr_failure_utxo_txid");
|
||||
|
||||
// Optional: if you often filter by recent failures/backoff window
|
||||
conn.execute(
|
||||
"CREATE INDEX IF NOT EXISTS idx_bcmr_failure_last_attempt ON bcmr_failure(last_attempt)",
|
||||
|
|
@ -483,3 +475,66 @@ pub fn get_well_known_bcmr(conn: &Connection, token_hex: &str) -> Result<Vec<Par
|
|||
|
||||
Ok(entries)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use bitcoin_hashes::hex::FromHex;
|
||||
|
||||
#[test]
|
||||
fn test_update_bcmr_failure_multiple_tokens_same_utxo_txid() {
|
||||
// Test that bcmr_failure can record failures for multiple tokens
|
||||
// that share the same (utxo, txid) - this happens when a single
|
||||
// transaction updates the auth chain for multiple tokens.
|
||||
|
||||
let conn = Connection::open_in_memory().unwrap();
|
||||
prepare_tables(&conn);
|
||||
|
||||
// Two different tokens
|
||||
let token_a =
|
||||
TokenID::from_hex("0101010101010101010101010101010101010101010101010101010101010101")
|
||||
.unwrap();
|
||||
let token_b =
|
||||
TokenID::from_hex("0202020202020202020202020202020202020202020202020202020202020202")
|
||||
.unwrap();
|
||||
|
||||
// Same utxo and txid (simulates a tx that updates auth chain for both tokens)
|
||||
let utxo = OutPointHash::from_hex(
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
)
|
||||
.unwrap();
|
||||
let txid =
|
||||
Txid::from_hex("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")
|
||||
.unwrap();
|
||||
|
||||
// Record failure for token A - should succeed
|
||||
update_bcmr_failure(&conn, &utxo, &txid, &token_a, "error A", false)
|
||||
.expect("first update_bcmr_failure should succeed");
|
||||
|
||||
// Record failure for token B with same (utxo, txid) - should also succeed
|
||||
update_bcmr_failure(&conn, &utxo, &txid, &token_b, "error B", false).expect(
|
||||
"second update_bcmr_failure with same utxo/txid but different token should succeed",
|
||||
);
|
||||
|
||||
// Verify both entries exist
|
||||
let count: i64 = conn
|
||||
.query_row("SELECT COUNT(*) FROM bcmr_failure", [], |row| row.get(0))
|
||||
.unwrap();
|
||||
assert_eq!(count, 2, "should have 2 failure entries");
|
||||
|
||||
// Verify we can update both independently
|
||||
update_bcmr_failure(&conn, &utxo, &txid, &token_a, "error A updated", false)
|
||||
.expect("updating token A failure should succeed");
|
||||
update_bcmr_failure(&conn, &utxo, &txid, &token_b, "error B updated", false)
|
||||
.expect("updating token B failure should succeed");
|
||||
|
||||
// Still only 2 entries (updates, not new inserts)
|
||||
let count: i64 = conn
|
||||
.query_row("SELECT COUNT(*) FROM bcmr_failure", [], |row| row.get(0))
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
count, 2,
|
||||
"should still have 2 failure entries after updates"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue