-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Store/deploy execution traces #602
Comments
Why we don't add the allowed contracts calls in a manifest (like permissions), for ensure that the VM know the possible relationships between contracts before the execution? |
|
So.. we should have enough information to know the relationship with the permission file. |
Code analysis is one way to try to determine what can be run in parallel; however, the solution needs to be able to support executing contracts that are using storage-get and storage-put. As long as there is guaranteed not to be any storage collisions it should execute them still in parallel. This is where the permission manifest should provide the necessary information. Having a solution that runs parts of a contract sequentially and other parts of a contract in parallel is more complex and likely shouldn't be in the initial design. What do you think? Perhaps we should discuss byte code / trace analysis as a mechanism to support parallel contract execution separately from adding support for a lightweight contract deployment in the form of an execution trace, since the two things shouldn't need to be coupled together, should they? |
I fully agree that the permission system is very fundamental, top priority, mainly from security aspects, and much less from parallel computing perspective. So, this discussion here is not meant to replace any existing proposal, but to complement some of them, if necessary. Going back to the permission system, I personally don't see how it will help us developing parallel code, because most of the information that will be provided to us can currently be extracted from contract bytecode. For example, if contract supports dynamic invoke, we could "know it" because of two things: (1) it payed for it (2) it has some Having this said, with manifest or not, we may already know, for most situations, which contracts could be invoked from others. Question is: how to explore these properties for parallel execution? This proposal tries to tackle efficient exploration of situations where a common code is often executed, including static invokes, with full parallelization (but storage-write-free). I agree that this is a huge flaw on the proposal (not having storage writes on the traces), because this would be useless for NEP-5, which is the most interesting scenario. In my opinion, this is also the hardest part (not the external contract invocation parts), which I've thought a lot but haven't yet found a good solution. The only thought I've had so far, which solves Native NEP-5 parallelization (but it's hard for other cases), is whitelisting storage writes. This way, user should provide a list of storage keys that are affected by its operation, so the transaction execution engine will know in advance which keys are affected, so non-conflicting transactions could be run in parallel. On the other hand, this will work on Native NEP-5, but will not work on contracts that have unpredictable results (depending on block height, random values and other info), which is a common use-case for blockchain too. Another problem is that, if too many keys are affected, a longer transaction would be issued (because of longer whitelisting list) and processing time could also increase for tx scheduler. |
* sync up recent changes related to neo-project#587, neo-project#590, neo-project#594, neo-project#596, neo-project#597, neo-project#602 * minor updates minor updates
This proposal is very abstract now, but perhaps can be useful in two aspects: (1) provide a good way of achieving parallelism on existing contracts, being Native or not (2) allow users to deploy of Native Contracts or parts of it ("Execution Traces" or "Native Functions").
The idea is to store the Execution Trace over an existing (or perhaps new) contract. Over an execution trace, besides being deterministic, all branch decisions should also be pre-determined, meaning that NeoVM/NeoContract will know exactly which opcodes to be executed, only varying some input parameters. The scripthash of the trace could consist of the set of operations executed on the contract (for specific calls of interest), and a binary could be automatically generated and cached on nodes, after trace creation is requested (perhaps someone could pay a price to "deploy" that, don't know yet...). The price payed by the user executing the trace could be the same as executed without it (the only advantage is faster execution), or a discounted/fixed price to incentive this model.
Consider this example (if x is more than 10, double it, else subtracts one):
It has the following opcodes:
Meaning that, if x = 30 (and all x>10), only a few opcodes will be used (asterisk are removed):
So, on this example, trace would be:
51c56b6c766b00527ac46a00c35aa1630e006a00c36165120051c56b6c766b00527ac46a00c35295616c7566616c7566
(scripthash:0xcab571c009a140cc7a0879592bcd3003ca3601fc
).Note that trace is smaller than avm, but if code contained loops, these loops could make trace even bigger than original avm. If any branch fails the follow the expected sequence, the trace fails and throws.
This way, we could possibly store the sequence of used opcodes as a Native Contract (or "Native Function" of a contract), and the user provides the desired trace during invocation.
Deploy Trace example:
Neo.Contract.DeployTrace Contract_scripthash + trace_operations
=>Neo.Contract.DeployTrace 0x8c2074abcdba9fec8a7559e6d1448fa64eda0d3d 51c56b6c766b00527ac46a00c35aa1630e006a00c36165120051c56b6c766b00527ac46a00c35295616c7566616c7566
.Invocation could be the same (passing trace scripthash as execution hash):
PUSH30, APPCALL 0xcab571c009a140cc7a0879592bcd3003ca3601fc
(instead ofAPPCALL 0x8c2074abcdba9fec8a7559e6d1448fa64eda0d3d
). Note thatPUSH9, APPCALL 0xcab571c009a140cc7a0879592bcd3003ca3601fc
would fail because of unexpected jumps (as x = 9 <= 10).Advantage: parallel code can explore the trace the predict conflicts and if no storage-write is used, all traces free of storage-put could be done in batch parallel.
Cons: The only extra overhead is the storage of these traces, so it would be important to have a price on that (but so much less than a regular contract...).
The text was updated successfully, but these errors were encountered: