Suggestion: Give the possibility to install a cap without a signature in a transaction payload
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_PAYERto 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.
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.
It's never a problem to install a cap, so we could just install GAS_PAYER in chainweb in all cases.
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.
@edmundnoble sorry I forgot that sigs are indeed how a GAS_PAYER cap is specified:
https://github.com/kadena-io/chainweb-node/blob/f13025ba5ca2a374559b9f8e709f636c391a1b95/src/Chainweb/Pact/TransactionExec.hs#L967
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.
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
Actually,
gasPayercould be a way to get away from Ethereum-centered naming (senderreally doesn't make sense as a gas payer in the Pact context.) The idea would be, deprecatesender, and havegasPayerreplace 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:
senderis a bad-chosen name. It confuses a lot of builders, especially people coming from Solidity wheresenderis used for a more general purpose than just paying gas.gasPayeris definitively better. - The
GAS_PAYERcap 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.