-
Notifications
You must be signed in to change notification settings - Fork 188
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
Modular systems / system to system calls #319
Comments
Back when I made #268 I myself wasn't sure subsystems were useful. Now I actually have a bunch of examples, so here's an updated pitch. System to system calls aren't common. Small projects wouldn't need them at all. Open this deploy.json, scroll down to What's a subsystem? Why do I need OwnableWritable? Why not just use Systems then?
Why not just use libraries?
Subsystem examples: |
@dk1a thanks for the updated pitch / explanation of subsystems and how they compare to regular systems and libraries. We can definitely agree on the usefulness of "stateful libraries" or calling systems from other systems. In my opinion the subsystem approach perfectly solves the "first party" issues (adding the possibility for stateful libraries for a developer's own systems), but I'd like to think about whether we can come up with a solution that would give the same benefits to third party developers (using existing systems as modules to create more complex higher level systems). Curious to hear your thoughts on this. |
@alvrs Interesting, I've never thought of that side of the problem in relation to subsystems. Lets say you have a character entity, and a MoveSystem. approvedAddress instead of approvedSystemId maybe avoids upgradeability phishing, but not really (it could call an upgradeable system, so is it even worth it?) my details may be off, haven't actually written any code for this |
The main point of that whole approval thing is, it's ok if you get phished. You character will just move incorrectly for a while. The attacker doesn't get full permission to do whatever |
Kind of related: https://blog.curio.gg/how-we-built-this-treaty-technical-overview/ |
Very interesting idea! It got me thinking about how we could use a general approval pattern to solve this issue (modular systems) as well as the session wallet issue (to move on from pure burner wallets). Created a proposal in #327, lmk what you think! |
Closing this since it's pre v2 (we basically implemented subsystems, and the global entry point is part of #1124) |
Problem description
Systems encapsulate logic. It would be nice if it was possible to use systems as modular building blocks to create higher level systems, but when a system is called from another system, any access control logic related to
msg.sender
fails, because the calling system is the newmsg.sender
.A common workaround is to encapsulate logic in libraries instead, use those libraries as building blocks and use systems only as entry points to the application. However, this comes with two issues:
Example of a situation where it would be nice to use systems as building blocks, but we run into the issue of
msg.sender
being different:MoveSystem
has access to aPositionComponent
and implements the rules of movement in the world (eg. the entity to be moved needs to be owned by the system caller (msg.sender
), and the target position needs to be adjacent to the current position)PathSystem
, which batches calls toMoveSystem
to move multiple steps in one transaction. In an ideal worldPathSystem
could just callMoveSystem
multiple times with valid steps, thus respecting the existing rules and adding a higher level system.PathSystem
toMoveSystem
fails, becausemsg.sender
isPathSystem
and not the owner of the entity to be moved.Approaches
1.
access control via tx.originusetx.origin
instead ofmsg.sender
-> not recommended because it can lead to phishing vulnerabilities and discriminates against smart contract wallets.2. Subsystems
3. Global entry point
World
contract.World
, before calling the requested systems, and finally resetting the caller variable to some placeholder value.msg.sender
, thereby allowing systems to call other systems while preserving the initial caller.tx.origin
for access control, with the exception of supporting smart contracts wallets, and maybe less phishing potential because the entry point call has to be explicit (instead of the possible use of fallback functions withtx.origin
).The text was updated successfully, but these errors were encountered: