My list:
Prefer managed languages. Although they can be constraining, languages like Java or C# are significantly harder to shoot yourself in the foot with. I've got nothing against C++, enjoy working with it (it's my primary language at work), and it's possible to write C++ securely - see how Satoshi did it for an example. But it's not easy, which is why Kaminsky was so surprised when he saw it had been done.
Don't try to reimplement Bitcoin. Seriously. It's tough, I should know
Either find a way to use Satoshis code, or consider taking a chance with bitcoinj. Bitcoinj can be used from C++ by the way, check out the native branch in the git repo to see how it's done using GCJ/CNI.
Minimize your surface area for attack - run your production code on a computer that doesn't do anything else. Use key-based SSH auth only, no passwords. Don't host it with cheap VPS providers that may be an avenue for attack, either prefer a physical box in a nearby datacenter you can drive to, or use VPS providers but hide the core of your app behind a Tor hidden service so nobody except you knows where to find it.
Consider sandboxing different parts of the app and using RPC between them. I wrote my degree thesis on this topic. Tools like SELinux or AppArmor can be used to constrain hackers if they do manage to break in via a vulnerable component. So learn about them and see how to use them. Managed platforms have another advantage here because they usually have convenient (but language specific) RPC mechanisms built in so communicating between sandboxed components is easy. But if your entire app is written in one language it doesn't matter. For C++ you could use ZeroC ICE or just use a custom protocol.
Use assertions liberally. It's better to crash the app and have some downtime than let it enter an undefined state that could be exploited. That said, obviously assertions are only to be used for internal state that should never be corrupted, it's not appropriate for transient conditions like bad input from the network. Once again, managed languages win. Exceptions in C++ are very hard to do right because it's much harder to write exception safe code when doing manual memory management. Exception-safety is rarely considered, in my experience, but it's important. In a language like C++ it can lead to memory corruption if you get it wrong, and that is often the start of an exploit. With garbage collection it's much easier.
TLS is a good choice for secure communications but as you obviously already know, it's not that useful in a P2P scenario because you (almost by definition) don't know who you are talking to. Make sure you really understand why you want to use encryption there, something that is willing to communicate with anything doesn't benefit much from encrypting that communication.