As you can notice, the right version (1.1.0/1.1.1) is far more concise and does not have all the rollback logic that is present in the left version (1.0.0). The reason for this is because we are delegating the rollback procedure to the database which is designed and battle tested to perform these kind of rollbacks in case something goes wrong.

Furthermore, in 1.1.0/1.1.1 there are ~20 extra lines of code that introduce performance optimisations that were not included in the core 1.0.0 release.

Data integrity is crucial in blockchain technology, therefore this is a big achievement for RISE. To date, RISE is the only DPOS blockchain forked from Crypti that features this functionality in mainnet.

Last but not least, we took our time on this release and updated ALL the third party dependencies to ensure we have the latest security updates included.

Improving Code Quality

Wait what? Wasn’t this the whole goal of having a TypeScript 1.0.0 released in the first place? — Yes but…

Things can, and should, always improve. Thats why in RISE core 1.1.0/1.1.1 we:

Upgraded from node 6 to 8

Upgraded from TypeScript 2.6 to 2.8

Upgraded from PostGres 9.6 to 10

Of course these are not the only improvements we made! One big improvement was moving away from pg-promise to sequelize: one of the most popular Github projects that allows developer express database queries using JavaScript/TypeScript.

This is important because core 1.0.0 (and previous versions) had a mixed “code”+”sql” codebase, whereas now we have migrated every basic sql statement to sequelize reducing the amount of SQL statements by 80%.

The reason for sequelize migration was well-thought, since RISE aim to be developer friendly and not many developers feel confident enough with SQL to play with it. Sequelize will ease basic SQL statements and will let future developers express their queries using just code (if required a developer could still express his queries using SQL).

Furthermore, we removed a considerable amount of duplicated/similar code, which means now the RISE codebase is even more concise, robust, easier to test and understand.

Improving Performances

Performance is one of the most impactful improvements of the core 1.1.0/1.1.1 release.

We improved code performances in several aspects of the code. RISE core is composed by several major modules and optimisation needs to be in parallel to achieve real performance optimisation.

A journey from 7 to 1000 Transactions per second — Never give up

Before we begin there are some notes to better understand the following paragraph:

All benchmarks test in the following paragraph take into account transaction processing + verification + persist to database and does intentionally bypass the network layer.

TPs ( T ransactions P er S econd) — Number of transactions that the code was able to validate and save to the underlying datastore (PostGres).

( ransactions er econd) — Number of transactions that the code was able to validate and save to the underlying datastore (PostGres). msPT ( m illi s econds p er T ransaction) — Milliseconds per transactions needed to perform the benchmark tests.

( illi econds er ransaction) — Milliseconds per transactions needed to perform the benchmark tests. All benchmarks ran on a i7 7700 CPU with some specific PostGres optimisation flags.

There is currently an enforced limit of 25 transactions per block for the RISE mainnet. This limit is not taken into account here for obvious reasons.

Note: What follows may result boring. I’m sorry :)

When I started working on RISE I ran some benchmarks to assess the ability to process, verify and save transactions. Back then the TPs value was approximately 7 TPs, and msTP was about ~140ms.

Note: While that might seem a very low amount, keep in mind that Ethereum can only process 15 TPs and BTC 7 TPs *. (* due to block size limit 1MB)

When I embarked on the quest of improving the TPs value, I thought that PostGres was the bottleneck that was preventing the indicator increase. Hence I created issue #133 to migrate from PostGres to Redis — a fast in-memory NoSQL database. Long story short: I was wrong!

Most of the time, difficult problems require elegant and short solutions.

In mid-April, after migrating to sequelize, I started to look at performance bottlenecks and started to rewrite the whole database logic in a more batched and logical way. After the first trials I was able to achieve 104 TPs which was, already, a great achievement as each transaction needed less than 10ms to be processed.

After the first successful trials, I decided to improve database queries to reduce PostGres load.

Fast forward to mid-May, after several performance improvement iterations the TPs value was already > 400, scoring a 4x improvement since first trials and an outstanding 57x improvement since the first benchmark.

I was happy with the results and unsure if the TPs value could be improved even more. I then built some utilities to easily execute some code profiling to double check my first assumptions about PostGres being the performance bottleneck.

It turned out that ~60% of the, now 2.5ms, msPT was not due to PostGres but rather code logic referring to validating and processing transactions. For example, one optimisation point was to leverage how Node.js worked and, in particular, the event loop.