2 puntos por GN⁺ 2023-08-30 | 1 comentarios | Compartir por WhatsApp
  • Es una plataforma de banking-as-a-service que permite a las fintech integrar directamente apertura de cuentas, pagos y onboarding como si se conectaran a la API de un banco, y en marzo de 2023 obtuvo una licencia bancaria del Reino Unido para convertirse en un banco regulado.
  • El sistema corre sobre Clojure on Kubernetes on AWS y combina una arquitectura de event sourcing que convierte la mayoría de las entradas en eventos con almacenamiento en FoundationDB.
  • FoundationDB es un strict-serializable key-value store que soporta transacciones y escrituras concurrentes, y Griffin construyó lecturas y escrituras atómicas con una capa similar a Datomic basada en un port de Datascript.
  • La lógica de negocio se separa alrededor de pequeños log processor que reciben un mapa de Clojure y devuelven otro mapa de Clojure, mientras que el acceso a sistemas externos se limita mediante protocolos y proc dedicados.
  • Consideran que la inmutabilidad de Clojure y su afinidad con los audit logs encajan con los requisitos de los servicios financieros, y que combinada con contratación remota facilita encontrar ingenieros de alta calidad incluso con un grupo pequeño de candidatos.

Plataforma bancaria regulada ofrecida por API

  • Griffin es una plataforma de banking-as-a-service que ayuda a las empresas fintech a integrar funciones bancarias de forma rápida y segura.
  • En marzo de 2023 recibió una UK banking license de la Financial Conduct Authority y se convirtió en un banco británico completamente regulado.
  • Griffin se describe como “the bank you can build on” y apunta a ser una base tipo AWS para la banca.
    • API de onboarding de clientes
    • API de creación de cuentas bancarias
    • API de pagos
  • Para que una fintech pueda ofrecer estas funciones, legalmente necesita colaborar con un banco, y hoy en día muchas veces termina trabajando con high street banks tradicionales que todavía usan mainframes.
  • Griffin busca ofrecer al mismo tiempo la licencia bancaria y la plataforma tecnológica, para convertirse en la base sobre la cual las fintech del futuro puedan construir servicios.
  • Aunque ya había obtenido la licencia, en ese momento estaba en la etapa de mobilization, que termina después de completar la auditoría, conseguir financiamiento adicional y finalizar el desarrollo del código.
    • El objetivo era cerrar esa etapa en el Q3 o Q4 de ese año.

Por qué eligieron Clojure

  • Clojure fue elegido como lenguaje de la plataforma por su inmutabilidad, su expresividad y su afinidad con los servicios financieros que requieren audit logs.
  • Allen Rohner vio una presentación de Clojure de Rich Hickey alrededor de 2007 y concluyó que era mejor que el Lisp que él mismo estaba construyendo.
  • Después de fundar CircleCI en 2011, usó Clojure durante mucho tiempo; funcionó bien en CircleCI y también le parecía adecuado para servicios financieros.
  • Respecto a la JVM, durante los primeros años no valoró del todo sus ventajas, pero luego cambió de opinión y pasó a verla como un gran beneficio.
    • Otros niche startup languages pueden sufrir por falta de librerías o por problemas de rendimiento del compilador y el runtime.
    • La JVM sirve como una base que reduce esos riesgos.
  • La elección del lenguaje refleja el carácter de la empresa, y consideraban que Clojure era una apuesta más fuerte que Python o Java.
  • Creen que usar un niche language reduce el número de candidatos, pero puede aumentar la proporción de talento senior.

Capa de datos construida sobre FoundationDB

  • La arquitectura de Griffin corre sobre Clojure, Kubernetes y AWS, y está compuesta casi por completo bajo un enfoque de event sourcing.
  • La base de datos que usan es FoundationDB.
  • FoundationDB es un strict-serializable key-value store con soporte para transacciones.
    • Comenzó como una startup de Silicon Valley.
    • En 2015 fue adquirida por Apple.
    • Hacia 2018 Apple la volvió a publicar como open source.
    • Apple la usa en producción para iCloud.
  • Apple hizo benchmarks donde FoundationDB opera en torno a 1 millón de transacciones por segundo.
  • Strict serializable corresponde al nivel más alto de consistencia de bases de datos.
  • Su API base se parece más a get a key y set a key que a SQL.
  • Griffin portó Datascript a FoundationDB para construir una capa similar a Datomic.
    • Permite consultas atómicas sobre un almacén de datos strict-serializable.
    • Soporta lecturas y escrituras basadas en transacciones.
  • FoundationDB no está limitado a un single writer, sino que soporta concurrent writes.
  • Griffin necesita más de 1,000 transacciones por segundo y está cumpliendo ese requisito.

Event sourcing y log processor

  • Todas las entradas del sistema de Griffin se convierten en eventos.
    • API request
    • webhook de terceros
  • Los eventos entran en un message log, y en Griffin un evento es un mapa de Clojure con un campo type, pares key/value y spec.
  • Todo el sistema está construido como una reacción a eventos.
  • A los log processor pequeños les llaman proc.
    • Un proc funciona como “escucha un message type A y como respuesta emite B o C”.
    • Cada proc tiene su propio estado privado.
  • El flujo de mensajes puede representarse como un grafo, y los eventos avanzan hasta llegar a un terminal node.
  • Por ejemplo, el servidor web recibe eventos HTTP, registra una solicitud de pago, luego espera un evento payment created o payment rejected y finalmente responde al cliente.
    • Este flujo usa un Netty asynchronous HTTP handler.
  • Todos los eventos se registran en FoundationDB.
    • Cada log processor tiene sus propios datos privados, como un namespace dentro de FoundationDB.
    • El proc observa cuándo se registra un tipo específico de evento y vuelve a registrar sus propios eventos en FoundationDB.
  • FoundationDB ofrece una función para vigilar cambios en las keys de la base de datos, lo que permite construir un sistema reactivo de forma eficiente.
  • Si se usa la base de datos junto con un sistema de mensajería separado, puede aparecer la posibilidad de race conditions.
    • Por ejemplo, un mensaje podría ir al disco y otro por la red, y un observador podría verlos en distinto orden.
    • Griffin simplifica esto escribiendo todo en FoundationDB por una sola ruta.

Monorepo y aislamiento de la lógica de negocio

  • Griffin usa un monorepo.
  • Actualmente, por eficiencia, muchos log process corren dentro de la misma JVM.
    • Como cada uno es independiente, también podrían ejecutarse como procesos JVM separados.
    • Hoy ejecutan proc en el rango de los low hundreds dentro de una sola JVM.
  • La lógica de negocio se mantiene lo más simple y limpia posible.
    • Cada namespace de log processor es casi completamente Clojure puro.
    • Casi no usan librerías de terceros.
    • También hay muy pocos side effects.
  • Un log processor se parece a una función que recibe un mapa de Clojure y devuelve uno o más mapas de Clojure.
  • El estado del proc tiene protocol, así que no necesita conocer la implementación del otro lado.
    • En pruebas puede usar una base de datos en memoria.
    • En ejecución real puede escribir en FoundationDB.
  • La interfaz con el mundo exterior se mantiene lo más pequeña posible.
  • La mayoría de los proc solo pueden escribir en su estado interno y emitir mensajes.
    • No pueden hacer llamadas de red.
    • No pueden llamar a AWS.
    • No hacen otras acciones externas.
  • Cuando necesitan comunicarse con sistemas externos, crean proc especiales con un dispatch handler dedicado.
    • proc que se comunica con AWS
    • proc que se comunica con el clearing bank
    • proc que se comunica con otras API

Ecosistema de Clojure que usan

  • Dentro de la lógica de negocio casi no usan librerías.
  • En las zonas que tocan el mundo exterior, como el API web server o el service gateway, usan lo siguiente.
    • ring
    • netty
    • reitit
  • Usan Clojure spec de manera extensiva.
  • Para la integración con AWS usan la librería aws-api de Cognitect.
  • Para la configuración de la aplicación y la gestión de recursos usan un enfoque basado en el post de blog closeable.
    • La idea es que with-open basta sin necesidad de Component o Integrant.
    • Así obtienen lexical scope, y el orden de declaración en los bindings fuerza el orden de construcción.
    • Usan un pequeño helper para declarar dentro de with-open objetos con estado u objetos stateless que no implementan Closeable.

Contratación y composición del equipo

  • Griffin considera que contratar para Clojure implica menos candidatos, pero una mayor proporción de buenos perfiles.
    • En contratación para Java pueden llegar 1,000 CV y quizá solo 10 sean buenos candidatos.
    • En contratación para Clojure, dicen, pueden llegar 13 CV y aun así 10 ser buenos candidatos.
  • En un pool de contratación pequeño, el trabajo remoto es importante.
    • Reducir la restricción geográfica permite ampliar el pool a nivel global, dentro de 3 husos horarios, o en toda Europa.
  • Consideran un anti-pattern tener que contratar 100 ingenieros en muy poco tiempo.
  • La empresa en total tiene alrededor de 70 personas.
  • El área de Engineering tiene unas 22 a 24 personas.
    • Aproximadamente dos tercios están en el Reino Unido.
    • Aproximadamente un tercio está en la UE.
    • Unas 4 personas en Alemania, 4 en Suecia y 1 en Irlanda.
    • La sede está en Londres, pero la mayoría de los desarrolladores en Reino Unido están fuera de Londres.

Pruebas de resiliencia operativa a nivel bancario

  • Griffin considera que, como banco, debe ser operationally resilient, lo que se acerca al requisito de no tener downtime.
  • Como manejan dinero, necesitan poder demostrar en la práctica que, incluso si algo falla, el dinero del cliente no se pierde.
  • La dirección de pruebas que más les interesa es similar al enfoque del equipo de FoundationDB.
    • El equipo de FoundationDB construyó un simulador de base de datos.
    • Escribieron unos 20 tipos de proceso, es decir, roles dentro del cluster, como una app C++ single-threaded.
    • Encima de C++ construyeron un compilador de concurrencia basado en actor model.
    • Todas las system call y network call pasan por protocolos para poder inyectar errores.
    • Incluso el multi-threading se maneja mediante un actor model basado en envío de mensajes.
  • En este entorno se pueden inyectar fallas de forma determinista.
    • Casos donde se enviaron los mensajes A y B, pero al otro lado llegan en orden B, A.
    • Casos donde ocurre un error de escritura en disco mientras se procesa un mensaje.
  • Esto puede verse como algo parecido al generative testing de test.check, donde toda la no determinación del sistema nace de un único número aleatorio controlable como seed.
  • Lo que quieren controlar son disk errors, network errors y message reordering.
  • El problema actual es que no tienen una forma de controlar el comportamiento de las Java threading libraries, NIO ni las escrituras a disco.
  • Comparten el espíritu de Jepsen, pero ven una diferencia.
    • Consideran que Jepsen se parece más a fuerza bruta: usar varias VM y matar procesos.
    • Como es difícil inspeccionar el estado interno de la base de datos, también es difícil saber qué cobertura se logró.
    • En un entorno completamente controlable, se pueden enumerar system calls o interleavings de mensajes y verificar todo muy rápido en memoria.
  • El equipo de FoundationDB construyó este entorno de pruebas desde el inicio, y eso es uno de los factores que les da confianza en FoundationDB.
  • Griffin está contratando, y se puede revisar más información en la página de carreras de Griffin.

1 comentarios

 
GN⁺ 2023-08-30
Opiniones de Hacker News
  • James Trunk, actual VP of Engineering de Griffin, dio la presentación de introducción técnica a Clojure más clara y entretenida que he visto. La recomiendo.
    https://youtu.be/C-kF25fWTO8?si=PnjMNLdBLJ8zqSu-

  • El problema ahora es que no hay forma de controlar la biblioteca de threading de Java subyacente, NIO ni el comportamiento de escritura a disco, y por la naturaleza de ese tipo de sistema parece que seguirá siendo imposible.
    No se puede obtener ejecución determinista en sistemas que usan orden no determinista de solicitudes o scheduling de tareas. Eso pasa cuando siempre se usan varios threads del SO o cuando en las pruebas se levantan varios procesos separados.
    Se podría forzar algo determinista, pero sería muy difícil porque habría que insertar puntos de sincronización controlables por las pruebas en cada transición de la máquina de estados de la aplicación.
    En la práctica, parece que la única opción es diseñar el núcleo del sistema de forma completamente sincrónica y agregar concurrencia en una capa superior al momento de la ejecución.

    • Es difícil, pero posible. Lo más importante es reducir la superficie de la aplicación. Casi toda nuestra lógica de negocio son funciones puras, y procs no tiene efectos secundarios salvo por lo que ocurre más allá de los protocolos de Clojure (interfaces de Java).
      Por eso, durante las pruebas podemos reemplazar todos los efectos secundarios por stubs. Nuestro código de “usuario” no tiene acceso a la biblioteca de threading, y el threading ocurre en el código del “kernel”.
      De hecho, se puede ver un buen ejemplo de este enfoque ya implementado en https://www.youtube.com/watch?v=4fFDFbi3toc
    • No diría que sea absolutamente imposible. Creo que podría ser posible modificando missionary, un DSL de concurrencia estructurada para Clojure/ClojureScript que también implementa supervisión de procesos.
      Ya se instrumentan los flujos de missionary y se verifican las transiciones de estado para las propias pruebas de missionary.
  • Es bastante genial que los dos fundadores hayan escrito juntos un libro llamado Learning ClojureScript.
    https://www.packtpub.com/product/learning-clojurescript/9781...

    • Vi que el tercer autor del libro es Allen Rohner. Trabajé con él en Compass Labs y era un desarrollador extremadamente talentoso. También fundó CircleCI.
  • La frase “solemos bromear diciendo que somos una empresa tecnológica con licencia bancaria” es una cita que podría verse muy mal después si algo sale mal.

    • No creo que usaría un banco con esa actitud. La etiqueta de empresa tecnológica suele venir acompañada de una arrogancia injustificada: creer que hacen todo bien solo porque escriben código.
      Mi empleador se describía como una empresa de investigación educativa que comercializaba resultados de investigación mediante software; para mí eso tenía mucho más sentido y también generaba una mejor cultura.
    • Una de las cosas que aprendí en fintech es que, aunque el código COBOL que ejecutan los bancos es viejo y difícil de mantener, contiene bastante conocimiento valioso que habría que volver a aprender si se reconstruyera.
      En banca, el costo de reaprender ese conocimiento puede ser muy alto.
  • Pregunta seria, y perdón por el tono brusco, pero ¿por qué debería importarme en qué lenguaje está escrito el servicio que uso? ¿Por qué importa que esté escrito en Clojure? Profesionalmente soy desarrollador de Clojure, así que me parece genial ver algo escrito en Clojure, pero no entiendo por qué debería importarme.
    Esta es una de las cosas que realmente detesto de la comunidad. Clojure es un lenguaje potente y disfruto usarlo, pero siento que en la comunidad hay algo parecido al síndrome del impostor, como si hubiera que contarle a los demás y justificar que se usa este lenguaje en algún proyecto, y eso me resulta raro.

    • Es una publicación de blog en la que una empresa de Clojure entrevista a otra empresa de Clojure, con foco en el stack tecnológico. En cualquier ecosistema de lenguaje, este tipo de artículos no es raro, y naturalmente los escriben y leen personas interesadas en esa tecnología.
      No entiendo bien el punto. ¿Se supone que esto es una conducta inapropiada en una sociedad civilizada?
      Suena bastante ignorante. Si “no te interesa”, no hace falta involucrarte; deja que el autor escriba lo que quiera escribir.
    • Normalmente, estas historias son más importantes en lenguajes que todavía no han sido lo suficientemente aceptados y donde uno tiene que preocuparse por obtener permiso para usarlos.
      Recuerdo que en los 90 los desarrolladores de PHP y Python compartían ejemplos así para responder preguntas de negocio como “¿por qué no usan Microsoft ASP?”.
    • Si la arquitectura permite enviar código para ejecutarlo dentro de una transacción del lado del servidor, quizá los desarrolladores también tengan que desarrollar en Clojure para usar esa API.
      O tal vez quieran atraer desarrolladores a su propia empresa.
  • ¿Por qué estos bancos con API siempre están en el Reino Unido? Hace años que quiero hacer operaciones bancarias con curl, pero nadie lo ofrece en Estados Unidos.

    • La banca en Estados Unidos está sorprendentemente atrasada y hace décadas que no lidera al mundo desde el punto de vista tecnológico o de innovación.
      En cambio, el Reino Unido ha fomentado activamente nuevos bancos y nuevas tecnologías. Las transferencias instantáneas y gratuitas entre cuentas personales existen desde hace casi 20 años; los pagos sin contacto, desde hace al menos 10; la banca móvil, desde hace décadas; y las API bancarias obligatorias por el gobierno, desde hace casi 5 años.
      En resumen, el Reino Unido tiene un sector bancario muy dinámico que, para los estándares bancarios, ha innovado rápido, y cuenta con un entorno y un ecosistema bien desarrollados para innovar aún más rápido.
      En Estados Unidos parece que los bancos abandonaron la innovación tecnológica hace décadas y prefirieron innovar en comisiones y en trato punitivo hacia los clientes. Por eso no hay un nuevo entorno de innovación, y a los bancos existentes les resulta mucho más fácil aplastar a la competencia que competir.
      Hasta hace poco, el Reino Unido también tenía una cantidad sorprendentemente baja de bancos independientes; si allí no ocurrió lo mismo, probablemente se deba a la naturaleza de sus leyes y regulaciones, que garantizan muchos derechos a los clientes y castigan activamente a los bancos que no los respetan.
    • En Estados Unidos es difícil obtener una nueva licencia bancaria, pero en el Reino Unido el camino para convertirse en un banco challenger es relativamente claro. Jarvis también volvió de SF a Londres para iniciar Griffin.
      En Estados Unidos, los bancos con API tienden a enfocarse en alianzas con grandes fintechs, así que incluso una API simple probablemente sea cara en comparación con una cuenta bancaria común. Por ejemplo, Grasshopper Bank en Estados Unidos es uno de los pocos bancos que ofrece una API sobre una cuenta bancaria comercial común.
      Trabajo en Treasury Prime, que da soporte a varios bancos estadounidenses que ofrecen API.
    • Después de la crisis financiera de 2008 y los escándalos bancarios que le siguieron, hubo que rescatar con dinero de los contribuyentes a varios bancos conocidos, y el gobierno británico de entonces introdujo una serie de medidas para promover los bancos pequeños.
      En el segmento de cuentas personales, Monzo y Starling son los más conocidos de los llamados bancos challenger[1].
      [1]: https://en.wikipedia.org/wiki/Challenger_bank
    • En el Reino Unido, el gobierno impuso requisitos de API a los bancos. En Estados Unidos se deja al “libre mercado”, lo que en la práctica significa que tienes que confiar en terceros poco confiables como Yodlee o Plaid.
    • Ahora existe https://column.com. También se cubrió aquí el año pasado.
      Column – un banco autorizado para desarrolladores
      https://news.ycombinator.com/item?id=31109170
  • Eso de “hay una tecnología propietaria adicional que deberíamos convertir en open source. Portamos Datascript a FoundationDB”... ojalá la publiquen.
    Me da curiosidad cómo funcionaría como alternativa a Datomic.

    • Todo el artículo se leía como una guía de “cómo sobreingenierizar un proyecto por diversión”.
  • La frase “legalmente, las fintech tienen que asociarse con un banco para hacer esto, y hoy eso significa bancos grandes tradicionales que usan mainframes. Griffin es el banco y la plataforma tecnológica sobre la que se construirán todas las fintech del futuro” suena como si la hubieran escrito en 2016.
    El mercado ya se movió. Griffin se ve bien, pero va varios años por detrás de muchos, y actores establecidos como ClearBank ya ofrecen muy buenas API bancarias.
    Hay espacio para que entren más jugadores, así que celebro la llegada de Griffin al mercado, pero ojalá el pitch no fuera tan flojo.

    • Todavía no hay una cantidad enorme de opciones en el mercado. ClearBank es, de hecho, uno de los tres bancos con un producto decente.
      Y una buena API por sí sola no basta. Se necesita todo un modelo operativo que encaje con la base de clientes, y construir eso es mucho más difícil.
    • La expresión “sobre la que se construirán todas las fintech del futuro” suena a punto único de falla, y parece mostrar tal cual el problema del capitalismo tardío, donde la competencia se vuelve una fantasía.
  • Todavía no. Dice: “Cuando terminemos la auditoría, levantemos más capital y terminemos de escribir el código, quitaremos las rueditas de apoyo. Será hacia el tercer o cuarto trimestre de este año”.

  • De verdad me molesta cuando un artículo empieza con “en una startup debes usar el lenguaje más poderoso disponible, y ese es Clojure”.
    Eso es simplemente tu opinión. En una startup debes usar el lenguaje que le permita al equipo construir y lanzar el MVP lo más rápido posible para conseguir los primeros clientes o inversión. Para una startup común, podría ser una plataforma low-code o no-code, aunque probablemente no en fintech.
    Si vamos al caso, por los LLM y el machine learning también se podría decir que Python es el lenguaje más poderoso, y yo normalmente soy desarrollador PHP. Python podría volverse aún más poderoso gracias a Mojo, que supuestamente hace que Python sea 36000 veces más rápido.
    Pero jamás diría que un lenguaje X es el único y más poderoso lenguaje que debe usarse en una startup. Eso es completamente falso y solo una opinión.

    • Por supuesto que es una opinión. Cada vez que alguien dice algo, es su opinión.
      Por ejemplo, en mi opinión estoy de acuerdo con esa opinión :-) Mi negocio de fundador en solitario no habría sido posible sin Clojure y ClojureScript, y eso demuestra el “poder” de este lenguaje.
      Lo considero “poderoso” porque permite que un solo desarrollador escriba y mantenga apps complejas durante años. Me da poder.
    • Esa frase se entiende mucho mejor si consideras que JUXT, aparte de Nubank, es una de las empresas especializadas en Clojure más conocidas, y que pone su logo al pie de casi cualquier conferencia que tenga aunque sea un poco que ver con Clojure.
      Clojure tiene una comunidad bastante introspectiva, que se solapa mucho más con otros Lisp que con lenguajes más populares como Python o PHP. Por eso el cliché de que Clojure es el lenguaje más poderoso, aunque tenga algo de verdad, puede sonar sorprendente para quienes no lo usan.
      Los desarrolladores de Clojure ya estamos acostumbrados, y a estas alturas hablar dando por sentada su superioridad es casi como un saludo.
    • Python es realmente poderoso, especialmente en 2023. Pero, curiosamente, yo orquesto LLM y modelos de difusión con Clojure.
      También prefiero Clojure para manejar salidas de LLM. Por supuesto, sigo usando Python donde Python encaja perfectamente.