godprotocol 1.0.831 → 1.0.834
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/Index.js +2 -6
- package/Loader_sequence/main.js +140 -6
- package/Objects/Account.js +53 -26
- package/Objects/Block.js +28 -7
- package/Objects/Blockweb.js +14 -0
- package/Objects/Chain.js +50 -8
- package/Objects/Filesystem.js +1 -1
- package/Objects/Manager.js +17 -2
- package/Objects/Opcodes.js +5 -2
- package/Objects/Oracle.js +69 -21
- package/Objects/Virtual_machine.js +12 -1
- package/opcodes.js +5 -3
- package/package.json +1 -1
- package/readme.md +1 -1
- package/utils/create_server.js +12 -7
package/Index.js
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import Manager from "./Objects/Manager";
|
|
2
2
|
import create_server from "./utils/create_server";
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
let initiator = manager.add_account(process.env.INITIATOR || "initiator");
|
|
7
|
-
|
|
8
|
-
export default manager;
|
|
9
|
-
export { initiator, create_server };
|
|
4
|
+
export default Manager;
|
|
5
|
+
export { create_server };
|
package/Loader_sequence/main.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { _id } from "generalised-datastore/utils/functions";
|
|
2
|
+
|
|
1
3
|
let num_pattern = /^[+-]?\d+(\.\d+)?$/;
|
|
2
4
|
// let str_pattern = /^["'][^"']*["']$/;
|
|
3
5
|
let var_pattern = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
|
|
@@ -12,6 +14,24 @@ class Loader {
|
|
|
12
14
|
this.instruction_stacks = [[]];
|
|
13
15
|
this.stacks = new Array(account.physical_address);
|
|
14
16
|
this.markers = new Array();
|
|
17
|
+
this.program_configs = new Array();
|
|
18
|
+
this.programs_index = -1;
|
|
19
|
+
|
|
20
|
+
// Code Repository
|
|
21
|
+
this.oracle = this.account.manager.oracle;
|
|
22
|
+
this.programs_folder = this.oracle.get_folder("programs", {
|
|
23
|
+
joins: ["codes"],
|
|
24
|
+
});
|
|
25
|
+
this.codes_folder = this.oracle.get_folder("codes");
|
|
26
|
+
|
|
27
|
+
this.globals = this.oracle.get_folder("globals", {
|
|
28
|
+
subfolder: ["global"],
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
if (!this.globals.readone({ global: "programs" }))
|
|
32
|
+
this.globals.write({ global: "programs", programs: [] });
|
|
33
|
+
if (!this.globals.readone({ global: "codes" }))
|
|
34
|
+
this.globals.write({ global: "codes", codes: [] });
|
|
15
35
|
}
|
|
16
36
|
|
|
17
37
|
instruction_index = () => {
|
|
@@ -220,6 +240,7 @@ class Loader {
|
|
|
220
240
|
if (line.type === "address")
|
|
221
241
|
return this.push_instruction(`pop ${path[path.length - 1]}`);
|
|
222
242
|
} else {
|
|
243
|
+
this.current_program().dimensions.push({ name: identifier.value });
|
|
223
244
|
this.push_instruction(`chain ${identifier.value}`);
|
|
224
245
|
this.stack_instruction([
|
|
225
246
|
`link ${this.stacks.slice(-1)[0]}`,
|
|
@@ -253,6 +274,10 @@ class Loader {
|
|
|
253
274
|
} else this.push_instruction(`pop ${identifier.value}`);
|
|
254
275
|
};
|
|
255
276
|
|
|
277
|
+
current_program = () => {
|
|
278
|
+
return this.program_configs[this.programs_index];
|
|
279
|
+
};
|
|
280
|
+
|
|
256
281
|
marker_pattern = /@[a-zA-Z_][a-zA-Z0-9_]*/;
|
|
257
282
|
|
|
258
283
|
parse_opcode = (line) => {
|
|
@@ -322,11 +347,23 @@ class Loader {
|
|
|
322
347
|
let curr_stack = this.stacks.slice(-1)[0].split("/");
|
|
323
348
|
new_stack = new_stack.split("/");
|
|
324
349
|
|
|
350
|
+
let physical_address = new_stack.join("/");
|
|
351
|
+
let program = {
|
|
352
|
+
program_name: new_stack[new_stack.length - 1],
|
|
353
|
+
physical_address,
|
|
354
|
+
codes: [],
|
|
355
|
+
dimensions: [],
|
|
356
|
+
sub_programs: [],
|
|
357
|
+
_id: _id("programs"),
|
|
358
|
+
};
|
|
359
|
+
let curr_program = this.current_program();
|
|
360
|
+
if (curr_program) curr_program.sub_programs.push(program._id);
|
|
361
|
+
|
|
362
|
+
this.programs_index++;
|
|
363
|
+
this.program_configs.push(program);
|
|
364
|
+
|
|
325
365
|
if (curr_stack[1] !== new_stack[1]) {
|
|
326
366
|
} else {
|
|
327
|
-
let i = 0;
|
|
328
|
-
while (curr_stack[i] === new_stack[i]) i++;
|
|
329
|
-
|
|
330
367
|
for (let j = 2; j < new_stack.length; j++)
|
|
331
368
|
this.stack_instruction(`chain ${new_stack[j]}`);
|
|
332
369
|
|
|
@@ -358,6 +395,7 @@ class Loader {
|
|
|
358
395
|
this.stack_instruction(`pop ${addr[j]}`);
|
|
359
396
|
|
|
360
397
|
this.instructions.push(...this.instruction_stacks.splice(-1)[0]);
|
|
398
|
+
this.programs_index--;
|
|
361
399
|
|
|
362
400
|
this.instruction_indexes.pop();
|
|
363
401
|
};
|
|
@@ -414,11 +452,47 @@ class Loader {
|
|
|
414
452
|
return line;
|
|
415
453
|
};
|
|
416
454
|
|
|
455
|
+
parse_comment = (line) => {
|
|
456
|
+
line = line.split(":");
|
|
457
|
+
if (line.length <= 1) return;
|
|
458
|
+
|
|
459
|
+
let curr_program = this.current_program();
|
|
460
|
+
let line1 = line[0].split(".");
|
|
461
|
+
let obj = curr_program;
|
|
462
|
+
|
|
463
|
+
for (let l = 0; l < line1.length - 1; l++) {
|
|
464
|
+
let term = line1[l];
|
|
465
|
+
|
|
466
|
+
if (term.trim() === "_id") break;
|
|
467
|
+
|
|
468
|
+
let n_term = Number(term);
|
|
469
|
+
|
|
470
|
+
if (n_term) {
|
|
471
|
+
obj = obj[n_term];
|
|
472
|
+
} else obj = obj[term];
|
|
473
|
+
}
|
|
474
|
+
if (!obj) return;
|
|
475
|
+
|
|
476
|
+
let index = line1[line1.length - 1];
|
|
477
|
+
let n_indx = Number(index);
|
|
478
|
+
if (!isNaN(n_indx)) index = n_indx;
|
|
479
|
+
|
|
480
|
+
if (index === "_id") return;
|
|
481
|
+
|
|
482
|
+
obj[index] = line.slice(1).join(":").trim();
|
|
483
|
+
};
|
|
484
|
+
|
|
417
485
|
compile = (codes) => {
|
|
418
486
|
let code_array = codes.split("\n");
|
|
419
487
|
|
|
420
488
|
for (let c = 0; c < code_array.length; c++) {
|
|
421
489
|
let line = code_array[c].trim();
|
|
490
|
+
|
|
491
|
+
let curr_program = this.current_program();
|
|
492
|
+
this.is_routine = line.startsWith(".") || line.startsWith("@");
|
|
493
|
+
|
|
494
|
+
this.handle_codes(line, curr_program);
|
|
495
|
+
|
|
422
496
|
if (!line) continue;
|
|
423
497
|
|
|
424
498
|
if (line.startsWith(":")) {
|
|
@@ -430,15 +504,31 @@ class Loader {
|
|
|
430
504
|
line = this.resolve_offset(line);
|
|
431
505
|
|
|
432
506
|
if (line === ";") this.pop();
|
|
433
|
-
else if (
|
|
434
|
-
|
|
435
|
-
else if (line.startsWith("//")) continue;
|
|
507
|
+
else if (this.is_routine) this.parse_routine(line);
|
|
508
|
+
else if (line.startsWith("//")) this.parse_comment(line.slice(2).trim());
|
|
436
509
|
else if (line.startsWith(">@")) this.parse_assignment(line, true);
|
|
437
510
|
else if (line.startsWith(">")) this.parse_assignment(line);
|
|
438
511
|
else this.parse_opcode(line);
|
|
512
|
+
|
|
513
|
+
(!curr_program || this.is_routine) &&
|
|
514
|
+
this.handle_codes(line, this.current_program());
|
|
439
515
|
}
|
|
440
516
|
};
|
|
441
517
|
|
|
518
|
+
handle_codes = (line, curr_program) => {
|
|
519
|
+
if (this.is_routine) {
|
|
520
|
+
let tilline = `~${line}`;
|
|
521
|
+
let prev_program = this.program_configs[this.programs_index - 1];
|
|
522
|
+
prev_program && prev_program.codes.push(tilline);
|
|
523
|
+
|
|
524
|
+
curr_program &&
|
|
525
|
+
!curr_program.codes.find((line) => !!line.trim()) &&
|
|
526
|
+
curr_program.codes.push(line);
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
!this.is_routine && curr_program && curr_program.codes.push(line);
|
|
530
|
+
};
|
|
531
|
+
|
|
442
532
|
run = (codes, meta) => {
|
|
443
533
|
if (!meta) meta = {};
|
|
444
534
|
this.pure = meta && meta.pure;
|
|
@@ -453,6 +543,50 @@ class Loader {
|
|
|
453
543
|
program: { instructions: [...this.instructions] },
|
|
454
544
|
callback: cb,
|
|
455
545
|
});
|
|
546
|
+
|
|
547
|
+
let programs = this.globals.readone({ global: "programs" });
|
|
548
|
+
let codes_global = this.globals.readone({ global: "codes" });
|
|
549
|
+
this.program_configs.map((config) => {
|
|
550
|
+
let program = programs.programs.find(
|
|
551
|
+
(prog) => prog.physical_address === config.physical_address
|
|
552
|
+
);
|
|
553
|
+
|
|
554
|
+
let code_str = config.codes.join("\n");
|
|
555
|
+
let code_hash = this.oracle.hash(code_str);
|
|
556
|
+
let code = codes_global.codes.find((cod) => cod.hash === code_hash);
|
|
557
|
+
let code_id = code && code.code_id;
|
|
558
|
+
if (!code_id) {
|
|
559
|
+
code_id = _id("codes");
|
|
560
|
+
|
|
561
|
+
this.globals.update(
|
|
562
|
+
{ global: "codes" },
|
|
563
|
+
{ codes: { $unshift: { code_id, hash: code_hash } } }
|
|
564
|
+
);
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
if (program) {
|
|
568
|
+
config._id = program.program_id;
|
|
569
|
+
this.programs_folder.update(config._id, {
|
|
570
|
+
...config,
|
|
571
|
+
codes: { $unshift: code_id },
|
|
572
|
+
});
|
|
573
|
+
} else {
|
|
574
|
+
this.programs_folder.write({ ...config, codes: [code_id] });
|
|
575
|
+
this.globals.update(
|
|
576
|
+
{ global: "programs" },
|
|
577
|
+
{
|
|
578
|
+
programs: {
|
|
579
|
+
$unshift: {
|
|
580
|
+
physical_address: config.physical_address,
|
|
581
|
+
program_id: config._id,
|
|
582
|
+
},
|
|
583
|
+
},
|
|
584
|
+
}
|
|
585
|
+
);
|
|
586
|
+
}
|
|
587
|
+
!code && this.codes_folder.write({ codes: code_str, _id: code_id });
|
|
588
|
+
});
|
|
589
|
+
this.program_configs = [];
|
|
456
590
|
this.instructions = [];
|
|
457
591
|
this.pure = false;
|
|
458
592
|
};
|
package/Objects/Account.js
CHANGED
|
@@ -88,11 +88,11 @@ class Account extends Filesystem {
|
|
|
88
88
|
buffer.blocks.push(block.stringify());
|
|
89
89
|
};
|
|
90
90
|
|
|
91
|
-
flush_buffer = (pid) => {
|
|
91
|
+
flush_buffer = (pid, payload) => {
|
|
92
92
|
let buff = this.mine_buffer[pid];
|
|
93
93
|
if (!buff) return;
|
|
94
94
|
|
|
95
|
-
buff.callback && this.run_callback(buff.callback, buff.blocks);
|
|
95
|
+
buff.callback && this.run_callback(buff.callback, payload || buff.blocks);
|
|
96
96
|
delete this.mine_buffer[pid];
|
|
97
97
|
};
|
|
98
98
|
|
|
@@ -110,35 +110,29 @@ class Account extends Filesystem {
|
|
|
110
110
|
};
|
|
111
111
|
|
|
112
112
|
parse = (program) => {
|
|
113
|
-
let { payload,
|
|
114
|
-
let {
|
|
113
|
+
let { payload, callback } = program;
|
|
114
|
+
let { account } = payload;
|
|
115
115
|
account = this.get_account(account);
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
return this.run_callback(callback, {
|
|
129
|
-
error: true,
|
|
130
|
-
error_message: "Address not found",
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
let data = query ? chain.explore(query) : chain;
|
|
134
|
-
|
|
135
|
-
this.run_callback(callback, data && data.stringify());
|
|
116
|
+
account.propagate(program, "parse");
|
|
117
|
+
|
|
118
|
+
account.manager.oracle.fetch(
|
|
119
|
+
payload,
|
|
120
|
+
(result) => account.run_callback(callback, result),
|
|
121
|
+
() =>
|
|
122
|
+
account.run_callback(callback, {
|
|
123
|
+
private: account.private,
|
|
124
|
+
error: true,
|
|
125
|
+
error_message: "Invalid signature",
|
|
126
|
+
})
|
|
127
|
+
);
|
|
136
128
|
};
|
|
137
129
|
|
|
138
130
|
run = (request) => {
|
|
139
131
|
let { payload, signature, callback } = request;
|
|
140
132
|
|
|
141
|
-
let { physical_address, account, query } = payload;
|
|
133
|
+
let { physical_address, account, query, history } = payload;
|
|
134
|
+
|
|
135
|
+
history = Math.abs(Number(history)) || 0;
|
|
142
136
|
account = this.get_account(account);
|
|
143
137
|
account.propagate(request, "run");
|
|
144
138
|
|
|
@@ -150,10 +144,38 @@ class Account extends Filesystem {
|
|
|
150
144
|
? this.manager.web.get(physical_address)
|
|
151
145
|
: account.vm.get_context();
|
|
152
146
|
|
|
153
|
-
if (!context)
|
|
147
|
+
if (!context) {
|
|
148
|
+
if (physical_address)
|
|
149
|
+
context = this.manager.web.split_set(physical_address);
|
|
150
|
+
else return account.flush_buffer(pid);
|
|
151
|
+
}
|
|
154
152
|
|
|
155
153
|
let blk = query ? context.explore(query) : context.get_latest_block();
|
|
156
154
|
|
|
155
|
+
if (!query) {
|
|
156
|
+
let index = context.height;
|
|
157
|
+
index -= 2;
|
|
158
|
+
|
|
159
|
+
if (blk && blk.metadata.program) {
|
|
160
|
+
if (history) {
|
|
161
|
+
history--;
|
|
162
|
+
blk = null;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
while (!blk && index >= 0) {
|
|
167
|
+
index--;
|
|
168
|
+
blk = context.get_block(index);
|
|
169
|
+
|
|
170
|
+
if (blk && blk.metadata.program) {
|
|
171
|
+
if (history) {
|
|
172
|
+
history--;
|
|
173
|
+
blk = null;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
157
179
|
if (blk && blk.metadata && blk.metadata.program) {
|
|
158
180
|
let program = this.read(blk.metadata.program);
|
|
159
181
|
|
|
@@ -183,6 +205,11 @@ class Account extends Filesystem {
|
|
|
183
205
|
};
|
|
184
206
|
|
|
185
207
|
flush_stdout = (block) => {
|
|
208
|
+
if (
|
|
209
|
+
block.chain.physical_address === `${this.physical_address}/Opcodes/stdout`
|
|
210
|
+
)
|
|
211
|
+
return;
|
|
212
|
+
|
|
186
213
|
for (let s = 0; s < this.stdout.length; s++) {
|
|
187
214
|
let out = this.stdout[s];
|
|
188
215
|
if (out.pid === this.vm.track.pid) {
|
package/Objects/Block.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { hash } from "../utils/hash";
|
|
2
|
+
import { _id } from "generalised-datastore/utils/functions";
|
|
2
3
|
|
|
3
4
|
class Block {
|
|
4
5
|
constructor(chain) {
|
|
@@ -7,6 +8,7 @@ class Block {
|
|
|
7
8
|
this.metadata = {};
|
|
8
9
|
this.children = new Array();
|
|
9
10
|
this.index = this.chain.blocks.length;
|
|
11
|
+
this._id = _id(this.chain.hash);
|
|
10
12
|
|
|
11
13
|
this.blocks_folder = this.chain.account.manager.oracle.gds.folder(
|
|
12
14
|
process.env.BLOCKS_FOLDER || "blocks"
|
|
@@ -51,13 +53,16 @@ class Block {
|
|
|
51
53
|
obj.index = this.index;
|
|
52
54
|
obj.hash = this.hash;
|
|
53
55
|
obj.data = this.data;
|
|
54
|
-
obj.
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
56
|
+
obj._id = this._id;
|
|
57
|
+
obj.children = this.children.map((ch) =>
|
|
58
|
+
ch.stringify
|
|
59
|
+
? new Object({
|
|
60
|
+
hash: ch.hash,
|
|
61
|
+
chain: ch.chain.hash,
|
|
62
|
+
_id: ch._id,
|
|
63
|
+
physical_address: ch.chain.physical_address,
|
|
64
|
+
})
|
|
65
|
+
: ch
|
|
61
66
|
);
|
|
62
67
|
obj.chain = {
|
|
63
68
|
hash: this.chain.hash,
|
|
@@ -66,6 +71,22 @@ class Block {
|
|
|
66
71
|
|
|
67
72
|
return str ? JSON.stringify(obj) : obj;
|
|
68
73
|
};
|
|
74
|
+
|
|
75
|
+
static build = (data, chain) => {
|
|
76
|
+
let blck = new Block(chain);
|
|
77
|
+
blck.chain = chain;
|
|
78
|
+
blck.metadata = data.metadata;
|
|
79
|
+
blck.datapath = data.datapath;
|
|
80
|
+
blck.timelapse = data.timelapse;
|
|
81
|
+
blck.index = data.index;
|
|
82
|
+
blck.hash = data.hash;
|
|
83
|
+
blck.data = data.data;
|
|
84
|
+
blck.children = data.children || [];
|
|
85
|
+
|
|
86
|
+
blck._id = data._id;
|
|
87
|
+
|
|
88
|
+
return blck;
|
|
89
|
+
};
|
|
69
90
|
}
|
|
70
91
|
|
|
71
92
|
export default Block;
|
package/Objects/Blockweb.js
CHANGED
|
@@ -15,7 +15,21 @@ class Blockweb {
|
|
|
15
15
|
return chain;
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
+
split_set = (physical_address) => {
|
|
19
|
+
let spli = physical_address.split("/");
|
|
20
|
+
|
|
21
|
+
let chain = this.get(physical_address);
|
|
22
|
+
if (!chain) {
|
|
23
|
+
chain = this.set(spli.slice(0, -1).join("/"), spli.slice(-1)[0]);
|
|
24
|
+
}
|
|
25
|
+
return chain;
|
|
26
|
+
};
|
|
27
|
+
|
|
18
28
|
set = (parent, name) => {
|
|
29
|
+
if (typeof parent === "string") {
|
|
30
|
+
parent = this.get(parent) || this.split_set(parent);
|
|
31
|
+
}
|
|
32
|
+
|
|
19
33
|
let chain = new Chain(parent, name);
|
|
20
34
|
this.chains[chain.hash] = chain;
|
|
21
35
|
|
package/Objects/Chain.js
CHANGED
|
@@ -28,13 +28,25 @@ class Chain extends Explorer {
|
|
|
28
28
|
this.generate_hash();
|
|
29
29
|
|
|
30
30
|
this.folder = this.account.manager.oracle.gds.folder(this.hash);
|
|
31
|
+
this.height = this.folder.config.total_files;
|
|
32
|
+
this.prev_hash = this.folder.config.recent_file;
|
|
31
33
|
|
|
32
|
-
this.manage_config();
|
|
34
|
+
this.manage_config(true);
|
|
33
35
|
|
|
34
36
|
this.account.set_paths(this);
|
|
35
37
|
}
|
|
36
38
|
|
|
37
|
-
manage_config = () => {
|
|
39
|
+
manage_config = (init) => {
|
|
40
|
+
if (init) {
|
|
41
|
+
let dir = this.account.manager.oracle.fs.readdirSync(
|
|
42
|
+
this.folder.folder_path
|
|
43
|
+
);
|
|
44
|
+
this.blocks = dir.filter((d) => d !== ".config");
|
|
45
|
+
this.height = this.blocks.length;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
this.folder.config.object = { ...this.stringify() };
|
|
49
|
+
};
|
|
38
50
|
|
|
39
51
|
append_buffer = () => {
|
|
40
52
|
this.buffs.push({});
|
|
@@ -56,8 +68,18 @@ class Chain extends Explorer {
|
|
|
56
68
|
this.hash = hash(this.physical_address);
|
|
57
69
|
};
|
|
58
70
|
|
|
71
|
+
build_block = (blk) => {
|
|
72
|
+
if (typeof blk === "string") {
|
|
73
|
+
let blk_data = this.folder.readone(blk);
|
|
74
|
+
|
|
75
|
+
blk = Block.build(blk_data, this);
|
|
76
|
+
}
|
|
77
|
+
return blk;
|
|
78
|
+
};
|
|
79
|
+
|
|
59
80
|
get_block = (index) => {
|
|
60
|
-
|
|
81
|
+
let blk = this.blocks[index];
|
|
82
|
+
return this.build_block(blk);
|
|
61
83
|
};
|
|
62
84
|
|
|
63
85
|
add_tx = (instruction) => {
|
|
@@ -87,7 +109,17 @@ class Chain extends Explorer {
|
|
|
87
109
|
|
|
88
110
|
block.timelapse = Date.now() - this.start_time;
|
|
89
111
|
|
|
90
|
-
this.
|
|
112
|
+
this.manage_config();
|
|
113
|
+
|
|
114
|
+
let data = block.stringify();
|
|
115
|
+
|
|
116
|
+
data = this.account.manager.oracle.handle_compression({
|
|
117
|
+
addr: this.folder.folder_path,
|
|
118
|
+
data,
|
|
119
|
+
no_string: true,
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
this.folder.write(data);
|
|
91
123
|
return block;
|
|
92
124
|
};
|
|
93
125
|
|
|
@@ -96,7 +128,12 @@ class Chain extends Explorer {
|
|
|
96
128
|
this.height = this.blocks.length;
|
|
97
129
|
};
|
|
98
130
|
|
|
99
|
-
get_latest_block = () =>
|
|
131
|
+
get_latest_block = () => {
|
|
132
|
+
let blk = this.blocks.slice(-1)[0];
|
|
133
|
+
blk = this.build_block(blk);
|
|
134
|
+
|
|
135
|
+
return blk;
|
|
136
|
+
};
|
|
100
137
|
|
|
101
138
|
stringify = (str) => {
|
|
102
139
|
let obj = {};
|
|
@@ -106,11 +143,16 @@ class Chain extends Explorer {
|
|
|
106
143
|
obj.parent = this.parent.path;
|
|
107
144
|
obj.account = this.parent.account.name;
|
|
108
145
|
obj.name = this.name;
|
|
109
|
-
obj.connections = this.connections.map(
|
|
110
|
-
|
|
146
|
+
obj.connections = this.connections.map((b) =>
|
|
147
|
+
b.stringify
|
|
148
|
+
? new Object({
|
|
149
|
+
chain: b.chain.hash,
|
|
150
|
+
block: { hash: b.hash, _id: b._id },
|
|
151
|
+
})
|
|
152
|
+
: b
|
|
111
153
|
);
|
|
112
154
|
obj.hash = this.hash;
|
|
113
|
-
obj.blocks = this.blocks.map((blk) => blk.hash);
|
|
155
|
+
obj.blocks = this.blocks.map((blk) => blk.hash || blk);
|
|
114
156
|
|
|
115
157
|
return str ? JSON.stringify(obj) : obj;
|
|
116
158
|
};
|
package/Objects/Filesystem.js
CHANGED
|
@@ -64,7 +64,7 @@ class Filesystem {
|
|
|
64
64
|
|
|
65
65
|
addr = `${chain.path}/${hash(JSON.stringify(obj))}`;
|
|
66
66
|
this;
|
|
67
|
-
if (obj != null) this.manager.oracle.write(addr, obj
|
|
67
|
+
if (obj != null) this.manager.oracle.write(addr, obj);
|
|
68
68
|
|
|
69
69
|
this.manager.oracle.set(addr, { obj, type });
|
|
70
70
|
|
package/Objects/Manager.js
CHANGED
|
@@ -5,14 +5,27 @@ import Blockweb from "./Blockweb";
|
|
|
5
5
|
import Oracle from "./Oracle";
|
|
6
6
|
|
|
7
7
|
class Manager {
|
|
8
|
-
constructor() {
|
|
8
|
+
constructor(meta) {
|
|
9
|
+
meta = meta || {};
|
|
10
|
+
|
|
11
|
+
this.compression = meta.compression;
|
|
12
|
+
|
|
9
13
|
this.accounts = new Object();
|
|
10
14
|
this.running = 0;
|
|
11
15
|
this.tracks = new Object();
|
|
12
16
|
this.web = new Blockweb(this);
|
|
13
|
-
this.oracle = new Oracle(this);
|
|
17
|
+
this.oracle = new Oracle(this, { compression: this.compression });
|
|
14
18
|
}
|
|
15
19
|
|
|
20
|
+
initiate = (meta) => {
|
|
21
|
+
let initiator = this.add_account(
|
|
22
|
+
process.env.INITIATOR || "initiator",
|
|
23
|
+
meta
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
return initiator;
|
|
27
|
+
};
|
|
28
|
+
|
|
16
29
|
start_clock = () => {
|
|
17
30
|
let frequency = Number(process.env.HERTS) || 10;
|
|
18
31
|
this.clock = setInterval(() => {
|
|
@@ -20,6 +33,8 @@ class Manager {
|
|
|
20
33
|
let track = this.tracks[account];
|
|
21
34
|
let program = track.slice(-1)[0];
|
|
22
35
|
|
|
36
|
+
if (program.hold) continue;
|
|
37
|
+
|
|
23
38
|
let instruction = program.sequence[program.pointer];
|
|
24
39
|
|
|
25
40
|
program.account.vm.execute(instruction, program);
|
package/Objects/Opcodes.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { obj } from "../framer";
|
|
2
|
-
import { transpile_object } from "../utils/functions";
|
|
3
2
|
|
|
4
3
|
class Opcodes {
|
|
5
4
|
constructor() {
|
|
@@ -30,7 +29,11 @@ class Opcodes {
|
|
|
30
29
|
};
|
|
31
30
|
|
|
32
31
|
stdin = (object, cb) => {
|
|
33
|
-
if (object == null)
|
|
32
|
+
if (object == null) {
|
|
33
|
+
this.flags.void = true;
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
this.flags.void = false;
|
|
34
37
|
|
|
35
38
|
this.flags.zero = !object;
|
|
36
39
|
if (typeof object === "number") this.flags.neg = object < 0;
|
package/Objects/Oracle.js
CHANGED
|
@@ -3,14 +3,22 @@ import GDS from "generalised-datastore";
|
|
|
3
3
|
import { hash } from "../utils/hash";
|
|
4
4
|
|
|
5
5
|
class Oracle {
|
|
6
|
-
constructor(mgr) {
|
|
6
|
+
constructor(mgr, meta) {
|
|
7
|
+
meta = meta || {};
|
|
8
|
+
|
|
9
|
+
this.compression = meta.compression;
|
|
7
10
|
this.fs = fs;
|
|
8
11
|
this.mgr = mgr;
|
|
9
12
|
this.datapaths = new Object();
|
|
10
|
-
this.gds = new GDS(process.env.DATASTORE || "godprotocol").sync(
|
|
13
|
+
this.gds = new GDS(process.env.DATASTORE || "godprotocol").sync({
|
|
14
|
+
manager: this.mgr,
|
|
15
|
+
});
|
|
11
16
|
}
|
|
12
17
|
|
|
13
|
-
get_folder = (physical_address) => {
|
|
18
|
+
get_folder = (physical_address, options) => {
|
|
19
|
+
if (typeof options !== "object") {
|
|
20
|
+
options = { no_new: options ? false : true };
|
|
21
|
+
}
|
|
14
22
|
return this.gds.folder(this.hash(physical_address));
|
|
15
23
|
};
|
|
16
24
|
|
|
@@ -28,7 +36,7 @@ class Oracle {
|
|
|
28
36
|
try {
|
|
29
37
|
obj = this.fs.readFileSync(path);
|
|
30
38
|
obj = JSON.parse(obj).data;
|
|
31
|
-
let type = typeof obj.data;
|
|
39
|
+
let type = obj && obj.data && typeof obj.data;
|
|
32
40
|
type =
|
|
33
41
|
type === "object" ? (Array.isArray(obj) ? "array" : "twain") : type;
|
|
34
42
|
|
|
@@ -45,32 +53,72 @@ class Oracle {
|
|
|
45
53
|
return hash(data);
|
|
46
54
|
};
|
|
47
55
|
|
|
48
|
-
|
|
49
|
-
|
|
56
|
+
handle_compression = ({ addr, data, no_string }) => {
|
|
57
|
+
if (this.compression) {
|
|
58
|
+
let res = this.compression({ addr, data, no_string });
|
|
59
|
+
if (res) data = res.data;
|
|
60
|
+
}
|
|
61
|
+
if (!no_string && (typeof addr !== "string" || typeof data !== "string"))
|
|
62
|
+
return;
|
|
63
|
+
|
|
64
|
+
return data;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
write = (address, payload) => {
|
|
68
|
+
payload = JSON.stringify({ payload });
|
|
69
|
+
let data = this.handle_compression({
|
|
70
|
+
addr: address,
|
|
71
|
+
data: payload,
|
|
72
|
+
});
|
|
50
73
|
|
|
51
|
-
this.fs.writeFileSync(
|
|
74
|
+
this.fs.writeFileSync(address, data, { encoding: "utf-8" });
|
|
52
75
|
};
|
|
53
76
|
|
|
54
|
-
fetch = (payload, callback) => {
|
|
55
|
-
let { physical_address, query, account, signature } = payload,
|
|
77
|
+
fetch = (payload, callback, val_err_cb) => {
|
|
78
|
+
let { physical_address, config, query, account, signature } = payload,
|
|
56
79
|
result;
|
|
57
80
|
|
|
58
81
|
account = this.mgr.get_account(account);
|
|
59
82
|
if (account && account.private)
|
|
60
|
-
if (
|
|
61
|
-
|
|
83
|
+
if (
|
|
84
|
+
!account.validate(
|
|
85
|
+
{ physical_address, account, query },
|
|
86
|
+
signature,
|
|
87
|
+
callback
|
|
88
|
+
)
|
|
89
|
+
)
|
|
90
|
+
return typeof val_err_cb === "function" && val_err_cb();
|
|
62
91
|
|
|
63
92
|
try {
|
|
64
|
-
let
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
if (
|
|
72
|
-
|
|
73
|
-
|
|
93
|
+
let folder = this.gds.folder(this.hash(physical_address));
|
|
94
|
+
|
|
95
|
+
if (config) {
|
|
96
|
+
folder.add_remote(config);
|
|
97
|
+
|
|
98
|
+
result = folder.config;
|
|
99
|
+
} else {
|
|
100
|
+
if (!folder.check_remote(query.operation)) {
|
|
101
|
+
result = {
|
|
102
|
+
error: true,
|
|
103
|
+
error_message: "Forbidden remote operations",
|
|
104
|
+
payload,
|
|
105
|
+
};
|
|
106
|
+
} else {
|
|
107
|
+
if (query.operation === "call") {
|
|
108
|
+
let compressed_result = this.compression({ payload, val_err_cb });
|
|
109
|
+
if (compressed_result && compressed_result.halt)
|
|
110
|
+
return (
|
|
111
|
+
typeof callback === "function" &&
|
|
112
|
+
callback({ compressed: true, data: compressed_result })
|
|
113
|
+
);
|
|
114
|
+
query = (compressed_result && compressed_result.query) || query;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
let operation = folder[query.operation];
|
|
118
|
+
|
|
119
|
+
result =
|
|
120
|
+
operation &&
|
|
121
|
+
operation(query.query, { ...query.options, account, payload });
|
|
74
122
|
}
|
|
75
123
|
}
|
|
76
124
|
} catch (e) {
|
|
@@ -11,6 +11,7 @@ class Virtual_machine extends Opcodes {
|
|
|
11
11
|
neg: false,
|
|
12
12
|
equal: false,
|
|
13
13
|
zero: false,
|
|
14
|
+
void: false,
|
|
14
15
|
};
|
|
15
16
|
}
|
|
16
17
|
|
|
@@ -84,6 +85,13 @@ class Virtual_machine extends Opcodes {
|
|
|
84
85
|
chain = context.account.add_chain(args, context);
|
|
85
86
|
this.contexts.push(chain);
|
|
86
87
|
|
|
88
|
+
let dim = context.folder.config.dimensions;
|
|
89
|
+
if (!dim) {
|
|
90
|
+
dim = [];
|
|
91
|
+
context.folder.config.dimensions = dim;
|
|
92
|
+
}
|
|
93
|
+
!dim.find((d) => d === args) && dim.push(args);
|
|
94
|
+
|
|
87
95
|
chain.append_buffer();
|
|
88
96
|
|
|
89
97
|
break;
|
|
@@ -91,7 +99,10 @@ class Virtual_machine extends Opcodes {
|
|
|
91
99
|
chain = context.account.manager.web.get(args);
|
|
92
100
|
|
|
93
101
|
if (!chain) {
|
|
94
|
-
this.account.flush_buffer(this.track.pid
|
|
102
|
+
this.account.flush_buffer(this.track.pid, {
|
|
103
|
+
error: true,
|
|
104
|
+
error_message: `LINKing Failed. - ${args}`,
|
|
105
|
+
});
|
|
95
106
|
this.track.pointer = this.track.sequence.length;
|
|
96
107
|
|
|
97
108
|
console.log(`LINKing Failed. - ${args}`);
|
package/opcodes.js
CHANGED
|
@@ -42,9 +42,11 @@ const opcodes = (account) => {
|
|
|
42
42
|
|
|
43
43
|
set("stdout", stdout);
|
|
44
44
|
|
|
45
|
-
set("
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
set("hold", (arg) => (vm.track.hold = !!arg.op0));
|
|
46
|
+
|
|
47
|
+
set("add_server", (args, vm) => account.add_server(args && args.op0));
|
|
48
|
+
|
|
49
|
+
[("run", "load", "parse", "create_account")].map((op) =>
|
|
48
50
|
set(op, (arg) => arg && arg.op0 && account[op](arg && arg.op0))
|
|
49
51
|
);
|
|
50
52
|
};
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -116,7 +116,7 @@ Type `method`
|
|
|
116
116
|
| | string | `account` | Account instance to execute the instructions in. |
|
|
117
117
|
| `cb` | function | | A function that is called with the blocks mined during the execution. |
|
|
118
118
|
|
|
119
|
-
See the [package source](https://github.com/
|
|
119
|
+
See the [package source](https://github.com/godprotocol4/GodProtocol) for more details.
|
|
120
120
|
|
|
121
121
|
[npm-url]: https://npmjs.org/package/godprotocol
|
|
122
122
|
[downloads-url]: https://npmjs.org/package/godprotocol
|
package/utils/create_server.js
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import http from "http";
|
|
2
2
|
import { is_port_available } from "./functions";
|
|
3
|
-
import { initiator } from "../Index";
|
|
4
3
|
|
|
5
4
|
let PORT = Number(process.env.PORT) || 1408;
|
|
6
5
|
|
|
7
6
|
const cb = (res, data) => {
|
|
8
7
|
if (typeof data !== "string") data = JSON.stringify(data);
|
|
9
8
|
|
|
10
|
-
res(data);
|
|
9
|
+
res.end(data);
|
|
11
10
|
};
|
|
12
11
|
|
|
13
12
|
let extensions = new Object();
|
|
@@ -22,7 +21,7 @@ const extension = (route, handler) => {
|
|
|
22
21
|
handlers.push(handler);
|
|
23
22
|
};
|
|
24
23
|
|
|
25
|
-
const handle_routes = (req, res, app) => {
|
|
24
|
+
const handle_routes = (req, res, app, initiator) => {
|
|
26
25
|
let data = "";
|
|
27
26
|
|
|
28
27
|
let is_in_default_routes = [
|
|
@@ -41,7 +40,11 @@ const handle_routes = (req, res, app) => {
|
|
|
41
40
|
try {
|
|
42
41
|
data = JSON.parse(data);
|
|
43
42
|
} catch (e) {
|
|
44
|
-
return cb(res
|
|
43
|
+
return cb(res, {
|
|
44
|
+
error_message: "Invalid data",
|
|
45
|
+
url: req.url,
|
|
46
|
+
error: true,
|
|
47
|
+
});
|
|
45
48
|
}
|
|
46
49
|
|
|
47
50
|
if (req.url === "/create_account") {
|
|
@@ -50,7 +53,7 @@ const handle_routes = (req, res, app) => {
|
|
|
50
53
|
} else if (["run", "load", "parse"].includes(req.url.slice(1))) {
|
|
51
54
|
let payload = {
|
|
52
55
|
...data,
|
|
53
|
-
callback: (datagram) => cb(res
|
|
56
|
+
callback: (datagram) => cb(res, datagram),
|
|
54
57
|
};
|
|
55
58
|
initiator.endpoint(req.url.slice(1), payload);
|
|
56
59
|
} else {
|
|
@@ -64,7 +67,7 @@ const handle_routes = (req, res, app) => {
|
|
|
64
67
|
});
|
|
65
68
|
|
|
66
69
|
req.on("error", (e) => {
|
|
67
|
-
res.writeHead(500, { "Content-Type": "application/json" });
|
|
70
|
+
// res.writeHead(500, { "Content-Type": "application/json" });
|
|
68
71
|
res.end(JSON.stringify({ status: "error", message: e.message }));
|
|
69
72
|
});
|
|
70
73
|
} else {
|
|
@@ -88,7 +91,9 @@ const create_server = async (app, settings) => {
|
|
|
88
91
|
}
|
|
89
92
|
PORT = port;
|
|
90
93
|
|
|
91
|
-
let server = http.createServer((req, res) =>
|
|
94
|
+
let server = http.createServer((req, res) =>
|
|
95
|
+
handle_routes(req, res, app, settings.initiator)
|
|
96
|
+
);
|
|
92
97
|
|
|
93
98
|
server.listen(port, () => {
|
|
94
99
|
console.log(`\n...GOD PROTOCOL RUNNING :${port}`);
|