Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions crates/idxdb-store/src/js/transactions.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,15 @@ export async function upsertTransactionRecord(dbId, transactionId, details, bloc
throw err;
}
}
export async function upsertTransactionRecordWithScript(dbId, transactionId, details, blockNum, statusVariant, status, scriptRoot, txScript) {
const db = getDatabase(dbId);
await db.dexie.transaction("rw", [db.transactions, db.transactionScripts], async (tx) => {
if (scriptRoot && txScript) {
await insertTransactionScript(dbId, scriptRoot, txScript, tx);
}
await upsertTransactionRecord(dbId, transactionId, details, blockNum, statusVariant, status, scriptRoot, tx);
});
}
/**
* Applies a batch of transaction updates atomically inside a single Dexie transaction.
*
Expand Down
12 changes: 3 additions & 9 deletions crates/idxdb-store/src/transaction/js_bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,16 @@ extern "C" {
#[wasm_bindgen(js_name = getTransactions)]
pub fn idxdb_get_transactions(db_id: &str, filter: String) -> js_sys::Promise;

#[wasm_bindgen(js_name = insertTransactionScript)]
pub fn idxdb_insert_transaction_script(
db_id: &str,
script_root: Vec<u8>,
tx_script: Option<Vec<u8>>,
) -> js_sys::Promise;

#[wasm_bindgen(js_name = upsertTransactionRecord)]
pub fn idxdb_upsert_transaction_record(
#[wasm_bindgen(js_name = upsertTransactionRecordWithScript)]
pub fn idxdb_upsert_transaction_record_with_script(
db_id: &str,
transaction_id: String,
details: Vec<u8>,
block_num: u32,
statusVariant: u8,
status: Vec<u8>,
scriptRoot: Option<Vec<u8>>,
txScript: Option<Vec<u8>>,
) -> js_sys::Promise;

#[wasm_bindgen(js_name = applyTransactionBatch)]
Expand Down
10 changes: 3 additions & 7 deletions crates/idxdb-store/src/transaction/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use miden_client::utils::Serializable;
use serde::Serialize;
use wasm_bindgen::prelude::wasm_bindgen;

use super::js_bindings::{idxdb_insert_transaction_script, idxdb_upsert_transaction_record};
use super::js_bindings::idxdb_upsert_transaction_record_with_script;
use crate::promise::await_ok;

// TYPES
Expand Down Expand Up @@ -111,19 +111,15 @@ pub(crate) async fn upsert_transaction_record(
) -> Result<(), StoreError> {
let serialized_data = serialize_transaction_record(transaction);

if let Some(root) = serialized_data.script_root.clone() {
let promise = idxdb_insert_transaction_script(db_id, root, serialized_data.tx_script);
await_ok(promise, "failed to insert script").await?;
}

let promise = idxdb_upsert_transaction_record(
let promise = idxdb_upsert_transaction_record_with_script(
db_id,
serialized_data.id,
serialized_data.details,
serialized_data.block_num,
serialized_data.status_variant,
serialized_data.status,
serialized_data.script_root,
serialized_data.tx_script,
);
await_ok(promise, "failed to insert transaction data").await?;

Expand Down
28 changes: 28 additions & 0 deletions crates/idxdb-store/src/ts/transactions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
getTransactions,
insertTransactionScript,
upsertTransactionRecord,
upsertTransactionRecordWithScript,
} from "./transactions.js";

let dbCounter = 0;
Expand Down Expand Up @@ -390,6 +391,33 @@ describe("transactions", () => {
expect(all[0].txScript).toEqual(script2);
});

it("rolls back the script when the transaction record write fails", async () => {
const dbId = await openTestDb();
const scriptRootBytes = new Uint8Array([0x0a, 0x0b]);
const txScriptBytes = new Uint8Array([0x0c, 0x0d]);

await expect(
upsertTransactionRecordWithScript(
dbId,
undefined as unknown as string,
new Uint8Array([1]),
1,
0,
new Uint8Array([2]),
scriptRootBytes,
txScriptBytes
)
).rejects.toThrow();

const db = getDatabase(dbId);
const storedScript = await db.transactionScripts
.where("scriptRoot")
.equals(toBase64(scriptRootBytes))
.first();

expect(storedScript).toBeUndefined();
});

// -------------------------------------------------------------------------
// Error paths — "never-opened" dbId
// -------------------------------------------------------------------------
Expand Down
34 changes: 34 additions & 0 deletions crates/idxdb-store/src/ts/transactions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,40 @@ export async function upsertTransactionRecord(
}
}

export async function upsertTransactionRecordWithScript(
dbId: string,
transactionId: string,
details: Uint8Array,
blockNum: number,
statusVariant: number,
status: Uint8Array,
scriptRoot?: Uint8Array,
txScript?: Uint8Array
) {
const db = getDatabase(dbId);

await db.dexie.transaction(
"rw",
[db.transactions, db.transactionScripts],
async (tx) => {
if (scriptRoot && txScript) {
await insertTransactionScript(dbId, scriptRoot, txScript, tx);
}

await upsertTransactionRecord(
dbId,
transactionId,
details,
blockNum,
statusVariant,
status,
scriptRoot,
tx
);
}
);
}

// BATCH APPLY
// ================================================================================================

Expand Down