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

Suggestion: Give the possibility to install a cap without a signature in a transaction payload #1702

Open
CryptoPascal31 opened this issue Jul 21, 2023 · 6 comments

Comments

@CryptoPascal31
Copy link
Contributor

CryptoPascal31 commented Jul 21, 2023

Currently:
In a transaction payload, a capability is always associated to a signer (pubKey) and a matching signature. It does make a lot of sense because most of the time, a capability code enforces a guard.

But in some cases the capability doesn't enforce any guard, and just need to be installed. One of these particular cases is in gas station triggered by the magic cap GAS_PAYER. Since this usually triggers a public gas station, it is a non-sense to associate GAS_PAYER to a pubKey. However, this is mandatory with the current Chainweb/Pact implementation.

Currently for a client or a Dapp there are 2 possible workarounds to make it work:

  • If the transaction contains already a signer with an already restricted signature, attach GAS_PAYER to the existing signer. From a functional point of view this is completely inconsistent. It just breaks the beauty and the concept of capabilities.
  • Create a fake signer, with a fake key pair just to install a capability that doesn't need a signer. This is stupid and inefficient.

I think that Chainweb should allow and always validate a payload containing a Signer object with an empty pubKey. In this case, I suggest to use a special marker like "NONE" or "NOVERIFY"in the scheme field, to indicate that signature verification must be bypassed.

NB: Not sure if this should be handled directly by Chainweb code or Pact code.

@edmundnoble
Copy link
Contributor

edmundnoble commented Feb 16, 2024

Thanks for the suggestion to deal with this using a verifier. Here's my thinking, which I think for the most part is a recap of your thinking. My reasoning earlier re: the GAS_PAYER cap is incomplete. Yes, a verifier cannot grant the GAS_PAYER cap, because as mentioned before, verifiers run after gas is bought. But that doesn't mean we can't find the GAS_PAYER cap regardless in a verifier, that is, "trigger a gas station from a verifier"; the only extra piece of machinery we're missing to do that is to make findPayer search for GAS_PAYER in the verifiers and not just in the signers.

The allow verifier is one way we can do that, but what I'd probably prefer is to have a specific verifier just called something like gas-station which has no proof, only grants GAS_PAYER caps, and is the only other place that findPayer looks in aside from signers. Let me know your thoughts.

Frankly I might prefer to not use a verifier for this either, and instead to have a special field in Command.

@sirlensalot
Copy link
Contributor

It's never a problem to install a cap, so we could just install GAS_PAYER in chainweb in all cases.

@edmundnoble
Copy link
Contributor

edmundnoble commented Feb 16, 2024

It's never a problem to install a cap, so we could just install GAS_PAYER in chainweb in all cases.

But which GAS_PAYER? We need the module + args so that we can call into the cap body to make sure that the module is ok with paying gas.

@sirlensalot
Copy link
Contributor

@edmundnoble sorry I forgot that sigs are indeed how a GAS_PAYER cap is specified:

findPayerCap = preview $ eeMsgSigs . folded . folded . to sigPayerCap . _Just

Frankly I might prefer to not use a verifier for this either, and instead to have a special field in Command.

Agree, adding something like gasPayer to Payload is probably better so that it's not in scope for the entire tx.

@sirlensalot
Copy link
Contributor

sirlensalot commented Feb 16, 2024

Actually, gasPayer could be a way to get away from Ethereum-centered naming (sender really doesn't make sense as a gas payer in the Pact context.) The idea would be, deprecate sender, and have gasPayer replace it with an object { account: "xxx", caps: [{cap: foo.bar.GAS_PAYER, args: [...]}] } . Just a thought

@CryptoPascal31
Copy link
Contributor Author

Actually, gasPayer could be a way to get away from Ethereum-centered naming (sender really doesn't make sense as a gas payer in the Pact context.) The idea would be, deprecate sender, and have gasPayer replace it with an object { account: "xxx", caps: [{cap: foo.bar.GAS_PAYER, args: [...]}] } . Just a thought

IMO: I agree with you. This makes a lot of sense:

  • Semantic: sender is a bad-chosen name. It confuses a lot of builders, especially people coming from Solidity where sender is used for a more general purpose than just paying gas. gasPayer is definitively better.
  • The GAS_PAYER cap has nothing to do with inside a signer or verifier cap (there is in fact no relation). Attaching it to the gas-paying account makes more sense.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants