-
Notifications
You must be signed in to change notification settings - Fork 212
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(swingset): liveslots: disable metering of GC-sensitive calls
We're trying to hedge against XS not necessarily performing "organic" (non-forced) GC at exactly the same across all members (validators) of a consensus machine, especially when some members have reloaded a vat from snapshot (i.e. restarted) recently and others have not. We rely upon finalizer callbacks only running at explicitly-deterministic times, but we must still guard against objects becoming collected spontaneously, which will cause a WeakRef to become "dead" (`wr.deref() === undefined`) at a random point in the middle of a turn. Any code which calls `wr.deref`, or is conditionally executed/skipped according to the results, is "GC-sensitive". This includes `convertSlotToVal`, and therefore `m.unserialize`. We cannot allow metering results to diverge between validators, because: * 1: it might make the difference between the crank completing successfully, and the vat being terminated for a per-crank metering fault * 2: it will change the large-scale Meter value, which is reported to userspace * 3: it might cause the runPolicy to finish the block earlier on one validator than on others all of which would cause a consensus failure. To prevent this, we run most of the "inbound" side of liveslots without metering. This includes the first turn of all `dispatch.*` methods, which runs entirely within liveslots: * `dispatch.deliver` performs argument deserialization in the first turn, then executes user code in the second and subsequent turns * `dispatch.notify` does the same * the GC deliveries (`dispatch.dropExport`, etc) only use one turn We also disable metering when deserializing the return value from a (synchronous) device call, and when retiring a promise ID (which touches `slotToVal`). Finally, we disable metering for all turns of the post-crank GC `finish()` call. This excludes all invocations of the finalizer callbacks, as well as all the `processDeadSet` code which is highly sensitive to the results. closes #3458
- Loading branch information
Showing
2 changed files
with
65 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters