- Plataforma de banking-as-a-service que permite a fintechs integrar diretamente abertura de contas, pagamentos e onboarding como se estivessem conectando APIs bancárias; em março de 2023, recebeu licença bancária no Reino Unido e se tornou um banco regulado
- O sistema roda em Clojure on Kubernetes on AWS e combina uma arquitetura de event sourcing, que transforma a maior parte das entradas em eventos, com armazenamento em FoundationDB
- O FoundationDB é um armazenamento key-value strict-serializable que oferece suporte a transações e escritas concorrentes; a Griffin construiu leituras e escritas atômicas com uma camada semelhante ao Datomic, baseada em um port do Datascript
- A lógica de negócio é separada em pequenos log processors centrados em receber um map em Clojure e retornar outro map em Clojure, enquanto o acesso a sistemas externos é limitado por protocolos e procs dedicados
- A imutabilidade do Clojure e sua afinidade com trilhas de auditoria combinam com os requisitos de serviços financeiros e, junto com contratação remota, a empresa acredita ser mais fácil encontrar engenheiros de alta qualidade mesmo com um grupo menor de candidatos
Plataforma bancária regulada oferecida por API
- A Griffin é uma plataforma de banking-as-a-service que ajuda empresas de fintech a integrar funcionalidades bancárias com rapidez e segurança
- Em março de 2023, recebeu uma UK banking license da Financial Conduct Authority e se tornou um banco totalmente regulado no Reino Unido
- A Griffin se define como “the bank you can build on” e quer ser uma base para bancos, como a AWS é para infraestrutura
- API de onboarding de clientes
- API de criação de contas bancárias
- API de pagamentos
- Para oferecer essas funções, fintechs precisam legalmente trabalhar com um banco, e hoje isso frequentemente significa lidar com bancos tradicionais high street que ainda usam mainframes
- A Griffin quer oferecer ao mesmo tempo a licença bancária e a plataforma tecnológica, tornando-se a base sobre a qual as fintechs do futuro possam construir serviços
- Embora já tivesse obtido a licença, naquela época ainda estava na fase de mobilization, que terminaria após a conclusão da auditoria, nova captação de recursos e finalização do código
- A meta era concluir isso no Q3 ou Q4 daquele ano
Por que escolheram Clojure
- O Clojure foi escolhido como linguagem da plataforma por sua imutabilidade, expressividade e adequação a serviços financeiros que exigem trilhas de auditoria
- Allen Rohner viu uma apresentação de Rich Hickey sobre Clojure por volta de 2007 e concluiu que era melhor do que o Lisp que ele próprio estava criando
- Depois de fundar a CircleCI em 2011, usou Clojure por muito tempo; a linguagem funcionou bem lá e ele entendeu que também se encaixava em serviços financeiros
- Sobre a JVM, nos primeiros anos ele não percebeu plenamente as vantagens, mas depois passou a vê-la como um grande benefício
- Outras linguagens nichadas para startups podem sofrer com falta de bibliotecas e problemas de desempenho de compilador ou runtime
- A JVM reduz esses riscos
- A escolha da linguagem revela o perfil da empresa, e eles avaliaram que Clojure era uma aposta mais forte do que Python ou Java
- Também acreditam que usar uma linguagem de nicho pode reduzir o número de candidatos, mas aumentar a proporção de talentos de alto nível
Camada de dados construída sobre FoundationDB
- A arquitetura da Griffin roda sobre Clojure, Kubernetes e AWS, e é quase toda baseada em event sourcing
- O banco de dados utilizado é o FoundationDB
- O FoundationDB é um armazenamento key-value strict-serializable com suporte a transações
- Começou como uma startup do Vale do Silício
- Foi adquirida pela Apple em 2015
- Por volta de 2018, a Apple o liberou novamente como open source
- A Apple o utiliza em produção no iCloud
- A Apple fez benchmarks em que o FoundationDB opera em cerca de 1 milhão de transações por segundo
- Strict serializable corresponde ao nível mais alto de consistência de banco de dados
- A API básica é mais próxima de
get a keyeset a keydo que de SQL - A Griffin portou o Datascript para o FoundationDB e construiu uma camada semelhante ao Datomic
- Isso permite consultas atômicas sobre um armazenamento strict-serializable
- Há suporte a leituras e escritas baseadas em transações
- O FoundationDB não trabalha com single writer; ele suporta concurrent writes
- A Griffin precisa de mais de 1.000 transações por segundo, e essa exigência está sendo atendida
Event sourcing e log processor
- Todas as entradas do sistema da Griffin viram eventos
- Requisições de API
- Webhooks de terceiros
- Os eventos entram em um message log; na Griffin, um evento é um map em Clojure com campo
type, pares de chave/valor e spec - O sistema inteiro é construído como reação a eventos
- Eles chamam os pequenos log processors de
proc- Um proc funciona mais ou menos como “escute mensagens do tipo A e, em resposta, emita B ou C”
- Cada proc tem seu próprio estado privado
- O fluxo de mensagens pode ser organizado como um grafo, e os eventos se movem até alcançar um nó terminal
- Por exemplo, o servidor web recebe um evento HTTP, registra uma requisição de pagamento e depois espera um evento
payment createdoupayment rejectedantes de responder ao cliente- Esse fluxo usa um handler HTTP assíncrono em Netty
- Todos os eventos são gravados no FoundationDB
- Cada log processor tem seus próprios dados privados, como se fossem um namespace dentro do FoundationDB
- O proc observa a gravação de certos tipos de evento e volta a registrar seus próprios eventos no FoundationDB
- O FoundationDB oferece recursos para observar alterações de chave no banco, o que ajuda a construir sistemas reativos com eficiência
- Usar o banco de dados junto com um sistema de mensageria separado pode introduzir race conditions
- Por exemplo, uma mensagem pode ir para disco e outra para a rede, e um observador pode vê-las em ordens diferentes
- A Griffin simplifica isso gravando tudo no FoundationDB como caminho único
Monorepo e isolamento da lógica de negócio
- A Griffin usa monorepo
- Hoje, por eficiência, muitos log processors rodam na mesma JVM
- Como cada um é independente, também poderiam rodar como processos JVM separados
- Atualmente, há algo na casa de algumas centenas baixas de procs executando em uma única JVM
- A lógica de negócio é mantida o mais simples e limpa possível
- Namespaces de log processor individuais são quase inteiramente Clojure puro
- Quase não há bibliotecas de terceiros
- Há muito poucos side effects
- Um log processor se parece bastante com uma função que recebe um map em Clojure e retorna um ou mais maps em Clojure
- O estado do proc tem protocolos, então a implementação do outro lado não precisa ser conhecida
- Em testes, pode usar um banco em memória
- Em execução real, pode escrever no FoundationDB
- A interface com o mundo externo é mantida o menor possível
- A maioria dos procs só pode escrever no próprio estado interno e emitir mensagens
- Não pode fazer chamadas de rede
- Não pode fazer chamadas à AWS
- Nem executar outras ações externas
- Quando é necessário falar com sistemas externos, usam um proc especial com dispatch handler dedicado
- Proc que fala com a AWS
- Proc que fala com o clearing bank
- Proc que fala com outras APIs
Ecossistema Clojure utilizado
- Dentro da lógica de negócio, quase não usam bibliotecas
- Nas áreas que encostam no mundo externo, como o servidor web da API ou o service gateway, usam:
ringnettyreitit
- Usam Clojure spec extensivamente
- Para integração com AWS, usam a biblioteca Cognitect
aws-api - A configuração da aplicação e o gerenciamento de recursos seguem uma abordagem baseada no post closeable
- A ideia é que
with-openbasta, sem Component ou Integrant - Isso fornece escopo léxico, e a ordem das declarações de binding impõe a ordem de composição
- Eles usam um pequeno helper para declarar no bloco
with-openobjetos de estado ou objetos stateless que não implementamCloseable
- A ideia é que
Contratação e composição da equipe
- A Griffin entende que contratar para Clojure reduz a quantidade de candidatos, mas aumenta a proporção de bons candidatos
- Em vagas Java, podem chegar 1.000 CVs e apenas 10 serem bons
- Em vagas Clojure, podem chegar 13 CVs e 10 serem bons
- Em um pool de contratação pequeno, trabalho remoto é importante
- Reduzir restrições geográficas permite formar um pool maior: global, dentro de 3 fusos horários, ou ao longo da Europa
- Eles consideram um anti-pattern a situação em que é preciso contratar 100 engenheiros em pouco tempo
- A empresa inteira tem cerca de 70 pessoas
- A engenharia tem cerca de 22 a 24 pessoas
- Aproximadamente dois terços estão no Reino Unido
- Cerca de um terço está na UE
- Há por volta de 4 pessoas na Alemanha, 4 na Suécia e 1 na Irlanda
- A sede fica em Londres, mas a maioria dos desenvolvedores está fora de Londres, no Reino Unido
Testes de resiliência operacional em nível bancário
- Como banco, a Griffin precisa ser operationally resilient, algo que eles tratam quase como uma exigência de não ter downtime
- Como lidam com dinheiro, precisam demonstrar na prática que, mesmo quando há problemas, o dinheiro do cliente não será perdido
- A direção de testes que mais lhes interessa é semelhante à abordagem da equipe do FoundationDB
- A equipe do FoundationDB construiu um simulador de banco de dados
- Escreveu cerca de 20 tipos de processo, ou seja, papéis internos do cluster, como um aplicativo C++ single-threaded
- Construiu sobre C++ um compilador de concorrência em modelo de atores
- Fez com que toda system call e network call passasse por protocolos, para permitir injeção de falhas
- Até o multi-threading é tratado por meio de um modelo de atores baseado em envio de mensagens
- Nesse ambiente, é possível injetar falhas de forma determinística
- Casos em que as mensagens A e B são enviadas, mas chegam do outro lado na ordem B, A
- Casos em que ocorre um erro de escrita em disco durante o processamento de uma mensagem
- Isso pode ser visto como algo parecido com o generative testing do
test.check, em que toda a não determinismo do sistema é semeada a partir de um único número aleatório controlável - O que eles querem controlar são erros de disco, erros de rede e reordenação de mensagens
- O problema atual é que não há uma forma de controlar o comportamento das bibliotecas de threading em Java, do NIO e das escritas em disco
- A ideia compartilha o espírito do Jepsen, mas com diferenças
- Eles veem o Jepsen como algo mais próximo de brute force, com múltiplas VMs e encerramento de processos
- Como é difícil inspecionar internamente o estado do banco, também é difícil saber qual é a cobertura
- Em um ambiente totalmente controlável, dá para enumerar system calls e interleavings de mensagens, e verificar tudo muito rapidamente em memória
- A equipe do FoundationDB construiu esse ambiente de testes cedo, e isso é um dos fatores que reforçam a confiança no FoundationDB
- A Griffin está contratando, e mais informações podem ser encontradas na página de carreiras da Griffin
1 comentários
Opiniões no Hacker News
James Trunk, atual VP of Engineering da Griffin, fez a apresentação de introdução técnica a Clojure mais clara e divertida que já vi. Recomendo
https://youtu.be/C-kF25fWTO8?si=PnjMNLdBLJ8zqSu-
O problema agora é que não há como controlar as bibliotecas Java de threading subjacentes, NIO e o comportamento de escrita em disco; pela natureza desse tipo de sistema, acho que isso continuará sendo impossível
Não dá para obter execução determinística em sistemas que usam ordem de requisições ou escalonamento de tarefas não determinísticos. Isso acontece quando se usa sempre várias threads do OS ou se sobem vários processos separados nos testes
Até seria possível forçar algo determinístico, mas seria muito difícil, porque seria preciso inserir pontos de sincronização controláveis pelos testes em todas as transições da máquina de estados da aplicação
Na prática, parece que a única saída é projetar o núcleo do sistema de forma totalmente síncrona e acrescentar concorrência em uma camada superior no momento da execução
procsnão tem efeitos colaterais, exceto pelo que acontece além dos protocolos Clojure (interfaces Java)Por isso, durante os testes, conseguimos substituir todos os efeitos colaterais por stubs. Nosso código de “usuário” não tem acesso a bibliotecas de threading; o threading acontece no código do “kernel”
Um bom exemplo real em que isso já foi implementado pode ser visto em https://www.youtube.com/watch?v=4fFDFbi3toc
O próprio missionary já instrumenta fluxos do missionary e verifica transições de estado para seus testes
É bem legal que os dois fundadores tenham escrito juntos um livro chamado Learning ClojureScript
https://www.packtpub.com/product/learning-clojurescript/9781...
A frase “costumamos brincar que somos uma empresa de tecnologia com licença bancária” é uma citação que pode pegar muito mal mais tarde se algo der errado
Meu empregador se descrevia como uma empresa de pesquisa educacional que comercializava resultados de pesquisa por meio de software, e isso fazia muito mais sentido para mim e também gerava uma cultura melhor
No setor bancário, o custo de reaprender esse conhecimento pode ser muito alto
Pergunta sincera, e desculpem o tom áspero, mas por que eu deveria me importar com a linguagem em que um serviço que uso foi escrito? Por que importa que tenha sido escrito em Clojure? Profissionalmente, sou desenvolvedor Clojure, então é legal ver algo assim escrito em Clojure, mas não entendo por que eu deveria me importar com isso
Essa é uma das partes da comunidade de que eu realmente não gosto. Clojure é uma linguagem poderosa e eu gosto de usá-la, mas é estranho: sinto que há na comunidade algo como uma síndrome do impostor, uma necessidade de contar aos outros e justificar que determinado projeto usa essa linguagem
Não entendi bem o ponto. Isso é algum comportamento inadequado em uma sociedade civilizada?
Soa bastante ignorante. Se você “não se importa”, não precisa se envolver; deixe o autor escrever o que quiser
Lembro que, nos anos 90, desenvolvedores PHP e Python compartilhavam exemplos assim para responder a perguntas de negócios como “por que não usar Microsoft ASP?”
Ou talvez seja uma tentativa de atrair desenvolvedores para trabalhar na empresa deles
Por que esses bancos de API ficam sempre no Reino Unido? Há anos eu queria fazer operações bancárias via curl, mas ninguém oferece isso nos EUA
Já o Reino Unido vem incentivando ativamente novos bancos e novas tecnologias. Transferências instantâneas e gratuitas entre contas pessoais existem há quase 20 anos, pagamentos por aproximação há pelo menos 10, mobile banking há décadas, e as APIs bancárias exigidas pelo governo existem há quase 5 anos.
Em resumo, o Reino Unido tem um setor bancário muito ativo que, pelos padrões bancários, vem inovando rapidamente, e conta com um ambiente e um ecossistema bem desenvolvidos para uma inovação ainda mais rápida.
Nos EUA, parece que os bancos desistiram da inovação tecnológica décadas atrás e preferiram inovar em tarifas e em tratamento punitivo aos clientes. Por isso não há um novo ambiente de inovação, e para os bancos estabelecidos é muito mais fácil esmagar concorrentes do que competir.
Até recentemente, o Reino Unido também tinha um número surpreendentemente pequeno de bancos independentes; o motivo de isso não ter acontecido lá provavelmente tem a ver com a natureza das leis e regulações, que garantem muitos direitos aos clientes e punem ativamente bancos que não os respeitam.
Nos EUA, os bancos que têm APIs tendem a focar em parcerias com grandes fintechs, então até uma API simples provavelmente será cara em comparação com uma conta bancária comum. Por exemplo, o Grasshopper Bank, nos EUA, é um dos poucos bancos que oferecem uma API em cima de uma conta bancária comercial comum.
Eu trabalho na Treasury Prime, que dá suporte a vários bancos dos EUA que oferecem APIs.
No lado das contas pessoais, Monzo e Starling são os mais conhecidos entre os chamados bancos challenger[1].
[1]: https://en.wikipedia.org/wiki/Challenger_bank
Column – um banco licenciado para desenvolvedores
https://news.ycombinator.com/item?id=31109170
“Há mais uma tecnologia proprietária que deveríamos tornar open source. Fizemos o port do Datascript para o FoundationDB” — por favor, publiquem isso.
Estou curioso para saber como funcionaria como alternativa ao Datomic.
A frase “Legalmente, fintechs precisam trabalhar com bancos para fazer esse tipo de coisa, e hoje isso significa grandes bancos tradicionais que usam mainframes. A Griffin é o banco e a plataforma tecnológica sobre a qual todas as fintechs do futuro serão construídas” parece ter sido escrita em 2016.
O mercado já se moveu. A Griffin parece boa, mas está alguns anos atrás de muita gente, e players estabelecidos como a ClearBank já oferecem APIs bancárias muito bem.
Há espaço para mais empresas entrarem, então é bom ver a Griffin chegando ao mercado, mas eu gostaria que o pitch não fosse tão fraco.
E uma boa API por si só não basta. É preciso todo um modelo operacional que combine com a base de clientes, e construir isso é muito mais difícil.
Ainda não. O texto diz: “Quando concluirmos a auditoria, levantarmos mais capital e terminarmos de escrever o código, tiraremos as rodinhas. Isso deve acontecer por volta do 3º ou 4º trimestre deste ano”.
Eu detesto quando um texto começa com “em uma startup, você deve usar a linguagem mais poderosa disponível, e essa linguagem é Clojure”.
Isso é só a sua opinião. Em uma startup, você deve usar a linguagem que permita à equipe criar e lançar o MVP o mais rápido possível para conseguir os primeiros clientes ou investimento. Para uma startup comum, isso pode até ser uma plataforma low-code ou no-code, embora em fintech isso provavelmente não se aplique.
Se fosse para argumentar, também daria para dizer que Python é a linguagem mais poderosa por causa de LLMs e machine learning, e eu normalmente sou desenvolvedor PHP. Python talvez fique ainda mais poderosa graças ao Mojo, que supostamente torna Python 36.000 vezes mais rápido.
Mas eu jamais diria que alguma linguagem X é a única e mais poderosa linguagem a ser usada em startups. Isso é uma falsidade total e apenas uma opinião.
Por exemplo, na minha opinião, eu concordo com essa opinião :-) Meu negócio solo não teria sido possível sem Clojure e ClojureScript, e isso mostra o “poder” dessa linguagem.
Eu considero a linguagem “poderosa” porque ela permite que um único desenvolvedor escreva e mantenha apps complexos por anos. Ela me dá poder.
Clojure tem uma comunidade bastante voltada para dentro, mais sobreposta a outros Lisps do que a linguagens mais populares como Python ou PHP. Por isso, o clichê de que Clojure é a linguagem mais poderosa pode soar surpreendente para quem não a usa, embora tenha seu fundo de verdade.
Nós, desenvolvedores Clojure, já estamos acostumados, e hoje falar partindo da premissa de superioridade virou quase uma forma de cumprimento.
Também prefiro Clojure para lidar com saídas de LLMs. Claro que continuo usando Python nos lugares em que Python é a ferramenta certa.