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

Inter Plugin Communication (IPC) #148

Closed
rigelrozanski opened this issue Jun 29, 2017 · 4 comments
Closed

Inter Plugin Communication (IPC) #148

rigelrozanski opened this issue Jun 29, 2017 · 4 comments

Comments

@rigelrozanski
Copy link
Contributor

This discussion is in the context of a refactored basecoin as a middleware (post 0.7). More context: each plugin, or instance of a plugin will have a unique domain within the state in which it is permissioned to use. However there are many situations for which a plugin may want/need to interact with a space which it is not inherently permissioned for such as:

  • app triggers sending an ibc packet
  • app sending coins to someone

We need to have as versatile an environment as possible without compromising safety or ease of use... IPC may allow what is currently one plugin to be further compartmentalized into a cluster of plugins, - right off the bat with tendermint/trackomatron I can imagine having separate but interacting plugin utilities for creating profiles, sending invoices, and paying invoices - These sometimes may need to interact in the same space.

@ethanfrey
Copy link
Contributor

One fundamental question is the model of these calls.

Do they call the other plugin directly and get a response. Possibly with an custom interface. (eg. SendCoin and CheckBalance)?

Are they able to make new TX and then execute a TX on another plugin and get the abci result. And then continue processing.

Both of these are synchronous, which allows complex calls graphs and is more powerful but also more susceptible to errors and infinite loops and such

Another approach is to model the asynchronous aspect of ibc and allow them to send message TXs that are executed in the next block. This allows us to control the communication much more at the framework level, but limits the actions the same way as ibc, as it is a one way message.

Of course any protocol can be modeled by a series of messages, it would just make state handling more complicated, as we must persist intermediate state

@rigelrozanski
Copy link
Contributor Author

  • Sounds like permissioning a plugin to diretly modify the state space of another plugin is just totally off the table? aka. Modify state space for PluginX from PluginY without calling PluginX at all (but being permissioned ahead of time)
  • We should def allow for the plugins to call each other directly, this has broader implications than just accessing the state space of the other plugin.
  • What do you mean by make tx? - Effectively construct the tx of another plugin and then call in that other plugins space... isn't that already possible? If you can construct a tx then you can call it. I guess this satisfies the first point too, in a medial way, If the changes to the state you wish to make are in accordance to how that plugin would normally modify its state, then just calling a tx would make sense.... Now that I'm reflecting, it seems as though all IPC transactions should occur with the same process stream as the TX as if it was being broadcast from the CLI - with the exception that special transaction types can be reserved for plugins... or better specific plugins which have been permissioned to work with this custom (not accessible from the CLI) transaction. - This way, a plugin state space could not get hacked (intentionally or accidentally) by another plugin as I suggested in the first bullet point - If a plugin needs to interact with another plugins state space in a nuance way, the second plugin must contain the nuance logic and execute it from its side
  • Thoughts on synchronicity: Just wrapping my head around what you're saying: is the problem that in normal operation we just order a list of transactions but somehow if transactions are calling other transactions it becomes a problem? - So long as we bypass the "broadcast" of the inner-Tx this seems like it should be okay?
    • infinite loops as in two transactions reference each other and call back and forth infinitely? This should be okay as should be stopped by the "gas" getting consumed.
    • interesting point about the intermediate state - if one Tx is calling another Tx and bypassing the tendermint broadcast then the new state must be an intermediate one... gets - AND worse how do we apply that intermediate state - the only way I can see is at the end of this complex IPC transaction there would need to be a broadcast of a mandatorily-grouped list of TXs with all the inner-TX calls made in order.. sounds totally do-able.
    • I'm honestly not a fan of the idea of separating out all the IPC transactions per block - it makes the application logic more confusing than it needs to be. All of a sudden have to consider a wide range of "what-if" scenarios for mid-transaction state changes to the state of the other plugin state the IPC transaction is attempting to affect - I think generally we want IPC transactions to be completely atomic - either the whole thing happens or it doesn't - by introducing multi-block transactions this become an arduous guarantee

@ethanfrey
Copy link
Contributor

Okay, I agree point 1 is totally off the table. I can give a long rant why admins editing dbs directly outside of the business logic is a major cause of fragility of most long loved applications. But seems you agree.

Point 4, also agree, too complex. But yes we need gas somehow...

Roughly then, I see the second and third points as two directions to pursue and we should support both, with some notion of gas to avoid infinite loops maybe.

The general case of dispatch another TX with the same context / permissions could work well and be quite flexible. Also make sure we always abide by the business logic. And I think this should he supported in some generalized manner.

However, the exposed actions and return values are not always what we want to build other apps.

For example, if the fee Middleware wants to check and later deduct the fee from the account, then S sendtx the proper way? Or creating an ibc packet?

If we can fit everything in the TX callback format, it would be nice. I think we may sometimes need to pass in custom interfaces for lower level access to the modules, but still constrained by their business logic. I have no clear idea how this looks, but let's talk.

@ethanfrey
Copy link
Contributor

Notes from talk:

  • Every plugin has a "state space", like a prefix in the keyspace that belongs to them completely.
  • If plugin wants to talk to another plugin, it can create a tx, and pass it to a dispatcher, which will execute it synchronously, and return the result to that plugin
  • permissioning is done by context
  • come sort of call-limits can be done in the dispatcher (# sub txs per tx)
  • dispatcher can implement basecoin.Handler
  • all plugins/modules register with the dispatcher
    • this is used for dispatching from chain tx as well a ipc

@zramsay zramsay closed this as completed Oct 11, 2017
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