nim-codex/tools/cirdl/cirdl.nim

108 lines
3.1 KiB
Nim
Raw Normal View History

2024-08-22 09:05:24 +00:00
import std/os
import std/streams
2024-08-22 10:02:12 +00:00
import pkg/chronicles
import pkg/chronos
import pkg/ethers
import pkg/questionable
import pkg/questionable/results
2024-08-22 11:40:03 +00:00
import pkg/zip/zipfiles
import pkg/chronos/apps/http/httpclient
2024-08-22 10:02:12 +00:00
import ../../codex/contracts/marketplace
2024-09-10 09:02:16 +00:00
proc consoleLog(logLevel: LogLevel, msg: LogOutputStr) {.gcsafe.} =
try:
stdout.write(msg)
stdout.flushFile()
except IOError as err:
logLoggingFailure(cstring(msg), err)
proc noOutput(logLevel: LogLevel, msg: LogOutputStr) = discard
defaultChroniclesStream.outputs[0].writer = consoleLog
defaultChroniclesStream.outputs[1].writer = noOutput
defaultChroniclesStream.outputs[2].writer = noOutput
2024-08-22 08:47:50 +00:00
proc printHelp() =
2024-08-22 10:02:12 +00:00
info "Usage: ./cirdl [circuitPath] [rpcEndpoint] [marketplaceAddress]"
info " circuitPath: path where circuit files will be placed."
info " rpcEndpoint: URL of web3 RPC endpoint."
info " marketplaceAddress: Address of deployed Codex marketplace contracts."
2024-08-22 09:05:24 +00:00
2024-08-22 10:02:12 +00:00
proc getCircuitHash(rpcEndpoint: string, marketplaceAddress: string): Future[?!string] {.async.} =
let provider = JsonRpcProvider.new(rpcEndpoint)
without address =? Address.init(marketplaceAddress):
return failure("Invalid address: " & marketplaceAddress)
let marketplace = Marketplace.new(address, provider)
let config = await marketplace.config()
return success config.proofs.zkeyHash
2024-08-22 09:05:24 +00:00
proc formatUrl(hash: string): string =
2024-08-22 11:40:03 +00:00
"https://circuit.codex.storage/proving-key/" & hash
2024-08-22 09:05:24 +00:00
proc retrieveUrl(uri: string): Future[seq[byte]] {.async.} =
let httpSession = HttpSessionRef.new()
2024-08-22 11:40:03 +00:00
try:
let resp = await httpSession.fetch(parseUri(uri))
return resp.data
finally:
await noCancel(httpSession.closeWait())
proc downloadZipfile(url: string, filepath: string): Future[?!void] {.async.} =
try:
let file = await retrieveUrl(url)
var s = newFileStream(filepath, fmWrite)
for b in file:
s.write(b)
s.close()
2024-08-22 11:40:03 +00:00
except Exception as exc:
return failure(exc.msg)
success()
2024-08-22 09:05:24 +00:00
proc unzip(zipfile:string, targetPath: string): ?!void =
2024-08-22 11:40:03 +00:00
var z: ZipArchive
if not z.open(zipfile):
return failure("Unable to open zip file: " & zipfile)
z.extractAll(targetPath)
z.close()
success()
2024-08-22 09:05:24 +00:00
2024-08-22 10:02:12 +00:00
proc main() {.async.} =
info "Codex Circuit Downloader, Aww yeah!"
2024-08-22 09:05:24 +00:00
let args = os.commandLineParams()
if args.len != 3:
printHelp()
return
let
circuitPath = args[0]
2024-08-22 11:40:03 +00:00
rpcEndpoint = args[1]
marketplaceAddress = args[2]
2024-08-22 09:05:24 +00:00
zipfile = circuitPath / "circuit.zip"
2024-08-22 11:40:03 +00:00
debug "Starting", circuitPath, rpcEndpoint, marketplaceAddress
discard existsOrCreateDir(circuitPath)
2024-08-22 10:02:12 +00:00
without circuitHash =? (await getCircuitHash(rpcEndpoint, marketplaceAddress)), err:
error "Failed to get circuit hash", msg = err.msg
return
2024-08-22 11:40:03 +00:00
debug "Got circuithash", circuitHash
2024-08-22 10:02:12 +00:00
let url = formatUrl(circuitHash)
if dlErr =? (await downloadZipfile(url, zipfile)).errorOption:
2024-08-22 11:40:03 +00:00
error "Failed to download circuit file", msg = dlErr.msg
return
debug "Download completed"
if err =? unzip(zipfile, circuitPath).errorOption:
error "Failed to unzip file", msg = err.msg
return
debug "Unzip completed"
2024-08-22 09:05:24 +00:00
removeFile(zipfile)
when isMainModule:
2024-08-22 10:02:12 +00:00
waitFor main()
info "Done!"