Skip to content

Commit 2ca9b86

Browse files
committed
runtime, graph: fix VID collisions in ipfs.map() callbacks
Each ipfs.map() callback created a fresh BlockState with vid_seq reset to RESERVED_VIDS. When multiple callbacks write to the same entity table, they all generate vids starting at (block<<32)+100, producing duplicates. Fix by threading vid_seq through the callback loop and updating it in EntityCache::extend() so the parent handler also continues from the right sequence after merging callback results. Addresses same underlying issue as PR #6336
1 parent eaac539 commit 2ca9b86

2 files changed

Lines changed: 13 additions & 2 deletions

File tree

graph/src/components/store/entity_cache.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,9 @@ impl EntityCache {
457457
for (key, op) in other.updates {
458458
self.entity_op(key, op);
459459
}
460+
// Carry forward vid_seq to prevent VID collisions when the caller
461+
// continues writing entities after merging.
462+
self.vid_seq = self.vid_seq.max(other.vid_seq);
460463
}
461464

462465
/// Generate an id.

runtime/wasm/src/host_exports.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ impl HostExports {
537537

538538
let host_metrics = wasm_ctx.host_metrics.clone();
539539
let valid_module = wasm_ctx.valid_module.clone();
540-
let ctx = wasm_ctx.ctx.derive_with_empty_block_state();
540+
let mut ctx = wasm_ctx.ctx.derive_with_empty_block_state();
541541
let callback = callback.to_owned();
542542
// Create a base error message to avoid borrowing headaches
543543
let errmsg = format!(
@@ -560,16 +560,24 @@ impl HostExports {
560560
let mut v = Vec::new();
561561
while let Some(sv) = stream.next().await {
562562
let sv = sv?;
563+
let mut derived = ctx.derive_with_empty_block_state();
564+
// Continue the vid sequence from the previous callback so
565+
// each iteration doesn't reset to RESERVED_VIDS and
566+
// produce duplicate VIDs.
567+
derived.state.entity_cache.vid_seq = ctx.state.entity_cache.vid_seq;
563568
let module = WasmInstance::from_valid_module_with_ctx_boxed(
564569
valid_module.clone(),
565-
ctx.derive_with_empty_block_state(),
570+
derived,
566571
host_metrics.clone(),
567572
wasm_ctx.experimental_features,
568573
)
569574
.await?;
570575
let result = module
571576
.handle_json_callback(&callback, &sv.value, &user_data)
572577
.await?;
578+
// Carry forward vid_seq so the next iteration continues
579+
// the sequence.
580+
ctx.state.entity_cache.vid_seq = result.entity_cache.vid_seq;
573581
// Log progress every 15s
574582
if last_log.elapsed() > Duration::from_secs(15) {
575583
debug!(

0 commit comments

Comments
 (0)