@super-protocol/addons-tee 0.5.0 → 0.6.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.
|
Binary file
|
|
@@ -10,27 +10,28 @@ const stream_1 = require("stream");
|
|
|
10
10
|
// @TODO: Read it from nodejs module
|
|
11
11
|
const PF_SIZE = 4096;
|
|
12
12
|
const chunkedTransformer = (chunkSize = PF_SIZE) => {
|
|
13
|
-
|
|
13
|
+
const accumulateBuf = {
|
|
14
|
+
buf: Buffer.alloc(chunkSize),
|
|
15
|
+
bufSize: 0,
|
|
16
|
+
};
|
|
14
17
|
return new stream_1.Transform({
|
|
15
|
-
objectMode:
|
|
16
|
-
highWaterMark: PF_SIZE,
|
|
17
|
-
writableHighWaterMark: PF_SIZE,
|
|
18
|
-
readableHighWaterMark: PF_SIZE,
|
|
18
|
+
objectMode: false,
|
|
19
19
|
flush: (callback) => {
|
|
20
|
-
callback(null,
|
|
21
|
-
|
|
20
|
+
callback(null, accumulateBuf.buf.subarray(0, accumulateBuf.bufSize));
|
|
21
|
+
accumulateBuf.buf = Buffer.alloc(0);
|
|
22
|
+
accumulateBuf.bufSize = 0;
|
|
22
23
|
},
|
|
23
24
|
transform: function (chunk, encoding, callback) {
|
|
24
|
-
if (
|
|
25
|
-
|
|
25
|
+
if (chunk.length + accumulateBuf.bufSize < chunkSize) {
|
|
26
|
+
const copied = chunk.copy(accumulateBuf.buf, accumulateBuf.bufSize);
|
|
27
|
+
accumulateBuf.bufSize += copied;
|
|
26
28
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
else {
|
|
30
|
+
const mergedBuf = Buffer.concat([accumulateBuf.buf.subarray(0, accumulateBuf.bufSize), chunk]);
|
|
31
|
+
accumulateBuf.bufSize = 0;
|
|
32
|
+
this.push(mergedBuf);
|
|
31
33
|
}
|
|
32
|
-
|
|
33
|
-
callback(null, chunks);
|
|
34
|
+
callback(null, null);
|
|
34
35
|
},
|
|
35
36
|
});
|
|
36
37
|
};
|
|
@@ -82,29 +83,47 @@ class EnclaveService {
|
|
|
82
83
|
const protectedFsKey = secretKey.length !== 16
|
|
83
84
|
? (0, crypto_1.createHash)("sha256", secretKey).update(secretKey).digest().slice(0, 16)
|
|
84
85
|
: secretKey;
|
|
85
|
-
|
|
86
|
+
let output = null;
|
|
86
87
|
try {
|
|
87
|
-
const
|
|
88
|
+
const benchTimingStart = new Date();
|
|
89
|
+
output = new GramineProtectedFS(tmpFileName, filepath, protectedFsKey, true);
|
|
88
90
|
let totalSize = 0;
|
|
91
|
+
let pfChunkSize = PF_SIZE;
|
|
92
|
+
if (process.env["GRAMINE_PROTECTED_FILES_STREAM_CACHE_SIZE"]) {
|
|
93
|
+
pfChunkSize = parseInt(process.env["GRAMINE_PROTECTED_FILES_STREAM_CACHE_SIZE"]);
|
|
94
|
+
}
|
|
89
95
|
let batchChunkIndex = 0;
|
|
90
96
|
const everyTenFlush = 10;
|
|
91
|
-
for await (const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
continue;
|
|
96
|
-
}
|
|
97
|
-
const writtenSize = await output.write(totalSize, chunk);
|
|
98
|
-
if (writtenSize !== chunk.length) {
|
|
99
|
-
throw new Error(`Fail to write ${chunk.length} to protected file ${filepath}:${tmpFileName}, written only ${writtenSize} bytes`);
|
|
100
|
-
}
|
|
101
|
-
totalSize += writtenSize;
|
|
97
|
+
for await (const chunk of inputStream.pipe(chunkedTransformer(pfChunkSize))) {
|
|
98
|
+
if (!chunk.length) {
|
|
99
|
+
// @TODO: It's may be normal, research
|
|
100
|
+
continue;
|
|
102
101
|
}
|
|
102
|
+
const writtenSize = await output.write(totalSize, chunk);
|
|
103
|
+
if (writtenSize !== chunk.length) {
|
|
104
|
+
throw new Error(`Fail to write ${chunk.length} to protected file ${filepath}:${tmpFileName}, written only ${writtenSize} bytes`);
|
|
105
|
+
}
|
|
106
|
+
totalSize += writtenSize;
|
|
103
107
|
if (batchChunkIndex && batchChunkIndex++ % everyTenFlush) {
|
|
104
108
|
await output.flush();
|
|
105
109
|
}
|
|
106
110
|
}
|
|
107
111
|
await output.close();
|
|
112
|
+
const repackTime = new Date().getTime() - benchTimingStart.getTime();
|
|
113
|
+
let timeSpent = "0";
|
|
114
|
+
if (repackTime > 0) {
|
|
115
|
+
timeSpent = ((1000 * totalSize) / 1024 / 1024 / repackTime).toFixed(3);
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
timeSpent = "Undef";
|
|
119
|
+
}
|
|
120
|
+
console.log("Repack PF-file: " +
|
|
121
|
+
(totalSize / 1024 / 1024).toFixed(3) +
|
|
122
|
+
" Mb - " +
|
|
123
|
+
(repackTime / 1000).toFixed(3) +
|
|
124
|
+
" sec = " +
|
|
125
|
+
timeSpent +
|
|
126
|
+
" Mb/Sec");
|
|
108
127
|
return {
|
|
109
128
|
filepath: tmpFileName,
|
|
110
129
|
filesize: (await fs_1.promises.stat(tmpFileName)).size,
|
|
@@ -191,4 +210,4 @@ class EnclaveService {
|
|
|
191
210
|
}
|
|
192
211
|
}
|
|
193
212
|
exports.EnclaveService = EnclaveService;
|
|
194
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
213
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW5jbGF2ZS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NneC1uYXRpdmUtbW9kdWxlL2VuY2xhdmUuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxNQUFNLEVBQUUsV0FBVyxFQUFFLGtCQUFrQixFQUFFLEdBQUcsT0FBTyxDQUFDLHlEQUF5RCxDQUFDLENBQUM7QUFDL0csbUNBQWlEO0FBQ2pELDJCQUF1RTtBQUN2RSwyQkFBNEI7QUFDNUIsK0JBQTRCO0FBQzVCLG1DQUF1RDtBQUd2RCxvQ0FBb0M7QUFDcEMsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDO0FBNkNyQixNQUFNLGtCQUFrQixHQUFHLENBQUMsU0FBUyxHQUFHLE9BQU8sRUFBYSxFQUFFO0lBQzFELE1BQU0sYUFBYSxHQUFHO1FBQ2xCLEdBQUcsRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQztRQUM1QixPQUFPLEVBQUUsQ0FBQztLQUNiLENBQUM7SUFFRixPQUFPLElBQUksa0JBQVMsQ0FBQztRQUNqQixVQUFVLEVBQUUsS0FBSztRQUVqQixLQUFLLEVBQUUsQ0FBQyxRQUFRLEVBQUUsRUFBRTtZQUNoQixRQUFRLENBQUMsSUFBSSxFQUFFLGFBQWEsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztZQUNyRSxhQUFhLENBQUMsR0FBRyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDcEMsYUFBYSxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUM7UUFDOUIsQ0FBQztRQUNELFNBQVMsRUFBRSxVQUFVLEtBQUssRUFBRSxRQUFRLEVBQUUsUUFBUTtZQUMxQyxJQUFJLEtBQUssQ0FBQyxNQUFNLEdBQUcsYUFBYSxDQUFDLE9BQU8sR0FBRyxTQUFTLEVBQUU7Z0JBQ2xELE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxJ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
|