minimumLedgerSlot devuelve el número de slot más bajo que un nodo de Solana mantiene actualmente en su ledger, es decir, su límite de retención. Al combinarlo con getSlot (la punta actual) y getFirstAvailableBlock, puedes construir una ventana de disponibilidad [minimumLedgerSlot, getSlot] y detectar nodos que parecen saludables pero tienen un límite superficial. Los indexadores y los trabajos de backfill deben verificar previamente cada endpoint: llamar a minimumLedgerSlot, compararlo con el rango de bloques objetivo y rechazar o enrutar la consulta cuando el rango sea anterior al límite. Este artículo explica el mecanismo, muestra sondeos ejecutables en Node.js y proporciona una tabla de comparación reproducible para tus propios endpoints. También cubre las limitaciones honestas: los balanceadores de carga pueden enrutar a nodos con límites diferentes, la retención es configurable por el operador y un límite profundo no garantiza que todos los slots intermedios estén completos.
El límite de retención y por qué importa
Cada nodo RPC de Solana mantiene un ledger de bloques recientes, pero el slot más antiguo que retiene es una configuración del operador, no una constante del protocolo. El método JSON-RPC minimumLedgerSlot devuelve el número de slot más bajo que el nodo mantiene actualmente en su ledger. Ese valor es el límite de retención del nodo: cualquier solicitud de un slot por debajo de él fallará en lugar de devolver datos.
Esto importa porque un nodo puede parecer perfectamente saludable en las comprobaciones de salud genéricas mientras tiene un límite superficial. Responde a getSlot y getHealth al instante, pero una getBlock histórica para un slot de la semana pasada puede devolver un error. La guía Monitorización de endpoints RPC cubre métricas de salud genéricas; minimumLedgerSlot añade la dimensión de disponibilidad de datos que las comprobaciones genéricas pasan por alto.
El método está documentado en la referencia de Solana minimumLedgerSlot. No toma parámetros y devuelve un único número de slot. Trátalo como un sondeo de capacidad que ejecutas antes de emitir cualquier lectura histórica, no como una métrica que recolectas una vez y almacenas en caché para siempre.
- Un nodo que poda agresivamente devuelve un límite reciente, a menudo solo unos pocos miles de slots por detrás de la punta.
- Un nodo de archivo o de retención larga devuelve un límite mucho más antiguo, potencialmente millones de slots por detrás.
- El límite es una propiedad del nodo específico al que llegaste, no de la marca del proveedor ni de la URL del endpoint.
Retención del ledger frente a disponibilidad del estado
La retención del ledger responde a la pregunta: ¿qué datos de bloques conserva este nodo? La disponibilidad del estado responde a una pregunta diferente: ¿qué instantáneas de cuentas y estado puede servir este nodo? minimumLedgerSlot se refiere a lo primero. Te indica el bloque más antiguo que el nodo puede devolver mediante getBlock, getBlockTime o getTransaction para transacciones de ese bloque.
Un nodo puede retener un ledger profundo pero seguir siendo incapaz de servir una consulta arbitraria de estado histórico de cuentas, porque las consultas de estado dependen de instantáneas y de la configuración de índices. A la inversa, un nodo con un límite de ledger superficial puede seguir sirviendo bien consultas de estado recientes. Mantener estos dos conceptos separados evita el error común de asumir que un minimumLedgerSlot profundo garantiza que todos los métodos históricos funcionarán.
Para un tratamiento más amplio de qué métodos sirven datos históricos y en qué se diferencian, consulta Consulta de datos históricos de Solana por RPC. Ese artículo complementa a este: explica la superficie de métodos, mientras que este artículo explica cómo verificar el límite de un nodo específico antes de depender de él.
Construir la ventana de disponibilidad con getSlot y getFirstAvailableBlock
minimumLedgerSlot por sí solo te da el límite. Para entender la ventana completa que un nodo puede servir, combínalo con getSlot, que devuelve la punta actual, y getFirstAvailableBlock, que devuelve el bloque confirmado más bajo que el nodo tiene disponible. Las referencias de Solana getFirstAvailableBlock y getSlot documentan ambos métodos.
La ventana de disponibilidad es conceptualmente [minimumLedgerSlot, getSlot]. La amplitud, getSlot - minimumLedgerSlot, es la profundidad de retención en slots. Un nodo con una amplitud de unos pocos miles de slots es un nodo de datos recientes; un nodo con una amplitud de decenas de millones es un nodo de clase archivo. Los umbrales exactos varían según el proveedor y se documentan como configuración del operador, así que mide en lugar de asumir.
getFirstAvailableBlock es útil como verificación cruzada. En algunas configuraciones de nodo puede diferir ligeramente de minimumLedgerSlot debido a cómo se indexan el almacén del ledger y el blockstore. Cuando no coincidan, confía en el límite más conservador (el más alto) para las decisiones de verificación previa, porque una consulta por debajo de cualquiera de los dos valores corre el riesgo de fallar.
- minimumLedgerSlot: el slot más bajo en el almacén del ledger.
- getFirstAvailableBlock: el bloque confirmado más bajo disponible para consultas de bloques.
- getSlot: la punta actual, el límite superior de la ventana.
- Amplitud de retención = getSlot - minimumLedgerSlot.
Verificación previa de consultas históricas antes de que fallen
Cuando se llama a getBlock o getTransaction para un slot por debajo del límite del nodo, el nodo devuelve un error en lugar de datos fabricados. Ese es el comportamiento correcto: la especificación JSON-RPC 2.0 define un objeto de error con un código y un mensaje, y la especificación JSON-RPC de Ethereum establece la misma convención para métodos de blockchain. Un cliente bien comportado debería tratar ese error como una señal para enrutar a otro lugar o rechazar la solicitud, no para reintentar a ciegas.
El patrón de verificación previa es sencillo. Antes de emitir una lectura histórica para un rango de slots objetivo, llama a minimumLedgerSlot en el endpoint que pretendes usar. Si el slot más bajo del rango objetivo está por debajo del límite, el endpoint no puede servirlo. O bien enruta la consulta a un endpoint con un límite más profundo, o falla rápido con un mensaje claro.
Un fallback silencioso a un endpoint diferente con un límite más profundo es peligroso porque oculta problemas de capacidad y puede producir resultados inconsistentes si el nodo de respaldo está en una bifurcación diferente o tiene datos distintos. Haz explícito el fallback: registra qué endpoint sirvió la consulta y por qué se rechazó el primario. La guía Tiempos de espera y reintentos de Solana RPC cubre la semántica de reintentos; las comprobaciones previas reducen el número de reintentos que necesitas en primer lugar.
- Llama a minimumLedgerSlot en el endpoint objetivo antes de la lectura histórica.
- Compara el slot más bajo del rango objetivo con el límite.
- Si está por debajo del límite, enruta a un endpoint más profundo o falla con un error claro.
- Registra la decisión de enrutamiento para que los fallbacks silenciosos no oculten problemas de capacidad.
Sondeo ejecutable en Node.js para límite, punta y amplitud
El siguiente script de Node.js consulta minimumLedgerSlot y getSlot, calcula la amplitud de retención en slots y estima la ventana de tiempo cubierta usando la duración del slot. El tiempo objetivo de slot de Solana es de aproximadamente 400 milisegundos, pero los tiempos reales de slot varían, así que trata la estimación de tiempo como aproximada y etiquétala como tal en tus registros.
El script usa la API estándar fetch disponible en Node.js moderno. Reemplaza la URL del endpoint por la tuya. La salida es un único objeto JSON que puedes registrar o alimentar a una decisión de enrutamiento.
const ENDPOINT = 'https://your-solana-rpc-endpoint';
const SLOT_MS = 400; // approximate target slot duration
async function rpc(method, params = []) {
const res = await fetch(ENDPOINT, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ jsonrpc: '2.0', id: 1, method, params })
});
const json = await res.json();
if (json.error) throw new Error(`${method}: ${json.error.message}`);
return json.result;
}
async function probe() {
const [floor, tip, firstBlock] = await Promise.all([
rpc('minimumLedgerSlot'),
rpc('getSlot'),
rpc('getFirstAvailableBlock')
]);
const span = tip - floor;
const spanHours = (span * SLOT_MS) / 1000 / 60 / 60;
return {
endpoint: ENDPOINT,
minimumLedgerSlot: floor,
getSlot: tip,
getFirstAvailableBlock: firstBlock,
retentionSpanSlots: span,
estimatedWindowHours: Number(spanHours.toFixed(2))
};
}
probe().then(console.log).catch(console.error);Enrutar lecturas históricas entre endpoints con límites diferentes
En una configuración con múltiples endpoints, ejecuta el mismo sondeo contra cada endpoint y balancea las lecturas históricas solo hacia los nodos cuyo límite sea lo suficientemente bajo para el rango objetivo. Esto es un problema de enrutamiento, no un problema de comprobación de salud. Un nodo puede estar saludable y seguir siendo inelegible para una consulta histórica profunda.
El siguiente script sondea una lista de endpoints, filtra aquellos cuyo límite está en o por debajo de un slot objetivo y devuelve el conjunto elegible. También informa de los endpoints no elegibles con el motivo, para que los operadores puedan ver qué nodos son superficiales. Este patrón es útil para indexadores y trabajos de backfill que necesitan saber dónde enviar trabajo.
Para una visión más amplia de cómo OnFinality estructura el acceso a Solana, consulta la página de la red Solana y la guía de la API de Solana. Esos recursos describen las opciones de endpoint; este script describe cómo verificar la retención antes de comprometer una consulta.
const ENDPOINTS = [
'https://endpoint-a.example',
'https://endpoint-b.example',
'https://endpoint-c.example'
];
async function rpc(endpoint, method, params = []) {
const res = await fetch(endpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ jsonrpc: '2.0', id: 1, method, params })
});
const json = await res.json();
if (json.error) throw new Error(`${method}: ${json.error.message}`);
return json.result;
}
async function probeAll(targetSlot) {
const results = await Promise.all(ENDPOINTS.map(async (endpoint) => {
try {
const floor = await rpc(endpoint, 'minimumLedgerSlot');
const tip = await rpc(endpoint, 'getSlot');
const eligible = floor <= targetSlot && targetSlot <= tip;
return { endpoint, floor, tip, eligible, reason: eligible ? 'ok' : 'below floor or above tip' };
} catch (err) {
return { endpoint, eligible: false, reason: err.message };
}
}));
return {
eligible: results.filter(r => r.eligible).map(r => r.endpoint),
ineligible: results.filter(r => !r.eligible)
};
}
probeAll(250000000).then(r => console.log(JSON.stringify(r, null, 2)));Tabla de comparación reproducible para tus endpoints
La única forma fiable de conocer la retención de tus endpoints es medirla. Ejecuta el script de sondeo anterior contra cada endpoint que uses, al mismo tiempo, y registra los resultados. Como la retención es configurable por el operador y puede cambiar, vuelve a ejecutar el sondeo periódicamente y trata la tabla como una instantánea, no como un hecho permanente.
Rellena la tabla a continuación con tus propias mediciones. No te fíes de las afirmaciones de marketing del proveedor sobre la profundidad de retención; mide el endpoint específico al que realmente llegas. Si tu endpoint está detrás de un balanceador de carga, ejecuta el sondeo varias veces y registra el rango de límites que observes.
- URL del endpoint: la URL exacta que llamas.
- minimumLedgerSlot: el límite devuelto por el sondeo.
- getSlot: la punta devuelta al mismo tiempo.
- Amplitud de retención (slots): punta menos límite.
- Ventana estimada (horas): amplitud por duración del slot, etiquetada como aproximada.
- Rango de límites observado en sondeos repetidos: mínimo y máximo, para detectar variación del balanceador de carga.
Limitaciones, compensaciones y advertencias honestas
minimumLedgerSlot refleja el nodo al que realmente llegaste. Detrás de un balanceador de carga, diferentes solicitudes pueden llegar a nodos con límites diferentes. Un sondeo que devuelve un límite profundo no garantiza que la siguiente solicitud llegue al mismo nodo. Ejecuta el sondeo repetidamente y registra el rango, o usa un mecanismo de afinidad de sesión si tu proveedor lo ofrece.
La retención es una configuración del operador que puede cambiar en cualquier momento. Un nodo que sirvió un rango profundo ayer puede podar hoy. No almacenes en caché un valor de límite indefinidamente; vuelve a sondear antes de grandes trabajos de backfill y periódicamente durante los de larga duración.
Un límite profundo no garantiza que todos los slots intermedios estén completos. Los slots omitidos siguen existiendo, y un nodo puede tener huecos en su ledger incluso dentro del rango retenido. Combina las comprobaciones de retención con la detección de huecos, como se describe en Solana getBlocks y detección de huecos por slots omitidos. La retención te dice los límites exteriores; la detección de huecos te dice si el interior es sólido.
Por último, minimumLedgerSlot es un único número y no describe la disponibilidad del estado. Un nodo puede retener bloques pero no servir estado histórico arbitrario de cuentas. Trátalo como una señal entre varias, no como una descripción completa de capacidades.
- Los balanceadores de carga pueden enrutar a nodos con límites diferentes.
- La retención es configurable por el operador y puede cambiar sin aviso.
- Un límite profundo no implica un ledger sin huecos.
- La retención del ledger no es lo mismo que la disponibilidad del estado.
Solución de problemas comunes de sondeo de retención
Si minimumLedgerSlot devuelve un error, el endpoint puede no admitir el método o puede estar temporalmente no disponible. Comprueba el código y el mensaje de error contra la especificación JSON-RPC 2.0. Un error de método no encontrado sugiere que el endpoint no es un nodo RPC completo de Solana o está detrás de un proxy que filtra métodos.
Si el sondeo tiene éxito pero las lecturas históricas siguen fallando, verifica que el slot objetivo esté dentro de [minimumLedgerSlot, getSlot] y que el slot no esté omitido. Un slot puede estar dentro de la ventana pero no tener bloque si fue omitido. Usa getBlocks para comprobar si hay huecos en el rango antes de emitir consultas de bloques.
Si diferentes sondeos devuelven límites muy distintos, probablemente estés detrás de un balanceador de carga con nodos heterogéneos. O acepta la variación y enruta de forma conservadora usando el límite observado más alto, o solicita un endpoint dedicado con retención estable. La página del servicio de API describe las opciones dedicadas.
Si el sondeo es lento o se agota el tiempo de espera, el endpoint puede estar bajo carga. La guía Tiempos de espera y reintentos de Solana RPC cubre el manejo de tiempos de espera. Un sondeo lento es en sí mismo una señal sobre la salud del endpoint.
- Método no encontrado: el endpoint puede no ser un nodo RPC completo.
- La lectura falla dentro de la ventana: comprueba si hay slots omitidos con getBlocks.
- Límites variables: balanceador de carga con nodos heterogéneos.
- Sondeo lento: endpoint bajo carga, trátalo como una señal de salud.
Próximos pasos para lecturas históricas fiables
Empieza ejecutando el script de sondeo contra cada endpoint de Solana que uses. Registra los resultados en la tabla de comparación y vuelve a ejecutarlo periódicamente. Esto te da una línea base medida para las decisiones de enrutamiento.
Después integra la comprobación previa en tu indexador o trabajo de backfill. Antes de emitir una lectura histórica, llama a minimumLedgerSlot y compáralo con el rango objetivo. Enruta a un endpoint elegible o falla rápido con un error claro. Registra la decisión de enrutamiento para que los fallbacks silenciosos no oculten problemas de capacidad.
Por último, combina las comprobaciones de retención con la detección de huecos y el manejo de tiempos de espera. La retención te dice los límites exteriores; la detección de huecos te dice si el interior está completo; el manejo de tiempos de espera mantiene el trabajo resiliente. Juntas, estas tres comprobaciones forman una rutina de verificación previa robusta para cualquier carga de trabajo histórica en Solana.
Para más contexto sobre los patrones de acceso a Solana y los precios, consulta el centro de aprendizaje de OnFinality, la página de precios de RPC y la guía de la API de Solana. Estos recursos te ayudan a elegir endpoints y a entender el modelo de costes para consultas históricas.
- Sondea cada endpoint y registra los límites en una tabla.
- Integra comprobaciones previas en indexadores y trabajos de backfill.
- Combina las comprobaciones de retención con la detección de huecos y el manejo de tiempos de espera.
- Revisa los precios y las opciones de endpoint para cargas de trabajo históricas.