Skip to content
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

convert makeBridgeProvisionTool from a Far to an Exo #10425

Closed
anilhelvaci opened this issue Nov 8, 2024 · 12 comments · Fixed by #10419
Closed

convert makeBridgeProvisionTool from a Far to an Exo #10425

anilhelvaci opened this issue Nov 8, 2024 · 12 comments · Fixed by #10419
Assignees
Labels
enhancement New feature or request

Comments

@anilhelvaci
Copy link
Collaborator

What is the Problem Being Solved?

#10419 (comment) talks about converting the maker function of the bridge handler created in provisionPoolKit.js from a Far object to an Exo object t make it durable. This is needed because #8849 shows makeBridgeProvisionTool returning a Far (along with other objects) prevents the bootstrap vat from upgrading.

Description of the Design

const prepareBridgeProvisionTool = (baggage) => {
  const makeHandler = prepareExoClass(
    baggage,
    'provisionHandler',
    BridgeHandlerI,
    (sendInitialPayment, onProvisioned) => ({ sendInitialPayment, onProvisioned }),
    {
      fromBridge: async obj => {
          obj.type === 'PLEASE_PROVISION' ||
            Fail`Unrecognized request ${obj.type}`;
          trace('PLEASE_PROVISION', obj);
          const { address, powerFlags } = obj;
          powerFlags.includes(PowerFlags.SMART_WALLET) ||
            Fail`missing SMART_WALLET in powerFlags`;

          const bank = E(bankManager).getBankForAddress(address);
          // only proceed if we can provide funds
          await sendInitialPayment(bank);

          const [_, created] = await E(walletFactory).provideSmartWallet(
            address,
            bank,
            namesByAddressAdmin,
          );
          if (created) {
            onProvisioned();
          }
          trace(created ? 'provisioned' : 're-provisioned', address);
        }, 
    }
  );
  
  return makeHandler;
}

Open Question: Are we sure handler is assigned to provisionWalletBridgeManager?

const handler = provisioning
? Far('provisioningHandler', {
async fromBridge(obj) {
switch (obj.type) {
case 'PLEASE_PROVISION': {
const { nickname, address, powerFlags: rawPowerFlags } = obj;
const powerFlags = rawPowerFlags || [];
let provisionP;
if (powerFlags.includes(PowerFlags.SMART_WALLET)) {
// Only provision a smart wallet.
provisionP = E(provisionWalletBridgeManager).fromBridge(obj);
} else {
// Provision a mailbox and REPL.
provisionP = E(provisioning).pleaseProvision(
nickname,
address,
powerFlags,
);
}
return provisionP
.catch(e =>
console.error(
`Error provisioning ${nickname} ${address}:`,
e,
),
)
.then(_ => {});
}
default: {
throw Fail`Unrecognized request ${obj.type}`;
}
}
},
})
: provisionWalletBridgeManager;

In the snippet above the handler seems to be assigned to a Far assuming provisioning is not undefined. makeProvisioner looks like it is assigning provisioning to vat-provisioning.

export const makeProvisioner = async ({
consume: { clientCreator, loadCriticalVat },
vats: { comms, vattp },
produce: { provisioning },
}) => {
const provisionerVat = await E(loadCriticalVat)('provisioning');
await E(provisionerVat).register(clientCreator, comms, vattp);
provisioning.resolve(provisionerVat);
};
harden(makeProvisioner);

My concern is that even if we make makeBridgeProvisionTool an Exo, I am not so sure it will help us make the handler vat-bootstrap holding on durable. Could you please help me understand this? @Chris-Hibbert @dckc

Security Considerations

Scaling Considerations

Test Plan

Need to make sure both auto-provisioning and agd tx swingset provision-one works in a3p.

Upgrade Considerations

@dckc
Copy link
Member

dckc commented Nov 12, 2024

I would really like to see a sequence diagram of inter-vat messages for the provisioning process. I suspect we may be constrained by...

Any chance somebody would run an agd tx swingset provision-one in an a3p context where a slogfile is being collected, extract the relevant interval, and drop it in https://causeway.agoric.net/ ?

@dckc
Copy link
Member

dckc commented Nov 12, 2024

In Description of the Design I see some code; where would that code go?

@anilhelvaci
Copy link
Collaborator Author

In Description of the Design I see some code; where would that code go?

It replaces this:

export const makeBridgeProvisionTool = (sendInitialPayment, onProvisioned) => {

@anilhelvaci
Copy link
Collaborator Author

I would really like to see a sequence diagram of inter-vat messages for the provisioning process. I suspect we may be constrained by...

Any chance somebody would run an agd tx swingset provision-one in an a3p context where a slogfile is being collected, extract the relevant interval, and drop it in https://causeway.agoric.net/ ?

I could drop the slogfile to https://causeway.agoric.net/ but I'll need help understanding how will we constrained by #8849. Maybe we could go over it tomorrow in the office hours?

@dckc
Copy link
Member

dckc commented Nov 12, 2024

I'll need help understanding how will we constrained by #8849.

The provisioning bridge handler was created, using makeBridgeProvisionTool, which returns a Far object; i.e. a non-durable object. When a vat such as the provision pool is upgraded, swingset docs tell us: "non-durable exported objects are abandoned". Vats which imported those objects will find themselves holding a broken reference (i.e. every message sent to it will be rejected with an Error).

Meanwhile, I suspect that the bootstrap vat imported this bridge handler, and bootstrap is not currently smart enough to recover from a broken reference to a bridge handler. Let's consider upgrading bootstrap to handle it. Problem: the bootstrap vat likewise exports a few other Far objects (as noted in #8849); so if we upgrade the bootstrap vat, those objects will be abandoned. And I doubt that all the vats that import those objects are robust in the face of broken references.

@anilhelvaci
Copy link
Collaborator Author

Thanks for the explanation! What I really wanted to understand how will a vat-to-vat communication sequence diagram will help to determine why we cannot upgrade bootstrap? And I understand that it will help us understand what references are exported by bootstrap that are not durable and who holds on to them.

However, the main thing I wanted to draw your attention is that even if we make the handler created by makeProvisionTool durable, I’m not so sure it’s going to make bootstrap hold on to a durable handler because of the code shown in Open Question section.

@Chris-Hibbert
Copy link
Contributor

the handler seems to be assigned to a Far assuming provisioning is not undefined. makeProvisioner looks like it is assigning provisioning to vat-provisioning.

makeProvisioner gives provisioning a non-null value, so handler gets that Far object defined in bridgeProvisioner(), which is held by provisionBridgeManager.

My concern is that even if we make makeBridgeProvisionTool an Exo, I am not so sure it will help us make the handler vat-bootstrap holding on durable.

As I trace it through, I see that smartWalletFactory calls .makeHandler(), and then uses initHandler to save this ephemeral object.

  const bridgeHandler = await E(ppFacets.creatorFacet).makeHandler();

  await Promise.all([
    E(provisionWalletBridgeManager).initHandler(bridgeHandler),
    ....
  ]);

I think we'd need to get the provisionWalletBridgeManager, and call E(provisionWalletBridgeManager).setHandler(persistentHandler) in order to replace this object.

The reaason for all of this is that the bootstrap vat is holding onto several ephemeral objects, and I think this is one of them. If we can replace it with a persistent object, we'd reduce the count by ond and be closer to being able to upgrade the bootstrap vat.

@anilhelvaci
Copy link
Collaborator Author

makeProvisioner gives provisioning a non-null value, so handler gets that Far object defined in bridgeProvisioner(), which is held by provisionBridgeManager.

I thought the end goal was to make handler assigned to an Exo instead of a Far. If the end goal is E(provisionWalletBridgeManager).setHandler(persistentHandler), I’m pretty clear with how to proceed. @Chris-Hibbert

@Chris-Hibbert
Copy link
Contributor

What we're concerned about is what objects are being retained in the bootstrap vat. handler inside bridgeProvisioner is just a name on the stack.

If you see other places the handler might be retained, please point it out, and we can talk about how to remediate.

@anilhelvaci anilhelvaci self-assigned this Nov 15, 2024
@anilhelvaci
Copy link
Collaborator Author

anilhelvaci commented Nov 15, 2024

image

Here's a screenshot of the sequence diagram generated after doing agd tx swingset provision-one. I'll drop the full image and the slogfile as well. (Look for 0.33 ko62.inbound(289))

Seems like only vat that talks to bootstrap is the bridge and the result of the action triggerred turns out communication between vat-zoe and vat-bank triggerred by vat-provisionPool.

Link to the full files
https://drive.google.com/drive/folders/187xCEq3-BVSZ5oIZX_0ObzP6PsqgfTOt?usp=sharing

cc @dckc @Chris-Hibbert

@dckc
Copy link
Member

dckc commented Nov 15, 2024

Thanks!

SVG works particularly nicely in github gists:

@Chris-Hibbert
Copy link
Contributor

I'm not sure what I should be look at. I see messages going back and forth, but I'm not sure how I would tell if the ephemeral object is retained or dropped. Do you see something in this transcript that helps you understand?

anilhelvaci added a commit that referenced this issue Nov 18, 2024
anilhelvaci added a commit that referenced this issue Nov 20, 2024
anilhelvaci added a commit that referenced this issue Nov 25, 2024
anilhelvaci added a commit that referenced this issue Nov 26, 2024
anilhelvaci added a commit that referenced this issue Nov 26, 2024
Make sure the handler returned from E(creatorFacet).makeHandler() is durable and provisionPool is upgradable multiple times.

Refs: #10425
Refs: 10564
anilhelvaci added a commit that referenced this issue Nov 26, 2024
Make sure the handler returned from E(creatorFacet).makeHandler() is durable and provisionPool is upgradable multiple times.

Refs: #10425
Refs: 10564

fix: remove unnecessary comment
anilhelvaci added a commit that referenced this issue Nov 27, 2024
Make sure the handler returned from E(creatorFacet).makeHandler() is durable and provisionPool is upgradable multiple times.

Refs: #10425
Refs: #10564

fix: remove unnecessary comment

chore: get rid of ephemera, address change requests

Refs: #10395
Refs: #10425
anilhelvaci added a commit that referenced this issue Nov 27, 2024
Make sure the handler returned from E(creatorFacet).makeHandler() is durable and provisionPool is upgradable multiple times.

Refs: #10425
Refs: #10564

fix: remove unnecessary comment

chore: get rid of ephemera, address change requests

Refs: #10395
Refs: #10425

fix: drop trace
anilhelvaci added a commit that referenced this issue Nov 27, 2024
Make sure the handler returned from E(creatorFacet).makeHandler() is durable and provisionPool is upgradable multiple times.

Refs: #10425
Refs: #10564

fix: remove unnecessary comment

chore: get rid of ephemera, address change requests

Refs: #10395
Refs: #10425

fix: drop trace
anilhelvaci added a commit that referenced this issue Nov 27, 2024
Make sure the handler returned from E(creatorFacet).makeHandler() is durable and provisionPool is upgradable multiple times.

Refs: #10425
Refs: #10564

fix: remove unnecessary comment

chore: get rid of ephemera, address change requests

Refs: #10395
Refs: #10425

fix: drop trace

chore: address change requests
anilhelvaci added a commit that referenced this issue Nov 27, 2024
Make sure the handler returned from E(creatorFacet).makeHandler() is durable and provisionPool is upgradable multiple times.

Refs: #10425
Refs: #10564

fix: remove unnecessary comment

chore: get rid of ephemera, address change requests

Refs: #10395
Refs: #10425

fix: drop trace

chore: address change requests

fix: rebase fixes
anilhelvaci added a commit that referenced this issue Nov 27, 2024
Make sure the handler returned from E(creatorFacet).makeHandler() is durable and provisionPool is upgradable multiple times.

Refs: #10425
Refs: #10564

fix: remove unnecessary comment

chore: get rid of ephemera, address change requests

Refs: #10395
Refs: #10425

fix: drop trace

chore: address change requests

fix: rebase fixes

fix: yarn.lock fix
anilhelvaci added a commit that referenced this issue Nov 27, 2024
Make sure the handler returned from E(creatorFacet).makeHandler() is durable and provisionPool is upgradable multiple times.

Refs: #10425
Refs: #10564

fix: remove unnecessary comment

chore: get rid of ephemera, address change requests

Refs: #10395
Refs: #10425

fix: drop trace

chore: address change requests

fix: rebase fixes

fix: yarn.lock fix

fix: bring back missing upgrade-paRegistry proposal
anilhelvaci added a commit that referenced this issue Dec 2, 2024
Make sure the handler returned from E(creatorFacet).makeHandler() is durable and provisionPool is upgradable multiple times.

Refs: #10425
Refs: #10564

fix: remove unnecessary comment

chore: get rid of ephemera, address change requests

Refs: #10395
Refs: #10425

fix: drop trace

chore: address change requests

fix: rebase fixes

fix: yarn.lock fix

fix: bring back missing upgrade-paRegistry proposal
anilhelvaci added a commit that referenced this issue Dec 3, 2024
Make sure the handler returned from E(creatorFacet).makeHandler() is durable and provisionPool is upgradable multiple times.

Refs: #10425
Refs: #10564

fix: remove unnecessary comment

chore: get rid of ephemera, address change requests

Refs: #10395
Refs: #10425

fix: drop trace

chore: address change requests

fix: rebase fixes

fix: yarn.lock fix

fix: bring back missing upgrade-paRegistry proposal
@mergify mergify bot closed this as completed in #10419 Dec 3, 2024
@mergify mergify bot closed this as completed in dcf2772 Dec 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants