Saltar al contenido principal

Arquitectura de Almacenamiento

Savitri Network utiliza RocksDB como backend de almacenamiento principal, con familias de columnas para el aislamiento de datos y patrones de acceso eficientes.

Familias de Columnas

Familia de ColumnaClaveValorPropósito
CF_BLOCKSaltura (u64 LE)Bloque (bincode)Almacenamiento de bloques
CF_TRANSACTIONStx_hash (32 bytes)Transacción (bincode)Búsqueda de transacciones
CF_ACCOUNTSdirección (32 bytes)Cuenta (24 bytes)Saldo + nonce
CF_METADATAclave stringvariableCabecera de cadena, configuración
CF_RECEIPTStx_hashRecibo (bincode)Recibos de transacciones
CF_CONTRACTSdirecciónContractInfoEstado de contratos inteligentes
CF_GOVERNANCEproposal_idPropuesta (bincode)Propuestas de gobernanza
CF_ORACLEfeed_idOracleDataFeeds de oráculos
CF_BONDSdirecciónMonto del bonoBonos de validadores
CF_VOTE_TOKENSdirecciónSaldo de VoteTokenTokens de voto en gobernanza
CF_TREASURYclaveEstado del tesoroTesoro de la red
CF_VESTINGschedule_idVestingScheduleVesting de tokens
CF_REWARD_COINSdirecciónSaldo de recompensasRecompensas de nodos
CF_FEE_METRICSclaveDatos de comisiónSeguimiento de comisiones
CF_SUPPLY_METRICSclaveDatos de ofertaOferta de tokens
CF_ACTIVE_NODESnode_idActividadDisponibilidad de nodos
CF_MONOLITHSmonolith_idMonolithCompresión de bloques
CF_FLclaveDatos FLAprendizaje federado
CF_POUnode_idPuntuación PoUPuntuaciones de consenso

Codificación de Cuentas

Las cuentas utilizan una codificación compacta de ancho fijo de 24 bytes:

Bytes 0-15:  balance (u128, little-endian)
Bytes 16-23: nonce (u64, little-endian)

Compatible hacia atrás: el formato antiguo de 16 bytes (solo saldo, nonce=0) sigue siendo compatible.

Las cuentas vacías (balance=0, nonce=0) nunca se persisten para ahorrar espacio de almacenamiento.

Raíz de Estado

La raíz de estado se calcula mediante una instantánea lexicográfica de la base de datos:

seed  = H("STATEv1-LE")
leaf = H("STATE" || key || value) para cada par clave-valor
root = rolling_accumulate(seed, leaf_1, leaf_2, ..., leaf_n)

Las claves se iteran en orden lexicográfico para garantizar el determinismo.

Trait de Almacenamiento

Todos los backends de almacenamiento implementan el StorageTrait:

pub trait StorageTrait: Send + Sync {
fn get_cf(&self, cf: &str, key: &[u8]) -> Result<Option<Vec<u8>>>;
fn put_cf(&self, cf: &str, key: &[u8], value: &[u8]) -> Result<()>;
fn delete_cf(&self, cf: &str, key: &[u8]) -> Result<()>;
fn get_cf_prefix(&self, cf: &str, prefix: &[u8]) -> Result<Vec<(Vec<u8>, Vec<u8>)>>;
// ... operaciones por lote, iteración, etc.
}

Deserialización Segura

Toda la deserialización con bincode utiliza un límite de tamaño máximo para prevenir el agotamiento de memoria:

const MAX_BINCODE_SIZE: u64 = 16 * 1024 * 1024; // 16MB

Caché

Capa de caché LRU para datos a los que se accede con frecuencia:

  • Caché de cuentas: reduce las lecturas a RocksDB para verificaciones de saldo/nonce
  • Caché de almacenamiento de contratos: almacena en caché los resultados de SLOAD dentro de la ejecución de contratos
  • Caché de puntuaciones: caché LRU para la puntuación de TX en el mempool (evita el recálculo)

Configuración de RocksDB

ParámetroDesarrolloProducción
Tamaño de caché256 MB1024 MB
Buffer de escritura16 MB64 MB
Máx. archivos abiertos1001000
Intervalo de sincronización5s30s
CompresiónDesactivadaActivada

Operaciones por Lote

Las escrituras atómicas por lote garantizan la consistencia:

let mut batch = storage.batch();
batch.put_cf(CF_ACCOUNTS, &addr, &account.encode());
batch.put_cf(CF_TRANSACTIONS, &tx_hash, &tx_bytes);
batch.put_cf(CF_BLOCKS, &height_key, &block_bytes);
batch.commit()?;

Sistema de Vesting

Los calendarios de vesting de tokens admiten tres tipos:

TipoComportamiento
LinearTokens liberados linealmente a lo largo de la duración
CliffSin tokens antes del período de bloqueo, luego liberación lineal
StagedModo de compatibilidad con génesis

Indicadores de Característica

IndicadorDescripción
rocksdbBackend RocksDB (por defecto)
memoryBackend en memoria (para pruebas)
prometheusExportación de métricas Prometheus
tempfileAlmacenamiento temporal para pruebas