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

Support for Parallel Contract Validation & Execution #546

Open
jsolman opened this issue Jan 13, 2019 · 12 comments
Open

Support for Parallel Contract Validation & Execution #546

jsolman opened this issue Jan 13, 2019 · 12 comments
Labels
discussion Initial issue state - proposed but not yet accepted

Comments

@jsolman
Copy link
Contributor

jsolman commented Jan 13, 2019

If it were possible to know what other contracts a contract can invoke by any means (either through direct references hard-coded in the contract or through dynamic invoke calls), then it would be possible to safely support parallel contract execution. This would be possible since it could be verified that the call chains of two contracts would not collide on a common contract that could have had its state changed depending on the order the contracts are run.

Suppose that all contracts that will call any other contract by any means required having a contract owner explicitly set what contract hashes could be invoked dynamically. It could be argued that they would no longer be 100% dynamic anymore, but they would still be dynamic since additional contracts could be called from a contract after it's deployment if the owner explicitly adds an additional contract hash. As it is most contracts that do any type of dynamic invoke already require the concept of a contract owner to whitelist contracts that can be called; this would just make that process more defined so that neo implementations can know this information for purposes of parallel execution.

Required changes:

  • Addition of a contract owner for contracts that will call any other contract
  • A new transaction type that can be called by a contract owner to add or remove hashes that can be invoked by a specified contract
@igormcoelho
Copy link
Contributor

igormcoelho commented Jan 13, 2019

In fact, Erik is proposing that feature manifest or abi may be changed later (via interop call, etc, I think its on two discussions a similar topic), so theres no.need to enforce an owner, the whole config could be updated (if provided a known open function I guess).. some will have owner, others will be fully dao. Regarding execution paralelism, we intend to explore that in this year (on NeoResearch public guideines). As soon as consensus and network layers are improved, we will also start digging into that, its a nice direction.

@jsolman
Copy link
Contributor Author

jsolman commented Jan 13, 2019

@igormcoelho If it can be changed through an Interop call changes to the permissions cannot take effect until the next block, otherwise it would break the ability to execute in parallel in the current block.

@jsolman
Copy link
Contributor Author

jsolman commented Jan 14, 2019

I guess it could also use a storage prefix within each contract and a specified format for defining the contract hashes that can be invoked by a contract. Then after each block if those hashes changed it could apply those permissions. Then no contract owner required and no new transaction types. I'll re-write the issue and close this one.

@erikzhang erikzhang added the discussion Initial issue state - proposed but not yet accepted label Jan 15, 2019
@erikzhang erikzhang added this to the NEO 3.0 milestone Jan 15, 2019
@lightszero
Copy link
Member

lightszero commented Jan 17, 2019

howabout design like this

TX
{
call "transfer"
param1 StorageSetter("FromAddress")
param2 StorageAdder("ToAddress")
param3 const 3
script
}

--- in script----

bool transfer(StorageSetter from,StorageAdder to,number v)
{
var num = from.getValue();
if(num<v)
    return false;
from.SetValue(num-v);

to.Add(v);

return true.
}

every thing can change state is a special param in TX.
so we will know what state a TX what to change,and do not to run it.

@lightszero
Copy link
Member

lightszero commented Feb 17, 2019

i create a prototype project for parallel contract execution

https://github.com/lightszero/Parallel_Contract_Prototype

with my design, tx with same contract can be parallel too, like a nep5 transfer. alice ->bob1,alice->bob2,can be parallel execution.

@erikzhang
Copy link
Member

@lightszero This is not true parallel execution. Because you used locks, the results of the execution are sequential.

For example, A has $100 in his account. There are two transactions, in the first transaction A transfers $80 to B, and in the second transaction A transfers $70 to C. We all know that only one of the two transactions can be executed successfully, and the final balance of A is related to the order in which the two transactions are executed.

In your prototype, if you execute the above two transactions, the results of the execution will be random and non-deterministic.

@lightszero
Copy link
Member

A -> B 80 and A->C 70, in this case, this 2 transaction need to be sort and not parallel execution.
but B->A 80 and C->A 70,can be parallel.

when we known A is a sender,we can make this 2 transaction in diff blocks.

@jsolman
Copy link
Contributor Author

jsolman commented Feb 18, 2019

@lightszero
It needs to be solved for operations that may occur on storage generically, not just for sending funds or specific use cases.

Also while giving the programmer facilities to manage locking would be a possible solution, I don’t think we want to make the programmer have the burden to manage locking, since it would be error prone, and errors could potentially affect contracts other than their own.

The optimal solution would be examining the reachable code from each contract abi entry point. The analysis must occur beginning from the initially invoked contract, since it may call another contract more than once which may read or write storage. The analysis can result in output such that transactions performing invokes can be arranged into groups that will be run in parallel, while the transactions in each single group will be run sequentially.

@lightszero
Copy link
Member

lightszero commented Feb 21, 2019

this is about how to modify a value in storage,not for transfer only.
check abi chain is about contract,same contract can not be parallel execute.
but if we check what state need to be changed(like a key in storage),only same state change can not be parallel execute.
and even more, "add a value and save it" can be parallel execute too.

so this is differect:

when you check abi chain

nep5_transfer(b->a) and nep5_transfer(c->a)
call contract same

can not be parallel

when you check state change

nep5_transfer(b->a) and nep5_transfer(c->a)
storage[b] -> dec ,storage[c]->dec storage[a]->inc storage[a]->inc
two inc op can be parallel

can be parallel execute.

@igormcoelho
Copy link
Contributor

@jsolman when you have time, please take a look at this proposal here: #602
I believe it can be fruitful to this discussion.

@jsolman jsolman changed the title Support for Parallel Contract Execution Support for Parallel Contract Validation & Execution Mar 7, 2019
@Tommo-L Tommo-L mentioned this issue Dec 4, 2019
7 tasks
@erikzhang erikzhang removed this from the NEO 3.0 milestone Dec 6, 2019
@Jim8y Jim8y closed this as completed Nov 12, 2023
@roman-khimov
Copy link
Contributor

Have we implemented it?

@Jim8y
Copy link
Contributor

Jim8y commented Nov 12, 2023

Have we implemented it?

No, but its an issue of 4 years old.

@shargon shargon reopened this Nov 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion Initial issue state - proposed but not yet accepted
Projects
None yet
Development

No branches or pull requests

7 participants