Okey, let's talk about one more TODO in you list
The blocks, transactions and accounts cache, and how much it will cost to kill our RPi nodes.
As we know since the beginning, blocks.nxt and transactions.nxt is just a result of standard ObjectInputStream work.
At startup they are fully loaded to memory and are there till the end.
So, NRS keeps
full blockchain in memory all the time.
Let's do rough calculations. Class Block:
int version;
int timestamp;
long previousBlock;
int numberOfTransactions;
int totalAmount, totalFee;
int payloadLength;
byte[] payloadHash;
byte[] generatorPublicKey;
byte[] generationSignature;
byte[] blockSignature;
byte[] previousBlockHash;
int index;
long[] transactions;
long baseTarget;
int height;
long nextBlock;
BigInteger cumulativeDifficulty;
This is from 0.5.0 actually (sorry for decompilation), but there's almost no difference with 0.4.7.
With 32-bit pointers and no alignment this gives us about 320 bytes for block without transactions, plus 8 byte for each transaction. 64-bit JRE with memory alignment can easily expand this to ~400 bytes. I can't tell you exact numbers, because it heavily depends on JRE implementation, operating system and so on.
Right now we have about 33000 block, which occupies about 11Mb of memory. I think, I should speak "at least 11Mb". Without accounting of long[] transactions...
Okey, take a look at class Transaction:
byte type, subtype;
int timestamp;
short deadline;
byte[] senderPublicKey;
long recipient;
int amount, fee;
long referencedTransaction;
byte[] signature;
Attachment attachment;
int index;
long block;
int height;
156 bytes without attachement (f.e. alias). Up to 200 in real world. 65000 transactions for now. More than 10Mb of memory. Plus 65000*8 = 0.5Mb of links from blocks to transactions (or we can assume that size of transaction is 164 bytes).
Actual things is even worse because blocks and transactions is not linear lists, but hash maps.
Actual things can be better, because of generatorPublicKey and senderPublicKey can be shared between blocks, transactions and accounts.
I'm bit tired and don't want to calculate size of accounts - it's too small comparing to blocks and transactions.
Next step is to calculate cost of attack.
Attacker can send 255 transactions in block. Let's use simple ordinary payment, 1 NXT amout, 1 NXT fee, 510 NXT for full block. 320+156*255 = 40100 bytes of memory.
According to
guide, JRE in RPi can use up to 430Mb for heap. Okey, let's assume, that 401Mb is available for blocks and transactions. 401M / 40100 = 10000. Yes, just
ten thousand blocks, and you RPi is dead. Or 5M NXT. F*ckin
five million coins.
This is very rough calculations. Very. My intuition tell me, that things are worse actually. Cheeper. Faster.
And then, after RPi, this attack will kill cheap 2Gb VPS's. And then - 32-bit JRE's, which actually hardly can get 2Gb of heap.
And before that we will hear the song of death from our HDD/SSD, tired to save that .nxt files everytime you get new fat block.
Solution?
I think devs know it and has in TODO list
We need to use some embedded DB and cache in memory only what we need right now: couple of last blocks.