@activeledger/activeprotocol 2.15.7 → 4.3.3

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