@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.
- package/es/protocol/interfaces/vm.interface.d.ts +6 -4
- package/es/protocol/interfaces/vm.interface.d.ts.map +1 -1
- package/es/protocol/permissionsChecker.d.ts +5 -3
- package/es/protocol/permissionsChecker.d.ts.map +1 -1
- package/es/protocol/permissionsChecker.js +149 -120
- package/es/protocol/permissionsChecker.js.map +1 -1
- package/es/protocol/process.d.ts +10 -9
- package/es/protocol/process.d.ts.map +1 -1
- package/es/protocol/process.js +276 -214
- package/es/protocol/process.js.map +1 -1
- package/es/protocol/shared.d.ts +6 -2
- package/es/protocol/shared.d.ts.map +1 -1
- package/es/protocol/shared.js +41 -29
- package/es/protocol/shared.js.map +1 -1
- package/es/protocol/streamUpdater.d.ts +1 -6
- package/es/protocol/streamUpdater.d.ts.map +1 -1
- package/es/protocol/streamUpdater.js +80 -109
- package/es/protocol/streamUpdater.js.map +1 -1
- package/es/protocol/vm.d.ts +12 -5
- package/es/protocol/vm.d.ts.map +1 -1
- package/es/protocol/vm.js +212 -137
- package/es/protocol/vm.js.map +1 -1
- package/es/protocol/vmscript.js +23 -10
- package/es/protocol/vmscript.js.map +1 -1
- package/lib/protocol/interfaces/vm.interface.d.ts +6 -4
- package/lib/protocol/interfaces/vm.interface.d.ts.map +1 -1
- package/lib/protocol/permissionsChecker.d.ts +5 -3
- package/lib/protocol/permissionsChecker.d.ts.map +1 -1
- package/lib/protocol/permissionsChecker.js +149 -120
- package/lib/protocol/permissionsChecker.js.map +1 -1
- package/lib/protocol/process.d.ts +10 -9
- package/lib/protocol/process.d.ts.map +1 -1
- package/lib/protocol/process.js +276 -240
- package/lib/protocol/process.js.map +1 -1
- package/lib/protocol/shared.d.ts +6 -2
- package/lib/protocol/shared.d.ts.map +1 -1
- package/lib/protocol/shared.js +41 -29
- package/lib/protocol/shared.js.map +1 -1
- package/lib/protocol/streamUpdater.d.ts +1 -6
- package/lib/protocol/streamUpdater.d.ts.map +1 -1
- package/lib/protocol/streamUpdater.js +80 -109
- package/lib/protocol/streamUpdater.js.map +1 -1
- package/lib/protocol/vm.d.ts +12 -5
- package/lib/protocol/vm.d.ts.map +1 -1
- package/lib/protocol/vm.js +211 -136
- package/lib/protocol/vm.js.map +1 -1
- package/lib/protocol/vmscript.js +23 -9
- package/lib/protocol/vmscript.js.map +1 -1
- package/package.json +9 -9
package/lib/protocol/process.js
CHANGED
|
@@ -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
|
|
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
|
|
39
|
-
const
|
|
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
|
-
|
|
73
|
-
|
|
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
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
73
|
+
if (this.entry.$broadcast) {
|
|
74
|
+
clearTimeout(this.broadcastTimeout);
|
|
75
|
+
Process.generalContractVM.destroy(umid);
|
|
76
|
+
delete this.entry;
|
|
82
77
|
}
|
|
83
78
|
else {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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
|
-
|
|
102
|
-
|
|
103
|
-
|
|
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
|
-
|
|
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
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
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
|
-
|
|
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
|
-
|
|
143
|
-
|
|
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
|
-
|
|
148
|
-
|
|
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 =
|
|
170
|
-
|
|
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
|
-
|
|
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
|
-
|
|
213
|
-
|
|
214
|
-
|
|
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,
|
|
256
|
+
this.process([], outputStreams, await this.getContractDate(contractData));
|
|
246
257
|
}
|
|
247
258
|
catch (error) {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
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(
|
|
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.
|
|
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
|
-
|
|
296
|
-
if (!
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
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
|
-
|
|
302
|
-
|
|
335
|
+
else {
|
|
336
|
+
contractData = { _id: "", data: {} };
|
|
303
337
|
}
|
|
338
|
+
this.emit("contractData", {
|
|
339
|
+
contract: this.contractId,
|
|
340
|
+
data: contractData,
|
|
341
|
+
});
|
|
304
342
|
}
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
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
|
-
|
|
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
|
|
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.
|
|
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:
|
|
412
|
-
contractData,
|
|
460
|
+
key: 0,
|
|
461
|
+
contractData: contractData ? contractData : { _id: "", data: {} },
|
|
413
462
|
};
|
|
414
|
-
|
|
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.
|
|
472
|
-
|
|
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
|
-
|
|
484
|
-
this.entry.$
|
|
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
|
-
|
|
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(
|
|
529
|
-
|
|
530
|
-
|
|
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.
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
this.
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
100 >=
|
|
564
|
-
|
|
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 &&
|
|
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 =
|
|
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.
|
|
692
|
+
if (((this.currentTrueVotes + outstandingVoters) / Process.networkNodeLength) *
|
|
693
|
+
100 >=
|
|
664
694
|
consensusNeeded) {
|
|
665
695
|
this.broadcastTimeout = setTimeout(() => {
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
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
|