@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.
- package/es/protocol/interfaces/vm.interface.d.ts +9 -5
- 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 +281 -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 -138
- 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 +9 -5
- 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 +281 -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 -137
- 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 {
|
|
@@ -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.
|
|
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:
|
|
407
|
-
contractData,
|
|
460
|
+
key: 0,
|
|
461
|
+
contractData: contractData ? contractData : { _id: "", data: {} },
|
|
408
462
|
};
|
|
409
|
-
|
|
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.
|
|
467
|
-
|
|
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
|
-
|
|
479
|
-
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;
|
|
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
|
-
|
|
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(
|
|
524
|
-
|
|
525
|
-
|
|
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.
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
this.
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
100 >=
|
|
559
|
-
|
|
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.
|
|
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 =
|
|
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.
|
|
692
|
+
if (((this.currentTrueVotes + outstandingVoters) / Process.networkNodeLength) *
|
|
693
|
+
100 >=
|
|
659
694
|
consensusNeeded) {
|
|
660
695
|
this.broadcastTimeout = setTimeout(() => {
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
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
|