fix: resolve data loss bugs in farm IP, node interface, and contract mapping handlers#209
fix: resolve data loss bugs in farm IP, node interface, and contract mapping handlers#209sameh-farouk wants to merge 1 commit intomaster-automate-typegenfrom
Conversation
d5deadd to
c07d9e0
Compare
a4fb1b7 to
f97b850
Compare
c07d9e0 to
bab6f37
Compare
…mapping handlers - B1: Replace async forEach with for...of in farmUpdated to fix race conditions on IP saves/removals - B2: Append IP string to PublicIp ID in farmStored/farmUpdated to prevent overwrites when multiple IPs exist - B3: Append interface name to Interfaces ID in nodeStored (matching nodeUpdated pattern) to prevent overwrites - B4: Add undefined guard for contractID in grace period handlers to prevent unpredictable queries - B5: Fix handlePublicConfigV105 fallthrough creating ghost PublicConfig with null fields when config is undefined - B6: Save inline PublicConfig in nodeStored for spec v9 nodes that carried publicConfig at creation time - Fix cross-farm duplicate IP handling: properly skip instead of silently overwriting gateway - Add '-' separator to composite IDs for readability (interfaces and public IPs) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
f97b850 to
94fdaf4
Compare
bab6f37 to
b2e5f55
Compare
|
Total PublicIPs: Increased from 1,364 to 1,367 (+3)
The fixed logic ensures the first farm keeps ownership while subsequent duplicates are logged and skipped. This match what was documnted, loged, and comunicated but it was broken. |
Summary
Closes #208
Fixes 7 data corruption bugs in the event mapping handlers, discovered during a code audit.
Fixes
B1 — Race conditions in
farmUpdated(farms.ts)Replace
async/awaitinside.forEach()withfor...ofloops for both IP save and IP removal iterations. Ensures sequential execution of read-modify-write operations.B2 — PublicIp ID collision in
farmStored(farms.ts)Multiple public IPs in a
FarmStoredevent all received the same ID (item.event.id), causing upsert overwrites. Now appends-{ip}to create unique IDs per IP.B3 — Interfaces ID collision in
nodeStored(nodes.ts)Same collision pattern — multiple interfaces got the same ID. Now appends
-{name}, matching the existing correct pattern innodeUpdated.B4 — Undefined
contractIDguard in grace period handlers (contracts.ts)contractGracePeriodStartedandcontractGracePeriodEndedhad no guard when the event version was unrecognized. Addedundefinedcheck with error log and early return.B5 —
handlePublicConfigV105fallthrough (nodes.ts)When config was
None(meaning "remove public config") and no existing record was found, the function fell through and created a ghostPublicConfigwith all-null fields. Now returns early for the entire!configbranch.B6 —
nodeStorednever saved inline PublicConfig (nodes.ts)In spec v9,
create_nodeaccepted apublic_configparameter.getNodePublicConfig()extracted it but the result was never persisted. Now saves when non-null.B7 — Cross-farm duplicate IP not actually skipped (farms.ts)
When an IP already existed on a different farm, the code logged "skipped" but continued to save — overwriting the original farm's gateway. Now properly
continues after the error log. Also removed the no-opsavedIP.ipreassignment.Additional cleanup
-separator to composite IDs for readability (eventId-eth0instead ofeventIdeth0)nodeStoredandnodeUpdatedinterface IDsBackwards compatibility
ip,contractId,farm.id,node.nodeID), never the rawid— ID format changes are safectx.store.save()is an upsert (INSERT ... ON CONFLICT (id) DO UPDATE) — confirmed in Subsquid's@subsquid/typeorm-storepublic_configincreate_node; spec 11+ (pallet 0.1.0-b4) hardcodedNoneadd_farm_iponly checks within same farm)Test plan
npx tsc --noEmit— compiles clean after each fix