@activeledger/activeprotocol 2.15.7 → 4.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/es/protocol/interfaces/vm.interface.d.ts +6 -4
  2. package/es/protocol/interfaces/vm.interface.d.ts.map +1 -1
  3. package/es/protocol/permissionsChecker.d.ts +5 -3
  4. package/es/protocol/permissionsChecker.d.ts.map +1 -1
  5. package/es/protocol/permissionsChecker.js +149 -120
  6. package/es/protocol/permissionsChecker.js.map +1 -1
  7. package/es/protocol/process.d.ts +10 -9
  8. package/es/protocol/process.d.ts.map +1 -1
  9. package/es/protocol/process.js +276 -214
  10. package/es/protocol/process.js.map +1 -1
  11. package/es/protocol/shared.d.ts +6 -2
  12. package/es/protocol/shared.d.ts.map +1 -1
  13. package/es/protocol/shared.js +41 -29
  14. package/es/protocol/shared.js.map +1 -1
  15. package/es/protocol/streamUpdater.d.ts +1 -6
  16. package/es/protocol/streamUpdater.d.ts.map +1 -1
  17. package/es/protocol/streamUpdater.js +80 -109
  18. package/es/protocol/streamUpdater.js.map +1 -1
  19. package/es/protocol/vm.d.ts +12 -5
  20. package/es/protocol/vm.d.ts.map +1 -1
  21. package/es/protocol/vm.js +212 -137
  22. package/es/protocol/vm.js.map +1 -1
  23. package/es/protocol/vmscript.js +23 -10
  24. package/es/protocol/vmscript.js.map +1 -1
  25. package/lib/protocol/interfaces/vm.interface.d.ts +6 -4
  26. package/lib/protocol/interfaces/vm.interface.d.ts.map +1 -1
  27. package/lib/protocol/permissionsChecker.d.ts +5 -3
  28. package/lib/protocol/permissionsChecker.d.ts.map +1 -1
  29. package/lib/protocol/permissionsChecker.js +149 -120
  30. package/lib/protocol/permissionsChecker.js.map +1 -1
  31. package/lib/protocol/process.d.ts +10 -9
  32. package/lib/protocol/process.d.ts.map +1 -1
  33. package/lib/protocol/process.js +276 -240
  34. package/lib/protocol/process.js.map +1 -1
  35. package/lib/protocol/shared.d.ts +6 -2
  36. package/lib/protocol/shared.d.ts.map +1 -1
  37. package/lib/protocol/shared.js +41 -29
  38. package/lib/protocol/shared.js.map +1 -1
  39. package/lib/protocol/streamUpdater.d.ts +1 -6
  40. package/lib/protocol/streamUpdater.d.ts.map +1 -1
  41. package/lib/protocol/streamUpdater.js +80 -109
  42. package/lib/protocol/streamUpdater.js.map +1 -1
  43. package/lib/protocol/vm.d.ts +12 -5
  44. package/lib/protocol/vm.d.ts.map +1 -1
  45. package/lib/protocol/vm.js +211 -136
  46. package/lib/protocol/vm.js.map +1 -1
  47. package/lib/protocol/vmscript.js +23 -9
  48. package/lib/protocol/vmscript.js.map +1 -1
  49. package/package.json +10 -10
@@ -1,4 +1,4 @@
1
- import * as fs from "fs";
1
+ import { promises as fs } from "fs";
2
2
  import { EventEmitter } from "events";
3
3
  import { VirtualMachine } from "./vm";
4
4
  import { ActiveOptions } from "@activeledger/activeoptions";
@@ -6,9 +6,41 @@ import { ActiveLogger } from "@activeledger/activelogger";
6
6
  import { Shared } from "./shared";
7
7
  import { StreamUpdater } from "./streamUpdater";
8
8
  import { PermissionsChecker } from "./permissionsChecker";
9
- import path from "path";
10
- const BROADCAST_TIMEOUT = 20 * 1000;
9
+ const BROADCAST_TIMEOUT_EARLY = 60 * 1000;
10
+ const BROADCAST_TIMEOUT_VOTE = 60 * 1000;
11
+ const BROADCAST_TIMEOUT_COMMIT = 60 * 1000;
11
12
  export class Process extends EventEmitter {
13
+ entry;
14
+ selfHost;
15
+ reference;
16
+ right;
17
+ db;
18
+ dbe;
19
+ dbev;
20
+ secured;
21
+ static networkNodeLength = 0;
22
+ static generalContractVM;
23
+ isDefault = false;
24
+ inputs;
25
+ outputs;
26
+ nodeResponse;
27
+ contractLocation;
28
+ contractId;
29
+ commiting = false;
30
+ voting = true;
31
+ storeSingleError = false;
32
+ errorOut = {
33
+ code: 0,
34
+ reason: "",
35
+ priority: 0,
36
+ };
37
+ broadcastTimeout;
38
+ currentTrueVotes;
39
+ securityCache;
40
+ shared;
41
+ permissionChecker;
42
+ willEmit;
43
+ willEmitData;
12
44
  constructor(entry, selfHost, reference, right, db, dbe, dbev, secured) {
13
45
  super();
14
46
  this.entry = entry;
@@ -19,18 +51,9 @@ export class Process extends EventEmitter {
19
51
  this.dbe = dbe;
20
52
  this.dbev = dbev;
21
53
  this.secured = secured;
22
- this.isDefault = false;
23
- this.checkRevs = true;
24
- this.commiting = false;
25
- this.voting = true;
26
- this.storeSingleError = false;
27
- this.errorOut = {
28
- code: 0,
29
- reason: "",
30
- priority: 0,
31
- };
32
54
  this.shared = new Shared(this.storeSingleError, this.entry, this.dbe, this);
33
55
  this.nodeResponse = entry.$nodes[reference];
56
+ Process.networkNodeLength = ActiveOptions.get("neighbourhood", []).length;
34
57
  try {
35
58
  if (!Process.generalContractVM) {
36
59
  Process.generalContractVM = new VirtualMachine(this.selfHost, this.secured, this.db, this.dbev);
@@ -40,23 +63,21 @@ export class Process extends EventEmitter {
40
63
  catch (error) {
41
64
  throw new Error(error);
42
65
  }
43
- if (!this.securityCache) {
44
- this.securityCache = ActiveOptions.get("security", null);
45
- }
46
- this.permissionChecker = new PermissionsChecker(this.entry, this.db, this.checkRevs, this.securityCache, this.shared);
66
+ this.securityCache = ActiveOptions.get("security", null);
67
+ this.permissionChecker = new PermissionsChecker(this.entry, this.db, this.securityCache, this.shared);
47
68
  }
48
69
  destroy(umid) {
49
- clearTimeout(this.broadcastTimeout);
50
- if (this.isDefault) {
51
- if (Process.defaultContractsVM)
52
- Process.defaultContractsVM.destroy(umid);
70
+ if (this.entry.$broadcast) {
71
+ clearTimeout(this.broadcastTimeout);
72
+ Process.generalContractVM.destroy(umid);
73
+ delete this.entry;
53
74
  }
54
75
  else {
55
- this.contractRef
56
- ? Process.singleContractVMHolder[this.contractRef].destroy(umid)
57
- : Process.generalContractVM.destroy(umid);
76
+ setTimeout(() => {
77
+ Process.generalContractVM.destroy(umid);
78
+ delete this.entry;
79
+ }, 60000);
58
80
  }
59
- delete this.entry;
60
81
  }
61
82
  sortVersions(a, b) {
62
83
  const padSorting = (v) => {
@@ -69,80 +90,98 @@ export class Process extends EventEmitter {
69
90
  };
70
91
  return padSorting(a).localeCompare(padSorting(b));
71
92
  }
72
- async start(contractVersion) {
73
- ActiveLogger.debug("New TX : " + this.entry.$umid);
74
- const setupDefaultLocation = () => {
93
+ static contractPathCache = {};
94
+ static clearContractPathCache(contractId) {
95
+ if (contractId) {
96
+ for (const key of Object.keys(Process.contractPathCache)) {
97
+ if (key === contractId || Process.contractPathCache[key].includes(contractId)) {
98
+ delete Process.contractPathCache[key];
99
+ }
100
+ }
101
+ }
102
+ else {
103
+ Process.contractPathCache = {};
104
+ }
105
+ }
106
+ async start(contractVersion, contractData) {
107
+ ActiveLogger.debug(`New TX : ${this.entry.$umid}`);
108
+ const setupDefaultLocation = async () => {
75
109
  this.isDefault = true;
76
- this.contractLocation = fs.realpathSync(`${process.cwd()}/default_contracts/${this.entry.$tx.$contract}.js`);
110
+ if (await fs.stat(`${process.cwd()}/default_contracts/_LOCK.${this.entry.$tx.$contract}`).catch(() => false)) {
111
+ throw new Error("Contract Global Lock");
112
+ }
113
+ this.contractLocation = await fs.realpath(`${process.cwd()}/default_contracts/${this.entry.$tx.$contract}.js`);
77
114
  };
78
- const setupLocation = () => {
79
- var _a;
115
+ const setupLocation = async () => {
80
116
  let contract = this.entry.$tx.$contract;
117
+ this.contractId = contract.split("@")[0];
81
118
  try {
82
- let contractId;
83
- let namespacePath;
84
- try {
85
- namespacePath = fs.realpathSync(`${process.cwd()}/contracts/${this.entry.$tx.$namespace}/`);
86
- const trueContractPath = fs.realpathSync(`${namespacePath}/${contract}.js`);
87
- contractId = path.basename(trueContractPath, path.extname(trueContractPath));
88
- if (contractId.indexOf("@") > -1) {
89
- contractId = contractId.split("@")[0];
119
+ if (!Process.contractPathCache[this.entry.$tx.$contract] ||
120
+ (contractVersion && !Process.contractPathCache[this.entry.$tx.$contract].endsWith(`${contractVersion}.js`))) {
121
+ let namespacePath = "";
122
+ try {
123
+ namespacePath = await fs.realpath(`${process.cwd()}/contracts/${this.entry.$tx.$namespace}/`);
124
+ }
125
+ catch {
126
+ throw new Error("Namespace not found");
90
127
  }
91
- }
92
- catch (_b) {
93
- throw new Error("Contract or Namespace not found");
94
- }
95
- this.contractId = contractId;
96
- if (this.entry.$tx.$contract.indexOf("@") === -1) {
97
128
  if (contractVersion) {
98
129
  contract = contractVersion;
99
130
  }
100
131
  else {
101
- try {
102
- contract =
103
- ((_a = fs
104
- .readdirSync(namespacePath)
105
- .filter((fn) => fn.includes(`${this.contractId}@`))
106
- .sort(this.sortVersions)
107
- .pop()) === null || _a === void 0 ? void 0 : _a.replace(".js", "")) || this.contractId;
108
- this.emit("contractLatestVersion", {
109
- contract: this.entry.$tx.$contract,
110
- file: contract,
111
- });
132
+ if (this.entry.$tx.$contract.indexOf("@=") !== -1) {
133
+ contract = this.entry.$tx.$contract.replace("@=", "@");
112
134
  }
113
- catch (_c) {
114
- throw new Error(`${this.contractId}@latest not found`);
135
+ else {
136
+ try {
137
+ contract = ((await fs
138
+ .readdir(namespacePath))
139
+ .filter((fn) => fn.includes(this.entry.$tx.$contract))
140
+ .sort(this.sortVersions)
141
+ .pop() || "notfound.404").replace(".js", "");
142
+ }
143
+ catch {
144
+ throw new Error("Contract not found");
145
+ }
115
146
  }
116
147
  }
148
+ if (!(await fs.stat(`${namespacePath}/${contract}.js`).catch(() => false))) {
149
+ throw new Error("Contract not found");
150
+ }
151
+ if (!contractVersion) {
152
+ this.emit("contractLatestVersion", {
153
+ contract: this.entry.$tx.$contract,
154
+ file: contract,
155
+ refresh: false,
156
+ });
157
+ }
158
+ if (await fs.stat(`${namespacePath}/_LOCK.${this.contractId}`).catch(() => false)) {
159
+ throw new Error("Contract Global Lock");
160
+ }
161
+ if (await fs.stat(`${namespacePath}/_LOCK.${contract}`).catch(() => false)) {
162
+ throw new Error(`Contract Version Lock ${contract.substring(contract.indexOf("@") + 1)}`);
163
+ }
164
+ Process.contractPathCache[this.entry.$tx.$contract] = await fs.realpath(`${namespacePath}/${contract}.js`);
117
165
  }
118
- if (fs.existsSync(`${namespacePath}/_LOCK.${this.contractId}`)) {
119
- throw new Error("Contract Global Lock");
120
- }
121
- if (fs.existsSync(`${namespacePath}/_LOCK.${contract}`)) {
122
- throw new Error(`Contract Version Lock ${contract.substring(contract.indexOf("@") + 1)}`);
123
- }
124
- this.contractLocation = fs.realpathSync(`${namespacePath}/${contract}.js`);
166
+ this.contractLocation =
167
+ Process.contractPathCache[this.entry.$tx.$contract];
125
168
  }
126
169
  catch (e) {
127
170
  throw e;
128
171
  }
129
172
  };
130
173
  try {
131
- this.entry.$tx.$namespace === "default"
174
+ await (this.entry.$tx.$namespace === "default"
132
175
  ? setupDefaultLocation()
133
- : setupLocation();
176
+ : setupLocation());
134
177
  }
135
178
  catch (error) {
136
- this.entry.$nodes[this.reference].error = `Init Contract Error - ${error.message}`;
179
+ this.entry.$nodes[this.reference].error = `Init Contract Error - ${error.message || error}`;
137
180
  this.emit("commited", { instant: true });
138
181
  return;
139
182
  }
140
- const virtualMachine = this.isDefault
141
- ? Process.defaultContractsVM
142
- : this.contractRef
143
- ? Process.singleContractVMHolder[this.contractRef]
144
- : Process.generalContractVM;
145
- if (fs.existsSync(this.contractLocation)) {
183
+ const virtualMachine = Process.generalContractVM;
184
+ if (await fs.stat(this.contractLocation).catch(() => false)) {
146
185
  this.inputs = Object.keys(this.entry.$tx.$i || {});
147
186
  if (this.inputs.length) {
148
187
  this.labelOrKey();
@@ -152,7 +191,6 @@ export class Process extends EventEmitter {
152
191
  this.labelOrKey(true);
153
192
  }
154
193
  if (!this.entry.$revs) {
155
- this.checkRevs = false;
156
194
  this.entry.$revs = {
157
195
  $i: {},
158
196
  $o: {},
@@ -162,28 +200,24 @@ export class Process extends EventEmitter {
162
200
  try {
163
201
  const inputStreams = await this.permissionChecker.process(this.inputs);
164
202
  const outputStreams = await this.permissionChecker.process(this.outputs, false);
165
- let contractData = undefined;
166
- if (!this.isDefault) {
167
- try {
168
- const contractDataStreams = await this.permissionChecker.process([`${this.contractId}:data`], false);
169
- if (contractDataStreams.length > 0) {
170
- contractData = contractDataStreams[0]
171
- .state;
172
- }
173
- }
174
- catch (e) {
175
- if (e.code === 1200) {
176
- throw e;
177
- }
178
- }
179
- }
180
- this.process(inputStreams, outputStreams, contractData);
203
+ this.process(inputStreams, outputStreams, await this.getContractDate(contractData));
181
204
  }
182
205
  catch (error) {
183
- this.postVote(virtualMachine, {
184
- code: error.code,
185
- reason: error.reason || error.message,
186
- });
206
+ const reason = error.reason || error.message || error;
207
+ if (this.entry.$unanimous &&
208
+ !this.entry.$broadcast &&
209
+ !this.entry.$spiRetry &&
210
+ (reason.indexOf("Position Incorrect") !== -1 ||
211
+ reason === "Stream(s) not found")) {
212
+ this.entry.$nodes[this.reference].error = reason;
213
+ this.emitFailed({ status: error.code || 1200, error: reason, entry: this.entry }, true);
214
+ }
215
+ else {
216
+ this.postVote(virtualMachine, {
217
+ code: error.code,
218
+ reason,
219
+ });
220
+ }
187
221
  }
188
222
  }
189
223
  else {
@@ -211,15 +245,29 @@ export class Process extends EventEmitter {
211
245
  }
212
246
  }
213
247
  }
248
+ else {
249
+ return this.shared.raiseLedgerError(1260, new Error("Self signed - Must have inputs"));
250
+ }
214
251
  try {
215
252
  const outputStreams = await this.permissionChecker.process(this.outputs, false);
216
- this.process([], outputStreams, undefined);
253
+ this.process([], outputStreams, await this.getContractDate(contractData));
217
254
  }
218
255
  catch (error) {
219
- this.postVote(virtualMachine, {
220
- code: error.code,
221
- reason: error.reason || error.message,
222
- });
256
+ const reason = error.reason || error.message || error;
257
+ if (this.entry.$unanimous &&
258
+ !this.entry.$broadcast &&
259
+ !this.entry.$spiRetry &&
260
+ (reason === "Stream(s) not found" ||
261
+ reason.indexOf("Position Incorrect") !== -1)) {
262
+ this.entry.$nodes[this.reference].error = reason;
263
+ this.emitFailed({ status: error.code || 1200, error: reason, entry: this.entry }, true);
264
+ }
265
+ else {
266
+ this.postVote(virtualMachine, {
267
+ code: error.code,
268
+ reason,
269
+ });
270
+ }
223
271
  }
224
272
  }
225
273
  }
@@ -234,10 +282,13 @@ export class Process extends EventEmitter {
234
282
  if (this.isCommiting()) {
235
283
  return;
236
284
  }
285
+ if (node[this.reference]) {
286
+ delete node[this.reference];
287
+ }
237
288
  this.entry.$nodes = Object.assign(this.entry.$nodes, node);
238
289
  if (this.willEmit) {
239
290
  const nodes = Object.keys(this.entry.$nodes);
240
- if (!this.hasOutstandingVotes(nodes.length) && !this.canCommit()) {
291
+ if (!(this.hasOutstandingVotes()) && !this.canCommit()) {
241
292
  this.emitFailed(this.willEmitData);
242
293
  }
243
294
  else {
@@ -251,42 +302,62 @@ export class Process extends EventEmitter {
251
302
  }
252
303
  else {
253
304
  if (!this.isCommiting() && !this.voting) {
254
- this.nodeResponse = this.entry.$nodes[this.reference];
255
- this.isDefault
256
- ? this.commit(Process.defaultContractsVM)
257
- : this.contractRef
258
- ? this.commit(Process.singleContractVMHolder[this.contractRef])
259
- : this.commit(Process.generalContractVM);
305
+ this.commit(Process.generalContractVM);
260
306
  }
261
307
  }
262
308
  }
263
309
  isCommiting() {
264
310
  return this.commiting;
265
311
  }
266
- processDefaultContracts(payload, contractName) {
267
- if (!Process.defaultContractsVM) {
268
- try {
269
- Process.defaultContractsVM = new VirtualMachine(this.selfHost, this.secured, this.db, this.dbev);
270
- Process.defaultContractsVM.initialiseVirtualMachine(["fs", "path", "os", "crypto"], ["typescript"]);
312
+ async getContractDate(contractData) {
313
+ if (!contractData && !this.isDefault) {
314
+ if (await this.db.exists(`${this.contractId}:data`)) {
315
+ try {
316
+ const contractDataStreams = await this.permissionChecker.process([`${this.contractId}:data`], false, 5);
317
+ if (contractDataStreams.length > 0) {
318
+ contractData = contractDataStreams[0]
319
+ .state;
320
+ }
321
+ }
322
+ catch (e) {
323
+ if (e.code === 1200) {
324
+ this.emit("contractData", {
325
+ contract: this.contractId,
326
+ data: {},
327
+ });
328
+ throw e;
329
+ }
330
+ }
271
331
  }
272
- catch (error) {
273
- throw new Error(error);
332
+ else {
333
+ contractData = { _id: "", data: {} };
274
334
  }
335
+ this.emit("contractData", {
336
+ contract: this.contractId,
337
+ data: contractData,
338
+ });
275
339
  }
276
- this.handleVM(Process.defaultContractsVM, payload, contractName);
277
- }
278
- processUnsafeContracts(payload, namespace, contractName, extraBuiltins, extraExternals, extraMocks) {
279
- this.contractRef = namespace;
280
- if (!Process.singleContractVMHolder[this.contractRef]) {
281
- try {
282
- Process.singleContractVMHolder[this.contractRef] = new VirtualMachine(this.selfHost, this.secured, this.db, this.dbev);
283
- Process.singleContractVMHolder[this.contractRef].initialiseVirtualMachine(extraBuiltins, extraExternals, extraMocks);
284
- }
285
- catch (error) {
286
- throw new Error(error);
340
+ else {
341
+ if (contractData && this.contractId) {
342
+ const rev = `0-context:${contractData._rev}`;
343
+ if (this.entry.$revs.$o[`${this.contractId}:data`]) {
344
+ if (this.entry.$revs.$o[`${this.contractId}:data`] !== rev) {
345
+ this.emit("contractData", {
346
+ contract: this.contractId,
347
+ data: {},
348
+ });
349
+ throw {
350
+ code: 1200,
351
+ reason: "Output Stream Position Incorrect",
352
+ };
353
+ }
354
+ }
355
+ else {
356
+ this.entry.$revs.$o[`${this.contractId}:data`] = rev;
357
+ }
287
358
  }
288
359
  }
289
- this.handleVM(Process.singleContractVMHolder[this.contractRef], payload, contractName);
360
+ return contractData;
290
361
  }
291
362
  async handleVM(virtualMachine, payload, contractName) {
292
363
  const handleVoteError = async (error) => {
@@ -294,7 +365,7 @@ export class Process extends EventEmitter {
294
365
  ActiveLogger.debug(this.nodeResponse.error, `Handle Vote Error ${payload.umid}`);
295
366
  ActiveLogger.debug(`Calling Contract Return Data - ${payload.umid}`);
296
367
  this.nodeResponse.return = virtualMachine.getReturnContractData(this.entry.$umid);
297
- this.postVote(virtualMachine);
368
+ this.postVote(virtualMachine, this.nodeResponse.error);
298
369
  };
299
370
  let continueProcessing = true;
300
371
  try {
@@ -320,7 +391,7 @@ export class Process extends EventEmitter {
320
391
  if (continueProcessing)
321
392
  ActiveLogger.debug(`Calling Contract Vote - ${payload.umid}`);
322
393
  const vote = await virtualMachine.vote(this.entry.$nodes, payload.umid);
323
- if (typeof (vote) !== 'boolean' && vote.leader) {
394
+ if (typeof vote !== "boolean" && vote.leader) {
324
395
  this.nodeResponse.vote = this.nodeResponse.leader = true;
325
396
  this.commit(virtualMachine);
326
397
  return;
@@ -332,6 +403,7 @@ export class Process extends EventEmitter {
332
403
  }
333
404
  if (continueProcessing) {
334
405
  this.nodeResponse.vote = true;
406
+ this.nodeResponse.early = false;
335
407
  ActiveLogger.debug(`Calling Contract INC - ${payload.umid}`);
336
408
  this.nodeResponse.incomms = virtualMachine.getInternodeCommsFromVM(payload.umid);
337
409
  ActiveLogger.debug(`Calling Contract Return Data - ${payload.umid}`);
@@ -347,6 +419,7 @@ export class Process extends EventEmitter {
347
419
  }
348
420
  catch (error) {
349
421
  this.nodeResponse.error = "Read Error - " + JSON.stringify(error);
422
+ this.nodeResponse.early = false;
350
423
  }
351
424
  this.nodeResponse.commit = true;
352
425
  this.emit("commited");
@@ -354,8 +427,10 @@ export class Process extends EventEmitter {
354
427
  }
355
428
  async process(inputs, outputs = [], contractData = undefined) {
356
429
  try {
357
- if (this.entry.$broadcast) {
358
- this.emit("broadcast", true);
430
+ if (this.entry.$broadcast && !this.entry.$wait) {
431
+ if (this.entry.$origin === this.reference) {
432
+ this.emit("broadcast", true);
433
+ }
359
434
  }
360
435
  const readonly = await this.getReadOnlyStreams();
361
436
  const contractName = this.contractLocation.substring(this.contractLocation.lastIndexOf("/") + 1);
@@ -379,46 +454,10 @@ export class Process extends EventEmitter {
379
454
  inputs,
380
455
  outputs,
381
456
  readonly,
382
- key: Math.floor(Math.random() * 100),
383
- contractData,
457
+ key: 0,
458
+ contractData: contractData ? contractData : { _id: "", data: {} },
384
459
  };
385
- if (!this.securityCache) {
386
- this.securityCache = ActiveOptions.get("security", null);
387
- }
388
- if (payload.transaction.$namespace === "default") {
389
- this.processDefaultContracts(payload, contractName);
390
- }
391
- else {
392
- if (this.securityCache &&
393
- this.securityCache.namespace &&
394
- this.securityCache.namespace[payload.transaction.$namespace]) {
395
- const builtin = [];
396
- const external = [];
397
- const mocks = [];
398
- const namespaceExtras = this.securityCache.namespace[payload.transaction.$namespace];
399
- if (namespaceExtras) {
400
- if (namespaceExtras.std) {
401
- namespaceExtras.std.forEach((item) => {
402
- builtin.push(item);
403
- });
404
- }
405
- if (namespaceExtras.external) {
406
- namespaceExtras.external.forEach((item) => {
407
- external.push(item);
408
- });
409
- }
410
- if (namespaceExtras.mock) {
411
- namespaceExtras.mock.forEach((item) => {
412
- mocks.push(item);
413
- });
414
- }
415
- }
416
- this.processUnsafeContracts(payload, payload.transaction.$namespace, contractName, builtin, external, mocks);
417
- }
418
- else {
419
- this.handleVM(Process.generalContractVM, payload, contractName);
420
- }
421
- }
460
+ this.handleVM(Process.generalContractVM, payload, contractName);
422
461
  }
423
462
  catch (error) {
424
463
  this.shared.raiseLedgerError(1210, new Error("Read Only Stream Error"));
@@ -427,6 +466,8 @@ export class Process extends EventEmitter {
427
466
  }
428
467
  postVote(virtualMachine, error = false) {
429
468
  this.voting = false;
469
+ this.nodeResponse.early = false;
470
+ delete this.nodeResponse.early;
430
471
  if (!this.entry) {
431
472
  ActiveLogger.debug(`postVote entry is missing?`);
432
473
  return;
@@ -437,25 +478,32 @@ export class Process extends EventEmitter {
437
478
  }
438
479
  if (this.entry.$broadcast) {
439
480
  if (error) {
440
- this.entry.$nodes[this.reference].error = error.reason;
481
+ this.entry.$nodes[this.reference].error = error.reason
482
+ ? error.reason
483
+ : error;
484
+ if (error.code === 950) {
485
+ this.shared.raiseLedgerError(error.code, error.reason);
486
+ }
441
487
  }
442
- this.emit("broadcast");
443
- if (this.canCommit()) {
444
- this.commit(virtualMachine);
488
+ if (!this.nodeResponse.leader) {
489
+ this.emit("broadcast");
445
490
  }
491
+ this.commit(virtualMachine);
446
492
  }
447
493
  else {
448
494
  if (this.right.reference != this.entry.$origin) {
449
- ActiveLogger.debug("Attempting commit with too early commit callback (to send right");
495
+ ActiveLogger.debug("Attempting commit with too early commit callback (to send right)");
450
496
  this.commit(virtualMachine, async () => {
451
497
  try {
452
498
  const response = await this.initRightKnock();
453
499
  if (!this.nodeResponse.commit) {
454
- this.entry.$territoriality = response.data.$territoriality;
455
- this.entry.$nodes = response.data.$nodes;
500
+ const data = response.data;
501
+ this.entry.$territoriality =
502
+ data.$territoriality ?? this.entry.$territoriality;
503
+ this.entry.$nodes = data.$nodes ?? this.entry.$nodes;
456
504
  this.nodeResponse = this.entry.$nodes[this.reference];
457
505
  if (error) {
458
- this.shared.raiseLedgerError(error.code, error.reason, true, 10);
506
+ this.shared.raiseLedgerError(error.code || 1000, error.reason || error, true, 10);
459
507
  }
460
508
  ActiveLogger.debug("Sending Commit without callback");
461
509
  this.commit(virtualMachine);
@@ -472,15 +520,16 @@ export class Process extends EventEmitter {
472
520
  else {
473
521
  ActiveLogger.debug("Origin is next (Sending Back)");
474
522
  error
475
- ? this.shared.raiseLedgerError(error.code, error.reason)
523
+ ? this.shared.raiseLedgerError(error.code || 1000, error.reason || error)
476
524
  : this.commit(virtualMachine);
477
525
  }
478
526
  }
479
527
  }
480
- emitFailed(data) {
481
- if (this.willEmit) {
528
+ emitFailed(data, noWait) {
529
+ this.commiting = false;
530
+ if (this.willEmit || noWait) {
482
531
  clearTimeout(this.willEmit);
483
- this.emit("failed", this.willEmitData);
532
+ this.emit("failed", this.willEmitData || data);
484
533
  }
485
534
  else {
486
535
  if (this.entry &&
@@ -496,14 +545,23 @@ export class Process extends EventEmitter {
496
545
  }
497
546
  }
498
547
  }
499
- hasOutstandingVotes(nodes) {
500
- const neighbours = ActiveOptions.get("neighbourhood", []).length;
501
- return !!(neighbours - (nodes || Object.keys(this.entry.$nodes).length));
548
+ hasOutstandingVotes() {
549
+ return !!(Process.networkNodeLength - this.countOutstandingVotes());
550
+ }
551
+ countOutstandingVotes() {
552
+ const nodes = Object.keys(this.entry.$nodes);
553
+ let votedNodes = 0;
554
+ for (let i = nodes.length; i--;) {
555
+ if (!this.entry.$nodes[nodes[i]].early) {
556
+ votedNodes++;
557
+ }
558
+ }
559
+ return votedNodes;
502
560
  }
503
561
  async initRightKnock(retries = 0) {
504
562
  try {
505
563
  ActiveLogger.debug(`Sending -> ${this.right.reference} - ${this.entry.$umid}`);
506
- return await this.right.knock("init", this.entry);
564
+ return await this.right.knock("init-legacy", this.entry);
507
565
  }
508
566
  catch (e) {
509
567
  if (retries <= 2) {
@@ -521,22 +579,27 @@ export class Process extends EventEmitter {
521
579
  }
522
580
  canCommit() {
523
581
  let networkNodes = Object.keys(this.entry.$nodes);
524
- this.currentVotes = 0;
525
- for (let i = networkNodes.length; i--;) {
526
- if (this.entry.$nodes[networkNodes[i]].vote)
527
- this.currentVotes++;
528
- }
529
- const percent = this.entry.$unanimous
530
- ? 100
531
- : ActiveOptions.get("consensus", {}).reached;
532
- return ((this.currentVotes /
533
- ActiveOptions.get("neighbourhood", []).length) *
534
- 100 >=
535
- percent || false);
582
+ this.currentTrueVotes = 0;
583
+ if (networkNodes) {
584
+ for (let i = networkNodes.length; i--;) {
585
+ if (!this.entry.$nodes[networkNodes[i]].early &&
586
+ this.entry.$nodes[networkNodes[i]].vote)
587
+ this.currentTrueVotes++;
588
+ }
589
+ const percent = this.entry.$unanimous
590
+ ? 100
591
+ : ActiveOptions.get("consensus", {}).reached;
592
+ const reached = (this.currentTrueVotes / Process.networkNodeLength) * 100 >= percent;
593
+ return reached;
594
+ }
595
+ else {
596
+ return false;
597
+ }
536
598
  }
537
599
  async commit(virtualMachine, earlyCommit) {
538
600
  if (!this.nodeResponse.commit && !this.isCommiting()) {
539
- if (this.nodeResponse.vote && (this.nodeResponse.leader || this.canCommit())) {
601
+ if (this.nodeResponse.vote &&
602
+ (this.nodeResponse.leader || this.canCommit())) {
540
603
  this.commiting = true;
541
604
  clearTimeout(this.broadcastTimeout);
542
605
  try {
@@ -547,15 +610,8 @@ export class Process extends EventEmitter {
547
610
  this.nodeResponse.incomms = virtualMachine.getInternodeCommsFromVM(this.entry.$umid);
548
611
  ActiveLogger.debug(`Calling Contract Return Data X2 - ${this.entry.$umid}`);
549
612
  this.nodeResponse.return = virtualMachine.getReturnContractData(this.entry.$umid);
550
- this.entry = this.shared.clearAllComms(virtualMachine, this.nodeResponse.incomms);
551
- let throws = virtualMachine.getThrowsFromVM(this.entry.$umid);
552
- if (throws && throws.length) {
553
- this.emit("throw", { locations: throws });
554
- }
555
613
  const streamUpdater = new StreamUpdater(this.entry, virtualMachine, this.reference, this.nodeResponse, this.db, this.dbev, this, this.shared, this.contractId);
556
- earlyCommit
557
- ? streamUpdater.updateStreams(earlyCommit)
558
- : streamUpdater.updateStreams();
614
+ await streamUpdater.updateStreams(earlyCommit);
559
615
  }
560
616
  catch (error) {
561
617
  if (earlyCommit)
@@ -580,7 +636,7 @@ export class Process extends EventEmitter {
580
636
  if (reconciled) {
581
637
  ActiveLogger.info("Self Reconcile Successful");
582
638
  const streamUpdater = new StreamUpdater(this.entry, virtualMachine, this.reference, this.nodeResponse, this.db, this.dbev, this, this.shared, this.contractId);
583
- streamUpdater.updateStreams();
639
+ await streamUpdater.updateStreams();
584
640
  }
585
641
  else {
586
642
  if (this.errorOut.code === 1505) {
@@ -612,9 +668,8 @@ export class Process extends EventEmitter {
612
668
  this.shared.raiseLedgerError(1510, new Error("Failed Network Voting Round - Non Broadcast"));
613
669
  }
614
670
  else {
615
- const neighbours = ActiveOptions.get("neighbourhood", []).length;
616
671
  const consensusNeeded = ActiveOptions.get("consensus", {}).reached;
617
- const outstandingVoters = neighbours - Object.keys(this.entry.$nodes).length;
672
+ const outstandingVoters = Process.networkNodeLength - this.countOutstandingVotes();
618
673
  if (!outstandingVoters) {
619
674
  clearTimeout(this.broadcastTimeout);
620
675
  if (this.nodeResponse.error) {
@@ -631,12 +686,17 @@ export class Process extends EventEmitter {
631
686
  }
632
687
  else {
633
688
  clearTimeout(this.broadcastTimeout);
634
- if (((this.currentVotes + outstandingVoters) / neighbours) * 100 >=
689
+ if (((this.currentTrueVotes + outstandingVoters) / Process.networkNodeLength) *
690
+ 100 >=
635
691
  consensusNeeded) {
636
692
  this.broadcastTimeout = setTimeout(() => {
637
- ActiveLogger.debug("VM Commit Failure, NETWORK Timeout");
638
- return this.shared.raiseLedgerError(1510, new Error("Failed Network Voting Timeout - Voters Timed Out"));
639
- }, BROADCAST_TIMEOUT);
693
+ if (!this.isCommiting()) {
694
+ ActiveLogger.debug("VM Commit Failure, NETWORK Timeout");
695
+ return this.shared.raiseLedgerError(1510, new Error("Failed Network Voting Timeout - Voters Timed Out"));
696
+ }
697
+ }, this.isCommiting()
698
+ ? BROADCAST_TIMEOUT_COMMIT
699
+ : this.currentTrueVotes === 0 ? BROADCAST_TIMEOUT_EARLY : BROADCAST_TIMEOUT_VOTE);
640
700
  }
641
701
  else {
642
702
  if (this.nodeResponse.error) {
@@ -704,9 +764,11 @@ export class Process extends EventEmitter {
704
764
  let streamId = txIO[streams[i]].$stream || streams[i];
705
765
  map[streamId] = streams[i];
706
766
  streams[i] = streamId;
767
+ if (!outputs && txIO[map[streamId]].$sigOnly) {
768
+ this.shared.sigOnly[streams[i]] = true;
769
+ }
707
770
  }
708
771
  }
709
772
  }
710
773
  }
711
- Process.singleContractVMHolder = {};
712
774
  //# sourceMappingURL=process.js.map