-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
ADR 033: Inter-Module Communication #7459
Conversation
…ronc/adr-protobuf-ocaps
…ronc/adr-protobuf-ocaps
Quick review with few ideas. In the section below, I'm describing a paradigm for inter-module communication rather than specification details. Protobuf Msg Services and hiding KeepersI really like the Protobuf Msg Services (ADR 31) concept and limit / remove the support for keepers. Keeper is a module primitive which works on the data level, without getting a bigger context. I don't see any benefits of exposing it outside, only disadvantages:
Essentially there is no way how we can protect a module without hiding keepers. So, ideally I would see a keeper as a Data Access Layer object, which would imply that keepers shouldn't call other services (note: if this make sense then we should update the examples). EncapsulationWhen thinking about modules, I'm considering them as independent blocks. More like a smart-contracts. With that in mind, modules should have a well defined interface, which will enable the communication with the modules. For authorization we need to know:
The former one can be easily passed as a call chain. For the latter one we have few options: Extracting a call stack from the runtimeAll popular languages allow to get a call stack and inspect who is calling the service. Using a runtime information removes a burden of passing and verifying module keys (at the end of the day this keys are available to the developer, so it's only about the developer culture to use them correctly). On the other hand usage of |
…ronc/adr-protobuf-ocaps
I see what you're getting at here @robert-zaremba and it might be the most secure way of doing ocaps. I imagine you're thinking of The |
It shouldn't be very hacky, but some runtime inspection will be required. This is how it could work:
|
@robert-zaremba so if something like that were to work I don't think it's incompatible with module keys. Modules will need reference to something at a minimum to get their module account address. And they will need something for That said I do think the call stack approach would be more complex and error prone to implement and doesn't provide any security guarantees over the module key approach because it is vulnerable to stack manipulation as well. Basically if an attacker is going to use stack manipulation they can just bypass the call stack check you're proposing altogether. So I would conclude that the only defense against that is static analysis. The best runtime defense we can get is against reflection attacks. |
Yes, it's more error prone. On the other hand it's more convenient, because we don't need At the end of the day, everything is in the power of the developer. IIUC, developer can manipulate the keys if he wants - he can use the same key in different modules. No need to hack the runtime. |
But in this model modules can't create addresses at will. The app assigns the module addresses and that's what it gets. So module keys seem necessary for that.
An app developer could hack module keys so that two modules use the same key if they wanted. But a module developer couldn't. This system creates that sort of isolation. It's important to distinguish between the two types of developers - module and app. |
…ronc/adr-protobuf-ocaps
Based on discussions in #8134 (specifically #8134 (comment)), I think it is likely better to make this design primarily asynchronous to support future parallel execution models. Here's what I'm thinking:
|
This approach won't really quite work, but I did a bit of a spike on a parallel design and came up with something that I think will (#8134 (reply in thread)). I am currently leaning to moving in that direction. |
Has a decision been made wrt to Inter-Module Communication and this ADR? |
ADR committee (@aaronc @alexanderbez me): are we positive with this? Can we just approve this and move on, please? |
Thanks @alessio. I think it makes sense to move forward with this for now. A parallel approach could be complementary and opt-in when we get there. |
Music to my ears! :) @alexanderbez are you OK with merging this? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's been sometime since I thoroughly reviewed this. I recall having some questions and just overall misunderstandings on some of the things this is really trying to solve. In addition, I think this might be too complicated and more engineering than what we might need. Perhaps if I spent more time really digging into it that would change...
That being said, a considerable amount of thought, time and discussion has went into this from many people and I think it has a strong foundation, so I'm giving my 👍
Habemus consensus. @robert-zaremba mind lifting your block, please? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm in favor of it from the beginning, I requested changes related to cosmetic updates, typos and adding more details. Before merging, let's:
- consider suggestions - there are few typos and style updates.
- maybe we can add a new section: Further Discussion to list related topics (as already listed in some comments).
|
||
... | ||
|
||
bankMsgClient := bank.NewMsgClient(fooMsgServer.moduleKey) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So how about creating required clients in the constructor and storing them as a private fields in the structure? It has few benefits:
- we clearly signal the dependencies
- we don't recreate the objects (caching).
### Negative | ||
|
||
- modules which adopt this will need significant refactoring | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can "deeper reuse of protobuf generated code"? I don't think it's negative, sounds more like neutral or positive.
Why it was merged without checking / answering the comments? |
The ADR committee approved it, thus it makes no sense to keep it open. Changes can be carried out in ensuing PRs. |
@robert-zaremba sorry about that. I had forgotten about your last comments, and was mostly acting on the fact that it had sufficient approvals |
@clevinson I created #8676 with cosmetic changes to improve (hopefully) reading of this ADR. |
ref: #7093 #7421
This ADR introduces a system for permissioned inter-module communication leveraging the protobuf
Query
andMsg
service definitions defined in ADR 021 and ADR 031 which provides:It is intended serve as a foundational piece in the roadmap towards Cosmos SDK v1.0.
Before we can merge this PR, please make sure that all the following items have been
checked off. If any of the checklist items are not applicable, please leave them but
write a little note why.
docs/
) or specification (x/<module>/spec/
)godoc
comments.Unreleased
section inCHANGELOG.md
Files changed
in the Github PR explorerCodecov Report
in the comment section below once CI passes