NEO founder and core developer Erik Zhang has recently released version 2.9.0 of the NEO-CLI. The NEO-CLI client is a NEO full node, meaning it will synchronize with and store a full copy of the NEO blockchain directly. Although it can be used as a basic wallet client, it is more commonly used to run RPC or consensus nodes which communicate with other nodes on the network.

NEO-CLI v2.9.0

The NEO-CLI changelog documents all notable alterations to the client between releases. The latest version includes the following additions, changes and fixes:

Added:

  • New RPC command: getblockheader
  • New RPC command: getwalletheight
  • Allow the location of the wallet index directory to be modified

Changed:

  • Significant stability improvements (Actor Model)
  • Improved Plugins system

Fixed:

  • NEO-CLI would close on ^D without errors (Linux only)

The Actor Model

In object-oriented programming, components called objects can modify internal data using a defined set of instructions known as a method. When a method is called on by an object and data is passed to that method, the object will execute the set of instructions contained in that method.

If the method was called synchronously, the caller will transfer control of the program to the object and will wait for the results. Once the object has finished execution of the method, it will pass back control to the caller along with the results, assuming there are any.

If all methods are called synchronously, then there will only be one thread of execution. The state will be changed in a consistent manner, because the methods are being executed one after the other.

In a multi-threaded system such as NEO, the caller does not hand control of the program over to the object. This can result in situations where multiple objects are called, but both of those objects (that are executing in the background) try to access another item in the system at the same time. In this example, a solution is required that allows both objects to access the shared item, but without one of them corrupting it while the other is trying to read from it.

To get around this issue, these systems may use locks to prevent objects accessing a particular item until execution is complete. During the lock, if one object is writing, other objects are prevented from reading the data until writing is finished. Although this ensures that the states are not changed arbitrarily, it also limits the performance and concurrency of the network because objects need to wait around for the thread to become accessible again (known as lock contention).

In an actor model, objects behave as actors that pass messages between each other. If a method is called, the actor will pass on that method request as a message to another actor. The recipient actor can execute the method, then pass on the results as another message. As the shared item is only accessible by one actor, only one actor is ever changing the state of that data at a time. This means there’s no need for global locks, though local locks within that actor’s class may still be used.

Each actor has a mailbox which can be filled up with requested processes. The actors then work through the queue sequentially, only ever handling one task at a time. This is much more efficient and allows the system to be more concurrent, as different actors can handle different tasks simultaneously without the delays caused by locks.

Erik Zhang proposed a code refactoring for NEO based on the .NET port of the Java/Scala actor model framework Akka. NEO-CLI v2.9.0 is the first NEO client that uses the actor model, which is expected to provide a huge increase to the network’s stability. These improvements could provide a foundation for larger blocks or lower block times in the future, both of which will enable NEO to unlock more of dBFT’s potential scalability.

Future Improvements

One of the next goals for NEO developers focused on consensus is the optimization of the consensus syncing time. Vitor Coelho of NeoResearch issued a proposal for the implementation of something akin to a Kalman Filter, which would allow a consensus node acting as speaker to use its experience of previous consensus rounds to better define a timeframe for the next round of consensus.

The more urgent change is the reintroduction of a third consensus stage. Omitting the third ‘commit’ stage of consensus created a small chance for the NEO network to encounter a single block fork.

Red4Sec and City of Zion member, Shargon, has put forward a proposal for the third stage of consensus that would prevent this occurring as an error in the future, but current discussions are exploring potential attack vectors that need to be ironed out. One example would be a dishonest node manually bypassing the commit stage by distributing a block after gathering enough signatures from other consensus nodes in stage two.