-
Notifications
You must be signed in to change notification settings - Fork 99
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add logic for fetching and storing MASP params
- Loading branch information
Showing
5 changed files
with
175 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
// TODO | ||
|
||
// Masp Params Atom |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
import { toBase64 } from "@cosmjs/encoding"; | ||
import { IndexedDBKVStore } from "@namada/storage"; | ||
import { sha256Hash } from "utils"; | ||
import { MASP_PARAMS_URL, MaspParam, MaspParamConfigs } from "./types"; | ||
|
||
export type MaspParamBytes = { | ||
param: MaspParam; | ||
bytes: Uint8Array; | ||
}; | ||
|
||
export type MaspParamBytesProgress = { | ||
param: MaspParam; | ||
chunkSize: number; | ||
expectedSize: number; | ||
progress: number; | ||
}; | ||
|
||
export type MaspParamBytesComplete = { | ||
param: MaspParam; | ||
progress: number; | ||
}; | ||
|
||
export const fetchMaspParam = async ( | ||
param: MaspParam, | ||
// Optional callback to track download progress | ||
onRead?: (progress: MaspParamBytesProgress) => void, | ||
// Optional callback for download complete | ||
onComplete?: (complete: MaspParamBytesComplete) => void | ||
): Promise<MaspParamBytes> => { | ||
return fetch([MASP_PARAMS_URL, param].join("/")) | ||
.then(async (response) => { | ||
if (response.ok) { | ||
const reader = response.body?.getReader(); | ||
if (!reader) { | ||
throw new Error("No readable stream returned!"); | ||
} | ||
return new ReadableStream({ | ||
start(controller) { | ||
// Track download progress | ||
const expectedSize = MaspParamConfigs[param].length; | ||
let progress: number = 0; | ||
// Start pumping the stream | ||
return pump(); | ||
async function pump(): Promise<typeof pump | undefined> { | ||
return reader?.read().then(({ done, value }) => { | ||
// Invoke callback if provided | ||
if (onRead && value) { | ||
const chunkSize = value.length; | ||
progress += chunkSize; | ||
onRead({ | ||
param, | ||
chunkSize, | ||
expectedSize, | ||
progress, | ||
}); | ||
} | ||
// When no more data needs to be consumed, close the stream | ||
if (done) { | ||
controller.close(); | ||
// Invoke callback with current param & progress if callback was provided | ||
if (onComplete) | ||
onComplete({ | ||
param, | ||
progress, | ||
}); | ||
return; | ||
} | ||
// Enqueue the next data chunk into our target stream | ||
controller.enqueue(value); | ||
return pump(); | ||
}); | ||
} | ||
}, | ||
}); | ||
} | ||
}) | ||
.then((stream) => new Response(stream)) | ||
.then((response) => response.blob()) | ||
.then(async (blob) => { | ||
const arrayBuffer = await blob.arrayBuffer(); | ||
return { | ||
param: param, | ||
bytes: new Uint8Array(arrayBuffer), | ||
}; | ||
}); | ||
}; | ||
|
||
export const storeMaspParam = async ( | ||
store: IndexedDBKVStore<string>, | ||
{ param, bytes }: MaspParamBytes | ||
): Promise<MaspParamBytes> => { | ||
console.info(`Storing ${param}...`); | ||
const base64Bytes = toBase64(bytes); | ||
await store.set(param, base64Bytes); | ||
return { | ||
param, | ||
bytes, | ||
}; | ||
}; | ||
|
||
export const validateMaspParamBytes = async ({ | ||
param, | ||
bytes, | ||
}: MaspParamBytes): Promise<MaspParamBytes> => { | ||
const { length, sha256sum } = MaspParamConfigs[param]; | ||
|
||
// Reject if invalid length (incomplete download or invalid) | ||
if (length !== bytes.length) { | ||
return Promise.reject( | ||
`Invalid data length for ${param}! Expected ${length}, received ${bytes.length}!` | ||
); | ||
} | ||
|
||
// Reject if invalid hash (otherwise invalid data) | ||
const hash = await sha256Hash(bytes); | ||
|
||
if (hash !== sha256sum) { | ||
return Promise.reject( | ||
`Invalid sha256 checksum for ${param}! Expected ${sha256sum}, received ${hash}!` | ||
); | ||
} | ||
|
||
return { param, bytes }; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from "./functions"; | ||
export * from "./types"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
const { NAMADA_INTERFACE_PROXY: isProxy } = process.env; | ||
|
||
const MASP_MPC_URL = | ||
"https://github.com/anoma/masp-mpc/releases/download/namada-trusted-setup"; | ||
|
||
export const MASP_PARAMS_URL = | ||
isProxy === "true" ? "http://localhost:8010/proxy" : MASP_MPC_URL; | ||
|
||
export const STORAGE_PREFIX = "namadillo"; | ||
|
||
export enum MaspParam { | ||
Output = "masp-output.params", | ||
Convert = "masp-convert.params", | ||
Spend = "masp-spend.params", | ||
} | ||
|
||
export const MaspParamConfigs: Record< | ||
MaspParam, | ||
{ length: number; sha256sum: string } | ||
> = { | ||
[MaspParam.Output]: { | ||
length: 16398620, | ||
sha256sum: | ||
"ed8b5d354017d808cfaf7b31eca5c511936e65ef6d276770251f5234ec5328b8", | ||
}, | ||
[MaspParam.Spend]: { | ||
length: 49848572, | ||
sha256sum: | ||
"62b3c60ca54bd99eb390198e949660624612f7db7942db84595fa9f1b4a29fd8", | ||
}, | ||
[MaspParam.Convert]: { | ||
length: 22570940, | ||
sha256sum: | ||
"8e049c905e0e46f27662c7577a4e3480c0047ee1171f7f6d9c5b0de757bf71f1", | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters