Skip to content

Commit 5ca2aa0

Browse files
authored
Use correct CIDs (#41)
* Use correct CIDs * Add default multicode for hash * Revert changes to hash test * CID type selection improvements
1 parent 1580e7c commit 5ca2aa0

15 files changed

+103
-45
lines changed

build/main.js

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -169,9 +169,9 @@ function checkKey(key) {
169169
throw new Error(`bad key: ${JSON.stringify(key)}`);
170170
}
171171
}
172-
async function createEntryFromFile(filepath) {
172+
async function createEntryFromFile(filepath, multicode) {
173173
const buffer = await Deno.readFile(filepath);
174-
const key = createCID(buffer);
174+
const key = createCID(buffer, multicode);
175175
return [key, buffer];
176176
}
177177
function createCID(data, multicode = multicodes.RAW) {
@@ -260,7 +260,15 @@ var init_utils = __esm({
260260
init_database_sqlite();
261261
backends = { fs: database_fs_exports, sqlite: database_sqlite_exports };
262262
multibase = base58btc;
263-
multicodes = { JSON: 512, RAW: 0 };
263+
multicodes = {
264+
RAW: 0,
265+
JSON: 512,
266+
SHELTER_CONTRACT_MANIFEST: 5316096,
267+
SHELTER_CONTRACT_TEXT: 5316097,
268+
SHELTER_CONTRACT_DATA: 5316098,
269+
SHELTER_FILE_MANIFEST: 5316099,
270+
SHELTER_FILE_CHUNK: 5316100
271+
};
264272
multihasher = default3.blake2b.blake2b256;
265273
readJsonFile = async (file) => {
266274
const contents = await Deno.readTextFile(path.resolve(String(file)));
@@ -297,8 +305,25 @@ async function upload(args, internal = false) {
297305
throw new Error(`missing files!`);
298306
const uploaded = [];
299307
const uploaderFn = await isDir(urlOrDirOrSqliteFile) ? uploadEntryToDir : urlOrDirOrSqliteFile.endsWith(".db") ? uploadEntryToSQLite : uploadEntryToURL;
300-
for (const filepath of files) {
301-
const entry = await createEntryFromFile(filepath);
308+
for (const filepath_ of files) {
309+
let type = multicodes.RAW;
310+
let filepath = filepath_;
311+
if (filepath_[1] === "|") {
312+
switch (filepath_[0]) {
313+
case "r":
314+
break;
315+
case "m":
316+
type = multicodes.SHELTER_CONTRACT_MANIFEST;
317+
break;
318+
case "t":
319+
type = multicodes.SHELTER_CONTRACT_TEXT;
320+
break;
321+
default:
322+
throw new Error("Unknown file type: " + filepath_[0]);
323+
}
324+
filepath = filepath_.slice(2);
325+
}
326+
const entry = await createEntryFromFile(filepath, type);
302327
const destination = await uploaderFn(entry, urlOrDirOrSqliteFile);
303328
if (!internal) {
304329
console.log(colors.green("uploaded:"), destination);
@@ -351,11 +376,11 @@ async function deploy(args) {
351376
const json = JSON.parse(Deno.readTextFileSync(manifestPath));
352377
const body = JSON.parse(json.body);
353378
const dirname = path.dirname(manifestPath);
354-
toUpload.push(path.join(dirname, body.contract.file));
379+
toUpload.push("t|" + path.join(dirname, body.contract.file));
355380
if (body.contractSlim) {
356-
toUpload.push(path.join(dirname, body.contractSlim.file));
381+
toUpload.push("t|" + path.join(dirname, body.contractSlim.file));
357382
}
358-
toUpload.push(manifestPath);
383+
toUpload.push("m|" + manifestPath);
359384
}
360385
await upload([urlOrDirOrSqliteFile, ...toUpload], true);
361386
}
@@ -458,13 +483,13 @@ async function get(args) {
458483

459484
// src/hash.ts
460485
init_utils();
461-
async function hash(args, internal = false) {
486+
async function hash(args, multicode = multicodes.RAW, internal = false) {
462487
const [filename] = args;
463488
if (!filename) {
464489
console.error("please pass in a file");
465490
Deno.exit(1);
466491
}
467-
const [cid] = await createEntryFromFile(filename);
492+
const [cid] = await createEntryFromFile(filename, multicode);
468493
if (!internal) {
469494
console.log(`CID(${filename}):`, cid);
470495
}
@@ -787,15 +812,15 @@ async function manifest(args) {
787812
name,
788813
version: version2,
789814
contract: {
790-
hash: await hash([contractFile], true),
815+
hash: await hash([contractFile], multicodes.SHELTER_CONTRACT_TEXT, true),
791816
file: contractBasename
792817
},
793818
signingKeys: publicKeys
794819
};
795820
if (slim) {
796821
body.contractSlim = {
797822
file: path.basename(slim),
798-
hash: await hash([slim], true)
823+
hash: await hash([slim], multicodes.SHELTER_CONTRACT_TEXT, true)
799824
};
800825
}
801826
const serializedBody = JSON.stringify(body);
@@ -920,12 +945,12 @@ var verifySignature2 = async (args, internal = false) => {
920945
if (!body.contract?.file) {
921946
exit("Invalid manifest: no contract file", internal);
922947
}
923-
const computedHash = await hash([path.join(parsedFilepath.dir, body.contract.file)], true);
948+
const computedHash = await hash([path.join(parsedFilepath.dir, body.contract.file)], multicodes.SHELTER_CONTRACT_TEXT, true);
924949
if (computedHash !== body.contract.hash) {
925950
exit(`Invalid contract file hash. Expected ${body.contract.hash} but got ${computedHash}`, internal);
926951
}
927952
if (body.contractSlim) {
928-
const computedHash2 = await hash([path.join(parsedFilepath.dir, body.contractSlim.file)], true);
953+
const computedHash2 = await hash([path.join(parsedFilepath.dir, body.contractSlim.file)], multicodes.SHELTER_CONTRACT_TEXT, true);
929954
if (computedHash2 !== body.contractSlim.hash) {
930955
exit(`Invalid slim contract file hash. Expected ${body.contractSlim.hash} but got ${computedHash2}`, internal);
931956
}

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/deploy.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
import { path } from './deps.ts'
66
import { upload } from './upload.ts'
77

8+
// Prefixes to use to select the correct CID to use
9+
const CONTRACT_TEXT_PREFIX = `t|`
10+
const CONTRACT_MANIFEST_PREFIX = `m|`
11+
812
export async function deploy (args: string[]) {
913
const [urlOrDirOrSqliteFile, ...manifests] = args
1014
if (manifests.length === 0) throw new Error('missing url or manifests!')
@@ -13,11 +17,11 @@ export async function deploy (args: string[]) {
1317
const json = JSON.parse(Deno.readTextFileSync(manifestPath))
1418
const body = JSON.parse(json.body)
1519
const dirname = path.dirname(manifestPath)
16-
toUpload.push(path.join(dirname, body.contract.file))
20+
toUpload.push(CONTRACT_TEXT_PREFIX + path.join(dirname, body.contract.file))
1721
if (body.contractSlim) {
18-
toUpload.push(path.join(dirname, body.contractSlim.file))
22+
toUpload.push(CONTRACT_TEXT_PREFIX + path.join(dirname, body.contractSlim.file))
1923
}
20-
toUpload.push(manifestPath)
24+
toUpload.push(CONTRACT_MANIFEST_PREFIX + manifestPath)
2125
}
2226
await upload([urlOrDirOrSqliteFile, ...toUpload], true)
2327
}

src/hash.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
'use strict'
22

3-
import { createEntryFromFile } from './utils.ts'
3+
import { createEntryFromFile, multicodes } from './utils.ts'
44

55
// TODO: use https://doc.deno.land/https://deno.land/[email protected]/streams/mod.ts/~/iterateReader instead to read in large files, and then use blake2b[Init,Update,Final] to iteratively calculate the hash
66
// Verify that it returns the same hash as when we use readAll https://doc.deno.land/https://deno.land/[email protected]/streams/mod.ts/~/readAll
77

8-
export async function hash (args: string[], internal = false) {
8+
export async function hash (args: string[], multicode: number = multicodes.RAW, internal = false) {
99
const [filename] = args
1010
if (!filename) {
1111
console.error('please pass in a file')
1212
Deno.exit(1)
1313
}
14-
const [cid] = await createEntryFromFile(filename)
14+
const [cid] = await createEntryFromFile(filename, multicode)
1515
if (!internal) {
1616
console.log(`CID(${filename}):`, cid)
1717
}

src/manifest.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import { flags, path, colors } from './deps.ts'
99
import { hash } from './hash.ts'
10-
import { exit, readJsonFile, revokeNet } from './utils.ts'
10+
import { exit, multicodes, readJsonFile, revokeNet } from './utils.ts'
1111
import { EDWARDS25519SHA512BATCH, deserializeKey, keyId, serializeKey, sign } from './lib/crypto.ts'
1212

1313
// import { writeAllSync } from "https://deno.land/[email protected]/streams/mod.ts"
@@ -45,15 +45,15 @@ export async function manifest (args: string[]) {
4545
name,
4646
version,
4747
contract: {
48-
hash: await hash([contractFile as string], true),
48+
hash: await hash([contractFile as string], multicodes.SHELTER_CONTRACT_TEXT, true),
4949
file: contractBasename
5050
},
5151
signingKeys: publicKeys
5252
}
5353
if (slim) {
5454
body.contractSlim = {
5555
file: path.basename(slim),
56-
hash: await hash([slim], true)
56+
hash: await hash([slim], multicodes.SHELTER_CONTRACT_TEXT, true)
5757
}
5858
}
5959
const serializedBody = JSON.stringify(body)

src/upload.ts

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict'
22

33
import { path, colors } from './deps.ts'
4-
import { type Entry, createEntryFromFile, isDir, revokeNet } from './utils.ts'
4+
import { type Entry, createEntryFromFile, isDir, multicodes, revokeNet } from './utils.ts'
55

66
// chel upload <url-or-dir-or-sqlitedb> <file1> [<file2> [<file3> ...]]
77

@@ -14,8 +14,28 @@ export async function upload (args: string[], internal = false) {
1414
: urlOrDirOrSqliteFile.endsWith('.db')
1515
? uploadEntryToSQLite
1616
: uploadEntryToURL
17-
for (const filepath of files) {
18-
const entry = await createEntryFromFile(filepath)
17+
for (const filepath_ of files) {
18+
let type = multicodes.RAW
19+
let filepath = filepath_
20+
if (internal) {
21+
// The `{type}|` prefix is used to determine which kind of CID is needed
22+
if (filepath_[1] !== '|') throw new Error('Invalid path format')
23+
switch (filepath_[0]) {
24+
case 'r':
25+
// raw file type
26+
break
27+
case 'm':
28+
type = multicodes.SHELTER_CONTRACT_MANIFEST
29+
break
30+
case 't':
31+
type = multicodes.SHELTER_CONTRACT_TEXT
32+
break
33+
default:
34+
throw new Error('Unknown file type: ' + filepath_[0])
35+
}
36+
filepath = filepath_.slice(2)
37+
}
38+
const entry = await createEntryFromFile(filepath, type)
1939
const destination = await uploaderFn(entry, urlOrDirOrSqliteFile)
2040
if (!internal) {
2141
console.log(colors.green('uploaded:'), destination)

src/utils.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,15 @@ import * as sqlite from './database-sqlite.ts'
88
const backends = { fs, sqlite }
99
const multibase = base58btc
1010
// Values from https://github.com/multiformats/multicodec/blob/master/table.csv
11-
const multicodes = { JSON: 0x0200, RAW: 0x00 }
11+
export const multicodes = {
12+
RAW: 0x00,
13+
JSON: 0x0200,
14+
SHELTER_CONTRACT_MANIFEST: 0x511e00,
15+
SHELTER_CONTRACT_TEXT: 0x511e01,
16+
SHELTER_CONTRACT_DATA: 0x511e02,
17+
SHELTER_FILE_MANIFEST: 0x511e03,
18+
SHELTER_FILE_CHUNK: 0x511e04
19+
}
1220
// @ts-ignore Property 'blake2b256' does not exist on type '{}'.
1321
const multihasher = blake.blake2b.blake2b256
1422

@@ -22,9 +30,9 @@ export function checkKey (key: string): void {
2230
}
2331
}
2432

25-
export async function createEntryFromFile (filepath: string): Promise<Entry> {
33+
export async function createEntryFromFile (filepath: string, multicode: number): Promise<Entry> {
2634
const buffer = await Deno.readFile(filepath)
27-
const key = createCID(buffer)
35+
const key = createCID(buffer, multicode)
2836
return [key, buffer]
2937
}
3038

src/verifySignature.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { hash } from './commands.ts'
22
import { colors, flags, path } from './deps.ts'
33
import { verifySignature as cryptoVerifySignature, deserializeKey, keyId } from './lib/crypto.ts'
4-
import { exit, readJsonFile, revokeNet } from './utils.ts'
4+
import { exit, multicodes, readJsonFile, revokeNet } from './utils.ts'
55

66
export const verifySignature = async (args: string[], internal = false) => {
77
await revokeNet()
@@ -64,13 +64,13 @@ export const verifySignature = async (args: string[], internal = false) => {
6464
if (!body.contract?.file) {
6565
exit('Invalid manifest: no contract file', internal)
6666
}
67-
const computedHash = await hash([path.join(parsedFilepath.dir, body.contract.file)], true)
67+
const computedHash = await hash([path.join(parsedFilepath.dir, body.contract.file)], multicodes.SHELTER_CONTRACT_TEXT, true)
6868
if (computedHash !== body.contract.hash) {
6969
exit(`Invalid contract file hash. Expected ${body.contract.hash} but got ${computedHash}`, internal)
7070
}
7171

7272
if (body.contractSlim) {
73-
const computedHash = await hash([path.join(parsedFilepath.dir, body.contractSlim.file)], true)
73+
const computedHash = await hash([path.join(parsedFilepath.dir, body.contractSlim.file)], multicodes.SHELTER_CONTRACT_TEXT, true)
7474
if (computedHash !== body.contractSlim.hash) {
7575
exit(`Invalid slim contract file hash. Expected ${body.contractSlim.hash} but got ${computedHash}`, internal)
7676
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"head":"{\"manifestVersion\":\"1.0.0\"}","body":"{\"version\":\"x\",\"contract\":{\"hash\":\"z9brRu3VFNnnn1BgyRBaQfs7Jyrx18K2ASgDKAiLyWx3KMVQGL8X\",\"file\":\"bundle-tampered.bundle.example\"},\"signingKeys\":[\"[\\\"edwards25519sha512batch\\\",\\\"PW6nt32OYuWpbHfUk5HtcSTgP+k28Uu752BkLun4U1Y=\\\",null]\",\"[\\\"edwards25519sha512batch\\\",\\\"PfdE8jdWCexc4vDrr6dHworStAhO4Jt8rf6cbdoLxT8=\\\",null]\"],\"contractSlim\":{\"file\":\"bundle-tampered.slim.example\",\"hash\":\"z9brRu3VFNnnn1BgyRBaQfs7Jyrx18K2ASgDKAiLyWx3KMVQGL8X\"}}","signature":{"keyId":"z2Drjgb5QQTKooY4YntALeT1uEQtpo9bP7J9gt5g6kUyhtL5bPd","value":"0kzsDs1sT2A9y8hVKlf7FQBOhnIxaOa1CHWf4+bVE3xBXFt+TyjKpdHKEZ3cc/Qn6i3l3nTKYACElsDv3oEoDw=="}}
1+
{"head":"{\"manifestVersion\":\"1.0.0\"}","body":"{\"name\":\"bundle-tampered.bundle\",\"version\":\"x\",\"contract\":{\"hash\":\"zLAeVmpcc88gFsh6ctZQuXNsnXG8GRX7XGPooEzmQAkAwWfcBmysv1Aw\",\"file\":\"bundle-tampered.bundle.example\"},\"signingKeys\":[\"[\\\"edwards25519sha512batch\\\",\\\"PW6nt32OYuWpbHfUk5HtcSTgP+k28Uu752BkLun4U1Y=\\\",null]\",\"[\\\"edwards25519sha512batch\\\",\\\"PfdE8jdWCexc4vDrr6dHworStAhO4Jt8rf6cbdoLxT8=\\\",null]\"],\"contractSlim\":{\"file\":\"bundle-tampered.slim.example\",\"hash\":\"zLAeVmpcc88gFsh6ctZQuXNsnXG8GRX7XGPooEzmQAkAwWfcBmysv1Aw\"}}","signature":{"keyId":"z2Drjgb5QQTKooY4YntALeT1uEQtpo9bP7J9gt5g6kUyhtL5bPd","value":"MXnrqDWcb80hjumpXb4GQ2fofLr5TTomuTbWgTYQ52VPylw7kG8BZRflQ1l7FMUrpL5ts51uy2cHAsqd8NMXDg=="}}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"head":"{\"manifestVersion\":\"1.0.0\"}","body":"{\"version\":\"x\",\"contract\":{\"hash\":\"z9brRu3VFNnnn1BgyRBaQfs7Jyrx18K2ASgDKAiLyWx3KMVQGL8X\",\"file\":\"slim-tampered.bundle.example\"},\"signingKeys\":[\"[\\\"edwards25519sha512batch\\\",\\\"PW6nt32OYuWpbHfUk5HtcSTgP+k28Uu752BkLun4U1Y=\\\",null]\",\"[\\\"edwards25519sha512batch\\\",\\\"PfdE8jdWCexc4vDrr6dHworStAhO4Jt8rf6cbdoLxT8=\\\",null]\"],\"contractSlim\":{\"file\":\"slim-tampered.slim.example\",\"hash\":\"z9brRu3VFNnnn1BgyRBaQfs7Jyrx18K2ASgDKAiLyWx3KMVQGL8X\"}}","signature":{"keyId":"z2Drjgb5QQTKooY4YntALeT1uEQtpo9bP7J9gt5g6kUyhtL5bPd","value":"W1bLtxCz11OgGhH9ttBS5d8wybkH6tilhdFNWy6U7UbCHQ5s9dYOwnU28G7ZoyWcwOFGjO7OY8fnea3u8H8qDQ=="}}
1+
{"head":"{\"manifestVersion\":\"1.0.0\"}","body":"{\"name\":\"slim-tampered.bundle\",\"version\":\"x\",\"contract\":{\"hash\":\"zLAeVmpcc88gFsh6ctZQuXNsnXG8GRX7XGPooEzmQAkAwWfcBmysv1Aw\",\"file\":\"slim-tampered.bundle.example\"},\"signingKeys\":[\"[\\\"edwards25519sha512batch\\\",\\\"PW6nt32OYuWpbHfUk5HtcSTgP+k28Uu752BkLun4U1Y=\\\",null]\",\"[\\\"edwards25519sha512batch\\\",\\\"PfdE8jdWCexc4vDrr6dHworStAhO4Jt8rf6cbdoLxT8=\\\",null]\"],\"contractSlim\":{\"file\":\"slim-tampered.slim.example\",\"hash\":\"zLAeVmpcc88gFsh6ctZQuXNsnXG8GRX7XGPooEzmQAkAwWfcBmysv1Aw\"}}","signature":{"keyId":"z2Drjgb5QQTKooY4YntALeT1uEQtpo9bP7J9gt5g6kUyhtL5bPd","value":"l+WiA6hZdDCZ2Tk2fGefN8Js6wTWnsCeA5axtN2BwsWQE+gG+0+dUX2bi3ssdN4dhR9jhG0+2hzfisK51dVyBg=="}}

0 commit comments

Comments
 (0)