Skip to content

Commit

Permalink
chore/feat: revist src/ schema
Browse files Browse the repository at this point in the history
  • Loading branch information
guidiaz committed Dec 23, 2024
1 parent 669222a commit dd17997
Show file tree
Hide file tree
Showing 16 changed files with 1,585 additions and 1,198 deletions.
1,000 changes: 531 additions & 469 deletions src/bin/toolkit.js

Large diffs are not rendered by default.

28 changes: 28 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import * as _RadonRetrievals from "./lib/radon/retrievals"
export const RadonRetrievals: typeof _RadonRetrievals = _RadonRetrievals;

import * as _RadonReducers from "./lib/radon/reducers"
export const RadonReducers: typeof _RadonReducers = _RadonReducers;

import * as _RadonFilters from "./lib/radon/filters"
export const RadonFilters: typeof _RadonFilters = _RadonFilters;

import * as _RadonTypes from "./lib/radon/types"
export const RadonTypes: typeof _RadonTypes = _RadonTypes;

export function RadonInnerScript<T extends _RadonTypes.RadonType = _RadonTypes.RadonString>(t: { new(): T; }): T { return new t(); }
export function RadonScript(): _RadonTypes.RadonString { return RadonInnerScript(_RadonTypes.RadonString); }

export { RadonRequest, RadonRequestTemplate as RadonTemplate } from "./lib/radon/artifacts"

export class RadonSLA {
public readonly numWitnesses: number;
public readonly unitaryFee: number;
constructor (numWitnesses: number, unitaryFee: number) {
this.numWitnesses = numWitnesses
this.unitaryFee = unitaryFee
}
}

import * as _Utils from "./utils"
export const Utils: typeof _Utils = _Utils;
173 changes: 117 additions & 56 deletions src/lib/radon/artifacts.ts
Original file line number Diff line number Diff line change
@@ -1,54 +1,122 @@
import { Class as Retrieval } from "./sources"
import { Class as Reducer, Mode } from "./reducers"
const helpers = require("./helpers")

import { RadonRetrieval } from "./retrievals"
import { RadonReducer, Mode } from "./reducers"
import * as Utils from '../../utils'

export type Args = string[] | string[][];

export interface Specs {
retrieve: Retrieval[];
aggregate: Reducer;
tally: Reducer;
maxSize?: number;
retrieve: RadonRetrieval[];
aggregate: RadonReducer;
tally: RadonReducer;
}

export class Class {
public specs: Specs
class Class {

public readonly retrieve: RadonRetrieval[];
public readonly aggregate: RadonReducer;
public readonly tally: RadonReducer;

constructor(specs: Specs) {
if (!specs.retrieve || !Array.isArray(specs.retrieve) || specs.retrieve.length == 0) {
throw EvalError("\x1b[1;33mArtifact: cannot build if no sources are specified\x1b[0m")
}
specs.retrieve?.forEach((retrieval, index) => {
if (retrieval === undefined) {
throw EvalError(`\x1b[1;31mArtifact: Retrieval #${index}\x1b[1;33m: undefined\x1b[0m`)
} else if (!(retrieval instanceof Retrieval)) {
throw EvalError(`\x1b[1;31mArtifact: Retrieval #${index}\x1b[1;33m: invalid type\x1b[0m`)
throw EvalError(`\x1b[1;31mArtifact: RadonRetrieval #${index}\x1b[1;33m: undefined\x1b[0m`)
} else if (!(retrieval instanceof RadonRetrieval)) {
throw EvalError(`\x1b[1;31mArtifact: RadonRetrieval #${index}\x1b[1;33m: invalid type\x1b[0m`)
}
})
this.specs = specs
this.specs.maxSize = specs?.maxSize || 0
this.retrieve = specs.retrieve;
this.aggregate = specs.aggregate;
this.tally = specs.tally;
}

public opsCount(): number {
return (this.retrieve?.map(retrieval => retrieval.opsCount()).reduce((sum, a) => sum + a) || 0)
+ this.aggregate?.opsCount()
+ this.tally?.opsCount()
}
}

export class Template extends Class {
public argsCount: number;
public tests?: Map<string, Args>;
export class RadonRequest extends Class {

public static from(hexString: string) {
return Utils.decodeRequest(hexString)
}

constructor(specs: {
retrieve: Retrieval | Retrieval[],
aggregate?: Reducer,
tally?: Reducer,
maxSize?: number,
retrieve: RadonRetrieval | RadonRetrieval[],
aggregate?: RadonReducer,
tally?: RadonReducer,
}) {
const retrieve = Array.isArray(specs.retrieve) ? specs.retrieve as RadonRetrieval[] : [ specs.retrieve ]
super({
retrieve,
aggregate: specs?.aggregate || Mode(),
tally: specs?.tally || Mode(),
})
let argsCount = retrieve.map(retrieval => retrieval.argsCount).reduce((prev, curr) => prev + curr)
if (argsCount > 0) {
throw EvalError("\x1b[1;33mRadonRequest: parameterized retrievals were passed\x1b[0m")
}
}

public async execDryRun(): Promise<string> {
return (await Utils.execDryRun(this.toBytecode(), '--json')).trim()
}

public radHash(): string {
return Utils.sha256(helpers.encodeRequest(this.toProtobuf()))//.slice(0, 40)
}

public toBytecode(): string {
return Utils.toHexString(helpers.encodeRequest(this.toProtobuf()))
}

public toJSON(): any {
return {
retrieve: this.retrieve.map(retrieval => retrieval.toJSON()),
aggregate: this.aggregate.toJSON(),
tally: this.tally.toJSON(),
}
}

public toProtobuf(): any {
return {
time_lock: 0,
retrieve: this.retrieve.map(retrieval => retrieval.toProtobuf()),
aggregate: this.aggregate.toProtobuf(),
tally: this.tally.toProtobuf(),
}
}

public weight(): number {
return this.toBytecode().slice(2).length / 2;
}
}

export class RadonRequestTemplate extends Class {
public readonly argsCount: number;
public readonly tests?: Map<string, Args>;
constructor(specs: {
retrieve: RadonRetrieval | RadonRetrieval[],
aggregate?: RadonReducer,
tally?: RadonReducer,
},
tests?: Map<string, Args>
) {
const retrieve = Array.isArray(specs.retrieve) ? specs.retrieve as Retrieval[] : [ specs.retrieve ]
const retrieve = Array.isArray(specs.retrieve) ? specs.retrieve as RadonRetrieval[] : [ specs.retrieve ]
super({
retrieve,
aggregate: specs?.aggregate || Mode(),
tally: specs?.tally || Mode(),
maxSize: specs?.maxSize || 32,
})
this.argsCount = retrieve.map(retrieval => retrieval?.argsCount).reduce((prev, curr) => Math.max(prev, curr), 0)
if (this.argsCount == 0) {
throw EvalError("\x1b[1;33mTemplate: cannot build w/ unparameterized sources\x1b[0m")
throw EvalError("\x1b[1;33mRadonRequestTemplate: no parameterized retrievals were passed\x1b[0m")
}
if (tests) {
Object.keys(tests).forEach(test => {
Expand All @@ -61,56 +129,49 @@ export class Template extends Class {
Object(tests)[test] = Array(retrieve.length).fill(testArgs)
testArgs = Object(tests)[test]
} else if (testArgs?.length != retrieve.length) {
throw EvalError(`\x1b[1;33mTemplate: arguments mismatch in test \x1b[1;31m'${test}'\x1b[1;33m: ${testArgs?.length} tuples given vs. ${retrieve.length} expected\x1b[0m`)
throw EvalError(`\x1b[1;33mRadonRequestTemplate: arguments mismatch in test \x1b[1;31m'${test}'\x1b[1;33m: ${testArgs?.length} tuples given vs. ${retrieve.length} expected\x1b[0m`)
}
testArgs?.forEach((subargs, index)=> {
if (subargs.length < retrieve[index].argsCount) {
throw EvalError(`\x1b[1;33mTemplate: arguments mismatch in test \x1b[1;31m'${test}'\x1b[1;33m: \x1b[1;37mRetrieval #${index}\x1b[1;33m: ${subargs?.length} parameters given vs. ${retrieve[index].argsCount} expected\x1b[0m`)
throw EvalError(`\x1b[1;33mRadonRequestTemplate: arguments mismatch in test \x1b[1;31m'${test}'\x1b[1;33m: \x1b[1;37mRetrieval #${index}\x1b[1;33m: ${subargs?.length} parameters given vs. ${retrieve[index].argsCount} expected\x1b[0m`)
}
})
}
})
this.tests = tests
}
}
}

export class Parameterized extends Class {
public args: string[][]
constructor(template: Template, args: Args) {
super(template.specs)
if (!args || !Array.isArray(args) || args.length == 0) {
throw EvalError(`\x1b[1;31mParameterized: no valid args were provided.\x1b[0m`);
} else if (!Array.isArray(args[0])) {
this.args = Array(this.specs.retrieve.length).fill(args);
} else {
this.args = args as string[][];
public buildRequest(...args: string[][]): RadonRequest {
const retrieve: RadonRetrieval[] = []
if (args.length !== this.retrieve.length) {
throw new EvalError(`\x1b[1;33mRadonRequest: mismatching args vectors (${args.length} != ${this.retrieve.length}): [${args}]}\x1b[0m`)
}
this.specs.retrieve.map((retrieve, index) => {
if (args[index].length !== retrieve.argsCount) {
throw EvalError(`\x1b[1;31mParameterized: Retrieval #${index}\x1b[1;33m: parameters mismatch: ${args[index].length} given vs. ${retrieve.argsCount} required\x1b[0m`)
this.retrieve.forEach((retrieval, index) => {
if (retrieval.argsCount !== args[index].length) {
throw new EvalError(`\x1b[1;33mRadonRequest: mismatching args passed to retrieval #${index + 1} (${args[index].length} != ${retrieval.argsCount}): [${args[index]}]\x1b[0m`)
}
retrieve.push(retrieval.foldArgs(...args[index]))
})
return new RadonRequest({
retrieve,
aggregate: this.aggregate,
tally: this.tally,
})
}
}

export class Precompiled extends Class {
constructor(specs: {
retrieve: Retrieval | Retrieval[],
aggregate?: Reducer,
tally?: Reducer,
maxSize?: number,
}) {
const retrieve = Array.isArray(specs.retrieve) ? specs.retrieve as Retrieval[] : [ specs.retrieve ]
super({
public buildRequestModal(...args: string[]): RadonRequest {
const retrieve: RadonRetrieval[] = []
this.retrieve.forEach((retrieval, index) => {
if (retrieval.argsCount !== args.length) {
throw new EvalError(`\x1b[1;33mRadonRequest: mismatching args passed to retrieval #${index + 1} (${args.length} != ${retrieval.argsCount}): [${args}]\x1b[0m`)
}
retrieve.push(retrieval.foldArgs(...args))
})
return new RadonRequest({
retrieve,
aggregate: specs?.aggregate || Mode(),
tally: specs?.tally || Mode(),
maxSize: specs?.maxSize || 32,
aggregate: this.aggregate,
tally: this.tally,
})
let argsCount = retrieve.map(retrieval => retrieval.argsCount).reduce((prev, curr) => prev + curr)
if (argsCount > 0) {
throw EvalError("\x1b[1;33mPrecompiled: static requests cannot be built w/ parameterized sources\x1b[0m")
}
}
}
36 changes: 30 additions & 6 deletions src/lib/radon/filters.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
enum Opcodes {
const cbor = require("cbor")

export enum Opcodes {
Mode = 0x08,
StandardDeviation = 0x05,
}

export class Class {
public opcode: Opcodes;
public args?: any;
export class RadonFilter {

readonly opcode: Opcodes;
readonly args?: any;

constructor(opcode: Opcodes, args?: any) {
this.opcode = opcode
this.args = args
Expand All @@ -16,7 +20,27 @@ export class Class {
}
}})
}

public toJSON(): any {
var json: any = {
op: Opcodes[this.opcode],
}
if (this.args) {
json.args = this.args
}
return json;
}

public toProtobuf(): any {
var protobuf: any = {
op: this.opcode,
}
if (this.args) {
protobuf.args = cbor.encode(this.args)
}
return protobuf
}
}

export function Mode () { return new Class(Opcodes.Mode); }
export function Stdev (stdev: number) { return new Class(Opcodes.StandardDeviation, stdev); }
export function Mode () { return new RadonFilter(Opcodes.Mode); }
export function Stdev (stdev: number) { return new RadonFilter(Opcodes.StandardDeviation, stdev); }
Loading

0 comments on commit dd17997

Please sign in to comment.