Progress reportTentacles are not always helpful... this is why it's taking so long...
--
Two days spent developing Sim Explorer, including PHP code to parse transaction blobs from the database. The fact that PHP doesn't have 64-bit integers makes things a bit more complicated.
Also converted my NxtAddress PHP classes into Simcoin format and tested.
Did some tests to make sure transaction ID doesn't cause significant collisions.
--
Working on finalizing the design and coding transaction pipeline and client protocol. Drew a detailed diagram of node's transaction pipeline.
--
The rest of the week was spent battling with SQLite performance: turns out that after I've replaced my old HDD with WD's Red, the transaction speed dropped to just 4 per second!
This makes my blood boil. Can you believe that a modern HDD can safely write only 4 things per second?! What the...
I guess, this is mostly because of WD's "intelliPower" marketing BS, which in reality probably means "5400 RPM or slower". Barracuda with 7200 RPM is about 4 times faster and SSD is about 7 times. Still, ridiculously slow.
OK, to be honest, these numbers are not yet catastrophic, they don't mean 4 TPS, because inside one database transaction I can write thousands of Simcoin transactions.
But when this transaction finally gets committed, the system will freeze for the same 500 M ticks (250 ms) and during that time I cannot do anything with the database, can't even read it, so the whole system is stalled.
If you are aiming for <1 sec confirmations, this is unacceptable. I can't just put everything on hold for 250 ms. Even 50 M ticks is too much.
The only solution seems to be switching SQLite to WAL mode and doing all writes in a separate thread. So I recompiled SQLite again, now with multi-threading turned on. I hate to do it, but using threads seems like the lesser of two evils.
Now the code needs to be reorganized to separate writes from reads and probably also to add queues to handle writing stalls.
It's annoying when libraries don't work out of the box and require a lot of reading and testing to figure out how to make them work the way you need. That's why I am a big fan of the
NIH syndrome.
Anyway, I did a hell of a lot of tests with various combinations of settings, locking modes, journaling modes, multi-threading modes, checkpointing modes, page sizes, auto-checkpointing intervals, same/different database connections, tried manual checkpoints in a separate thread, all this while measuring average/peak performance of concurrent writes and reads on both WD and SSD drives. (So stop complaining that this project is taking too long – go invest in toy coins that don't pay attention to this kind of stuff).
The end result is documented in my local wiki and I am now confident that after the changes the system will be able to handle at least 100 TPS even on consumer-grade hardware or VPS.
--
I also discovered that SQLite doesn't free shared locks unless you explicitly call finalize() or reset() and this makes working with prepared statements a bit of a hassle. Had to write additional code to manage automatic destruction of these statements too...
Databases are hard!