3
3
import { makeMarshal , Remotable , getInterfaceOf } from '@agoric/marshal' ;
4
4
import { assert , details } from '@agoric/assert' ;
5
5
import { importBundle } from '@agoric/import-bundle' ;
6
- import { makeVatManagerFactory } from './vatManager/vatManager' ;
6
+ import { assertKnownOptions } from '../assertOptions' ;
7
+ import { makeVatManagerFactory } from './vatManager/factory' ;
7
8
import makeDeviceManager from './deviceManager' ;
8
9
import { wrapStorage } from './state/storageWrapper' ;
9
10
import makeKernelKeeper from './state/kernelKeeper' ;
@@ -82,16 +83,21 @@ export default function buildKernel(kernelEndowments) {
82
83
// in the kernel table, promises and resolvers are both indexed by the same
83
84
// value. kernelPromises[promiseID] = { decider, subscribers }
84
85
85
- // The 'staticVatPowers' are given to vats as arguments of setup().
86
- // Liveslots provides them, and more, as the only argument to
87
- // buildRootObject(). They represent controlled authorities that come from
88
- // the kernel but that do not go through the syscall mechanism (so they
89
- // aren't included in the replay transcript), so they must not be
90
- // particularly stateful. If any of them behave differently from one
91
- // invocation to the next, the vat code which uses it will not be a
92
- // deterministic function of the transcript, breaking our
93
- // orthogonal-persistence model. They can have access to state, but they
94
- // must not let it influence the data they return to the vat.
86
+ // The "Vat Powers" are given to vats as arguments of setup(). Liveslots
87
+ // provides them, and more, as the only argument to buildRootObject(). They
88
+ // represent controlled authorities that come from the kernel but that do
89
+ // not go through the syscall mechanism (so they aren't included in the
90
+ // replay transcript), so they must not be particularly stateful. If any of
91
+ // them behave differently from one invocation to the next, the vat code
92
+ // which uses it will not be a deterministic function of the transcript,
93
+ // breaking our orthogonal-persistence model. They can have access to
94
+ // state, but they must not let it influence the data they return to the
95
+ // vat.
96
+
97
+ // Not all vats get all powers. We're phasing out in-vat metering, so
98
+ // `makeGetMeter` and `transformMetering` are only available to static vats
99
+ // in a local worker, and will eventually go away entirely once Spawner
100
+ // uses dynamic vats.
95
101
96
102
// These will eventually be provided by the in-worker supervisor instead.
97
103
@@ -101,9 +107,9 @@ export default function buildKernel(kernelEndowments) {
101
107
// maybe transformMetering) are imported by the vat, not passed in an
102
108
// argument. The powerful one (makeGetMeter) should only be given to the
103
109
// root object, to share with (or withhold from) other objects as it sees
104
- // fit. TODO: makeGetMeter and transformMetering will go away once #1288
105
- // lands and zoe no longer needs to do metering within a vat.
106
- const staticVatPowers = harden ( {
110
+ // fit. TODO: makeGetMeter and transformMetering will go away
111
+
112
+ const allVatPowers = harden ( {
107
113
Remotable,
108
114
getInterfaceOf,
109
115
makeGetMeter : meterManager . makeGetMeter ,
@@ -114,14 +120,6 @@ export default function buildKernel(kernelEndowments) {
114
120
testLog,
115
121
} ) ;
116
122
117
- // dynamic vats don't get control over their own metering, nor testLog
118
- const dynamicVatPowers = harden ( {
119
- Remotable,
120
- getInterfaceOf,
121
- transformTildot : ( ...args ) =>
122
- meterManager . runWithoutGlobalMeter ( transformTildot , ...args ) ,
123
- } ) ;
124
-
125
123
function vatNameToID ( name ) {
126
124
const vatID = kernelKeeper . getVatIDForName ( name ) ;
127
125
insistVatID ( vatID ) ;
@@ -405,21 +403,20 @@ export default function buildKernel(kernelEndowments) {
405
403
if ( typeof setup !== 'function' ) {
406
404
throw Error ( `setup is not a function, rather ${ setup } ` ) ;
407
405
}
408
- const knownCreationOptions = new Set ( [ 'enablePipelining' , 'metered' ] ) ;
409
- for ( const k of Object . keys ( creationOptions ) ) {
410
- if ( ! knownCreationOptions . has ( k ) ) {
411
- throw Error ( `unknown option ${ k } ` ) ;
412
- }
413
- }
414
-
406
+ assertKnownOptions ( creationOptions , [ 'enablePipelining' , 'metered' ] ) ;
415
407
if ( started ) {
416
408
throw Error ( `addGenesisVat() cannot be called after kernel.start` ) ;
417
409
}
418
410
if ( genesisVats . has ( name ) ) {
419
411
throw Error ( `vatID ${ name } already added` ) ;
420
412
}
421
-
422
- genesisVats . set ( name , { setup, vatParameters, creationOptions } ) ;
413
+ const managerOptions = {
414
+ ...creationOptions ,
415
+ setup,
416
+ enableSetup : true ,
417
+ vatParameters,
418
+ } ;
419
+ genesisVats . set ( name , managerOptions ) ;
423
420
}
424
421
425
422
function addGenesisVat (
@@ -434,19 +431,33 @@ export default function buildKernel(kernelEndowments) {
434
431
if ( typeof bundle !== 'object' ) {
435
432
throw Error ( `bundle is not an object, rather ${ bundle } ` ) ;
436
433
}
437
- const knownCreationOptions = new Set ( [ 'enablePipelining' , 'metered' ] ) ;
438
- for ( const k of Object . getOwnPropertyNames ( creationOptions ) ) {
439
- if ( ! knownCreationOptions . has ( k ) ) {
440
- throw Error ( `unknown option ${ k } ` ) ;
441
- }
442
- }
434
+ assertKnownOptions ( creationOptions , [
435
+ 'enablePipelining' ,
436
+ 'metered' ,
437
+ 'managerType' ,
438
+ 'enableSetup' ,
439
+ 'enableInternalMetering' ,
440
+ ] ) ;
443
441
if ( started ) {
444
442
throw Error ( `addGenesisVat() cannot be called after kernel.start` ) ;
445
443
}
446
444
if ( genesisVats . has ( name ) ) {
447
445
throw Error ( `vatID ${ name } already added` ) ;
448
446
}
449
- genesisVats . set ( name , { bundle, vatParameters, creationOptions } ) ;
447
+ // TODO: We need to support within-vat metering (for the Spawner) until
448
+ // #1343 is fixed, after which we can remove
449
+ // managerOptions.enableInternalMetering . For now, it needs to be
450
+ // enabled for our internal unit test (which could easily add this to its
451
+ // config object) and for the spawner vat (not so easy). To avoid deeper
452
+ // changes, we enable it for *all* static vats here. Once #1343 is fixed,
453
+ // remove this addition and all support for internal metering.
454
+ const managerOptions = {
455
+ ...creationOptions ,
456
+ bundle,
457
+ enableInternalMetering : true ,
458
+ vatParameters,
459
+ } ;
460
+ genesisVats . set ( name , managerOptions ) ;
450
461
}
451
462
452
463
function addGenesisDevice ( name , bundle , endowments ) {
@@ -547,11 +558,10 @@ export default function buildKernel(kernelEndowments) {
547
558
}
548
559
549
560
const vatManagerFactory = makeVatManagerFactory ( {
550
- dynamicVatPowers ,
561
+ allVatPowers ,
551
562
kernelKeeper,
552
563
makeVatEndowments,
553
564
meterManager,
554
- staticVatPowers,
555
565
testLog,
556
566
transformMetering,
557
567
waitUntilQuiescent,
@@ -565,13 +575,13 @@ export default function buildKernel(kernelEndowments) {
565
575
* might tell the manager to replay the transcript later, if it notices
566
576
* we're reloading a saved state vector.
567
577
*/
568
- function addVatManager ( vatID , manager , creationOptions ) {
578
+ function addVatManager ( vatID , manager , managerOptions ) {
569
579
// addVatManager takes a manager, not a promise for one
570
580
assert (
571
581
manager . deliver && manager . setVatSyscallHandler ,
572
582
`manager lacks .deliver, isPromise=${ manager instanceof Promise } ` ,
573
583
) ;
574
- const { enablePipelining = false } = creationOptions ;
584
+ const { enablePipelining = false } = managerOptions ;
575
585
// This should create the vatKeeper. Other users get it from the
576
586
// kernelKeeper, so we don't need a reference ourselves.
577
587
kernelKeeper . allocateVatKeeperIfNeeded ( vatID ) ;
@@ -715,22 +725,12 @@ export default function buildKernel(kernelEndowments) {
715
725
716
726
// instantiate all vats
717
727
for ( const name of genesisVats . keys ( ) ) {
718
- const { setup, bundle, vatParameters, creationOptions } = genesisVats . get (
719
- name ,
720
- ) ;
728
+ const managerOptions = genesisVats . get ( name ) ;
721
729
const vatID = kernelKeeper . allocateVatIDForNameIfNeeded ( name ) ;
722
730
console . debug ( `Assigned VatID ${ vatID } for genesis vat ${ name } ` ) ;
723
731
// eslint-disable-next-line no-await-in-loop
724
- const manager = await ( setup
725
- ? vatManagerFactory . createFromSetup ( setup , vatID )
726
- : vatManagerFactory . createFromBundle ( bundle , vatID , {
727
- metered : false ,
728
- vatPowerType : 'static' ,
729
- allowSetup : true , // TODO: only needed by comms, disallow elsewhere
730
- vatParameters,
731
- creationOptions,
732
- } ) ) ;
733
- addVatManager ( vatID , manager , creationOptions ) ;
732
+ const manager = await vatManagerFactory ( vatID , managerOptions ) ;
733
+ addVatManager ( vatID , manager , managerOptions ) ;
734
734
}
735
735
736
736
function createVatDynamicallyByName ( bundleName , options ) {
@@ -854,6 +854,12 @@ export default function buildKernel(kernelEndowments) {
854
854
return count ;
855
855
}
856
856
857
+ // mostly used by tests, only needed with thread/process-based workers
858
+ function shutdown ( ) {
859
+ const vatRecs = Array . from ( ephemeral . vats . values ( ) ) ;
860
+ return Promise . all ( vatRecs . map ( rec => rec . manager . shutdown ( ) ) ) ;
861
+ }
862
+
857
863
const kernel = harden ( {
858
864
// these are meant for the controller
859
865
addGenesisVat,
@@ -867,6 +873,8 @@ export default function buildKernel(kernelEndowments) {
867
873
step,
868
874
run,
869
875
876
+ shutdown,
877
+
870
878
// the rest are for testing and debugging
871
879
872
880
addGenesisVatSetup,
0 commit comments