@Gromak
Currently we are using acid-state
as the only persistent storage. There are many reasons why we do it and it's fine for experiments, but we are not sure about its applicability in production. I have written some thoughts about it in [slack|https://serokell.slack.com/archives/pos-prototype/p1477579716003107], let me copy them here (but better click link and see there):
Ok, about DB. First, about acid-state.
Pros:
• convenient interface in general, you have some data type which stores all the data you need and you operate in MonadState and MonadReader. Amazing. That's probably the best way to write code which uses db. Especially when we have lens. With other databases you'll need to invent something cool to work with them this way. Maybe something cool already exists (e. g. persistent for SQL), but I have never used it.
• We know how to use it, moreover @neongreen (and partly I) knows how it works under the hood and made at least one patch. We have experience with it.
• Migrations are easy because of SafeCopy. Note, however, that it's advantage of SafeCopy, not acid-state. We can use SafeCopy with other approaches.
• Very good guarantees about ACID properties, SQL databases usually provide slightly less strict guarantees, AFAIK.
• Probably easy rollback because of checkpoints. I am not sure.
• Code which uses it is already written 😄
Cons:
• last commit was in August, though some issues and PRs are pendings. Site is dead for a long time, nobody cares. That's one of the main reasons why I want to forget about acid-state for production. Alternatively we can concentrate on our fork and maintain it by ourselves.
• All state is in memory, nothing smart is done when you have a big map and want to get a single element. It's just loaded in memory and used as map. Well, we can store limited amount of data there and store blocks and old data in other database. Apart from blocks we probably have to store utxo on disk, don't we? In a long run I mean.
Actually, we need to understand which data should be persisted and which part of it can definitely fit in memory even in long run. If we see that we need to use another DB for big data, then does it make sense to use two different DBs? I don't know now.
• No support for reporting errors in Updates. What should I do if whether update will succeed or not depends on data stored in state? Currently we are forced to use throw which sounds dirty. Well, it can also be fixed in our fork if we decide to maintain it.About SQL vs NoSQL.
I have never used SQL except university course, my personal feeling is that SQL is not for our purpose, but I am not sure. For example, bitcoin reference implementation doesn't use it, quick googling about ethereum told me that at least one implementation uses leveldb too.
I would rather use leveldb or rocksdb (the latter is more modern, but haskell bindings are less mature and probably we'll need to maintain them by ourselves).
Also I want to know about iodb, whether it's applicable in our case, what are cons and pros, etc. I only know that it exists and was developed bu Jan Kotek, but don't know anything about it.
Can you say how you're planning to do migrations with LevelDB? I don't have any experience with LevelDB so I don't know whether it'll be easy or hard, but it's better to have it figured out now than “oops, we used wrong LevelDB settings / integrated acid-state with LevelDB in an improper way / something else, and now migrations are goddamn hard and nobody knows how to do them”
I see at least two approaches:
• use SafeCopy serialization
• steal ideas from bitcoin (I don't know how they deal with it, but we can see) 😄
Why LevelDB and not e.g. postgresSQL?
I guess you ask it because you used postrgreSQL more often than leveldb. For me it's vice versa. So for me it's more reasonable to use leveldb. But it's also very subjective.Actually, this whole task is to do research and understand what to use. It's not only about implementation, it's also research.