@activeledger/activeprotocol 2.15.6 → 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 +9 -5
  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 +281 -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 -138
  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 +9 -5
  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 +281 -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 -137
  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 {
@@ -348,7 +393,12 @@ class Process extends events_1.EventEmitter {
348
393
  try {
349
394
  if (continueProcessing)
350
395
  activelogger_1.ActiveLogger.debug(`Calling Contract Vote - ${payload.umid}`);
351
- await virtualMachine.vote(this.entry.$nodes, payload.umid);
396
+ const vote = await virtualMachine.vote(this.entry.$nodes, payload.umid);
397
+ if (typeof vote !== "boolean" && vote.leader) {
398
+ this.nodeResponse.vote = this.nodeResponse.leader = true;
399
+ this.commit(virtualMachine);
400
+ return;
401
+ }
352
402
  }
353
403
  catch (error) {
354
404
  handleVoteError(error);
@@ -356,6 +406,7 @@ class Process extends events_1.EventEmitter {
356
406
  }
357
407
  if (continueProcessing) {
358
408
  this.nodeResponse.vote = true;
409
+ this.nodeResponse.early = false;
359
410
  activelogger_1.ActiveLogger.debug(`Calling Contract INC - ${payload.umid}`);
360
411
  this.nodeResponse.incomms = virtualMachine.getInternodeCommsFromVM(payload.umid);
361
412
  activelogger_1.ActiveLogger.debug(`Calling Contract Return Data - ${payload.umid}`);
@@ -371,6 +422,7 @@ class Process extends events_1.EventEmitter {
371
422
  }
372
423
  catch (error) {
373
424
  this.nodeResponse.error = "Read Error - " + JSON.stringify(error);
425
+ this.nodeResponse.early = false;
374
426
  }
375
427
  this.nodeResponse.commit = true;
376
428
  this.emit("commited");
@@ -378,8 +430,10 @@ class Process extends events_1.EventEmitter {
378
430
  }
379
431
  async process(inputs, outputs = [], contractData = undefined) {
380
432
  try {
381
- if (this.entry.$broadcast) {
382
- 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
+ }
383
437
  }
384
438
  const readonly = await this.getReadOnlyStreams();
385
439
  const contractName = this.contractLocation.substring(this.contractLocation.lastIndexOf("/") + 1);
@@ -403,46 +457,10 @@ class Process extends events_1.EventEmitter {
403
457
  inputs,
404
458
  outputs,
405
459
  readonly,
406
- key: Math.floor(Math.random() * 100),
407
- contractData,
460
+ key: 0,
461
+ contractData: contractData ? contractData : { _id: "", data: {} },
408
462
  };
409
- if (!this.securityCache) {
410
- this.securityCache = activeoptions_1.ActiveOptions.get("security", null);
411
- }
412
- if (payload.transaction.$namespace === "default") {
413
- this.processDefaultContracts(payload, contractName);
414
- }
415
- else {
416
- if (this.securityCache &&
417
- this.securityCache.namespace &&
418
- this.securityCache.namespace[payload.transaction.$namespace]) {
419
- const builtin = [];
420
- const external = [];
421
- const mocks = [];
422
- const namespaceExtras = this.securityCache.namespace[payload.transaction.$namespace];
423
- if (namespaceExtras) {
424
- if (namespaceExtras.std) {
425
- namespaceExtras.std.forEach((item) => {
426
- builtin.push(item);
427
- });
428
- }
429
- if (namespaceExtras.external) {
430
- namespaceExtras.external.forEach((item) => {
431
- external.push(item);
432
- });
433
- }
434
- if (namespaceExtras.mock) {
435
- namespaceExtras.mock.forEach((item) => {
436
- mocks.push(item);
437
- });
438
- }
439
- }
440
- this.processUnsafeContracts(payload, payload.transaction.$namespace, contractName, builtin, external, mocks);
441
- }
442
- else {
443
- this.handleVM(Process.generalContractVM, payload, contractName);
444
- }
445
- }
463
+ this.handleVM(Process.generalContractVM, payload, contractName);
446
464
  }
447
465
  catch (error) {
448
466
  this.shared.raiseLedgerError(1210, new Error("Read Only Stream Error"));
@@ -451,6 +469,8 @@ class Process extends events_1.EventEmitter {
451
469
  }
452
470
  postVote(virtualMachine, error = false) {
453
471
  this.voting = false;
472
+ this.nodeResponse.early = false;
473
+ delete this.nodeResponse.early;
454
474
  if (!this.entry) {
455
475
  activelogger_1.ActiveLogger.debug(`postVote entry is missing?`);
456
476
  return;
@@ -461,25 +481,32 @@ class Process extends events_1.EventEmitter {
461
481
  }
462
482
  if (this.entry.$broadcast) {
463
483
  if (error) {
464
- 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
+ }
465
490
  }
466
- this.emit("broadcast");
467
- if (this.canCommit()) {
468
- this.commit(virtualMachine);
491
+ if (!this.nodeResponse.leader) {
492
+ this.emit("broadcast");
469
493
  }
494
+ this.commit(virtualMachine);
470
495
  }
471
496
  else {
472
497
  if (this.right.reference != this.entry.$origin) {
473
- 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)");
474
499
  this.commit(virtualMachine, async () => {
475
500
  try {
476
501
  const response = await this.initRightKnock();
477
502
  if (!this.nodeResponse.commit) {
478
- this.entry.$territoriality = response.data.$territoriality;
479
- 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;
480
507
  this.nodeResponse = this.entry.$nodes[this.reference];
481
508
  if (error) {
482
- this.shared.raiseLedgerError(error.code, error.reason, true, 10);
509
+ this.shared.raiseLedgerError(error.code || 1000, error.reason || error, true, 10);
483
510
  }
484
511
  activelogger_1.ActiveLogger.debug("Sending Commit without callback");
485
512
  this.commit(virtualMachine);
@@ -496,15 +523,16 @@ class Process extends events_1.EventEmitter {
496
523
  else {
497
524
  activelogger_1.ActiveLogger.debug("Origin is next (Sending Back)");
498
525
  error
499
- ? this.shared.raiseLedgerError(error.code, error.reason)
526
+ ? this.shared.raiseLedgerError(error.code || 1000, error.reason || error)
500
527
  : this.commit(virtualMachine);
501
528
  }
502
529
  }
503
530
  }
504
- emitFailed(data) {
505
- if (this.willEmit) {
531
+ emitFailed(data, noWait) {
532
+ this.commiting = false;
533
+ if (this.willEmit || noWait) {
506
534
  clearTimeout(this.willEmit);
507
- this.emit("failed", this.willEmitData);
535
+ this.emit("failed", this.willEmitData || data);
508
536
  }
509
537
  else {
510
538
  if (this.entry &&
@@ -520,14 +548,23 @@ class Process extends events_1.EventEmitter {
520
548
  }
521
549
  }
522
550
  }
523
- hasOutstandingVotes(nodes) {
524
- const neighbours = activeoptions_1.ActiveOptions.get("neighbourhood", []).length;
525
- 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;
526
563
  }
527
564
  async initRightKnock(retries = 0) {
528
565
  try {
529
566
  activelogger_1.ActiveLogger.debug(`Sending -> ${this.right.reference} - ${this.entry.$umid}`);
530
- return await this.right.knock("init", this.entry);
567
+ return await this.right.knock("init-legacy", this.entry);
531
568
  }
532
569
  catch (e) {
533
570
  if (retries <= 2) {
@@ -545,22 +582,27 @@ class Process extends events_1.EventEmitter {
545
582
  }
546
583
  canCommit() {
547
584
  let networkNodes = Object.keys(this.entry.$nodes);
548
- this.currentVotes = 0;
549
- for (let i = networkNodes.length; i--;) {
550
- if (this.entry.$nodes[networkNodes[i]].vote)
551
- this.currentVotes++;
552
- }
553
- const percent = this.entry.$unanimous
554
- ? 100
555
- : activeoptions_1.ActiveOptions.get("consensus", {}).reached;
556
- return ((this.currentVotes /
557
- activeoptions_1.ActiveOptions.get("neighbourhood", []).length) *
558
- 100 >=
559
- 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
+ }
560
601
  }
561
602
  async commit(virtualMachine, earlyCommit) {
562
603
  if (!this.nodeResponse.commit && !this.isCommiting()) {
563
- if (this.canCommit() && this.nodeResponse.vote) {
604
+ if (this.nodeResponse.vote &&
605
+ (this.nodeResponse.leader || this.canCommit())) {
564
606
  this.commiting = true;
565
607
  clearTimeout(this.broadcastTimeout);
566
608
  try {
@@ -571,15 +613,8 @@ class Process extends events_1.EventEmitter {
571
613
  this.nodeResponse.incomms = virtualMachine.getInternodeCommsFromVM(this.entry.$umid);
572
614
  activelogger_1.ActiveLogger.debug(`Calling Contract Return Data X2 - ${this.entry.$umid}`);
573
615
  this.nodeResponse.return = virtualMachine.getReturnContractData(this.entry.$umid);
574
- this.entry = this.shared.clearAllComms(virtualMachine, this.nodeResponse.incomms);
575
- let throws = virtualMachine.getThrowsFromVM(this.entry.$umid);
576
- if (throws && throws.length) {
577
- this.emit("throw", { locations: throws });
578
- }
579
616
  const streamUpdater = new streamUpdater_1.StreamUpdater(this.entry, virtualMachine, this.reference, this.nodeResponse, this.db, this.dbev, this, this.shared, this.contractId);
580
- earlyCommit
581
- ? streamUpdater.updateStreams(earlyCommit)
582
- : streamUpdater.updateStreams();
617
+ await streamUpdater.updateStreams(earlyCommit);
583
618
  }
584
619
  catch (error) {
585
620
  if (earlyCommit)
@@ -604,7 +639,7 @@ class Process extends events_1.EventEmitter {
604
639
  if (reconciled) {
605
640
  activelogger_1.ActiveLogger.info("Self Reconcile Successful");
606
641
  const streamUpdater = new streamUpdater_1.StreamUpdater(this.entry, virtualMachine, this.reference, this.nodeResponse, this.db, this.dbev, this, this.shared, this.contractId);
607
- streamUpdater.updateStreams();
642
+ await streamUpdater.updateStreams();
608
643
  }
609
644
  else {
610
645
  if (this.errorOut.code === 1505) {
@@ -636,9 +671,8 @@ class Process extends events_1.EventEmitter {
636
671
  this.shared.raiseLedgerError(1510, new Error("Failed Network Voting Round - Non Broadcast"));
637
672
  }
638
673
  else {
639
- const neighbours = activeoptions_1.ActiveOptions.get("neighbourhood", []).length;
640
674
  const consensusNeeded = activeoptions_1.ActiveOptions.get("consensus", {}).reached;
641
- const outstandingVoters = neighbours - Object.keys(this.entry.$nodes).length;
675
+ const outstandingVoters = Process.networkNodeLength - this.countOutstandingVotes();
642
676
  if (!outstandingVoters) {
643
677
  clearTimeout(this.broadcastTimeout);
644
678
  if (this.nodeResponse.error) {
@@ -655,12 +689,17 @@ class Process extends events_1.EventEmitter {
655
689
  }
656
690
  else {
657
691
  clearTimeout(this.broadcastTimeout);
658
- if (((this.currentVotes + outstandingVoters) / neighbours) * 100 >=
692
+ if (((this.currentTrueVotes + outstandingVoters) / Process.networkNodeLength) *
693
+ 100 >=
659
694
  consensusNeeded) {
660
695
  this.broadcastTimeout = setTimeout(() => {
661
- activelogger_1.ActiveLogger.debug("VM Commit Failure, NETWORK Timeout");
662
- return this.shared.raiseLedgerError(1510, new Error("Failed Network Voting Timeout - Voters Timed Out"));
663
- }, 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);
664
703
  }
665
704
  else {
666
705
  if (this.nodeResponse.error) {
@@ -728,10 +767,12 @@ class Process extends events_1.EventEmitter {
728
767
  let streamId = txIO[streams[i]].$stream || streams[i];
729
768
  map[streamId] = streams[i];
730
769
  streams[i] = streamId;
770
+ if (!outputs && txIO[map[streamId]].$sigOnly) {
771
+ this.shared.sigOnly[streams[i]] = true;
772
+ }
731
773
  }
732
774
  }
733
775
  }
734
776
  }
735
777
  exports.Process = Process;
736
- Process.singleContractVMHolder = {};
737
778
  //# sourceMappingURL=process.js.map