SIMD-0163: Lift the CPI caller restriction#163
Conversation
buffalojoec
left a comment
There was a problem hiding this comment.
This is a great change! Eliminating the requirement for programs to contain the callee program account - in the cases of loaders v2 and v4 - will be a drastic improvement on CUs.
f5abfcf to
55578ff
Compare
|
Can you clarify why this is a massive improvement in CU cost? It seems to me like it's more of a general improvement to VM performance and just removes the need to construct one or a few more As an extreme example, a noop program pub extern "C" fn entrypoint(input: *mut u8) -> u64 {
0
}would see no reduction in CUs from being invoked with one less 10 MB account |
|
@cavemanloverboy For top-level instructions this is in deed irrelevant. But, not so for nested CPI. In nested CPI the program runtime does copy the program data (except for those owned by loader-v3) of instruction accounts, and taxes the caller for it here: https://github.com/anza-xyz/agave/blob/77b4d131502e095d18f3df7caab8b6a1cf7c1887/programs/bpf_loader/src/syscalls/cpi.rs#L886 |
jstarry
left a comment
There was a problem hiding this comment.
I really like this SIMD but I'm wondering if we should also update the tx format to make it explicit which programs may be invoked during tx execution. Rather than just appending program ids to the readonly accounts in a transaction, we could have a new message header value which defines how many of the trailing readonly accounts are invokable and should therefore be loaded into the program cache before execution.
Good idea, however outside of this SIMD. This is only about CPI, it does not affect the message accounts. |
|
I agree. New transaction format needs to be thought through in great detail alongside #172. I will draft something up in the next few weeks. |
|
should we specify that non-instruction non-payer accounts must be read-only and enforce this in sanitize? or specify that writable non-instruction non-payer accounts are demoted to read-only? it wouldnt really affect lock contention because the only reason to append a writable account is to be annoying, and they could be just as annoying by taking it as an instruction account, but it would mean we dont need to check if a non-instruction account was invoked to skip it during account saving |
|
I don't think this SIMD is that much related to account loading. It needs all accounts containing programs to be loaded in the program cache, that's it. And that happens anyway, independent of writeability and later account saving. |
|
It looks like there's consensus here. If no one objects within the next week, I'll merge this on 25 November. |
|
We think there is a risk that some programs rely on inspecting instructions to determine whether other instructions might make a CPI call to a particular program. |
Related to this, the changes proposed in this SIMD expands the behaviour of what instructions can access in unpredictable ways, since now all instructions have access to program accounts even if they are not explicitly listed. It will be practically impossible for programs to make sure third-party programs they CPI into are not going to do something that they should not. It would also make transaction building a bit complicated, since an instruction might not list a program account as required, but only succeed if a particular program is in the transaction. The model that we have today provides a way to restrict what programs can access by requiring program accounts to be explicitly listed – this behaviour most likely should be maintained. |
|
I had thought that this feature only restricts at the level of top-level instruction, meaning that each program in a top-level instruction could CPI into other programs declared within the top-level instruction, but I was told this isn't the case. While I think it's OK to lift the CPI caller restriction at the level of each top-level instruction, if we lift it at the transaction level, there are some dangerous possibilities, as Febo mentioned. Currently, it's possible to see dangers by looking at top-level instructions. For example, if you see an instruction take in the system program and your wallet as a signer, then you know that program could drain your wallet. With this change, however, if you provide your wallet as a signer to any top-level instruction, then that top-level instruction could rug you if the system program happens to be elsewhere in the same transaction. It becomes safer to send multiple transactions rather than put everything in one transaction, which is not behavior we should encourage. |
There was a problem hiding this comment.
EDIT: I didn't read the latest comments before commenting. My bad! Anyway, here's the same point articulated again.
We were discussing offline about some potential concerns with this SIMD. I had previously cast my approval, but I believe the following concerns should be explored before this SIMD is implemented, allowing for any revisions to the proposal and its design.
A few other SIMDs have requested more information from what we call in Agave the "transaction context". An example is SIMD-0258, which requests access to the signatures. Furthermore, instruction introspection via the Instructions sysvar can also give a program insight into the entire list of accounts involved in a transaction.
If on-chain programs can - now or eventually - access the entire list of transaction accounts, then they can behave maliciously as a result of this SIMD.
Consider the following scenario:
- A user crafts a transaction where the first instruction is a System program transfer from their wallet to some destination.
- They include a second transaction to interact with some protocol.
- Even though they did not place the System program in the list of account metas for the second instruction, the protocol can CPI into the System program and drain the user's wallet.
One could argue that there are plenty of exploits like these that are already possible, simply due to the inherent nature of untrusted third-party permissionless software. Regardless, it's worth understanding what kind of footguns this SIMD can create, even if we retain that users should always only interact with trusted protocols.
At a minimum, I request this concern be added to the Impact section.
cc @febo @joncinque
No description provided.