Comments (11)
Unless I missed something, network message handler is currently called protocol.
from nearcore.
Typo. Fixed.
from nearcore.
Some tasks for me and @azban :
-
network/src/service.rs
should be spawning a new protocol on each new network message, cloning protocol in the process. -
cli/.../lib.rs
should be spawning tasks instead of creating a bunch ofArc
s. -
TxFlowTask
should be connected to the protocol and the network (for sending gossips). -
InMemorySigner
should be copied instead of shared, because it is lightweight. -
RpcImpl
should send transactions on channel forTxFlow
rather than takingClient
(in review) -
RpcImpl
should spawn runtime task for view calls (deferring until later) -
remove transaction pool from client?
-
remove import queue from client?
from nearcore.
Signer is a trait - it can be implemented with expensive implementation.
Specifically, there should be implementation that maintains connection to other process/another machine to do signing there.
If that's ok to copy, then no problem.
@nearmax I'm unclear what you mean by pool of Runtimes
Also where is the chains/client?
from nearcore.
s/Signer/InMemorySigner
We are going to be executing multiple contracts concurrently. Currently the contracts are executed by Runtime. To execute them concurrently we would need a pool of workers that runs Runtimes. The reason why we cannot spawn them as separate tasks is because we want to control the number of threads they are running on and prevent them from affecting other async tasks, like the network listener.
Chain is a heavy resource with frequent access requirements, we will wrap it into lock+arc for now.
We also need a separate task that listens for chain updated from the network and updates the chain with the recent blocks (in the cases when these blocks were produced without participation of the current node).
Regarding the Client
. Consider how we produce a block. A block is produced by first computing the consensus and then executing transactions in the consensus based on the previous state which produces the new state, so the creation of the block is initiated by the consensus and not the client. The flow is as follows:
- TxFlow+BeaconChainConsensus would produce a consensus (a signed set of N transactions) and put it in a channel;
- Runtime Pool (or for the sake of separation of concerns we can have a separate class called ConsensusListener) would be reading from this channel and upon receiving the consensus it would retrieve the current ChainContext from the Chain (ChainContext would provide all the necessary information for the Runtime) and produce N tasks for the workers that run Runtime's. Runtime workers then would finish these tasks and produce a new state which it would send back to the network and to the Chain.
Therefore, the following functions that we are currently using to produce fake blocks are going to go away: prod_block
in chain.rs
and produce_blocks.rs
. What would be left in the Client
struct is the functionality to import blocks upon the start of the node we can then rename it to BlockImporter
and execute one time synchronously upon the start of the node.
from nearcore.
We probably don't need a pool of runtimes for now, as doing so seems error-prone and requires more effort than we can afford. The main reason is that the order of transactions matter in a lot of cases and trying to separate them into independent tasks requires careful manipulation and also incurs some overhead on its own.
I am also not entirely convinced that we need to spawn a network message handler whenever a new message comes in. There will be some shared state anyways (things like peer_info) and processing each message should take very little time on the protocol level. I guess we should do some experiments and see how much concurrency helps there.
from nearcore.
We cannot be computing the state one transaction at a time, it is too slow. I also disagree that the separation is hard to implement. It is a simple greedy system. TxFlow already defines for us the global order of the transactions which only matters for those transactions that touch same addresses. So at each step we look in the bucket of unprocessed transactions and take any transaction that does not have unprocessed dependencies. Otherwise we wait.
Regarding having one handler per message. See the first two examples in tokio documentation: https://tokio.rs/docs/getting-started/echo/ . What we have currently is the first example. What I suggest is the second example. Even if protocol turns out to be lightweight we have need to spawn a separate task per message anyway to send the data down the channel, like here: https://github.com/nearprotocol/nearcore/blob/7f6ec43f8a9147d4bae80ff9859ec55fa7ccc516/core/txflow/src/txflow_task/mod.rs#L104
There is really no problem with copying the handler: the lightweight fields like config are fast to copy because it uses memcpy, while the heavy fields (not sure if peer_info is a heavy field) can have shared state.
from nearcore.
I think we can probably parallelize executions of cross-shard calls and same-shard calls without too much trouble. For calls in the same shard, it is much harder because one call could lead to some other calls in the same shard again and the current design is to execute them in the same block, which makes parallelizing them hard due to possibly complicated dependencies. Some static analysis could help, but I am not too sure about that. @ilblackdragon
from nearcore.
For calls in the same shard, it is much harder because one call could lead to some other calls in the same shard again and the current design is to execute them in the same block, which makes parallelizing them hard due to possibly complicated dependencies.
Yes, that's a special case. I think most of our transactions are not going to be like that. We can make a static analysis of the contract and establish what addresses it can potentially touch and then execute all contracts that are not affected by it independently in parallel.
Also, for MVB we might consider dropping the guarantee to execute them in the same block for now.
Also, remember that we are targeting 100k tps. With 1-4k shards it means each verifier needs to execute 25-100 contracts a second. The beacon chain witnesses will need to be executing even more! That means if we execute them sequentially it should be faster than 10-40ms, which is ridiculously fast.
from nearcore.
@nearmax let's implement single-threaded design first and make it work. I don't think we have time to handle additional complexity (like static analyzer) now.
After it's working properly (but slowly) we'll measure whether anything needs to be sped up. Note that we don't want to over-utilize CPU anyway (running on mobiles) so shouldn't aim for 100% CPU load.
from nearcore.
Ok, let's have one worker and parallelize it later after we measure the load.
from nearcore.
Related Issues (20)
- [Project tracking] Cross shard bandwidth limits
- Handle protocol upgrades in congestion control HOT 6
- Large State values cache as part of the protocol
- Gas costs post-memtrie HOT 4
- WARN near_store::db::rocksdb: target="store::db::rocksdb" making a write batch took a very long time, make smaller transactions! HOT 2
- WARN [...] GC Error: block on canonical chain shouldn't have refcount 0 HOT 1
- feat(release) - log an error if the blockchain voted for version higher than the node's
- Header sync incorrectly disregards peers at startup
- [Epoch Sync] EpochInfoAggregator treatment is awkward at the epoch sync boundary
- [Epoch Sync] Implement EpochSyncProof validation
- [Epoch Sync] Network message size optimization
- [Epoch Sync] Implement deriving EpochSyncProof from an older EpochSyncProof
- [Epoch Sync] Error in gc: DB Not Found Error: BLOCK HEADER: 11111111111111111111111111111111
- [Epoch Sync] Implement network rate limiting and caching for EpochSyncRequest
- [Epoch Sync] Minor: Header sync progress is misleading after epoch sync
- Spoofed compute costs metrics
- Chunk endorsement by shard metrics must use shards chunks-endorsed, instead of shard chunks-produced
- Tracking issue for fixing minimal required stake HOT 2
- [Epoch Sync] Blocks received during state sync marked as invalid
- mainnet: synced node has regular Downloading blocks logs HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from nearcore.