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");
|
.expect("failed to create bcmr_data table");
|
||||||
|
|
||||||
// NOTE: PRIMARY KEY (utxo, txid) is required for ON CONFLICT(utxo, txid)
|
|
||||||
conn.execute(
|
conn.execute(
|
||||||
"CREATE TABLE bcmr_failure (
|
"CREATE TABLE bcmr_failure (
|
||||||
token_id TEXT NOT NULL,
|
token_id TEXT NOT NULL,
|
||||||
|
|
@ -133,13 +132,6 @@ pub fn prepare_tables(conn: &Connection) {
|
||||||
)
|
)
|
||||||
.expect("failed to create idx_bcmr_data_utxo");
|
.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
|
// Optional: if you often filter by recent failures/backoff window
|
||||||
conn.execute(
|
conn.execute(
|
||||||
"CREATE INDEX IF NOT EXISTS idx_bcmr_failure_last_attempt ON bcmr_failure(last_attempt)",
|
"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)
|
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