General design principles

Over the last decade, as the scope, complexity and test coverage of the codebase has increased, there has been a general effort to not only break Bitcoin Core down from its monolithic structure but also to move towards it being a collection of self-contained subsystems. The rationale for such a goal is that this makes components easier to reason about, easier to test, and less-prone to layer violations, as subsystems can contain a full view of all the information they need to operate.

Subsystems can be notified of events relevant to them and take appropriate actions on their own. On the GUI/QT side this is handled with signals and slots, but in the core daemon this is largely still a producer/consumer pattern.

The various subsystems are often suffixed with Manager or man, e.g. CConnman or ChainstateManager.

The extra "C" in CConnman is a hangover from the Hungarian notation used originally by Satoshi. This is being phased out as-and-when affected code is touched during other changes.

You can see some (but not all) of these subsystems being initialized in init.cpp#AppInitMain().

There is a recent preference to favour python over bash/sh for scripting, e.g. for linters, but many shell scripts remain in place for CI and contrib/ scripts.