1
1
'use strict'
2
2
3
- const CID = require ( 'cids ' )
3
+ const { CID } = require ( 'multiformats/cid ' )
4
4
const Key = require ( 'interface-datastore' ) . Key
5
- const mb = require ( 'multibase' )
6
5
const log = require ( 'debug' ) ( 'ipfs:repo:migrator:migration-8' )
7
- const uint8ArrayToString = require ( 'uint8arrays/to-string' )
8
- const { createStore } = require ( '../../src/utils' )
6
+
9
7
const length = require ( 'it-length' )
8
+ const { base32 } = require ( 'multiformats/bases/base32' )
9
+ const raw = require ( 'multiformats/codecs/raw' )
10
+ const mhd = require ( 'multiformats/hashes/digest' )
10
11
11
12
/**
12
13
* @typedef {import('../../src/types').Migration } Migration
14
+ * @typedef {import('interface-datastore').Datastore } Datastore
15
+ */
16
+
17
+ /**
18
+ * @param {* } blockstore
19
+ * @returns {Datastore }
13
20
*/
21
+ function unwrap ( blockstore ) {
22
+ if ( blockstore . child ) {
23
+ return unwrap ( blockstore . child )
24
+ }
25
+
26
+ return blockstore
27
+ }
14
28
15
29
/**
16
30
* @param {Key } key
17
31
*/
18
32
function keyToMultihash ( key ) {
19
- const buf = mb . decode ( `b${ key . toString ( ) . slice ( 1 ) } ` )
20
-
21
- // Extract multihash from CID
22
- let multihash = new CID ( buf ) . multihash
33
+ try {
34
+ const buf = base32 . decode ( `b${ key . toString ( ) . toLowerCase ( ) . slice ( 1 ) } ` )
23
35
24
- // Encode and slice off multibase codec
25
- multihash = mb . encode ( 'base32' , multihash ) . slice ( 1 )
36
+ // Extract multihash from CID
37
+ let multihash = CID . decode ( buf ) . multihash . bytes
26
38
27
- // Should be uppercase for interop with go
28
- const multihashStr = uint8ArrayToString ( multihash ) . toUpperCase ( )
39
+ // Encode and slice off multibase codec
40
+ // Should be uppercase for interop with go
41
+ const multihashStr = base32 . encode ( multihash ) . slice ( 1 ) . toUpperCase ( )
29
42
30
- return new Key ( `/${ multihashStr } ` , false )
43
+ return new Key ( `/${ multihashStr } ` , false )
44
+ } catch ( err ) {
45
+ return key
46
+ }
31
47
}
32
48
33
49
/**
34
50
* @param {Key } key
35
51
*/
36
52
function keyToCid ( key ) {
37
- const buf = mb . decode ( `b${ key . toString ( ) . slice ( 1 ) } ` )
53
+ try {
54
+ const buf = base32 . decode ( `b${ key . toString ( ) . toLowerCase ( ) . slice ( 1 ) } ` )
55
+ const digest = mhd . decode ( buf )
38
56
39
- // CID to Key
40
- const multihash = mb . encode ( 'base32' , new CID ( 1 , ' raw' , buf ) . bytes ) . slice ( 1 )
57
+ // CID to Key
58
+ const multihash = base32 . encode ( CID . createV1 ( raw . code , digest ) . bytes ) . slice ( 1 )
41
59
42
- return new Key ( `/${ uint8ArrayToString ( multihash ) } ` . toUpperCase ( ) , false )
60
+ return new Key ( `/${ multihash . toUpperCase ( ) } ` , false )
61
+ } catch {
62
+ return key
63
+ }
43
64
}
44
65
45
66
/**
46
- * @param {string } repoPath
47
- * @param {* } repoOptions
67
+ * @param {import('../../src/types').Backends } backends
48
68
* @param {(percent: number, message: string) => void } onProgress
49
69
* @param {(key: Key) => Key } keyFunction
50
70
*/
51
- async function process ( repoPath , repoOptions , onProgress , keyFunction ) {
52
- const blockstore = createStore ( repoPath , ' blocks' , repoOptions )
71
+ async function process ( backends , onProgress , keyFunction ) {
72
+ const blockstore = backends . blocks
53
73
await blockstore . open ( )
54
74
75
+ const unwrapped = unwrap ( blockstore )
76
+
55
77
let blockCount
56
78
57
- blockCount = await length ( blockstore . queryKeys ( {
79
+ blockCount = await length ( unwrapped . queryKeys ( {
58
80
filters : [ ( key ) => {
59
81
const newKey = keyFunction ( key )
60
82
@@ -65,15 +87,16 @@ async function process (repoPath, repoOptions, onProgress, keyFunction) {
65
87
try {
66
88
let counter = 0
67
89
68
- for await ( const block of blockstore . query ( { } ) ) {
90
+ for await ( const block of unwrapped . query ( { } ) ) {
69
91
const newKey = keyFunction ( block . key )
70
92
71
93
// If the Key is base32 CIDv0 then there's nothing to do
72
94
if ( newKey . toString ( ) !== block . key . toString ( ) ) {
73
95
counter += 1
74
- log ( `Migrating Block from ${ block . key } to ${ newKey } ` )
75
- await blockstore . delete ( block . key )
76
- await blockstore . put ( newKey , block . value )
96
+ log ( `Migrating Block from ${ block . key } to ${ newKey } ` , await unwrapped . has ( block . key ) )
97
+
98
+ await unwrapped . delete ( block . key )
99
+ await unwrapped . put ( newKey , block . value )
77
100
78
101
onProgress ( ( counter / blockCount ) * 100 , `Migrated Block from ${ block . key } to ${ newKey } ` )
79
102
}
@@ -87,10 +110,10 @@ async function process (repoPath, repoOptions, onProgress, keyFunction) {
87
110
module . exports = {
88
111
version : 8 ,
89
112
description : 'Transforms key names into base32 encoding and converts Block store to use bare multihashes encoded as base32' ,
90
- migrate : ( repoPath , repoOptions , onProgress = ( ) => { } ) => {
91
- return process ( repoPath , repoOptions , onProgress , keyToMultihash )
113
+ migrate : ( backends , onProgress = ( ) => { } ) => {
114
+ return process ( backends , onProgress , keyToMultihash )
92
115
} ,
93
- revert : ( repoPath , repoOptions , onProgress = ( ) => { } ) => {
94
- return process ( repoPath , repoOptions , onProgress , keyToCid )
116
+ revert : ( backends , onProgress = ( ) => { } ) => {
117
+ return process ( backends , onProgress , keyToCid )
95
118
}
96
119
}
0 commit comments