Skip to content
This repository has been archived by the owner on Sep 14, 2023. It is now read-only.

Commit

Permalink
...
Browse files Browse the repository at this point in the history
  • Loading branch information
tjjfvi committed Apr 4, 2023
1 parent f0105eb commit 0955f20
Show file tree
Hide file tree
Showing 40 changed files with 316 additions and 292 deletions.
13 changes: 7 additions & 6 deletions capi.config.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
import { binary, CapiConfig } from "./capn/mod.ts"
import { binary, CapiConfig } from "./mod.ts"

const polkadot = binary("polkadot", "v0.9.37")
const polkadot40 = binary("polkadot", "v0.9.40")
const polkadot37 = binary("polkadot", "v0.9.37")
const polkadotParachain = binary("polkadot-parachain", "v0.9.370")
const substrateContractsNode = binary("substrate-contracts-node", "v0.24.0")

export const config: CapiConfig = {
server: "https://capi.dev/@capn/",
server: "http://localhost:4646/",
chains: {
polkadot: {
url: "wss://rpc.polkadot.io/",
version: "v0.9.40",
},
polkadotDev: {
binary: polkadot,
binary: polkadot40,
chain: "polkadot-dev",
},
westendDev: {
binary: polkadot,
binary: polkadot40,
chain: "westend-dev",
},
contractsDev: {
Expand All @@ -27,7 +28,7 @@ export const config: CapiConfig = {
networks: {
rococoDev: {
relay: {
binary: polkadot,
binary: polkadot37,
chain: "rococo-local",
nodes: 4,
},
Expand Down
24 changes: 24 additions & 0 deletions capn/CapiConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Binary } from "./binary.ts"

export interface ProxyChain {
url: string
binary?: never
version: string
}

export interface BinaryChain {
url?: never
binary: Binary
chain: string
}

export interface CapiConfig {
server: string
chains?: Record<string, ProxyChain | BinaryChain>
networks?: Record<string, NetworkConfig>
}

export interface NetworkConfig {
relay: BinaryChain & { nodes?: number }
parachains: Record<string, BinaryChain & { id: number; nodes?: number }>
}
36 changes: 0 additions & 36 deletions capn/foo.ts

This file was deleted.

5 changes: 3 additions & 2 deletions capn/getMetadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ import { WsConnection } from "../rpc/mod.ts"
import { getFreePort, portReady } from "../util/port.ts"
import { withSignal } from "../util/withSignal.ts"
import { resolveBinary } from "./binary.ts"
import { BinaryChain } from "./mod.ts"
import { BinaryChain } from "./CapiConfig.ts"

export async function getBinaryMetadata({ binary, chain }: BinaryChain, signal: AbortSignal) {
const bin = await resolveBinary(binary, signal)
const port = getFreePort()
return await withSignal(async (signal) => {
console.log(bin)
new Deno.Command(bin, {
args: ["--chain", chain, "--ws-port", `${port}`],
args: ["--tmp", "--chain", chain, "--ws-port", `${port}`],
stdin: "null",
stdout: "piped",
stderr: "piped",
Expand Down
112 changes: 10 additions & 102 deletions capn/mod.ts
Original file line number Diff line number Diff line change
@@ -1,103 +1,11 @@
export * from "./binary.ts"

import { blake2_512, blake2_64, Hasher } from "../crypto/hashers.ts"
import { hex } from "../crypto/mod.ts"
import { $codegenSpec, CodegenEntry, CodegenSpec } from "../server/codegenSpec.ts"
import { normalizePackageName, withSignal } from "../util/mod.ts"
import { Binary } from "./binary.ts"
import { getBinaryMetadata, getUrlMetadata } from "./getMetadata.ts"
import { startNetwork } from "./startNetwork.ts"

export interface ProxyChain {
url: string
binary?: never
version: string
}

export interface BinaryChain {
url?: never
binary: Binary
chain: string
}

export interface CapiConfig {
server: string
chains?: Record<string, ProxyChain | BinaryChain>
networks?: Record<string, NetworkConfig>
}
// moderate

export interface NetworkConfig {
relay: BinaryChain & { nodes?: number }
parachains: Record<string, BinaryChain & { id: number; nodes?: number }>
}

export async function processConfig(config: CapiConfig) {
return withSignal(async (signal) => {
const { server } = config
const entries = (await Promise.all([
...Object.entries(config.chains ?? {}).map(
async ([name, chain]): Promise<[string[], CodegenEntry][]> => {
const metadata = chain.url !== undefined
? await getUrlMetadata(chain, signal)
: await getBinaryMetadata(chain, signal)
const metadataHash = await uploadMetadata(server, metadata)
return [[[normalizePackageName(name)], {
type: "frame",
metadata: metadataHash,
chainName: name.replace(/^./, (x) => x.toUpperCase()),
connection: chain.url !== undefined
? { type: "ws", discovery: chain.url }
: { type: "capnChain", name },
}]]
},
),
...Object.entries(config.networks ?? {}).map(async ([networkName, network]) => {
const chains = await startNetwork(network, signal)
return await Promise.all(
Object.entries(chains).map(
async ([name, [port]]): Promise<[string[], CodegenEntry]> => {
const metadata = await getUrlMetadata({ url: `ws://localhost:${port}` }, signal)
const metadataHash = await uploadMetadata(server, metadata)
return [[
normalizePackageName(networkName),
normalizePackageName(name),
], {
type: "frame",
metadata: metadataHash,
chainName: name.replace(/^./, (x) => x.toUpperCase()),
connection: { type: "capnNetworkChain", network: networkName, name },
}]
},
),
)
}),
])).flat()
const codegenHash = await uploadCodegenSpec(server, {
type: "v0",
codegen: new Map(entries),
})
console.log(
entries.map(([key]) =>
new URL(codegenHash + "/" + key.join("/") + "/mod.js", server).toString()
).join("\n"),
)
})
}

async function _upload(server: string, kind: string, data: Uint8Array, hasher: Hasher) {
const hash = hasher.hash(data)
const url = new URL(`upload/${kind}/${hex.encode(hash)}`, server)
const exists = await fetch(url, { method: "HEAD" })
if (exists.ok) return hash
const response = await fetch(url, { method: "PUT", body: data })
if (!response.ok) throw new Error(await response.text())
return hash
}

export async function uploadMetadata(server: string, metadata: Uint8Array) {
return await _upload(server, "metadata", metadata, blake2_512)
}

export async function uploadCodegenSpec(server: string, spec: CodegenSpec) {
return hex.encode(await _upload(server, "codegen", $codegenSpec.encode(spec), blake2_64))
}
export * from "./api.ts"
export * from "./binary.ts"
export * from "./CapiConfig.ts"
export * from "./getMetadata.ts"
export * from "./processConfig.ts"
export * from "./scald.ts"
export * from "./server.ts"
export * from "./startNetwork.ts"
export * from "./testUsers.ts"
77 changes: 77 additions & 0 deletions capn/processConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
export * from "./binary.ts"

import { blake2_512, blake2_64, Hasher } from "../crypto/hashers.ts"
import { hex } from "../crypto/mod.ts"
import { $codegenSpec, CodegenEntry, CodegenSpec } from "../server/codegenSpec.ts"
import { normalizePackageName, withSignal } from "../util/mod.ts"
import { CapiConfig } from "./CapiConfig.ts"
import { getBinaryMetadata, getUrlMetadata } from "./getMetadata.ts"
import { startNetwork } from "./startNetwork.ts"

export async function processConfig(config: CapiConfig) {
return withSignal(async (signal) => {
const { server } = config
const entries = (await Promise.all([
...Object.entries(config.chains ?? {}).map(
async ([name, chain]): Promise<[string[], CodegenEntry][]> => {
const metadata = chain.url !== undefined
? await getUrlMetadata(chain, signal)
: await getBinaryMetadata(chain, signal)
const metadataHash = await uploadMetadata(server, metadata)
console.log(name, metadataHash)
return [[[normalizePackageName(name)], {
type: "frame",
metadata: metadataHash,
chainName: name.replace(/^./, (x) => x.toUpperCase()),
connection: chain.url !== undefined
? { type: "ws", discovery: chain.url }
: { type: "capnChain", name },
}]]
},
),
...Object.entries(config.networks ?? {}).map(async ([networkName, network]) => {
const chains = await startNetwork(network, signal)
return await Promise.all(
Object.entries(chains).map(
async ([name, [port]]): Promise<[string[], CodegenEntry]> => {
const metadata = await getUrlMetadata({ url: `ws://localhost:${port}` }, signal)
const metadataHash = await uploadMetadata(server, metadata)
return [[
normalizePackageName(networkName),
normalizePackageName(name),
], {
type: "frame",
metadata: metadataHash,
chainName: name.replace(/^./, (x) => x.toUpperCase()),
connection: { type: "capnNetworkChain", network: networkName, name },
}]
},
),
)
}),
])).flat()
const codegenHash = await uploadCodegenSpec(server, {
type: "v0",
codegen: new Map(entries),
})
return new URL(codegenHash + "/", server).toString()
})
}

async function _upload(server: string, kind: string, data: Uint8Array, hasher: Hasher) {
const hash = hasher.hash(data)
const url = new URL(`upload/${kind}/${hex.encode(hash)}`, server)
const exists = await fetch(url, { method: "HEAD" })
if (exists.ok) return hash
const response = await fetch(url, { method: "PUT", body: data })
if (!response.ok) throw new Error(await response.text())
return hash
}

async function uploadMetadata(server: string, metadata: Uint8Array) {
return await _upload(server, "metadata", metadata, blake2_512)
}

async function uploadCodegenSpec(server: string, spec: CodegenSpec) {
return hex.encode(await _upload(server, "codegen", $codegenSpec.encode(spec), blake2_64))
}
10 changes: 5 additions & 5 deletions capn/scald.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ const $message = $.taggedUnion("type", [

type ResolutionMessage = Extract<Message, { type: "resolve" | "reject" }>

export interface Connection {
export interface Link {
send(data: Uint8Array): void
recv(cb: (data: Uint8Array) => void, signal: AbortSignal): void
}

class Scald {
constructor(readonly connection: Connection, readonly signal: AbortSignal) {
constructor(readonly connection: Link, readonly signal: AbortSignal) {
this.connection.recv((data) => {
const message = $message.decode(data)
this.recv(message)
Expand Down Expand Up @@ -141,7 +141,7 @@ export function $fn<A extends unknown[], R>(
})
}

export class WsConnection implements Connection {
export class WsLink implements Link {
ready = deferred()
constructor(readonly ws: WebSocket, signal: AbortSignal) {
ws.binaryType = "arraybuffer"
Expand Down Expand Up @@ -169,7 +169,7 @@ export class WsConnection implements Connection {
export function serveScald<T>(
$api: $.Codec<T>,
api: T,
connection: Connection,
connection: Link,
signal: AbortSignal,
) {
const scald = new Scald(connection, signal)
Expand All @@ -178,7 +178,7 @@ export function serveScald<T>(

export async function connectScald<T>(
$api: $.Codec<T>,
connection: Connection,
connection: Link,
signal: AbortSignal,
): Promise<T> {
const scald = new Scald(connection, signal)
Expand Down
Loading

0 comments on commit 0955f20

Please sign in to comment.