@@ -74,8 +74,15 @@ function makeContractHost(E, evaluate, additionalEndowments = {}) {
74
74
// Refill a meter each crank.
75
75
const { meter, refillFacet } = makeMeter ( ) ;
76
76
const doRefill = ( ) => {
77
- // Refill the meter, since we're leaving a crank.
78
- refillFacet . combined ( ) ;
77
+ if ( ! meter . isExhausted ( ) ) {
78
+ // We'd like to have fail-stop semantics, which means we associate
79
+ // a meter with a spawn and not with an installation, and failed
80
+ // spawns die forever. Check functions, on the other hand, should
81
+ // be billed to the installation, which may die forever.
82
+
83
+ // Refill the meter, since we're leaving a crank.
84
+ refillFacet . combined ( ) ;
85
+ }
79
86
} ;
80
87
81
88
// Make an endowment to get our meter.
@@ -131,21 +138,13 @@ function makeContractHost(E, evaluate, additionalEndowments = {}) {
131
138
// contract.
132
139
install ( contractSrcs , moduleFormat = 'object' ) {
133
140
let installation ;
134
- let startFn ;
135
141
if ( moduleFormat === 'object' ) {
136
142
installation = extractCheckFunctions ( contractSrcs ) ;
137
- startFn = evaluateStringToFn ( contractSrcs . start ) ;
138
143
} else if ( moduleFormat === 'getExport' ) {
139
- const getExports = evaluateStringToFn ( contractSrcs ) ;
140
- const ns = getExports ( ) ;
144
+ // We don't support 'check' functions in getExport format,
145
+ // because we only do a single evaluate, and the whole
146
+ // contract must be metered per-spawn, not per-installation.
141
147
installation = { } ;
142
- for ( const fname of Object . getOwnPropertyNames ( ns ) ) {
143
- if ( typeof fname === 'string' && fname . startsWith ( 'check' ) ) {
144
- const fn = ns [ fname ] ;
145
- installation [ fname ] = ( ...args ) => fn ( installation , ...args ) ;
146
- }
147
- }
148
- startFn = ns . default ;
149
148
} else {
150
149
assert . fail ( details `Unrecognized moduleFormat ${ moduleFormat } ` ) ;
151
150
}
@@ -160,6 +159,17 @@ function makeContractHost(E, evaluate, additionalEndowments = {}) {
160
159
// source code itself. The check... methods must be evaluated on install,
161
160
// since they become properties of the installation.
162
161
function spawn ( termsP ) {
162
+ let startFn ;
163
+ if ( moduleFormat === 'object' ) {
164
+ startFn = evaluateStringToFn ( contractSrcs . start ) ;
165
+ } else if ( moduleFormat === 'getExport' ) {
166
+ const getExports = evaluateStringToFn ( contractSrcs ) ;
167
+ const ns = getExports ( ) ;
168
+ startFn = ns . default ;
169
+ } else {
170
+ assert . fail ( details `Unrecognized moduleFormat ${ moduleFormat } ` ) ;
171
+ }
172
+
163
173
return Promise . resolve ( allComparable ( termsP ) ) . then ( terms => {
164
174
const inviteMaker = harden ( {
165
175
// Used by the contract to make invites for credibly
0 commit comments