I've read Mastering Bitcoin and other high level resources and I believe I have a decent understanding of Bitcoin. I'd now like to read and understand the source code. However, I'm very new to cpp and don't know a good way to approach this task. Is there a systematic approach I can use to effectively learn the codebase?
Some good places to start are the places that the user or the network input something into Bitcoin Core. The obvious two places for these are the RPC functions and the network message processing. The RPC code is in
src/rpcdump.cpp. The network message processing is in
src/net_processing.cpp. By tracing through the function calls and also looking up where the global variables are being added to and set, you can get into most parts of the codebase.
For example, suppose you looked at
sendtoaddress. You would start at the RPC function in
src/wallet/rpcwallet.cpp and trace the execution path. You would see that it eventually goes to
src/wallet/wallet.cpp and how it uses the
CreateTransaction function. From here, you would learn how coin selection works.
Now you would see how the wallet chooses coins for transaction spending. But how does it find out about those in the first place? Well, as you are tracing
sendtoaddress, you will come across the
AvailableCoins which iterates through some variable named
mapWallet and pulls from stuff in
mapWallet to build a list of selectable coins. Thus
mapWallet must be where transactions are stored, so you can search for the variable
mapWallet in the codebase. This will tell you where that variable is being used and you can trace through the uses of
mapWallet to learn how it is populated and used.
Doing so will lead you to the functions that populate
mapWallet. So now you want to trace backwards: what are calling those functions, how did we get to that function. For example, for populating
mapWallet, you will run into
AddToWallet. What calls
AddToWallet? The function
AddToWalletIfInvolvingMe. And you can keep going backwards to get an idea of how it all works.
The same methodology can be applied to the network message processing. For example, suppose you wanted to learn about block processing. The place to start is when a block is received, so in
src/net_processing.cpp, look for
NetMsgType::BLOCK within the
ProcessMessage function. From here you can trace the function calls and global variables like we did with the RPCs. It will take you to the Proof of Work validation and how the target is calculated for a block. It will take you to transaction validation. You will end up looking at the script interpreter and how it evaluates scripts in a transaction. And so on.
You can repeat this for every RPC and every network message type to find out where and how things are processed. This will get you through the majority of the codebase. Network message processing will get you through all of consensus and the bulk of the codebase. Tracing RPCs will get you through basically everything else because almost everything a user can do can be done through the RPCs. These two general entry points are great places to go through the codebase and learn about what Bitcoin Core is doing internally.
I'm not sure about "learning the codebase", but I can point you to some files which are in my opinion good starting points for explorations:
- The init.cpp: "what happens when I start my bitcoind ?"
- The rpc calls in src/rpc or src/wallet/rpcwallet.
For example, "what happens when I