What is the lesson learnt then ? I think there are two many more:
i think this shows us that in any
complex codebase at some point you can't simply rule out errors just by a human looking at it. therefore you need to rely on as much automated error checking as possible.
maybe its different for you, but in my experience this tells me:
- use a statically compiled, strongly typed language with good IDE support
- stay away from dynamic programming like bytecode manipulation or metaprogramming
- use as many automated tools as possible for error checking (compiler, IDE inspections, findbugs..)
- when dealing with threads a whole new class of errors are possible that are not easy to detect for tools, so be extra careful. avoid threading where it makes sense, use proven platform tools where it is neccesary. if possible, stick to an actor library.
- garbage collection is your friend. except when writing a 3d shooter.
- unit test things wich are critical but are not run often in production, and possibly more
- only use libs where you can access the source code to be able to understand and debug them
again, i will certainly not force anyone to adopt this methodology. i'm just saying those are the principles i use to avoid a vast range of errors, including memory issues, buffer overflows, bad macro behavior.
for very simple problems or problems with very specific performance requirements you have to be pragmatic and drop some of those restrictions.
i am very happy that there is a very good implementation of Bitcoin in Java. Any developer who agrees with the issues i raised should consider using BitcoinJ instead of a c++ based Bitcoind. It is not perfect but at the moment the safest choice.