Skip to content

Commit

Permalink
adding checkIfUpcycle()
Browse files Browse the repository at this point in the history
tweaks

rounding out directoryLeaves

creating exception for root folder

trying to clean up errors

set conversion

tweak to upcycleFile

adding file unavailable bypass

wrong parent

circular reference

more flexible folder parents

ref compatibility

adding id restriction
  • Loading branch information
karnthis committed Oct 16, 2024
1 parent c585847 commit cccf199
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 54 deletions.
123 changes: 93 additions & 30 deletions src/classes/filetreeReader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export class FiletreeReader implements IFiletreeReader {

protected ulidLeaves: Record<string, Record<string, string>>
protected directoryLeaves: Record<string, Record<string, IChildMetaDataMap>>
protected directoriesByUlid: Record<string, Record<string, IChildMetaDataMap>>
protected yellowpages: Record<string, Record<string, DQueryFileTreeFile>>
protected legacyMetaLeaves: Record<string, ILegacyFolderMetaData>
protected refCounts: Record<string, number>
Expand All @@ -76,6 +77,8 @@ export class FiletreeReader implements IFiletreeReader {
this.ulidLeaves[ownerAddress] = {}
this.directoryLeaves = {}
this.directoryLeaves[ownerAddress] = {}
this.directoriesByUlid = {}
this.directoriesByUlid[ownerAddress] = {}
this.yellowpages = {}
this.yellowpages[ownerAddress] = {}
this.legacyMetaLeaves = {}
Expand Down Expand Up @@ -139,11 +142,14 @@ export class FiletreeReader implements IFiletreeReader {
try {
const final: TConversionPair[] = []
for (let ulid of this.conversionQueue) {
if (ulid === '-1') {
continue
}
const meta = await this.loadMetaByUlid(ulid)

if (meta.metaDataType === 'file') {
const parent = meta.location.split('/').slice(-1)[0]
const files = this.directoryLeaves[this.clientAddress][parent].files
const { files } = this.readDirectoryLeafByUlid(parent)
for (let index of Object.keys(files)) {
if (files[Number(index)].fileMeta.name === meta.fileMeta.name) {
const refIndex = Number(index)
Expand All @@ -163,7 +169,7 @@ export class FiletreeReader implements IFiletreeReader {
final.push([meta.metaDataType, handler])
} else {
this.nullConversions.push(parent)
const nulls = this.directoryLeaves[this.clientAddress][parent].nulls
const { nulls } = this.readDirectoryLeafByUlid(parent)
for (let index of Object.keys(nulls)) {
const handler = await NullMetaHandler.create({
location: parent,
Expand All @@ -175,28 +181,41 @@ export class FiletreeReader implements IFiletreeReader {
}
} else if (meta.metaDataType === 'folder') {
const parent = meta.location.split('/').slice(-1)[0]
const folders = this.directoryLeaves[this.clientAddress][parent].folders
for (let index of Object.keys(folders)) {
if (folders[Number(index)].whoAmI === meta.whoAmI) {
const refIndex = Number(index)
const handler = await FolderMetaHandler.create({
count: hexToInt(meta.count),
description: meta.description,
location: parent,
name: meta.whoAmI,
refIndex,
ulid,
})
final.push([meta.metaDataType, handler])
break
if (parent.length < 26) {
const handler = await FolderMetaHandler.create({
count: hexToInt(meta.count),
description: meta.description,
location: meta.whoAmI,
name: meta.whoAmI,
refIndex: 0,
ulid,
})
final.push([meta.metaDataType, handler])
} else {
const { folders } = this.readDirectoryLeafByUlid(parent)
for (let index of Object.keys(folders)) {
if (folders[Number(index)].whoAmI === meta.whoAmI) {
const refIndex = Number(index)
const handler = await FolderMetaHandler.create({
count: hexToInt(meta.count),
description: meta.description,
location: parent,
name: meta.whoAmI,
refIndex,
ulid,
})
final.push([meta.metaDataType, handler])
break
}
}
}

} else if (meta.metaDataType === 'rootlookup') {
const handler = await FolderMetaHandler.create({
count: 0,
location: 'ulid',
name: 'Home',
ulid,
ulid: meta.ulid,
})
final.push([meta.metaDataType, handler])
}
Expand Down Expand Up @@ -233,7 +252,7 @@ export class FiletreeReader implements IFiletreeReader {
const segments = path.split('/')
const parentPath = segments.slice(0, -1).join('/')
const target = segments.slice(-1)[0]
const details = this.directoryLeaves[this.clientAddress][parentPath]
const details = this.readDirectoryLeafByPath(parentPath)

for (let index of Object.keys(details.folders)) {
const ref = Number(index)
Expand Down Expand Up @@ -270,10 +289,10 @@ export class FiletreeReader implements IFiletreeReader {

try {
if (this.directoryLeaves[owner][path] && !refresh) {
return this.directoryLeaves[owner][path]
return this.readDirectoryLeafByPath(path, owner)
} else {
await this.pathToLookupPostProcess(path, owner, this.yellowpages[owner][path])
return this.directoryLeaves[owner][path]
return this.readDirectoryLeafByPath(path, owner)
}
} catch (err) {
throw warnError('filetreeReader readFolderContents()', err)
Expand Down Expand Up @@ -440,7 +459,7 @@ export class FiletreeReader implements IFiletreeReader {
ownerAddress: await hashAndHexOwner(hexAddress, this.clientAddress),
}
const { file } = await this.jackalSigner.queries.fileTree.file(lookup)
const meta = await this.loadMeta(file, ulid)
const meta = await this.loadMeta(file, '-1')
return (meta.metaDataType === 'ref') ? meta as IRefMetaData : meta as INullRefMetaData
} catch (err) {
throw warnError('filetreeReader loadRefMeta()', err)
Expand Down Expand Up @@ -501,7 +520,11 @@ export class FiletreeReader implements IFiletreeReader {
* @returns {Promise<TMetaDataSets>}
*/
async loadMetaByPath (path: string): Promise<TMetaDataSets> {
return await this.loadMetaByExternalPath(path, this.clientAddress)
try {
return await this.loadMetaByExternalPath(path, this.clientAddress)
} catch (err) {
throw warnError('filetreeReader loadMetaByPath()', err)
}
}

/**
Expand Down Expand Up @@ -932,9 +955,9 @@ export class FiletreeReader implements IFiletreeReader {
const isCleartext = contents.includes('metaDataType')
const access = await this.checkViewAuthorization(file, isCleartext)
if (access) {
const id = this.ulidLookup(path, ownerAddress)
let parsed
if (!isCleartext) {
const id = this.ulidLookup(path, ownerAddress)
parsed = await this.decryptAndParseContents(file, id)
} else {
parsed = JSON.parse(contents) as TMetaDataSets
Expand All @@ -944,7 +967,7 @@ export class FiletreeReader implements IFiletreeReader {
if (ownerAddress === this.clientAddress) {
this.refCountSet(path, count)
}
this.directoryLeaves[ownerAddress][path] = this.basicFolderShell()
this.startDirectoryLeaf(path, id, ownerAddress)
const post = []
for (let i = 0; i < count; i++) {
post.push(this.singleLoadMeta(path, ownerAddress, i))
Expand Down Expand Up @@ -979,7 +1002,7 @@ export class FiletreeReader implements IFiletreeReader {
if (refMeta.metaDataType === 'nullref') {
return
}
const leaf = this.directoryLeaves[ownerAddress][path]
const leaf = this.readDirectoryLeafByPath(path, ownerAddress)
const meta = await this.loadMetaByUlid(refMeta.pointsTo)
if (meta.metaDataType === 'folder') {
const loopPath = `${path}/${meta.whoAmI}`
Expand Down Expand Up @@ -1011,6 +1034,44 @@ export class FiletreeReader implements IFiletreeReader {
}
}

/**
*
* @param {string} path
* @param {string} ulid
* @param {string} [ownerAddress]
* @protected
*/
protected startDirectoryLeaf (path: string, ulid: string, ownerAddress?: string): void {
const owner = ownerAddress || this.clientAddress
const shell = this.basicFolderShell()
this.directoryLeaves[owner][path] = shell
this.directoriesByUlid[owner][ulid] = shell
}

/**
*
* @param {string} path
* @param {string} [ownerAddress]
* @returns {IChildMetaDataMap}
* @protected
*/
protected readDirectoryLeafByPath (path: string, ownerAddress?: string): IChildMetaDataMap {
const owner = ownerAddress || this.clientAddress
return this.directoryLeaves[owner][path]
}

/**
*
* @param {string} ulid
* @param {string} [ownerAddress]
* @returns {IChildMetaDataMap}
* @protected
*/
protected readDirectoryLeafByUlid (ulid: string, ownerAddress?: string): IChildMetaDataMap {
const owner = ownerAddress || this.clientAddress
return this.directoriesByUlid[owner][ulid]
}

/**
*
* @param {string} path
Expand Down Expand Up @@ -1212,10 +1273,12 @@ export class FiletreeReader implements IFiletreeReader {
return [await genAesBundle(), false]
} else {
try {
return [await stringToAes(this.keyPair, parsedAccess[user]), false]
} catch (_) {
const parsed = await stringToAes(this.keyPair, parsedAccess[user])
return [parsed, false]
} catch {
try {
return [await stringToAes(this.defaultKeyPair, parsedAccess[user]), true]
const parsed = await stringToAes(this.defaultKeyPair, parsedAccess[user])
return [parsed, true]
} catch (err) {
throw err
}
Expand Down Expand Up @@ -1292,8 +1355,8 @@ export class FiletreeReader implements IFiletreeReader {
try {
const safe = prepDecompressionForAmino(data.contents)
const aes = await this.extractViewAccess(data)
if (aes[1]) {
this.conversionQueue.push(id)
if (id !== '-1' && aes[1]) {
this.conversionQueue = [...new Set([...this.conversionQueue, id])]
}
let decrypted = await cryptString(safe, aes[0], 'decrypt')
if (decrypted.startsWith('jklpc1')) {
Expand Down
66 changes: 43 additions & 23 deletions src/classes/storageHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,32 +192,36 @@ export class StorageHandler extends EncodingHandler implements IStorageHandler {

const hostAddress = client.getHostAddress()
const chainId = client.getHostChainId()
let signatureAsHex = ''
let signed, signatureAsHex
switch (selectedWallet) {
case 'keplr':
if (!window.keplr) {
throw 'Missing wallet extension'
} else {
const { signature } = await window.keplr.signArbitrary(
signed = await window.keplr.signArbitrary(
chainId,
hostAddress,
signatureSeed,
)
signatureAsHex = await stringToShaHex(signature)
signatureAsHex = await stringToShaHex(signed.signature)
}
break
case 'leap':
if (!window.leap) {
throw 'Missing wallet extension'
} else {
const { signature } = await window.leap.signArbitrary(
signed = await window.leap.signArbitrary(
chainId,
hostAddress,
signatureSeed,
)
signatureAsHex = await stringToShaHex(signature)
signatureAsHex = await stringToShaHex(signed.signature)
}
break
default:
throw new Error(
'No wallet selected but one is required to init StorageHandler',
)
}
return [PrivateKey.fromHex(signatureAsHex), true]
} catch (err) {
Expand Down Expand Up @@ -360,10 +364,12 @@ export class StorageHandler extends EncodingHandler implements IStorageHandler {
*/
async upgradeSigner (): Promise<void> {
try {
;[this.keyPair, this.fullSigner] = await StorageHandler.enableFullSigner(
const [pair, signer] = await StorageHandler.enableFullSigner(
this.jackalClient,
)
await this.resetReader(this.keyPair)
this.keyPair = pair
this.fullSigner = signer
await this.resetReader(pair)
} catch (err) {
throw warnError('storageHandler upgradeSigner()', err)
}
Expand Down Expand Up @@ -1234,6 +1240,16 @@ export class StorageHandler extends EncodingHandler implements IStorageHandler {
}
}

/**
*
* @returns {boolean}
*/
checkIfUpcycle (): boolean {
const len = this.reader.getConversionQueueLength()
console.log('ConversionQueueLength:', len)
return len > 0
}

/**
*
* @param {IBroadcastOptions} [options]
Expand All @@ -1250,19 +1266,23 @@ export class StorageHandler extends EncodingHandler implements IStorageHandler {
let upcycleMsgs
switch (one[0]) {
case 'file':
const pkg = await this.upcycleFile(one[1])
const { files } =
await this.jackalSigner.queries.storage.allFilesByMerkle({
merkle: one[1].export().merkleRoot,
try {
const pkg = await this.upcycleFile(one[1])
const { files } =
await this.jackalSigner.queries.storage.allFilesByMerkle({
merkle: one[1].export().merkleRoot,
})
const [details] = files
const sourceMsgs = this.fileDeleteToMsgs({
creator: this.jklAddress,
merkle: details.merkle,
start: details.start,
})
const [details] = files
const sourceMsgs = this.fileDeleteToMsgs({
creator: this.jklAddress,
merkle: details.merkle,
start: details.start,
})
upcycleMsgs = await this.pkgToMsgs(pkg, blockheight)
msgs.push(...sourceMsgs, ...upcycleMsgs)
upcycleMsgs = await this.pkgToMsgs(pkg, blockheight)
msgs.push(...sourceMsgs, ...upcycleMsgs)
} catch {
console.log(`Skipping ${one[1].export().fileMeta.name}`)
}
break
case 'null':
upcycleMsgs = await this.filetreeDeleteToMsgs({ meta: one[1], aes: await genAesBundle() })
Expand All @@ -1278,7 +1298,7 @@ export class StorageHandler extends EncodingHandler implements IStorageHandler {
break
}
}
const ready = prompt('Ready to Upcycle?')
const ready = confirm('Are you ready to Upcycle?')
this.upcycleQueue = msgs
if (ready) {
await this.runUpcycleQueue(options)
Expand Down Expand Up @@ -1336,10 +1356,10 @@ export class StorageHandler extends EncodingHandler implements IStorageHandler {
const { providerIps } = await this.jackalSigner.queries.storage.findFile({
merkle: sourceMeta.merkleRoot,
})
console.log('providerIps:', providerIps)
let baseFile
for (const _ of providerIps) {
const provider =
providerIps[Math.floor(Math.random() * providerIps.length)]
for (let i = 0; i < providerIps.length; i++) {
const provider = providerIps[0]
const url = `${provider}/download/${sourceMeta.merkleHex}`
try {
const resp = await fetch(url, { method: 'GET' })
Expand Down
2 changes: 2 additions & 0 deletions src/interfaces/classes/IStorageHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ export interface IStorageHandler {

convert (options?: IBroadcastOrChainOptions): Promise<IWrappedEncodeObject[]>

checkIfUpcycle (): boolean

checkAndUpcycle (options?: IBroadcastOptions): Promise<void>

runUpcycleQueue (options?: IBroadcastOptions): Promise<void>
Expand Down
2 changes: 1 addition & 1 deletion src/utils/converters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ export function safeStringifyFileTree (source: TMetaDataSets): string {
export function safeParseFileTree (source: string): TMetaDataSets {
try {
const base = JSON.parse(source)
if (base.merkleRoot) {
if ('merkleRoot' in base) {
if (Array.isArray(base.merkleRoot)) {
base.merkleRoot = new Uint8Array(base.merkleRoot)
} else {
Expand Down

0 comments on commit cccf199

Please sign in to comment.