Saltar al contenido principal

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: CamelCase para clases, snake_case para funciones y variables
  • Prefijo: C para clases (CBlock, CTransaction), m_ para variables miembro
  • Smart pointers: std::unique_ptr y std::shared_ptr sobre 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

HerramientaPropósito
gdb / lldbDepurador para C++
valgrindDetección de errores de memoria
clang-formatFormateo de código (el proyecto tiene .clang-format)
clang-tidyAnálisis estático
ccacheCaché del compilador para rebuilds más rápidos
bearGenera compile_commands.json para soporte de IDE
flamegraphVisualizació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

Lectura Recomendada