Lenguajes y Herramientas
El desarrollo de Bitcoin Core utiliza principalmente C++ para el código principal y Python para el framework de tests. Entender los idioms específicos de C++ y las herramientas utilizadas en el proyecto es esencial.
C++ en Bitcoin Core
Bitcoin Core usa C++ moderno (actualmente C++20). El proyecto tiene convenciones de código específicas:
Estilo y Convenciones
- Nombrado:
CamelCasepara clases,snake_casepara funciones y variables - Prefijo:
Cpara clases (CBlock,CTransaction),m_para variables miembro - Smart pointers:
std::unique_ptrystd::shared_ptrsobre punteros raw - Sin excepciones en código de consenso — Manejo de errores mediante valores de retorno
- Sin RTTI — La información de tipo en tiempo de ejecución está deshabilitada
Características Clave de C++ Usadas
// std::optional para valores anulables
std::optional<CBlockIndex*> FindBlock(const uint256& hash);
// Span para vistas no propietarias
bool VerifyScript(Span<const unsigned char> scriptSig, ...);
// Structured bindings
auto [iter, inserted] = mapBlockIndex.emplace(hash, new_index);
// Patrones RAII para locks
LOCK(cs_main); // Adquiere mutex, se libera al salir del scope
Seguridad de Hilos
Bitcoin Core usa anotaciones para aplicar seguridad de hilos en tiempo de compilación:
// Mutexes anotados
RecursiveMutex cs_main ACQUIRED_BEFORE(cs_wallet);
// Variables protegidas por mutexes específicos
int nBestHeight GUARDED_BY(cs_main);
Framework de Tests en Python
La suite de tests funcionales (test/functional/) está escrita en Python y es crítica para los desarrolladores de protocolo:
# Ejecutar todos los tests funcionales
test/functional/test_runner.py
# Ejecutar un test específico
test/functional/test_runner.py wallet_basic.py
# Ejecutar con salida detallada
test/functional/feature_block.py --loglevel=debug
Escribir un Test Funcional
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal
class ExampleTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 2
def run_test(self):
# Minar algunos bloques
self.generate(self.nodes[0], 101)
# Verificar saldo
balance = self.nodes[0].getbalance()
assert_equal(balance, 50)
# Enviar fondos y verificar
txid = self.nodes[0].sendtoaddress(
self.nodes[1].getnewaddress(), 10
)
self.generate(self.nodes[0], 1)
assert_equal(self.nodes[1].getbalance(), 10)
Herramientas de Desarrollo
| Herramienta | Propósito |
|---|---|
gdb / lldb | Depurador para C++ |
valgrind | Detección de errores de memoria |
clang-format | Formateo de código (el proyecto tiene .clang-format) |
clang-tidy | Análisis estático |
ccache | Caché del compilador para rebuilds más rápidos |
bear | Genera compile_commands.json para soporte de IDE |
flamegraph | Visualización de profiling de rendimiento |
Depurar Bitcoin Core
# Compilar con símbolos de depuración
cmake -B build -DCMAKE_BUILD_TYPE=Debug
cmake --build build
# Ejecutar bajo depurador
gdb --args ./build/src/bitcoind -regtest
# Comandos útiles de GDB
(gdb) break validation.cpp:ProcessNewBlock
(gdb) run
(gdb) bt # backtrace
(gdb) p block.GetHash().ToString() # imprimir expresión