-
Notifications
You must be signed in to change notification settings - Fork 212
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Manage parameters for a contract (#3208)
* feat: manage parameters for a contract closes #3186 outstanding issues: * should this validate types? * is there a clean way to assert something is an amount? * should managed amounts (and ratios) only set the value and leave the brand to the managed contract? * are there others types to add or remove? * chore: convert functions to arrow functions * chore: add types for handle and any. * chore: drop an inadvertant import * feat: add lookup for param names and details * chore: update version info * chore: review suggestions dependency reduction support instance and installation rather than handle support NAT type which must be a bigint rename publicFacet to params * refactor: paramManager separates each param updater change 'any' to 'unknown' drop an unneeded guard clause a single getParams() describes all parameters * chore: typescript corrections Thanks to Michael Fig. * chore: review cleanups dependency trimming better test for AMOUNT. improve some error messages narrow some type declarations add tests for INSTANCE and INSTALLATION * chore: correct esm import
- Loading branch information
1 parent
e02286c
commit 8447993
Showing
8 changed files
with
541 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
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,5 @@ | ||
# Change Log | ||
|
||
All notable changes to this project will be documented in this file. | ||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. | ||
|
Empty file.
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,18 @@ | ||
// This file can contain .js-specific Typescript compiler config. | ||
{ | ||
"compilerOptions": { | ||
"target": "esnext", | ||
|
||
"noEmit": true, | ||
/* | ||
// The following flags are for creating .d.ts files: | ||
"noEmit": false, | ||
"declaration": true, | ||
"emitDeclarationOnly": true, | ||
*/ | ||
"downlevelIteration": true, | ||
"strictNullChecks": true, | ||
"moduleResolution": "node", | ||
}, | ||
"include": ["src/**/*.js", "test/**/*.js"], | ||
} |
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,71 @@ | ||
{ | ||
"name": "@agoric/governance", | ||
"version": "0.1.0", | ||
"description": "Core governance support", | ||
"parsers": { | ||
"js": "mjs" | ||
}, | ||
"main": "src/paramManager.js", | ||
"engines": { | ||
"node": ">=14.15.0" | ||
}, | ||
"scripts": { | ||
"build": "exit 0", | ||
"test": "ava", | ||
"test:xs": "exit 0", | ||
"lint-fix": "yarn lint:eslint --fix && yarn lint:types", | ||
"lint-check": "yarn lint", | ||
"lint": "yarn lint:types && yarn lint:eslint", | ||
"lint:eslint": "eslint '**/*.js'", | ||
"lint:types": "tsc -p jsconfig.json" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/Agoric/agoric-sdk.git" | ||
}, | ||
"author": "Agoric", | ||
"license": "Apache-2.0", | ||
"bugs": { | ||
"url": "https://github.com/Agoric/agoric-sdk/issues" | ||
}, | ||
"homepage": "https://github.com/Agoric/agoric-sdk#readme", | ||
"dependencies": { | ||
"@agoric/assert": "^0.3.0", | ||
"@agoric/ertp": "^0.11.2", | ||
"@agoric/marshal": "^0.4.13", | ||
"@agoric/nat": "^4.1.0", | ||
"@agoric/notifier": "^0.3.14", | ||
"@agoric/store": "^0.4.15", | ||
"@agoric/zoe": "^0.16.0" | ||
}, | ||
"devDependencies": { | ||
"@agoric/install-ses": "^0.5.13", | ||
"ava": "^3.12.1", | ||
"esm": "agoric-labs/esm#Agoric-built" | ||
}, | ||
"files": [ | ||
"src/", | ||
"NEWS.md" | ||
], | ||
"ava": { | ||
"files": [ | ||
"test/**/test-*.js" | ||
], | ||
"require": [ | ||
"esm" | ||
], | ||
"timeout": "10m" | ||
}, | ||
"eslintConfig": { | ||
"extends": [ | ||
"@agoric" | ||
] | ||
}, | ||
"prettier": { | ||
"trailingComma": "all", | ||
"singleQuote": true | ||
}, | ||
"publishConfig": { | ||
"access": "public" | ||
} | ||
} |
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,127 @@ | ||
// @ts-check | ||
|
||
import { assert, details as X } from '@agoric/assert'; | ||
import { assertIsRatio } from '@agoric/zoe/src/contractSupport'; | ||
import { AmountMath, looksLikeBrand } from '@agoric/ertp'; | ||
import { Far } from '@agoric/marshal'; | ||
import { assertKeywordName } from '@agoric/zoe/src/cleanProposal'; | ||
|
||
/** | ||
* @type {{ | ||
* AMOUNT: 'amount', | ||
* BRAND: 'brand', | ||
* INSTANCE: 'instance', | ||
* INSTALLATION: 'installation', | ||
* NAT: 'nat', | ||
* RATIO: 'ratio', | ||
* STRING: 'string', | ||
* UNKNOWN: 'unknown', | ||
* }} | ||
*/ | ||
const ParamType = { | ||
AMOUNT: 'amount', | ||
BRAND: 'brand', | ||
INSTANCE: 'instance', | ||
INSTALLATION: 'installation', | ||
NAT: 'nat', | ||
RATIO: 'ratio', | ||
STRING: 'string', | ||
UNKNOWN: 'unknown', | ||
}; | ||
harden(ParamType); | ||
|
||
const assertType = (type, value, name) => { | ||
switch (type) { | ||
case ParamType.AMOUNT: | ||
// It would be nice to have a clean way to assert something is an amount. | ||
AmountMath.coerce(value.brand, value); | ||
break; | ||
case ParamType.BRAND: | ||
assert( | ||
looksLikeBrand(value), | ||
X`value for ${name} must be a brand, was ${value}`, | ||
); | ||
break; | ||
case ParamType.INSTALLATION: | ||
// TODO(3344): add a better assertion once Zoe validates installations | ||
assert( | ||
typeof value === 'object' && !Object.getOwnPropertyNames(value).length, | ||
X`value for ${name} must be an Installation, was ${value}`, | ||
); | ||
break; | ||
case ParamType.INSTANCE: | ||
// TODO(3344): add a better assertion once Zoe validates instances | ||
assert( | ||
typeof value === 'object' && !Object.getOwnPropertyNames(value).length, | ||
X`value for ${name} must be an Instance, was ${value}`, | ||
); | ||
break; | ||
case ParamType.NAT: | ||
assert.typeof(value, 'bigint'); | ||
break; | ||
case ParamType.RATIO: | ||
assertIsRatio(value); | ||
break; | ||
case ParamType.STRING: | ||
assert.typeof(value, 'string'); | ||
break; | ||
// This is an escape hatch for types we haven't added yet. If you need to | ||
// use it, please file an issue and ask us to support the new type. | ||
case ParamType.UNKNOWN: | ||
break; | ||
default: | ||
assert.fail(X`unrecognized type ${type}`); | ||
} | ||
}; | ||
|
||
const parse = paramDesc => { | ||
const typesAndValues = {}; | ||
// manager has an updateFoo() for each Foo param. It will be returned. | ||
const manager = {}; | ||
|
||
paramDesc.forEach(({ name, value, type }) => { | ||
// we want to create function names like updateFeeRatio(), so we insist that | ||
// the name has Keyword-nature. | ||
assertKeywordName(name); | ||
|
||
assert( | ||
!typesAndValues[name], | ||
X`each parameter name must be unique: ${name} duplicated`, | ||
); | ||
assertType(type, value, name); | ||
|
||
typesAndValues[name] = { type, value }; | ||
manager[`update${name}`] = newValue => { | ||
assertType(type, newValue, name); | ||
typesAndValues[name].value = newValue; | ||
}; | ||
}); | ||
|
||
const getParams = () => { | ||
/** @type {Record<Keyword,ParamDescription>} */ | ||
const descriptions = {}; | ||
Object.getOwnPropertyNames(typesAndValues).forEach(name => { | ||
descriptions[name] = { | ||
name, | ||
type: typesAndValues[name].type, | ||
value: typesAndValues[name].value, | ||
}; | ||
}); | ||
return harden(descriptions); | ||
}; | ||
|
||
return { getParams, manager }; | ||
}; | ||
|
||
/** @type {BuildParamManager} */ | ||
const buildParamManager = paramDesc => { | ||
const { getParams, manager } = parse(paramDesc); | ||
|
||
return Far('param manager', { | ||
getParams, | ||
...manager, | ||
}); | ||
}; | ||
harden(buildParamManager); | ||
|
||
export { ParamType, buildParamManager }; |
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,34 @@ | ||
// @ts-check | ||
|
||
/** | ||
* @typedef { 'amount' | 'brand' | 'installation' | 'instance' | 'nat' | 'ratio' | 'string' | 'unknown' } ParamType | ||
*/ | ||
|
||
/** | ||
* @typedef { Amount | Brand | Installation | Instance | bigint | Ratio | string | unknown } ParamValue | ||
*/ | ||
|
||
/** | ||
* @typedef {Object} ParamDescription | ||
* @property {string} name | ||
* @property {ParamValue} value | ||
* @property {ParamType} type | ||
*/ | ||
|
||
/** | ||
* @typedef {Object} ParamManagerBase | ||
* @property {() => Record<Keyword,ParamDescription>} getParams | ||
* | ||
* @typedef {{ [updater: string]: (arg: ParamValue) => void }} ParamManagerUpdaters | ||
* @typedef {ParamManagerBase & ParamManagerUpdaters} ParamManagerFull | ||
*/ | ||
|
||
/** | ||
* @typedef {Array<ParamDescription>} ParamDescriptions | ||
*/ | ||
|
||
/** | ||
* @callback BuildParamManager | ||
* @param {ParamDescriptions} paramDesc | ||
* @returns {ParamManagerFull} | ||
*/ |
Oops, something went wrong.