@theqrl/hypc 0.0.2 → 0.2.0
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/README.md +4 -4
- package/build/clean.js +2 -4
- package/hypc.js +2 -2
- package/hypjson.js +47 -47
- package/linker.js +43 -32
- package/package.json +4 -4
- package/test/cli.js +1 -1
- package/test/compiler.js +21 -21
- package/test/linker.js +46 -90
- package/test/translate.js +2 -2
- package/translate.js +3 -3
- package/contractA_hyp_A.bin +0 -1
- package/contractB_hyp_B.bin +0 -1
- package/importA_hyp_C.bin +0 -1
- package/importB_hyp_D.bin +0 -1
- package/libX_hyp_X.bin +0 -1
- package/libY_hyp_Y.bin +0 -1
- package/libZ_hyp_Z.bin +0 -1
- package/test/resources/fixtureAsmJson.hyp +0 -8
- package/test/resources/fixtureAsmJson.output +0 -101
- package/test/resources/fixtureIncorrectSource.hyp +0 -1
- package/test/resources/fixtureSmoke.hyp +0 -5
- package/test/resources/importA.hyp +0 -7
- package/test/resources/importB.hyp +0 -5
- package/test/resources/importCallback/base/contractA.hyp +0 -8
- package/test/resources/importCallback/base/contractB.hyp +0 -6
- package/test/resources/importCallback/contractC.hyp +0 -4
- package/test/resources/importCallback/includeA/libX.hyp +0 -4
- package/test/resources/importCallback/includeA/libY.hyp +0 -6
- package/test/resources/importCallback/includeA/utils.hyp +0 -4
- package/test/resources/importCallback/includeB/libZ.hyp +0 -4
- package/test/resources/smtChecker/loop.hyp +0 -8
- package/test/resources/smtChecker/smoke.hyp +0 -5
- package/test/resources/smtChecker/smoke_with_engine.hyp +0 -6
- package/test/resources/smtChecker/smoke_with_multi_engine.hyp +0 -8
- package/test_resources_fixtureSmoke_hyp_C.abi +0 -1
- package/test_resources_fixtureSmoke_hyp_C.bin +0 -1
- package/test_resources_importA_hyp_C.bin +0 -1
- package/test_resources_importB_hyp_D.bin +0 -1
- package/utils_hyp_Utils.bin +0 -1
package/linker.js
CHANGED
|
@@ -5,6 +5,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
const assert_1 = __importDefault(require("assert"));
|
|
6
6
|
const js_sha3_1 = require("js-sha3");
|
|
7
7
|
const helpers_1 = require("./common/helpers");
|
|
8
|
+
const ADDRESS_HEX_LENGTH = 128;
|
|
9
|
+
const ADDRESS_PREFIX = 'Q';
|
|
10
|
+
const PREFIXED_ADDRESS_LENGTH = ADDRESS_HEX_LENGTH + ADDRESS_PREFIX.length;
|
|
11
|
+
const PLACEHOLDER_MARKER_LENGTH = 4;
|
|
12
|
+
const HASH_PLACEHOLDER_MARKER_LENGTH = 6;
|
|
13
|
+
const PLACEHOLDER_BODY_LENGTH = ADDRESS_HEX_LENGTH - PLACEHOLDER_MARKER_LENGTH;
|
|
14
|
+
const HASH_PLACEHOLDER_BODY_LENGTH = ADDRESS_HEX_LENGTH - HASH_PLACEHOLDER_MARKER_LENGTH;
|
|
8
15
|
/**
|
|
9
16
|
* Generates a new-style library placeholder from a fully-qualified library name.
|
|
10
17
|
*
|
|
@@ -13,8 +20,15 @@ const helpers_1 = require("./common/helpers");
|
|
|
13
20
|
*
|
|
14
21
|
* @param fullyQualifiedLibraryName Fully qualified library name.
|
|
15
22
|
*/
|
|
23
|
+
function libraryHash(fullyQualifiedLibraryName, length) {
|
|
24
|
+
let hash = (0, js_sha3_1.keccak256)(fullyQualifiedLibraryName);
|
|
25
|
+
while (hash.length < length) {
|
|
26
|
+
hash += (0, js_sha3_1.keccak256)(hash);
|
|
27
|
+
}
|
|
28
|
+
return hash.slice(0, length);
|
|
29
|
+
}
|
|
16
30
|
function libraryHashPlaceholder(fullyQualifiedLibraryName) {
|
|
17
|
-
return `$${(
|
|
31
|
+
return `$${libraryHash(fullyQualifiedLibraryName, HASH_PLACEHOLDER_BODY_LENGTH)}$`;
|
|
18
32
|
}
|
|
19
33
|
/**
|
|
20
34
|
* Finds all placeholders corresponding to the specified library label and replaces them
|
|
@@ -30,9 +44,8 @@ function libraryHashPlaceholder(fullyQualifiedLibraryName) {
|
|
|
30
44
|
* It will **not** be padded with zeros if too short.
|
|
31
45
|
*/
|
|
32
46
|
function replacePlaceholder(bytecode, label, address) {
|
|
33
|
-
|
|
34
|
-
const
|
|
35
|
-
const libLabel = `__${truncatedName.padEnd(36, '_')}__`;
|
|
47
|
+
const truncatedName = label.slice(0, PLACEHOLDER_BODY_LENGTH);
|
|
48
|
+
const libLabel = `__${truncatedName.padEnd(PLACEHOLDER_BODY_LENGTH, '_')}__`;
|
|
36
49
|
while (bytecode.indexOf(libLabel) >= 0) {
|
|
37
50
|
bytecode = bytecode.replace(libLabel, address);
|
|
38
51
|
}
|
|
@@ -44,14 +57,14 @@ function replacePlaceholder(bytecode, label, address) {
|
|
|
44
57
|
* See [Library Linking](https://docs.soliditylang.org/en/latest/using-the-compiler.html#library-linking)
|
|
45
58
|
* for a full explanation of the linking process.
|
|
46
59
|
*
|
|
47
|
-
* Example of
|
|
48
|
-
* Example of a new-style placeholder: `__
|
|
60
|
+
* Example of an old-style placeholder: `__lib.hyp:L...__` padded to 64 bytes.
|
|
61
|
+
* Example of a new-style placeholder: `__$<122 hex characters>$__`
|
|
49
62
|
*
|
|
50
|
-
* @param bytecode Hex-encoded bytecode string. All
|
|
63
|
+
* @param bytecode Hex-encoded bytecode string. All 64-byte substrings starting and ending with
|
|
51
64
|
* `__` will be interpreted as placeholders.
|
|
52
65
|
*
|
|
53
66
|
* @param libraries Mapping between fully qualified library names and the hex-encoded
|
|
54
|
-
* addresses they should be replaced with.
|
|
67
|
+
* addresses they should be replaced with.
|
|
55
68
|
*
|
|
56
69
|
* @returns bytecode Hex-encoded bytecode string with placeholders replaced with addresses.
|
|
57
70
|
* Note that some placeholders may remain in the bytecode if `libraries` does not provide addresses for all of them.
|
|
@@ -66,7 +79,7 @@ function linkBytecode(bytecode, libraries) {
|
|
|
66
79
|
throw new Error(`No address provided for library ${fullyQualifiedLibraryName}`);
|
|
67
80
|
}
|
|
68
81
|
// API compatible with the standard JSON i/o
|
|
69
|
-
// {"lib.hyp": {"L": "
|
|
82
|
+
// {"lib.hyp": {"L": "Q..."}}
|
|
70
83
|
if ((0, helpers_1.isObject)(libraryObjectOrAddress)) {
|
|
71
84
|
for (const [unqualifiedLibraryName, address] of Object.entries(libraryObjectOrAddress)) {
|
|
72
85
|
librariesComplete[unqualifiedLibraryName] = address;
|
|
@@ -85,11 +98,13 @@ function linkBytecode(bytecode, libraries) {
|
|
|
85
98
|
}
|
|
86
99
|
for (const libraryName in librariesComplete) {
|
|
87
100
|
let hexAddress = librariesComplete[libraryName];
|
|
88
|
-
if (!hexAddress.startsWith(
|
|
101
|
+
if (!hexAddress.startsWith(ADDRESS_PREFIX) ||
|
|
102
|
+
hexAddress.length !== PREFIXED_ADDRESS_LENGTH ||
|
|
103
|
+
!/^[0-9a-fA-F]+$/.test(hexAddress.slice(ADDRESS_PREFIX.length))) {
|
|
89
104
|
throw new Error(`Invalid address specified for ${libraryName}`);
|
|
90
105
|
}
|
|
91
|
-
// remove
|
|
92
|
-
hexAddress = hexAddress.slice(
|
|
106
|
+
// remove address prefix
|
|
107
|
+
hexAddress = hexAddress.slice(ADDRESS_PREFIX.length);
|
|
93
108
|
bytecode = replacePlaceholder(bytecode, libraryName, hexAddress);
|
|
94
109
|
bytecode = replacePlaceholder(bytecode, libraryHashPlaceholder(libraryName), hexAddress);
|
|
95
110
|
}
|
|
@@ -97,17 +112,17 @@ function linkBytecode(bytecode, libraries) {
|
|
|
97
112
|
}
|
|
98
113
|
/**
|
|
99
114
|
* Finds locations of all library address placeholders in the hex-encoded bytecode.
|
|
100
|
-
* Returns information in a format matching `
|
|
115
|
+
* Returns information in a format matching `qrvm.bytecode.linkReferences` output
|
|
101
116
|
* in Standard JSON.
|
|
102
117
|
*
|
|
103
118
|
* See [Library Linking](https://docs.soliditylang.org/en/latest/using-the-compiler.html#library-linking)
|
|
104
119
|
* for a full explanation of library placeholders and linking process.
|
|
105
120
|
*
|
|
106
|
-
* WARNING: The output matches `
|
|
121
|
+
* WARNING: The output matches `qrvm.bytecode.linkReferences` exactly only in
|
|
107
122
|
* case of old-style placeholders created from fully qualified library names
|
|
108
123
|
* of no more than 36 characters, and even then only if the name does not start
|
|
109
124
|
* or end with an underscore. This is different from
|
|
110
|
-
* `
|
|
125
|
+
* `qrvm.bytecode.linkReferences`, which uses fully qualified library names.
|
|
111
126
|
* This is a limitation of the placeholder format - the fully qualified names
|
|
112
127
|
* are not preserved in the compiled bytecode and cannot be reconstructed
|
|
113
128
|
* without external information.
|
|
@@ -116,37 +131,33 @@ function linkBytecode(bytecode, libraries) {
|
|
|
116
131
|
*
|
|
117
132
|
* @returns linkReferences A mapping between library labels and their locations
|
|
118
133
|
* in the bytecode. In case of old-style placeholders the label is a fully
|
|
119
|
-
* qualified library name truncated to
|
|
120
|
-
* it's the
|
|
121
|
-
*
|
|
134
|
+
* qualified library name truncated to 124 characters. For new-style placeholders
|
|
135
|
+
* it's the address-width hash label of the fully qualified library name, with a leading
|
|
136
|
+
* and trailing $ character added. Note that the
|
|
122
137
|
* offsets and lengths refer to the *binary* (not hex-encoded) bytecode, just
|
|
123
|
-
* like in `
|
|
138
|
+
* like in `qrvm.bytecode.linkReferences`.
|
|
124
139
|
*/
|
|
125
140
|
function findLinkReferences(bytecode) {
|
|
126
141
|
(0, assert_1.default)(typeof bytecode === 'string');
|
|
127
|
-
// find
|
|
128
|
-
// e.g. __Lib.hyp:L_____________________________
|
|
142
|
+
// find 64-byte placeholders in the pattern of __...__
|
|
143
|
+
// e.g. __Lib.hyp:L_____________________________ or __$<122 hex digits>$__
|
|
129
144
|
const linkReferences = {};
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
if (!found) {
|
|
134
|
-
break;
|
|
135
|
-
}
|
|
145
|
+
const placeholderPattern = /__(.{124})__/g;
|
|
146
|
+
let found;
|
|
147
|
+
while ((found = placeholderPattern.exec(bytecode)) !== null) {
|
|
136
148
|
const start = found.index;
|
|
149
|
+
const placeholder = found[1];
|
|
137
150
|
// trim trailing underscores
|
|
138
151
|
// NOTE: this has no way of knowing if the trailing underscore was part of the name
|
|
139
|
-
const libraryName =
|
|
152
|
+
const libraryName = placeholder.replace(/_+$/gm, '');
|
|
140
153
|
if (!linkReferences[libraryName]) {
|
|
141
154
|
linkReferences[libraryName] = [];
|
|
142
155
|
}
|
|
143
156
|
// offsets are in bytes in binary representation (and not hex)
|
|
144
157
|
linkReferences[libraryName].push({
|
|
145
|
-
start:
|
|
146
|
-
length:
|
|
158
|
+
start: start / 2,
|
|
159
|
+
length: ADDRESS_HEX_LENGTH / 2
|
|
147
160
|
});
|
|
148
|
-
offset += start + 20;
|
|
149
|
-
bytecode = bytecode.slice(start + 20);
|
|
150
161
|
}
|
|
151
162
|
return linkReferences;
|
|
152
163
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theqrl/hypc",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Hyperion compiler",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -15,10 +15,10 @@
|
|
|
15
15
|
"prepack": "node build/pack-publish-block.js",
|
|
16
16
|
"build:tarball": "npm run updateBinary && npm run build && BYPASS_SAFETY_CHECK=true npm pack ./dist",
|
|
17
17
|
"publish:tarball": "tarball=$(npm run --silent tarballName) && ls \"$tarball\" && BYPASS_SAFETY_CHECK=true npm publish --access public \"$tarball\"",
|
|
18
|
-
"tarballName": "jq --raw-output '.name + \"-\" + .version + \".tgz\"' package.json",
|
|
18
|
+
"tarballName": "jq --raw-output '(.name | sub(\"@\"; \"\") | gsub(\"/\"; \"-\")) + \"-\" + .version + \".tgz\"' package.json",
|
|
19
19
|
"copyTestFiles": "cp -r ./test/resources ./dist/test/",
|
|
20
20
|
"pretest": "npm run lint && npm run build && npm run copyTestFiles",
|
|
21
|
-
"test": "cd dist && tape ./test/index.js",
|
|
21
|
+
"test": "cd dist && tape ./test/index.js --no-remote-versions",
|
|
22
22
|
"coverage": "nyc npm run test",
|
|
23
23
|
"coveralls": "npm run coverage && coveralls <coverage/lcov.info"
|
|
24
24
|
},
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"url": "git+https://github.com/theQRL/hypc-js.git"
|
|
28
28
|
},
|
|
29
29
|
"keywords": [
|
|
30
|
-
"
|
|
30
|
+
"qrl",
|
|
31
31
|
"hyperion",
|
|
32
32
|
"compiler"
|
|
33
33
|
],
|
package/test/cli.js
CHANGED
package/test/compiler.js
CHANGED
|
@@ -56,7 +56,7 @@ function runTests(hypc, versionText) {
|
|
|
56
56
|
function getBytecodeStandard(output, fileName, contractName) {
|
|
57
57
|
try {
|
|
58
58
|
const outputFile = output.contracts[fileName];
|
|
59
|
-
return outputFile[contractName].
|
|
59
|
+
return outputFile[contractName].qrvm.bytecode.object;
|
|
60
60
|
}
|
|
61
61
|
catch (e) {
|
|
62
62
|
return '';
|
|
@@ -69,7 +69,7 @@ function runTests(hypc, versionText) {
|
|
|
69
69
|
[fileName, contractName] = resplitFileNameOnFirstColon(fileName, contractName);
|
|
70
70
|
}
|
|
71
71
|
const outputFile = output.contracts[fileName];
|
|
72
|
-
return outputFile[contractName].
|
|
72
|
+
return outputFile[contractName].qrvm.gasEstimates;
|
|
73
73
|
}
|
|
74
74
|
catch (e) {
|
|
75
75
|
return '';
|
|
@@ -314,7 +314,7 @@ function runTests(hypc, versionText) {
|
|
|
314
314
|
settings: {
|
|
315
315
|
outputSelection: {
|
|
316
316
|
'*': {
|
|
317
|
-
'*': ['
|
|
317
|
+
'*': ['qrvm.bytecode']
|
|
318
318
|
}
|
|
319
319
|
}
|
|
320
320
|
},
|
|
@@ -329,7 +329,7 @@ function runTests(hypc, versionText) {
|
|
|
329
329
|
};
|
|
330
330
|
function bytecodeExists(output, fileName, contractName) {
|
|
331
331
|
try {
|
|
332
|
-
return output.contracts[fileName][contractName].
|
|
332
|
+
return output.contracts[fileName][contractName].qrvm.bytecode.object.length > 0;
|
|
333
333
|
}
|
|
334
334
|
catch (e) {
|
|
335
335
|
return false;
|
|
@@ -351,7 +351,7 @@ function runTests(hypc, versionText) {
|
|
|
351
351
|
settings: {
|
|
352
352
|
outputSelection: {
|
|
353
353
|
'*': {
|
|
354
|
-
'*': ['
|
|
354
|
+
'*': ['qrvm.bytecode']
|
|
355
355
|
}
|
|
356
356
|
}
|
|
357
357
|
},
|
|
@@ -384,7 +384,7 @@ function runTests(hypc, versionText) {
|
|
|
384
384
|
settings: {
|
|
385
385
|
outputSelection: {
|
|
386
386
|
'*': {
|
|
387
|
-
'*': ['
|
|
387
|
+
'*': ['qrvm.bytecode']
|
|
388
388
|
}
|
|
389
389
|
}
|
|
390
390
|
},
|
|
@@ -404,14 +404,13 @@ function runTests(hypc, versionText) {
|
|
|
404
404
|
}
|
|
405
405
|
function bytecodeExists(output, fileName, contractName) {
|
|
406
406
|
try {
|
|
407
|
-
return output.contracts[fileName][contractName].
|
|
407
|
+
return output.contracts[fileName][contractName].qrvm.bytecode.object.length > 0;
|
|
408
408
|
}
|
|
409
409
|
catch (e) {
|
|
410
410
|
return false;
|
|
411
411
|
}
|
|
412
412
|
}
|
|
413
413
|
const output = JSON.parse(hypc.lowlevel.compileStandard(JSON.stringify(input), { import: findImports }));
|
|
414
|
-
console.log(JSON.stringify(input));
|
|
415
414
|
st.ok(bytecodeExists(output, 'a.hyp', 'A'));
|
|
416
415
|
st.ok(bytecodeExists(output, 'b.hyp', 'B'));
|
|
417
416
|
st.end();
|
|
@@ -422,7 +421,7 @@ function runTests(hypc, versionText) {
|
|
|
422
421
|
settings: {
|
|
423
422
|
outputSelection: {
|
|
424
423
|
'*': {
|
|
425
|
-
'*': ['
|
|
424
|
+
'*': ['qrvm.bytecode', 'qrvm.gasEstimates']
|
|
426
425
|
}
|
|
427
426
|
}
|
|
428
427
|
},
|
|
@@ -459,7 +458,7 @@ function runTests(hypc, versionText) {
|
|
|
459
458
|
settings: {
|
|
460
459
|
outputSelection: {
|
|
461
460
|
'*': {
|
|
462
|
-
'*': ['
|
|
461
|
+
'*': ['qrvm.bytecode', 'qrvm.gasEstimates']
|
|
463
462
|
}
|
|
464
463
|
}
|
|
465
464
|
},
|
|
@@ -504,7 +503,7 @@ function runTests(hypc, versionText) {
|
|
|
504
503
|
settings: {
|
|
505
504
|
outputSelection: {
|
|
506
505
|
'*': {
|
|
507
|
-
'*': ['
|
|
506
|
+
'*': ['qrvm.bytecode', 'qrvm.gasEstimates']
|
|
508
507
|
}
|
|
509
508
|
}
|
|
510
509
|
},
|
|
@@ -533,7 +532,7 @@ function runTests(hypc, versionText) {
|
|
|
533
532
|
settings: {
|
|
534
533
|
outputSelection: {
|
|
535
534
|
'*': {
|
|
536
|
-
'*': ['
|
|
535
|
+
'*': ['qrvm.bytecode']
|
|
537
536
|
}
|
|
538
537
|
}
|
|
539
538
|
},
|
|
@@ -574,12 +573,12 @@ function runTests(hypc, versionText) {
|
|
|
574
573
|
settings: {
|
|
575
574
|
libraries: {
|
|
576
575
|
'lib.hyp': {
|
|
577
|
-
L: '
|
|
576
|
+
L: 'Q42424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242'
|
|
578
577
|
}
|
|
579
578
|
},
|
|
580
579
|
outputSelection: {
|
|
581
580
|
'*': {
|
|
582
|
-
'*': ['
|
|
581
|
+
'*': ['qrvm.bytecode']
|
|
583
582
|
}
|
|
584
583
|
}
|
|
585
584
|
},
|
|
@@ -609,7 +608,7 @@ function runTests(hypc, versionText) {
|
|
|
609
608
|
settings: {
|
|
610
609
|
outputSelection: {
|
|
611
610
|
'*': {
|
|
612
|
-
'*': ['
|
|
611
|
+
'*': ['qrvm.bytecode']
|
|
613
612
|
}
|
|
614
613
|
}
|
|
615
614
|
},
|
|
@@ -634,12 +633,12 @@ function runTests(hypc, versionText) {
|
|
|
634
633
|
settings: {
|
|
635
634
|
libraries: {
|
|
636
635
|
'lib.hyp': {
|
|
637
|
-
L: '
|
|
636
|
+
L: 'Q42424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242'
|
|
638
637
|
}
|
|
639
638
|
},
|
|
640
639
|
outputSelection: {
|
|
641
640
|
'*': {
|
|
642
|
-
'*': ['
|
|
641
|
+
'*': ['qrvm.bytecode']
|
|
643
642
|
}
|
|
644
643
|
}
|
|
645
644
|
},
|
|
@@ -695,7 +694,7 @@ function runTests(hypc, versionText) {
|
|
|
695
694
|
settings: {
|
|
696
695
|
outputSelection: {
|
|
697
696
|
'*': {
|
|
698
|
-
'*': ['
|
|
697
|
+
'*': ['qrvm.bytecode']
|
|
699
698
|
}
|
|
700
699
|
}
|
|
701
700
|
},
|
|
@@ -718,7 +717,7 @@ function runTests(hypc, versionText) {
|
|
|
718
717
|
settings: {
|
|
719
718
|
outputSelection: {
|
|
720
719
|
'*': {
|
|
721
|
-
'*': ['
|
|
720
|
+
'*': ['qrvm.bytecode']
|
|
722
721
|
}
|
|
723
722
|
}
|
|
724
723
|
},
|
|
@@ -755,7 +754,7 @@ function runTests(hypc, versionText) {
|
|
|
755
754
|
settings: {
|
|
756
755
|
outputSelection: {
|
|
757
756
|
'*': {
|
|
758
|
-
'*': ['
|
|
757
|
+
'*': ['qrvm.bytecode']
|
|
759
758
|
}
|
|
760
759
|
}
|
|
761
760
|
},
|
|
@@ -778,7 +777,8 @@ runTests(__1.default, 'latest');
|
|
|
778
777
|
if (!noRemoteVersions) {
|
|
779
778
|
// New compiler interface features 0.0.1
|
|
780
779
|
const versions = [
|
|
781
|
-
'v0.0.1+commit.
|
|
780
|
+
'v0.0.1+commit.360d2d05',
|
|
781
|
+
'v0.1.0+commit.4b493011'
|
|
782
782
|
];
|
|
783
783
|
for (let version in versions) {
|
|
784
784
|
version = versions[version];
|
package/test/linker.js
CHANGED
|
@@ -5,6 +5,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const tape_1 = __importDefault(require("tape"));
|
|
7
7
|
const linker_1 = __importDefault(require("../linker"));
|
|
8
|
+
const LIB_HYP_L_64_BYTE_HASH = '7b407da2c9e54c64181b59f93be76d2e1be3a7a0dd4078c3bae5ca6125235fe45e6d0232229f7006f00e49901dd0bb51b52ac3ea8beef0422713a65cf0';
|
|
9
|
+
const LIB_HYP_L_64_BYTE_PLACEHOLDER = `__$${LIB_HYP_L_64_BYTE_HASH}$__`;
|
|
10
|
+
const ADDRESS_64_BYTES = '42'.repeat(64);
|
|
11
|
+
const PREFIXED_ADDRESS_64_BYTES = `Q${ADDRESS_64_BYTES}`;
|
|
12
|
+
function oldStylePlaceholder(libraryName) {
|
|
13
|
+
return `__${libraryName.slice(0, 124).padEnd(124, '_')}__`;
|
|
14
|
+
}
|
|
8
15
|
(0, tape_1.default)('Link references', function (t) {
|
|
9
16
|
t.test('Empty bytecode', function (st) {
|
|
10
17
|
st.deepEqual(linker_1.default.findLinkReferences(''), {});
|
|
@@ -14,119 +21,68 @@ const linker_1 = __importDefault(require("../linker"));
|
|
|
14
21
|
st.deepEqual(linker_1.default.findLinkReferences('6060604052341561000f57600080fd'), {});
|
|
15
22
|
st.end();
|
|
16
23
|
});
|
|
17
|
-
t.test('One reference', function (st) {
|
|
18
|
-
const bytecode =
|
|
19
|
-
st.deepEqual(linker_1.default.findLinkReferences(bytecode), {
|
|
24
|
+
t.test('One 64-byte hashed reference', function (st) {
|
|
25
|
+
const bytecode = `6060${LIB_HYP_L_64_BYTE_PLACEHOLDER}6060`;
|
|
26
|
+
st.deepEqual(linker_1.default.findLinkReferences(bytecode), { [`$${LIB_HYP_L_64_BYTE_HASH}$`]: [{ start: 2, length: 64 }] });
|
|
20
27
|
st.end();
|
|
21
28
|
});
|
|
22
|
-
t.test('
|
|
23
|
-
const bytecode = '
|
|
24
|
-
st.deepEqual(linker_1.default.findLinkReferences(bytecode), { '
|
|
29
|
+
t.test('One 64-byte old-style reference', function (st) {
|
|
30
|
+
const bytecode = `6060${oldStylePlaceholder('lib.hyp:L')}6060`;
|
|
31
|
+
st.deepEqual(linker_1.default.findLinkReferences(bytecode), { 'lib.hyp:L': [{ start: 2, length: 64 }] });
|
|
25
32
|
st.end();
|
|
26
33
|
});
|
|
27
|
-
t.test('
|
|
28
|
-
const bytecode = '
|
|
29
|
-
st.deepEqual(linker_1.default.findLinkReferences(bytecode), { '
|
|
30
|
-
st.end();
|
|
31
|
-
});
|
|
32
|
-
t.test('Library name with leading underscore (without fqdn)', function (st) {
|
|
33
|
-
const bytecode = '6060604052341561000f57600080fd5b60f48061001d6000396000f300606060405260043610603e5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166326121ff081146043575b600080fd5b3415604d57600080fd5b60536055565b005b73___L____________________________________6326121ff06040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160006040518083038186803b151560b357600080fd5b6102c65a03f4151560c357600080fd5b5050505600a165627a7a7230582089689827bbf0b7dc385ffcb4b1deb9f9e61741f61f89b4af65f806ff2b0d73470029';
|
|
34
|
-
st.deepEqual(linker_1.default.findLinkReferences(bytecode), { _L: [{ start: 116, length: 20 }] });
|
|
35
|
-
st.end();
|
|
36
|
-
});
|
|
37
|
-
t.test('Library name with underscore in the name', function (st) {
|
|
38
|
-
const bytecode = '6060604052341561000f57600080fd5b60f48061001d6000396000f300606060405260043610603e5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166326121ff081146043575b600080fd5b3415604d57600080fd5b60536055565b005b73__lib2.hyp:L_L__________________________6326121ff06040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160006040518083038186803b151560b357600080fd5b6102c65a03f4151560c357600080fd5b5050505600a165627a7a723058205cb324a27452cc7f8894a57cb0e3ddce2dce0c423e4fc993a3dd51287abd49110029';
|
|
39
|
-
st.deepEqual(linker_1.default.findLinkReferences(bytecode), { 'lib2.hyp:L_L': [{ start: 116, length: 20 }] });
|
|
40
|
-
st.end();
|
|
41
|
-
});
|
|
42
|
-
// Note: this is a case the reference finder cannot properly handle as there's no way to tell
|
|
43
|
-
t.test('Library name with trailing underscore', function (st) {
|
|
44
|
-
const bytecode = '6060604052341561000f57600080fd5b60f48061001d6000396000f300606060405260043610603e5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166326121ff081146043575b600080fd5b3415604d57600080fd5b60536055565b005b73__lib2.hyp:L____________________________6326121ff06040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160006040518083038186803b151560b357600080fd5b6102c65a03f4151560c357600080fd5b5050505600a165627a7a7230582058e61511a603707222cfa83fd3ae4269f94eb86513cb9042cf0b44877403d85c0029';
|
|
45
|
-
st.deepEqual(linker_1.default.findLinkReferences(bytecode), { 'lib2.hyp:L': [{ start: 116, length: 20 }] });
|
|
46
|
-
st.end();
|
|
47
|
-
});
|
|
48
|
-
t.test('Invalid input (too short)', function (st) {
|
|
49
|
-
const bytecode = '6060604052341561000____66606060606060';
|
|
50
|
-
st.deepEqual(linker_1.default.findLinkReferences(bytecode), {});
|
|
34
|
+
t.test('Two references with same library name', function (st) {
|
|
35
|
+
const bytecode = `6060${oldStylePlaceholder('lib.hyp:L')}6060${oldStylePlaceholder('lib.hyp:L')}6060`;
|
|
36
|
+
st.deepEqual(linker_1.default.findLinkReferences(bytecode), { 'lib.hyp:L': [{ start: 2, length: 64 }, { start: 68, length: 64 }] });
|
|
51
37
|
st.end();
|
|
52
38
|
});
|
|
53
|
-
t.test('Invalid
|
|
54
|
-
const bytecode = '
|
|
39
|
+
t.test('Invalid 20-byte reference is ignored', function (st) {
|
|
40
|
+
const bytecode = '6060__$7484607a72fb0587588e5a1e608f0b16de$__6060';
|
|
55
41
|
st.deepEqual(linker_1.default.findLinkReferences(bytecode), {});
|
|
56
42
|
st.end();
|
|
57
43
|
});
|
|
58
|
-
t.test('Two references with same library name', function (st) {
|
|
59
|
-
const bytecode = '6060604052341561000f57600080fd5b61011a8061001e6000396000f30060606040526004361060255763ffffffff60e060020a60003504166326121ff08114602a575b600080fd5b3415603457600080fd5b603a603c565b005b73__lib2.hyp:L____________________________6326121ff06040518163ffffffff1660e060020a02815260040160006040518083038186803b1515608157600080fd5b6102c65a03f41515609157600080fd5b50505073__lib2.hyp:L____________________________6326121ff06040518163ffffffff1660e060020a02815260040160006040518083038186803b151560d957600080fd5b6102c65a03f4151560e957600080fd5b5050505600a165627a7a72305820fdfb8eab411d7bc86d7dfbb0c985c30bebf1cc105dc5b807291551b3d5aa29d90029';
|
|
60
|
-
st.deepEqual(linker_1.default.findLinkReferences(bytecode), { 'lib2.hyp:L': [{ start: 92, length: 20 }, { start: 180, length: 20 }] });
|
|
61
|
-
st.end();
|
|
62
|
-
});
|
|
63
44
|
});
|
|
64
45
|
(0, tape_1.default)('Linking', function (t) {
|
|
65
|
-
t.test('
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
*/
|
|
70
|
-
let bytecode = '608060405234801561001057600080fd5b5061011f806100206000396000f300608060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063e2179b8e146044575b600080fd5b348015604f57600080fd5b5060566058565b005b73__lib.hyp:L_____________________________6326121ff06040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801560b757600080fd5b505af415801560ca573d6000803e3d6000fd5b505050506040513d602081101560df57600080fd5b8101908080519060200190929190505050505600a165627a7a72305820ea2f6353179c181d7162544d637b7fe2d9e8da9803a0e2d9eafc2188d1d59ee30029';
|
|
71
|
-
bytecode = linker_1.default.linkBytecode(bytecode, { 'lib.hyp:L': 'Z123456' });
|
|
72
|
-
st.ok(bytecode.indexOf('_') < 0);
|
|
46
|
+
t.test('64-byte hashed placeholder', function (st) {
|
|
47
|
+
let bytecode = `6060${LIB_HYP_L_64_BYTE_PLACEHOLDER}6060`;
|
|
48
|
+
bytecode = linker_1.default.linkBytecode(bytecode, { 'lib.hyp:L': PREFIXED_ADDRESS_64_BYTES });
|
|
49
|
+
st.equal(bytecode, `6060${ADDRESS_64_BYTES}6060`);
|
|
73
50
|
st.end();
|
|
74
51
|
});
|
|
75
|
-
t.test('
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
*/
|
|
80
|
-
let bytecode = '608060405234801561001057600080fd5b5061011f806100206000396000f300608060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063e2179b8e146044575b600080fd5b348015604f57600080fd5b5060566058565b005b73__lib.hyp:L_____________________________6326121ff06040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801560b757600080fd5b505af415801560ca573d6000803e3d6000fd5b505050506040513d602081101560df57600080fd5b8101908080519060200190929190505050505600a165627a7a72305820ea2f6353179c181d7162544d637b7fe2d9e8da9803a0e2d9eafc2188d1d59ee30029';
|
|
81
|
-
bytecode = linker_1.default.linkBytecode(bytecode, { 'lib.hyp': { L: 'Z123456' } });
|
|
82
|
-
st.ok(bytecode.indexOf('_') < 0);
|
|
52
|
+
t.test('64-byte old-style placeholder', function (st) {
|
|
53
|
+
let bytecode = `6060${oldStylePlaceholder('lib.hyp:L')}6060`;
|
|
54
|
+
bytecode = linker_1.default.linkBytecode(bytecode, { 'lib.hyp:L': PREFIXED_ADDRESS_64_BYTES });
|
|
55
|
+
st.equal(bytecode, `6060${ADDRESS_64_BYTES}6060`);
|
|
83
56
|
st.end();
|
|
84
57
|
});
|
|
85
|
-
t.test('
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
*/
|
|
90
|
-
let bytecode = '608060405234801561001057600080fd5b5061011f806100206000396000f300608060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063e2179b8e146044575b600080fd5b348015604f57600080fd5b5060566058565b005b73__lib.hyp:L_____________________________6326121ff06040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801560b757600080fd5b505af415801560ca573d6000803e3d6000fd5b505050506040513d602081101560df57600080fd5b8101908080519060200190929190505050505600a165627a7a72305820ea2f6353179c181d7162544d637b7fe2d9e8da9803a0e2d9eafc2188d1d59ee30029';
|
|
91
|
-
bytecode = linker_1.default.linkBytecode(bytecode, {});
|
|
92
|
-
st.ok(bytecode.indexOf('_') >= 0);
|
|
58
|
+
t.test('64-byte old-style placeholder with two-level configuration', function (st) {
|
|
59
|
+
let bytecode = `6060${oldStylePlaceholder('lib.hyp:L')}6060`;
|
|
60
|
+
bytecode = linker_1.default.linkBytecode(bytecode, { 'lib.hyp': { L: PREFIXED_ADDRESS_64_BYTES } });
|
|
61
|
+
st.equal(bytecode, `6060${ADDRESS_64_BYTES}6060`);
|
|
93
62
|
st.end();
|
|
94
63
|
});
|
|
95
|
-
t.test('
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
'cont.hyp': 'import "lib.hyp"; contract x { function g() public { L.f(); } }'
|
|
99
|
-
*/
|
|
100
|
-
const bytecode = '608060405234801561001057600080fd5b5061011f806100206000396000f300608060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063e2179b8e146044575b600080fd5b348015604f57600080fd5b5060566058565b005b73__lib.hyp:L_____________________________6326121ff06040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801560b757600080fd5b505af415801560ca573d6000803e3d6000fd5b505050506040513d602081101560df57600080fd5b8101908080519060200190929190505050505600a165627a7a72305820ea2f6353179c181d7162544d637b7fe2d9e8da9803a0e2d9eafc2188d1d59ee30029';
|
|
101
|
-
st.throws(function () {
|
|
102
|
-
linker_1.default.linkBytecode(bytecode, { 'lib.hyp:L': '' });
|
|
103
|
-
});
|
|
64
|
+
t.test('missing library leaves placeholder unresolved', function (st) {
|
|
65
|
+
const bytecode = `6060${oldStylePlaceholder('lib.hyp:L')}6060`;
|
|
66
|
+
st.equal(linker_1.default.linkBytecode(bytecode, {}), bytecode);
|
|
104
67
|
st.end();
|
|
105
68
|
});
|
|
106
|
-
t.test('
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
let bytecode = '608060405234801561001057600080fd5b5061011f806100206000396000f300608060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063e2179b8e146044575b600080fd5b348015604f57600080fd5b5060566058565b005b73__lib.hyp:L123456789012345678901234567__6326121ff06040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801560b757600080fd5b505af415801560ca573d6000803e3d6000fd5b505050506040513d602081101560df57600080fd5b8101908080519060200190929190505050505600a165627a7a723058209f88ff686bd8ceb0fc08853dc1332d5ff81dbcf5af3a1e9aa366828091761f8c0029';
|
|
112
|
-
bytecode = linker_1.default.linkBytecode(bytecode, { 'lib.hyp:L1234567890123456789012345678901234567890': 'Z123456' });
|
|
113
|
-
st.ok(bytecode.indexOf('_') < 0);
|
|
69
|
+
t.test('short address is invalid', function (st) {
|
|
70
|
+
const bytecode = `6060${oldStylePlaceholder('lib.hyp:L')}6060`;
|
|
71
|
+
st.throws(function () {
|
|
72
|
+
linker_1.default.linkBytecode(bytecode, { 'lib.hyp:L': 'Q123456' });
|
|
73
|
+
});
|
|
114
74
|
st.end();
|
|
115
75
|
});
|
|
116
|
-
t.test('
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
76
|
+
t.test('non-hex address is invalid', function (st) {
|
|
77
|
+
const bytecode = `6060${oldStylePlaceholder('lib.hyp:L')}6060`;
|
|
78
|
+
st.throws(function () {
|
|
79
|
+
linker_1.default.linkBytecode(bytecode, { 'lib.hyp:L': `Q${'z'.repeat(128)}` });
|
|
80
|
+
});
|
|
120
81
|
st.end();
|
|
121
82
|
});
|
|
122
|
-
t.test('
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
'cont.hyp': 'import "lib.hyp"; contract x { function g() public { L.f(); } }'
|
|
126
|
-
*/
|
|
127
|
-
let bytecode = '608060405234801561001057600080fd5b5061011f806100206000396000f300608060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063e2179b8e146044575b600080fd5b348015604f57600080fd5b5060566058565b005b73__libName_______________________________6326121ff06040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801560b757600080fd5b505af415801560ca573d6000803e3d6000fd5b505050506040513d602081101560df57600080fd5b8101908080519060200190929190505050505600a165627a7a72305820ea2f6353179c181d7162544d637b7fe2d9e8da9803a0e2d9eafc2188d1d59ee30029';
|
|
128
|
-
bytecode = linker_1.default.linkBytecode(bytecode, { libName: 'Z123456' });
|
|
129
|
-
st.ok(bytecode.indexOf('_') < 0);
|
|
83
|
+
t.test('20-byte placeholder is not linked', function (st) {
|
|
84
|
+
const bytecode = '6060__$7484607a72fb0587588e5a1e608f0b16de$__6060';
|
|
85
|
+
st.equal(linker_1.default.linkBytecode(bytecode, { 'lib2.hyp:L': PREFIXED_ADDRESS_64_BYTES }), bytecode);
|
|
130
86
|
st.end();
|
|
131
87
|
});
|
|
132
88
|
});
|
package/test/translate.js
CHANGED
|
@@ -53,11 +53,11 @@ const versionToSemver = translate_1.default.versionToSemver;
|
|
|
53
53
|
st.end();
|
|
54
54
|
});
|
|
55
55
|
t.test('Broken 0.1.3', function (st) {
|
|
56
|
-
st.equal(versionToSemver('0.1.3-0/.-/clang/int linked to
|
|
56
|
+
st.equal(versionToSemver('0.1.3-0/.-/clang/int linked to libqrl-0.9.92-0/.-/clang/int'), '0.1.3');
|
|
57
57
|
st.end();
|
|
58
58
|
});
|
|
59
59
|
t.test('Old style 0.2.0', function (st) {
|
|
60
|
-
st.equal(versionToSemver('0.2.0-e7098958/.-Emscripten/clang/int linked to
|
|
60
|
+
st.equal(versionToSemver('0.2.0-e7098958/.-Emscripten/clang/int linked to libqrl-1.1.1-bbb80ab0/.-Emscripten/clang/int'), '0.2.0+commit.e7098958');
|
|
61
61
|
st.end();
|
|
62
62
|
});
|
|
63
63
|
t.test('Old style 0.3.5', function (st) {
|
package/translate.js
CHANGED
|
@@ -7,8 +7,8 @@ const linker_1 = __importDefault(require("./linker"));
|
|
|
7
7
|
/// Old style: 0.3.6-3fc68da5/Release-Emscripten/clang
|
|
8
8
|
/// 0.3.5-371690f0/Release-Emscripten/clang/Interpreter
|
|
9
9
|
/// 0.3.5-0/Release-Emscripten/clang/Interpreter
|
|
10
|
-
/// 0.2.0-e7098958/.-Emscripten/clang/int linked to
|
|
11
|
-
/// 0.1.3-0/.-/clang/int linked to
|
|
10
|
+
/// 0.2.0-e7098958/.-Emscripten/clang/int linked to libqrl-1.1.1-bbb80ab0/.-Emscripten/clang/int
|
|
11
|
+
/// 0.1.3-0/.-/clang/int linked to libqrl-0.9.92-0/.-/clang/int
|
|
12
12
|
/// 0.1.2-5c3bfd4b*/.-/clang/int
|
|
13
13
|
/// 0.1.1-6ff4cd6b/RelWithDebInfo-Emscripten/clang/int
|
|
14
14
|
/// New style: 0.4.5+commit.b318366e.Emscripten.clang
|
|
@@ -106,7 +106,7 @@ function translateJsonCompilerOutput(output, libraries) {
|
|
|
106
106
|
const contractOutput = {
|
|
107
107
|
abi: JSON.parse(contractInput.interface),
|
|
108
108
|
metadata: contractInput.metadata,
|
|
109
|
-
|
|
109
|
+
qrvm: {
|
|
110
110
|
legacyAssembly: contractInput.assembly,
|
|
111
111
|
bytecode: {
|
|
112
112
|
object: contractInput.bytecode && linker_1.default.linkBytecode(contractInput.bytecode, libraries || {}),
|
package/contractA_hyp_A.bin
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
6080604052348015600e575f80fd5b50603e80601a5f395ff3fe60806040525f80fdfea26469706673582212207da9777c17d9abc5309ba89332ae703efba54bf7fb9c290d475d6c0f7cb7a6c86468797063430000020033
|
package/contractB_hyp_B.bin
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
6080604052348015600e575f80fd5b50603e80601a5f395ff3fe60806040525f80fdfea264697066735822122019ceaad2fc0893d39b61042424757a67bf6723d77172da4c38279007c2723bbf6468797063430000020033
|
package/importA_hyp_C.bin
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
6080604052348015600e575f80fd5b5060ab8061001b5f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c806326121ff014602a575b5f80fd5b60306044565b604051603b9190605e565b60405180910390f35b5f90565b5f819050919050565b6058816048565b82525050565b5f602082019050606f5f8301846051565b9291505056fea264697066735822122003aa2795a073c7ca2063308c3a8a13fb3a1ce6028c399f889636bd9eabe1f73f6468797063430000020033
|
package/importB_hyp_D.bin
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
6080604052348015600e575f80fd5b5060ab8061001b5f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c806326121ff014602a575b5f80fd5b60306044565b604051603b9190605e565b60405180910390f35b5f90565b5f819050919050565b6058816048565b82525050565b5f602082019050606f5f8301846051565b9291505056fea2646970667358221220f96d6c685f4fe201ee93ca17a8b69d8182984a86c16908f46d7becc54efcfb846468797063430000020033
|
package/libX_hyp_X.bin
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
6055604b600b8282823980515f1a607314603f577f4e487b71000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b305f52607381538281f3fe730000000000000000000000000000000000000000301460806040525f80fdfea2646970667358221220e78306f3d7dc80c45acbd51f639ead3e6f620f10144ea624b2c7e88c6c1504e96468797063430000020033
|
package/libY_hyp_Y.bin
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
6055604b600b8282823980515f1a607314603f577f4e487b71000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b305f52607381538281f3fe730000000000000000000000000000000000000000301460806040525f80fdfea2646970667358221220fe2cbe5e62e395650d519ac764d3d5271e9af30d3e271d1c291677812e14d7ce6468797063430000020033
|
package/libZ_hyp_Z.bin
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
6055604b600b8282823980515f1a607314603f577f4e487b71000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b305f52607381538281f3fe730000000000000000000000000000000000000000301460806040525f80fdfea26469706673582212208cf9773d6268fc017aed7c3282d7e4ec482fd3b5d956250412103e5d65854bfc6468797063430000020033
|