-
Notifications
You must be signed in to change notification settings - Fork 208
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ContractGovernor manages parameter updating for a contract #3448
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Below are comments mostly about small details. This is only a partial review, and I didn't dig into everything.
I think I would prefer a model where the governing is outside the governed contract, similar to #3453
I think it would also help to have a write up for the following two scenarios:
Scenario 1: As a user, I want to use contract instance x
, but only if it is well governed. How can I check that it is well governed, if I only start with knowledge of the instance object for x
? (We can assume a method in Zoe to get installation from instance).
Scenario 2: I want to participate in a vote to change the y
parameter of contract instance x
. How do I do it? How do I know that I can vote or not? What information do I have to start? (For instance, in the case of a committee vote, I might have the instance for x
, the governed contract, and an invitation that represents the ability to vote.)
|
||
const MALLEABLE_NUMBER = 'MalleableNumber'; | ||
|
||
export const governedParameterTerms = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, why this particular structure? It seems to have an unnecessary level. Could it just be:
export const governedParameterTerms = [MALLEABLE_NUMBER];
Also, why export this? Is that for testing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In #3310 the treasury declares two paramManagers for the parameters that relate to the AMM and to the Pools. Each Pool has a separate set of parameters, so the number of parameters being managed grows with the number of Pools.
The description of the parameters is exported so that the contract can refer to it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this example still has an unnecessary level to it. I'm not understanding why two sets of parameters requires the additional level.
packages/governance/test/swingsetTests/contractGovernor/governedContract.js
Outdated
Show resolved
Hide resolved
packages/governance/test/swingsetTests/contractGovernor/governedContract.js
Outdated
Show resolved
Hide resolved
// read and trust the contract to enforce that the instance in its terms was | ||
// for the same instance as the private facet it uses. Having it public | ||
// means anyone can ask the governor to manage other compatible contracts. | ||
governContract, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Who pays for this contract instance? My guess is that they will not want to make the governContract
method public, since its probably pretty costly to call, let alone to create new BallotCounters through createQuestion
. So having governContract
be public doesn't seem like a usable solution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was in the context where the governor was made inside the governedContract. In governedContract.js
, this was only accessible via the creatorFacet
, so we have the same instincts about keeping it closely held.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like this method no longer exists, but the type for it still exists
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I removed it.
packages/governance/test/swingsetTests/contractGovernor/governedContract.js
Outdated
Show resolved
Hide resolved
f22bdb4
to
6e1a3b5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a partial review. There's a few large security problems:
- There's a security vulnerability in the
contractGovernor
where thecreatorFacet
of thegovernedContract
(which is how you get theparamManager
) is returned to the creator of thecontractGovernor
. That means the creator can change the values willy-nilly, which is exactly what we must ensure we prevent, since only the governance process in code should be able to change the values. - There's a potential vulnerability in the
contractGovernor
where the creator of thecontractGovernor
instance could trick the user into thinking that a different registrar is used. Theregistrar
instance is gotten from theregistrarCreatorFacet
that is supplied by the creator. The user is given this registrar instance. How does the user know this registrar is actually part of the governance of this contract?
Because of the two problems above, can I have a step-by-step walkthrough (with code would be even better) of the two scenarios I mentioned earlier? I think this will force both of us to be explicit about what the user can prove to themselves and where they might be tricked.
Scenario 1: As a user, I want to use contract instance x, but only if it is well governed. How can I check that it is well governed, if I only start with knowledge of the instance object for x? (We can assume a method in Zoe to get installation from instance).
Scenario 2: I want to participate in a vote to change the y parameter of contract instance x. How do I do it? How do I know that I can vote or not? What information do I have to start? (For instance, in the case of a committee vote, I might have the instance for x, the governed contract, and an invitation that represents the ability to vote.)
Here's one that I started for Scenario 1 that includes the changes I would make:
Scenario 1: As a user, I want to use contract instance x, but only if it is well governed. How can I check that it is well governed, if I only start with knowledge of the instance object for x? (We can assume a method in Zoe to get installation from instance).
-
I start knowing contract instance X.
-
I call E(zoe).getInstallation(X) to get the installation.
-
I get the code (??) (TODO: fill in)
-
I see that the code for contract instance X includes the standard
helper "handleGovernance". This means that the terms must have the
governedParams in this particular format: [TODO: fill in]. It also means
there's a paramManager that manages them. The paramManager is code
I know and trust. I know that the paramManager is returned as part
of the creatorFacet. Lastly, this means that the "governor"
contract instance is in the terms of contract instance X. -
I do
const terms = E(zoe).getTerms(X);
-
I get the "governor" contract instance, Y from the terms of
contract instance X:const { governor } = terms;
-
I call
E(zoe).getInstallation(Y)
to get the installation for the
governor contract instance. -
The contract governor installation is a widely known and audited
one. If I am familiar with it, I skip to step [TODO: fill in] Otherwise I continue. -
I get the code for the governor installation TODO: fill in??
-
In the code, I can see that the publicFacet has a method
getGovernedContract
which returns the governedContract instance
that the governor creates. -
I need to confirm that governedContract and the governor mutually
agree on their relationship. I use the helpervalidateGoverning
:const validateGoverning = async (zoe, allegedGoverned, allegedGovernor) => { const allegedGovernorPF = E(zoe).getPublicFacet(allegedGovernor); const allegedGovernedTermsP = E(zoe).getTerms(allegedGoverned); const realGovernedP = E(allegedGovernorPF).getGovernedInstance(); const [{ governor: realGovernor }, realGoverned] = await Promise.all([ allegedGovernedTermsP, realGovernedP, ]); assert( allegedGovernor === realGovernor, X`The alleged governor did not match the governor gotten from the governed contract`, ); assert( allegedGoverned === realGoverned, X`The alleged governed did not match the governed contract gotten from the governor`, ); };
-
I must also confirm that the creatorFacet of the governedContract is never released to the
creator of the governor. I can do this by visually inspecting the
code of the governor and ensuring that both the param manager and
the creatorFacet for the governedContract never escape. -
A method
voteOnParamChange
is available to the caller of
startGovernedInstance
on the creatorFacet of the governor. The
voteOnParamChange
method takes as arguments:paramMgrName
paramName,
proposedValue,
closingTimeThis means that these are entirely up to the whims of the holder
of the object with the voteOnParamChange method, and are not baked
into the smart contract.This seems to be the bare minimum required to specify when
specifying a parameter to change, which makes sense. Everything
else is either specified as a term or as code in the governor
contract. -
How can I find the electorate that makes decisions for this
contract? The registrar contract instance is listed... [TODO: complete]
|
||
const creatorFacet = Far('creator facet of governed contract', { | ||
getContractGovernor: () => electionManager, | ||
getParamMgrAccessor, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't this just be a function that returns the paramManager itself? Why return an object with a function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we want to be able to return multiple paramManagers, I suggest returning an object like:
{ ammManager: paramManager1, treasuryManager: paramManager2 }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the treasury, the multiple treasury paramManagers are selected by collateralType. Passing the collateralType to getParameterMgrAccessor()
seemed clearer than any structure I was able to think of. I would prefer a structure if there were a simple way to do that.
packages/governance/test/swingsetTests/contractGovernor/governedContract.js
Outdated
Show resolved
Hide resolved
/** @type {ContractStartFn} */ | ||
const start = async zcf => { | ||
const { | ||
/** @type {Instance} */ electionManager, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fascinating! WebStorm shows it, for once.
I don't think it would be a productive use of my time to open VS Code and hover over every type to find things like this. Can you help me figure out how/why yarn lint
isn't complaining and VS Code isn't seeing it? The syntax looks right to me, and WebStorm seems happy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Attn @mhofman @michaelfig
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you help me figure out how/why
yarn lint
isn't complaining
We don't have "Typescript noImplicitAny" enabled.
and VS Code isn't seeing it?
We don't have the JSDoc linting rules cranked up high enough to diagnose this questionable syntax. Since this syntax of typing the destructuring isn't supported, VSCode doesn't complain (which is a major feature of using JSDoc).
The syntax looks right to me
It doesn't look right to me, but that's probably because I'm conditioned by using VSCode, and this attempt to assign types to destructured properties has never worked.
I think the portable syntax you're reaching for is:
/** @type {{ electionManager: Instance, governedParams: ParameterNameList }} */
const { electionManager, governedParams } = zcf.getTerms();
Even better would be to have a regularly-defined @typedef
to name the terms for this contract, and use that defined name directly in /** @type {MyKindOfTerms} */
.
and WebStorm seems happy.
I don't know why WebStorm is happy. It must not be using the Typescript Language Server which so many other systems rely on. Or maybe your IDE is somehow using a different version of Typescript?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I couldn't get /** @type {{ electionManager: Instance, governedParams: ParameterNameList }} */
to work (standalone or as a typedef), and I couldn't find any contracts that declared the types of the values returned from zcf.getTerms()
, so I dropped the declaration with disappointment.
const paramManager = buildParamManager(paramDesc); | ||
|
||
assert( | ||
sameStructure(governedParams, harden(governedParameterTerms)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, if governedParams
is of type ParamDescriptions, I don't see how these can be the same structure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the declaration of governedParameterTerms
was wrong. I don't understand why yarn lint
wasn't complaining.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Attn @mhofman @michaelfig
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the declaration of
governedParameterTerms
was wrong. I don't understand whyyarn lint
wasn't complaining.
How would you expect it to complain? Can you please be more specific?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If yarn lint
and WebStorm have different understandings of typescript, then that explains why there were no complaints.
|
||
const { | ||
publicFacet: counterPublicFacet, | ||
instance: ballotCounter, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How is the ballotCounter
used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not used in governParams
directly. It is returned to the caller of voteOnParamChange
, who wants it to do cross checks and wait for the outcome.
* its creatorFacet. getParamMgrAccessor() takes a paramDesc, which identifies | ||
* the parameter to be voted on. If the contract has a single paramMgr, the | ||
* paramDesc can be just the parameter name. If the contract has more than one, | ||
* then it must accept enough details to identify the paramMgr and parameter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trying to identify the paramMgr by the paramName doesn't seem right. What if there are multiple paramNames that are the same? I think it would be better for the governed contract to return an object with string keys and ParamManagerFull values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trying to identify the paramMgr by the paramName doesn't seem right.
That's correct.
Each paramName needs to be unique for each paramManager. If there's only one paramManager, the paramManagerAccessor doesn't have to require a specifier that includes which paramManager. When there are multiple paramManagers that might have overlapping paramNames, then the paramDesc has to specify both.
I think it would be better for the governed contract to return an object with string keys and ParamManagerFull values.
Yeah, that would be better if it would work. The Treasury distinguishes paramManagers for the vault params by the collateralType. Using the collateralType as a parameter to a function seemed better than a string key for a record.
*/ | ||
const start = async zcf => { | ||
const zoe = zcf.getZoeService(); | ||
let registrar; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can the registrar instance be in the terms, and can we confirm that the registrar public facet passed in, is associated with that instance going both directions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We use a tightly-held facet of the Registrar
to limit who can create new questions, so it can't be included in the terms.
I'm now getting the registrar instance from an invitation, so we have Zoe's guarantee for that connection.
packages/governance/README.md
Outdated
(https://github.com/Agoric/agoric-sdk/issues/3449), which allows you to examine | ||
the souce. | ||
|
||
The governedContract will provide the registrar, which allows you to check the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does a user check the electorate? As far as I can tell, the governedContract gives me an instance for a registrar that may or may not actually be the instance associated with the passed-in registrarCreatorFacet
. So I could be misled to another instance altogether. Putting that aside, let's say I get the installation for the registrar instance, and that it's for the committee registrar. How do I know who is voting?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a correct analysis.
The governedContract (or other things) can indicate an alleged Registrar. The validation has to come from the other end.
The committeeRegistrar is a particular Registrar that doesn't itself provide any validation for who the committee members are. A contract that was started knowing the Registrar will trust it. Others might have access to the bootstrap.js that created it, or find it in a public registry that they have reason to trust. More often, we'll use other kinds of Registrars that provide more legibility for how they were constituted.
Once you know a registrar that you trust (or that you are reliant on), you can follow it back to its installation and review the code or check with a trusted reviewer. The Registrar itself will tell you about elections it manages, which gives you the ballot details and the ballot counter, so you can tell how the election will be run and outcome determined.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoops, realized I had intended to "request changes" rather than comment on my previous review. This review is just fixing that status.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just added myself as a reviewer in order to give feedback about the Fred problem. When we were first discussing governance, it was immediately clear to me that the Fred problem was the central challenge in designing a governance system, so that invites would still be meaningful assets even when issued by a governed contract. Unfortunately we have not established clear methodology about how to evaluate whether a contract has adequately addressed the Fred problem. The methodology here, using prose descriptions to establish that it is possible for Fred to reliably examine an invitation, should always have been suspect. But when the Fred issue gets as deep as this, "solving" it in prose is clearly inadequate.
Back in the days of the covered call running on the contractHost, you introduced an essential observation: The author of a contract is the one who is in the best position to author some helpful predicates for Fred to use, to approve or disapprove an invite. Let's call these "fredicates". (Ok, I don't expect anyone to call these that but me ;).) Each fredicate represents the contract author's theory about what Fred might want, such that Fred can express a desire-that-fits-the-theory by parameterizing the fredicate that embodies that theory. You wrote such a fredicate for that old covered call contract.
My first feedback on this PR is to request at least one such fredicate. With a fredicate, we do not need prose describing what Fred would check. The code itself expresses that. What we do need is a description of what Fred wants, such that
- Fred expresses this want by a parameterization of a fredicate, and
- Alice cannot construct an invite to send to Fred that simultaneously passes the fredicate and fails to satisfy Fred's desire that this parameterization was supposed to represent.
In other words, the fredicate represents a good attack target. Attacking the contract will often start with an attack on the fredicate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I addressed the comments. I'd be happy to see reactions to my responses, but I've changed the PR state to Draft, as it's not ready for final review at this point.
const voteOnParamChange = async ( | ||
paramName, | ||
proposedValue, | ||
ballotCounterInstallation, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm hoping/expecting contractGovernor
can be canonical, but I expect there will be multiple ballotCounter
s. It's true that contractGovernor
expects a binary counter, but I don't think it's unreasonable for there to be improvements on the first one. Leaving this to be set when each governed contract starts up makes it easier to migrate.
paramName, | ||
proposedValue, | ||
ballotCounterInstallation, | ||
closingRule, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea.
*/ | ||
const start = async zcf => { | ||
const zoe = zcf.getZoeService(); | ||
let registrar; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We use a tightly-held facet of the Registrar
to limit who can create new questions, so it can't be included in the terms.
I'm now getting the registrar instance from an invitation, so we have Zoe's guarantee for that connection.
...binaryBallotDetails, | ||
instance: ballotCounter, | ||
details, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The details
result is the place where the ballot creator learns the ballot handle and the counterInstance when they care about that. All the voters will be notified of the new question, but this is the creator's chance to find out.
The distinction for BinaryBallotDetails evaporated. It's just BallotDetails now.
ballotCounterInstance it is. I'll look for more places to add that kind of clarity.
16af4da
to
cb88451
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just some preliminary comments while I absorb orienting material. Since I am not yet oriented, some may be based on my misunderstandings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still working my way through. Sorry it is taking so long.
534368f
to
c50e0dc
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I responded to some of your comments. I continue to proceed through them.
e16874f
to
3badae2
Compare
packages/governance/test/swingsetTests/committeeBinary/bootstrap.js
Outdated
Show resolved
Hide resolved
8ebabda
to
20e1ec6
Compare
afd01b5
to
e3fa924
Compare
@dckc following a recent discussion, I added a few |
* @property {ERef<Timer>} timer | ||
* @property {Timestamp} deadline |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as we just discovered, deadline
s are RelativeTime
s.
* @property {ERef<Timer>} timer | |
* @property {Timestamp} deadline | |
* @property {ERef<Timer>} timer | |
* @property {RelativeTime} deadline |
* @param {ParamSpecification} paramSpec | ||
* @param {ParamValue} proposedValue | ||
* @param {Installation} voteCounterInstallation | ||
* @param {bigint} deadline |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* @param {bigint} deadline | |
* @param {RelativeTime} deadline |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks ready to be the next step in development of our governance framework.
@katelynsills , @erights , over to you to conclude your reviews.
The design looks solid (the diagrams are quite helpful) and the argument for correctness is reasonably clear. I look forward to the integration into the treasury etc.
During my review I locally added static types to the tests, which helped me understand a bunch of details such as QuestionSpec
vs QuestionDetails
and how they flow. @Chris-Hibbert and I agreed that's cost effective to keep and maintain, so I plan to land it in a follow-on PR.
p.s. The Verifying Governance in ContractGovernor discussion document was crucial to my understanding of the argument for correctness. The README here has much of it, such as Examining a Contract before use, but I have read it all too many times by now to be sure that nothing worth preserving in agoric-sdk wasn't copied over.
ca51b3b
to
b97320c
Compare
packages/governance/README.md
Outdated
counting contract. The QuestionSpec consists of `{ choiceMethod, issue, | ||
positions, electionType, maxChoices }`. The issue and positions can be | ||
strings or structured objects. ChoiceMethod is one of UNRANKED and ORDER, which |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code uses method
, not choiceMethod
.
counting contract. The QuestionSpec consists of `{ choiceMethod, issue, | |
positions, electionType, maxChoices }`. The issue and positions can be | |
strings or structured objects. ChoiceMethod is one of UNRANKED and ORDER, which | |
counting contract. The QuestionSpec consists of `{ method, issue, | |
positions, electionType, maxChoices }`. The issue and positions can be | |
strings or structured objects. Method is one of UNRANKED and ORDER, which |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
packages/governance/README.md
Outdated
connected to so that voters can verify that their votes mean what they say and | ||
will be tabulated as expected. | ||
|
||
Any occasion of governance starts with the creation of a Registrar. Two kinds |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Chris-Hibbert writes in #3869 (comment)
I wrote a note-to-self on finding something public-facing to rename to be the electorate.
I'm putting it here so that maybe github will help us track it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I couldn't find a way to distinguish between Registrar and Electorate, so I just renamed everything. The committeeRegistrar
became just committee
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @Chris-Hibbert most sorry this took so long. AFAICT all my issues that needed to be resolved are. LGTM!!!!
@dckc I wanted to mention to you how extraordinarily valuable your UI was for deepening my understanding. After many hours of reading the code, talking to @Chris-Hibbert (recording somewhere) and looking at abstraction diagrams, within three minutes of interacting with your UI mockup, suddenly all these distinction were tangible and made complete sense. The many hours were not unusual or unique to this subject area. The three minutes of immediate clarification were. It was an important lesson.
In light of that, @Chris-Hibbert I now see that the particular abstraction boundaries and composition choices you made have a rightness to them that I'm sorry I was struggling to appreciate when you were explaining them to me. Starting from this division into compositional concepts, we are in a more powerful position to assemble novel governance arrangements than I expected. Not that they're perfect ;) . But they are a great starting point to iterate from. I'm happy to see them merged now. Thanks!
packages/governance/README.md
Outdated
In order to make the management of parameters visible to clients of the | ||
contract, it should | ||
* validate that the declaration of the parameters is included in its terms, | ||
* publish the accessor facet of the paramManager in its publicFacet, and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIUC, this "accessor facet" terminology is now stale.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks
8554897
to
8b17382
Compare
ContractGovernor is an ElectionManager that knows its Registrar, and starts up and manages one contract. The managed contract returns a facet that describes the managed parameters to the governor. The ContractGovernor returns a facet that allows the creation of new Ballot questions to ask the electorate to approve changing the values of those parameters. There's a README.md that gives on overview of the interdependent APIs. The swingsetTest exercise the ContractGovernor over a trivial governedContract that shows how a contract can configure its parameters, and the methods that have to be available in order for everything to be found and verified. The tests include a verification step that cross-checks the Registrar, ElectionManager (i.e. ContractGovernor in this case), and questions to see that they are consistent. add a helper for governedContracts add index.js add comments for CRUCIAL governance security attributes
8b17382
to
3a20634
Compare
Dean said that he and @erights agreed that Kate's review is no longer blocking this merge.
ContractGovernor is an ElectionManager that knows a particular
Registrar, and can manage multiple contracts. It queries the public
facet of the contract to find which params are supposed to be maanged,
and can create new Ballot questions to ask its electorate to change
the values of those parameters.
There's a README.md that gives on overview of the interdependent
APIs.
The swingsetTest exercise the ContractGovernor over a trivial
governedContract that shows how a contract can configure its
parameters, and the methods that have to be available in order for
everythign to be found and verified. The tests include a verification
step that cross-checks the Registrar,
ElectionManager (i.e. ContractGovernor in this case), and Ballots to
see that they are consistent.
The API os Ballot and others is changed to bundle the details of a
question into BallotSpec. This affects some of the unit tests.
One open issue: I suspect that the question name should be a
structured object. It's currently a string, which is required to be
unique. I'd prefer to leave that to a refactoring to clean up.
closes #3189
closes #3783