Skip to main content
Hay cosas que un exchange necesita saber sobre una cuenta y que no se pueden calcular mientras se ejecuta un bloque. Un nivel por volumen depende de treinta días de trading. Una recompensa depende de una ventana que aún no se ha cerrado. Una atribución de referido depende de una relación establecida hace meses. Meter ese trabajo dentro de la ejecución del bloque sería un error por partida doble: haría que todos los bloques pagaran por un cálculo que casi ningún bloque necesita, y obligaría al kernel a cargar con un historial que no tiene ninguna otra razón para guardar. Los servicios de programa lo resuelven invirtiendo la dirección. El cálculo se ejecuta fuera del bloque, sobre el registro confirmado. Su resultado se confirma después de vuelta en la cadena como estado de protocolo, donde la ejecución puede leerlo en tiempo constante como cualquier otra configuración.
Historial confirmado de operaciones
Servicio de programacálculo por ventanas, fuera del bloquelee las comisiones en vivo desde la cadena
¿Cambió desde lo aplicado?
No se escribe nada
Transacción de protocolo
Estado de la cadena
Se lee al ejecutaren tiempo constante
Se compara por comisiones, no por nivelUn umbral que se mueve, o un nivel al que se cambia el precio, altera lo que paga una cuenta sin cambiar su índice de nivel.
La cadena resuelve la comisión finalUn periodo se registra como aplicado solo tras confirmarse todos los lotes; una caída reejecuta el periodo entero, y es seguro porque el cálculo es idempotente.
La cadena sigue siendo la autoridad. Un servicio no guarda estado del que dependa la red: propone un valor, y solo lo que la cadena aceptó es real.

Qué funciona hoy

Niveles de comisiones por volumen. El servicio consume el historial de operaciones que un nodo transmite, acumula el volumen por cuenta y toma instantáneas según un calendario. Cuando un periodo se cierra, calcula el volumen de la ventana móvil de cada cuenta, lo mapea contra la configuración de comisiones leída en vivo desde la cadena y escribe de vuelta por lotes las cuentas que cambiaron. Varios detalles de esa frase son estructurales:
  • La tabla de niveles se lee de la cadena, nunca está codificada en el servicio. Un servicio que guardara su propia copia seguiría aplicando el esquema de ayer después de que la red lo cambiara.
  • La comparación se hace contra las comisiones, no contra la posición en la tabla de niveles. Comparar índices de nivel deja fuera dos casos reales: que un umbral se mueva y una cuenta sin cambios acabe en otro nivel, y que se cambie el precio de un nivel mientras su índice sigue igual. Ambos cambian lo que paga una cuenta; ninguno cambia su índice.
  • La cadena resuelve la comisión final. La transacción lleva un índice de nivel; la ejecución lo resuelve contra la configuración de comisiones vigente. Un índice de nivel fuera del rango válido hace fallar el lote entero en lugar de aplicarse parcialmente.
  • Un periodo se registra como aplicado solo después de que todos los lotes se confirmen. Una caída a mitad de un periodo hace que se reejecute el periodo entero, lo cual es seguro porque el cálculo es idempotente: la misma ventana produce el mismo resultado.

El modelo de fallos

Estos servicios se sitúan entre dos sistemas que, cada uno por su lado, a veces no estarán disponibles. El diseño lo da por supuesto en lugar de tratarlo como algo excepcional. Los fallos de dependencias (la base de datos, el flujo del nodo, la API del nodo) se reintentan con espera creciente (backoff). No terminan el proceso, porque reiniciar no arregla una dependencia inalcanzable; solo añade un arranque en frío a la interrupción. Lo que sigue siendo fatal es aquello que un reinicio sí puede arreglar o que un operador tiene que ver: configuración inválida al arrancar, no poder abrir el endpoint de salud, y los panics. Durante una interrupción el proceso sigue vivo, se declara no listo y cuenta los errores. La señal operativa útil es por tanto “¿lleva esto N minutos sin estar listo?” y no “¿está vivo el proceso?”, porque un proceso vivo que lleva una hora sin poder ingerir datos es el incidente de verdad. El apagado es ordenado ante las señales que envía un orquestador: el trabajo se detiene, los puntos de control se vuelcan y el proceso termina limpiamente. Sin eso, cada despliegue rutinario costaría una ventana sin volcar y una reejecución.
Un periodo que se ha calculado pero aún no se ha aplicado no es un periodo perdido. Como el cálculo es idempotente y el periodo aplicado se registra solo después de que la escritura tenga éxito, una ejecución interrumpida se reanuda rehaciendo la ventana en lugar de saltársela.

Por qué el patrón generaliza

La ruta de escritura de vuelta es genérica. Existen transacciones de protocolo para fijar configuración a nivel de cuenta y para fijar configuración global, y un servicio de programa es cualquier proceso que calcule un valor para alguna de ellas a partir del historial confirmado. Los niveles de comisiones son el único que está en marcha. Los programas de incentivos, la atribución de referidos y la elegibilidad para campañas tendrían la misma forma: un cálculo por ventanas sobre el historial de operaciones, una comparación contra lo que está aplicado ahora mismo y una escritura de vuelta por lotes. Pertenecerían aquí y no al kernel por la misma razón que los niveles de comisiones: el cálculo es periódico e histórico, mientras que la ejecución necesita que la respuesta sea una consulta en tiempo constante. Ninguno está construido; lo que generaliza es el patrón, no un compromiso de que vayan a usarlo. Las condiciones comerciales de estos programas viven en Comisiones y programas. Esta página trata de cómo el resultado llega a la cadena.

Qué leer a continuación

Indexador

El flujo que consumen estos servicios.

Comisiones

El lado comercial: cuáles son los niveles y cuánto cuestan.

IntentionKernel

Cómo se lee durante la ejecución la configuración escrita de vuelta.

Modelo de estado

Por qué las claves de configuración están versionadas y por qué los clientes deberían resolverlas en vivo.