Agoric / agoric-sdk

monorepo for the Agoric Javascript smart contract platform
Apache License 2.0
327 stars 208 forks source link

separate E(zoe).install() authority from E(zoe).offer() #4395

Open warner opened 2 years ago

warner commented 2 years ago

Problem Description?

zoe is widely shared; everyone is welcome to E(zoe).offer(). But contract installation is a power reserved to the BLD stakers, in MN-1. By POLA, different authorities should be represented by different objects. So E(zoe).install() should move to some other object.

Original Description

Under what circumstances should a new contract be installable on MN-1? We don't want to admit a lot of unvetted code until a later stage, but we might still decide to install some new carefully-audited contracts during MN-1: how does the chain know what is ok and what is not?

When we switch to MN-2 and start to open it up, this mechanism will change. How?

There are a couple of separate aspects to this question:

Two implementation tools which come to mind are:

In the long run, we may want to use deposits of some sort, or something to make sure the installer 1: is serious, and 2: is providing long-term benefit to the chain, both to compensate for the cost they're imposing upon validators and their storage space. Paying a fee proportional to the size of the installed bundle (and remembering the perpetual storage obligation they're purchasing) might be enough. Discouraging spam is important.

But fees are independent of our policy around permissioned/permissionless contracts, and the latter needs a concrete mechanism to be in place by MN-1.

Description of the Design

Separating out the installation authority into a separate ocap.

Security Considerations

We'll rely upon this mechanism to protect the chain against malicious contracts that might seek to cause a chain halt, or to cause non-determinism and validator problems.

Test Plan

TBD

dckc commented 2 years ago

This overlaps with #3724; is it a dup?

michaelfig commented 2 years ago

@warner I would prefer to just charge fees for bundle installation at the Cosmos level. Otherwise, we're forced to use ACLs or the possession of a Cosmos token to decide who is allowed to do it, and that's a political problem.

Much better to do the ocap split you're suggesting, and initially say "governance has access to E(zoeInstanceManager).install() and instantiate()", then later another governance action can distribute the ZIM to everybody's wallet, which is the kind of operation we already support in core bootstrap.

dckc commented 2 years ago

an idea: home.zoe1 wraps zoe so that install and startInstance always throw. full home.zoe is only granted in the sim chain. It was simple enough that I coded it up: #4405

warner commented 2 years ago

From our conversation today, it sounds like:

I want to make sure that the MN-3 transition doesn't require a for loop over millions of user objects: it should only change one forwarder's behavior. I think that means users should get home.zoe instead of home.zoe1, despite the potential confusion of "but it says zoe, why doesn't it provide all of Zoe's methods?".

dckc commented 2 years ago

@erights , @dtribble suggests another approach to this issue:

It's worth considering just separating out the instance creation authority into a separate ocap.

I suppose part of my hesitation to consider it is the amount of tests and docs such that it would impact.

That effort seems better directed at Zoe 2.

dckc commented 1 year ago

As discussed in yesterday's Zoe meeting:

This risk is mitigated by the policy that mailbox/ag-solo access is limited to devnet (#5965), so home.zoe is not so widely available.

I was concerned about postponing this, as it would mean a backwards-incompatible upgrade of zoe. But it's not clear that we need to share zoe widely until MN-3, at which point installation is permissionless anyway. So while this would be nice to address, we don't seem to have any essential requirement for it, as long as we charge sufficiently for InstallBundle transactions (#6858).

erights commented 1 year ago

Another consideration: Our MN3 is permissionless. But our stack is not just for ourselves. From the beginning (see https://www.youtube.com/watch?v=52SgGFpWjsY&list=PLzDw4TTug5O1oHRbp2HkcvKABAY9FKsmG&t=154 at 2:34) we are building our stack to run on chains and non-chains, public, private, permissioned, permissionless, etc. Our current experience already reveals that, for some uses and some scenarios, it is useful to separate the ability to install a contract from the ability to instantiate and run installed contracts. Given that experience, POLA suggests that we do separate them into separate objects. Then, for permissionless chains including our MN3, we just make both objects generally available. But there's no need to bundle them together into one object.

Clearly this is not an immediate issue for the Vaults release. Important but not urgent.