Armando una Blockchain (6)

Anterior Post

Esta semana pasada, agregué proceso de transacciones a mi proyecto personal de blockchain:

https://github.com/ajlopez/BlockchainSharp

En el anterior post, describí el Trie inmutable que estuve armando. Ahora voy a usarlo para guardar el AccountState por dirección de cuenta:

public class AccountState
{
    private BigInteger balance;

    public AccountState(BigInteger balance)
    {
        if (BigInteger.Compare(BigInteger.Zero, balance) > 0)
            throw new InvalidOperationException("Invalid balance");

        this.balance = balance;
    }

    public BigInteger Balance { get { return this.balance; } }

    public AccountState AddToBalance(BigInteger amount)
    {
        return new AccountState(BigInteger.Add(this.balance, amount));
    }

    public AccountState SubtractFromBalance(BigInteger amount)
    {
        return new AccountState(BigInteger.Subtract(this.balance, amount));
    }
}

Decidí implementar cuentas como en Ethereum: tener una cuenta con saldo en luegar de inputs y outputs. Por ahora, la única propiedad es el Balance, pero iré agregando más datos.  Vean arriba que los saldos negativos son rechazadas. He agregado un  TransactionProcessor:

public class TransactionProcessor
{
    private Trie<AccountState> states;

    public TransactionProcessor(Trie<AccountState> states)
    {
        this.states = states;
    }

    public Trie<AccountState> States { get { return this.states; } }

    public bool ExecuteTransaction(Transaction transaction)
    {
        var states = this.states;

        try
        {
            foreach (var av in transaction.Inputs)
            {
                var addr = av.Address.ToString();
                var state = states.Get(addr);
                var newstate = state.SubtractFromBalance(av.Value);
                states = states.Put(addr, newstate);
            }

            foreach (var av in transaction.Outputs)
            {
                var addr = av.Address.ToString();
                var state = states.Get(addr);
                var newstate = state.AddToBalance(av.Value);
                states = states.Put(addr, newstate);
            }

            this.states = states;

            return true;
        }
        catch (Exception ex)
        {
            return false;
        }
    }
}

Que parte de un estado de cuentas y va construyedo otro. Si la transacción es procesado, un nuevo trie es generado, y ExecuteTransaction retorna true. Si la transacción es rechazada (la causa podría ser que al aplicarla resulte un saldo negativo), el trie inicial se mantiene. Un test típico que escribí:

[TestMethod]
public void ExecuteTransaction()
{
    var transaction = CreateTransaction(100);

    var addr1 = transaction.Inputs.First().Address;
    var addr2 = transaction.Outputs.First().Address;

    var states = new Trie<AccountState>(new AccountState(BigInteger.Zero));

    states = states.Put(addr1.ToString(), new AccountState(new BigInteger(200)));

    var processor = new TransactionProcessor(states);

    Assert.IsTrue(processor.ExecuteTransaction(transaction));

    var newstates = processor.States;

    Assert.IsNotNull(newstates);
    Assert.AreNotSame(states, newstates);

    Assert.AreEqual(new BigInteger(200), states.Get(addr1.ToString()).Balance);
    Assert.AreEqual(BigInteger.Zero, states.Get(addr2.ToString()).Balance);

    Assert.AreEqual(new BigInteger(100), newstates.Get(addr1.ToString()).Balance);
    Assert.AreEqual(new BigInteger(100), newstates.Get(addr2.ToString()).Balance);
}

El método auxiliar CreateTransaction crea una transacción con un monton, y dos direcciones creadas al azar.

Estoy pensando en tener solamente una cuenta sender y una cuenta receiver por transacción, como en Ethereum. De hecho, ya ayer lo reimplementé así, haciendo rediseño y refactor, ayudado por toda la batería de tests que ya me daba TDD. El cambio fue fácil y apenas tomó unos minutos.

Próximos temas: ejecutar bloques con transacciones, guardar el estado resultante en un almacén persistente, implementación de la máquina virtual y su ejecución de bytecodes, el compilador simple que armé, etc…

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Posted in Bitcoin, Blockchain, C#, Ethereum, Proyectos Open Source, Test-Driven Development | Leave a comment

Armando una Blockchain (5)

Anterior Post
Siguiente Post

En esta semana pasada estuve trabajando bastante en mi proyecto personal:

https://github.com/ajlopez/BlockchainSharp

implementando una blockchain en C#, usando como es habitual el flujo de trabajo de TDD (Test-Driven Development). Un elemento que necesito implementar es el almacenamiento (store) de los estados de cuentas (en principio, voy a guardar sus balances). El balance de una cuenta debe poder ser recuperado por el id de la cuenta (un hash). Pero en muchos casos de uso, necesito conocer los balances de algunas cuentas a UN INSTANTE dado de tiempo. No es suficiente tener los balances de las cuentas al tiempo actual, solamente. Para cumplir con esos casos de uso, implementé un trie pero inmutable.

Un trie es un árbol donde los nodos no terminales almacenan parte de la clave:

En el ejemplo de la figura de arriba, el valor V1 está asociado con la clave AAA, y el valor V5 está asociado con la clave ACA. CUando cambio el valor asociado con la clave ABC desde V4 a V7, entonces, un nuevo trie es creado, manteniéndose el anterior sin modificarlo:

Puedo acceder el par original clave/valor usando a partir de la “vieja raíz” del trie, y cuando necesito valores más actuales, cambio a usar la “nueva raíz” del nuevo trie. Si algún nodo o porción del árbol queda inalcanzable, el recolector de basura liberará la memoria asociada.

La implementación del trie que tengo ahora es simple, y está basada en haber escrito los test e implementado el código que hace que los test pases. Un ejemplo de test:

[TestMethod]
public void PutAndGetKeyValue()
{
    Trie<string> trie = new Trie<string>();

    var trie2 = trie.Put("012", "foo");

    Assert.IsNotNull(trie2);
    Assert.AreNotSame(trie2, trie);
    Assert.IsNull(trie.Get("012"));
    Assert.AreEqual("foo", trie2.Get("012"));
}

Otro ejemplo que muestra que los tries mantienen sus valores, aún cuando se crean nuevos tries en cada actualización:

[TestMethod]
public void ReplaceValue()
{
    Trie<string> trie = new Trie<string>();

    var trie2 = trie.Put("012", "foo");
    var trie3 = trie2.Put("012", "bar");

    Assert.IsNotNull(trie2);
    Assert.AreNotSame(trie2, trie);
    Assert.IsNull(trie.Get("012"));
    Assert.AreEqual("foo", trie2.Get("012"));

    Assert.IsNotNull(trie3);
    Assert.AreNotSame(trie3, trie2);
    Assert.AreEqual("bar", trie3.Get("012"));
}

Mi idea es usar Trie<AccountState> como un almacén de los estados de cuenta. Al final del proceso de cada bloque y de cada transacción, habrá un trie de estado de cuentas. Y al final del siguiente bloque, habrá otro trie, con los balances actualizados. En cualquier momento, puedo recuperar los estados de las cuentas al final de bloque 1, o al final del bloque 2, partiendo de los respectivos tries.

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Posted in Bitcoin, Blockchain, C#, Ethereum, Proyectos Open Source, Test-Driven Development | Leave a comment

Armando una Blockchain (4)

Anterior Post
Siguiente Post

En este post quiero describir algunas de las partes esenciales a implementar en el ejemplo de blockchain que estoy escribiendo en:

https://github.com/ajlopez/BlockchainSharp

usando C# y TDD (Test-Driven Development). Lo principal a implementar son:

– Bloques
– Transacciones

y los conceptos de:

– Cuenta
– Estado de Cuenta
– Smart Contracts (ejecutados en una máquina virtual)

He decidido usar Cuenta y Saldo, a la Ethereum, en vez de usar los UTXO (Unspent Transactions Output) de Bitcoin. Ver un buen post sobre la diferencia en Thoughts on UTXOs by Vitalik Buterin, Co-Founder of Ethereum.

Además, necesito utilitarios para:

– Codificar/Decodificar entidades a ser transmitidas/recibidas entre los nodos (he decidido usar arreglos de bytes para transmitir, bien podría, en otra implementación, por ejemplo, JavaScript pero aún en ésta de C#, usar simples JSONs).
– Calcular Hashes
– Implementar Tries immutables (algo hay ya de código en el proyecto)
– Firmar transacciones y verificar la firma
– Verificar la integridad del bloque
– Verificar que las transacciones son válidas (p.ej. que las cuentas que envían valores tienen saldo suficiente)
– Cálculo de Proof of Work en los mineros, como es usual en las implementaciones de Bitcoin y Ethereum.
– Almacenar algunas entidades: bloques completos, bloques parciales (Ethereum usa Block Header), estado de cuenta (saldo…), en general usar tries inmutables con algún soporte fuera de memoria.

Hace unos días, comencé a escribir una clase Transaction, que tiene cuentas y valores. Cada cuenta es identificada por una dirección (actualmente un string hexadecimal aleatorio):

Cada transacción tiene uno o más entradas y salidas. Cada entrada/salida es una dirección y un valor. Los valores son instancias de System.Numerics.BigInteger, así puedo manejar grandes cantidades de unidades pequeñas. En el mundo de las criptomonedas es usual el uso de valores enteros que expresan fracciones mínimas..

Próximos pasos: agregar transacciones a los bloques, aplicar transacciones a los estados de cuenta, validar que los valores estén disponibles, almacenar los estados resultantes en tries, etc,…

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Posted in Bitcoin, Blockchain, C#, Ethereum, Proyectos Open Source | Leave a comment

Resoluciones del Nuevo Mes: Abril 2016

Un nuevo mes comienza, ya vamos adentrándonos en el año, y es tiempo de escribir las nuevas resoluciones mensuales. Y tiempo de revisar las del mes pasado:

– Mejorar AjGenesisNode-Express [pendiente]
– Trabajar en CrysJS [completo] ver repo
– Trabajar en CrysSharp [pendiente]
– Mejorar mis ejemplos de SimpleGA [pendiente
– Trabajar en SharpGo [pendiente]
– Trabajar en EthSharp [completo] ver repo

También trabajé en:

– Mejorar SimpleForth en JavaScript [completo] ver repo
– Comenzar WangTiles en C# [completo] ver repo
– Publicar una nueva versión de SimpleArgs [completo] ver repo
– Comenzar BlockchainSharp en C# [completo] ver repo
– Mejorar los ejemplos de SimpleDT [completo] ver repo
– Mover AjGo a GitHub [completo] ver repo
– Mejorar RuScript [completo] ver repo
– Agregar Code Coverate a ethereumjs rlp [complete] ver repo
– Dar una nueva charla sobre Machine Learning en JavaScript [completo] ver repo ver charla

Mis nuevas resoluciones:

– Mejorar WangTiles
– Mejorar BlockchainSharp
– Comenzar Blockchain en JavaScript
– Trabajar en EthSharp
– Mejorar SimpleGA
– Mejorar AjGenesisNode-Express
– Trabajar on CrysJS
– Trabajar en CrysSharp

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Posted in Uncategorized | Leave a comment

Armando una Blockchain (3)

Anterior post
Siguiente post

Agregué bastante código en estos días a mi simple implementación de una blockchain, escrita en C#:

https://github.com/ajlopez/BlockchainSharp

Como es usual, seguí el flujo de trabajo de TDD (Test-Driven Development), persiguiendo también la simplicidad en cada paso, haciendo baby steps, avanzando de a poco pero firme. En el anterior post mencioné el uso de un DSL (Domain Specific Language) para especificar algunos procesos de bloques que tienen un preparado (setup) largo.

Inicialmente, escribí test como:

[TestMethod]
public void ProcessTwoBlocksAndTwoUncles()
{
    Block genesis = new Block(0, null);
    Block block = new Block(1, genesis.Hash);
    Block uncle1 = new Block(1, genesis.Hash);
    Block uncle2 = new Block(2, uncle1.Hash);

    BlockProcessor processor = new BlockProcessor();

    processor.Process(genesis);
    processor.Process(block);
    processor.Process(uncle1);
    processor.Process(uncle2);

    Assert.IsNotNull(processor.BlockChain);
    Assert.AreEqual(2, processor.BlockChain.BestBlockNumber);
    Assert.AreEqual(genesis, processor.BlockChain.GetBlock(0));
    Assert.AreEqual(uncle1, processor.BlockChain.GetBlock(1));
    Assert.AreEqual(uncle2, processor.BlockChain.GetBlock(2));
}

La idea es:

– Crear algunos bloques
– Enviar los bloques al procesador de bloques
– Revisar los bloques que entonces quedaron en la blockchain

Los bloques creados están vinculados por relaciones de padre-hijo. Algunas veces, un bloque competitivo es creado, y el procesador de bloques debe manejar la existencia de ramas alternativas, que compiten por llegar a ser la nueva blockchain.

El preparado, setup del código puede ser largo. Así que en unos minutos pude escribir un DSL que me permite escribir tests como:

[TestMethod]
public void SendTwoBlocksAndTwoUncles()
{
    var processor = new BlockProcessor();
    var dsl = new BlockProcessorDsl(processor);

    dsl.Run(new string[] 
    {
        "chain g0 b1 b2",
        "chain b1 c2 c3",
        "send b1 b2",
        "send c2 c3",
        "top c3"
    });
}

Cada comando del DSL es un texto, con verbo y argumentos. El bloque g0 es el bloque génesis. El verbo “chain” enumera una lista de bloques a ser creados, cada uno es bloque hijo del anterior. El verbo “send” envía los bloques creados en memoria al procesador de bloques. El verbo “top” verifica que el bloque especificado sea el mejor de la blockchain actual.

El resultado no debe depender del orden de llegada de los bloques, por ejemplo:

[TestMethod]
public void SendTwoBlocksInReversedOrder()
{
    var processor = new BlockProcessor();
    var dsl = new BlockProcessorDsl(processor);

    dsl.Run(new string[] 
    {
        "chain g0 b1 b2",
        "send b2 b1",
        "top b2"
    });
}

Podría agregar texto en archivos, cada uno representado un test, y ejecutarlos todos desde código. Por ahora, sigo con estos tests explícitos en código.

En los próximos posts: las implementaciones esenciales del problema (bloque, transacción, estado…) que son necesarios para armar  una block chain, serialización (a bytes), e implementaciones como tries inmutables para almacenar los estados mutables.

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Posted in Bitcoin, Blockchain, C#, Ethereum, Proyectos Open Source, Test-Driven Development | Leave a comment

Armando una Blockchain (2)

Anterior Post
Siguiente Post

En los días pasados, escribí una primera implementación de una blockchain, usando TDD (Test-Driven Development). Las decisiones que tomé fueron guiadas por la simplicidad: la blockchain reside en memoria, y los bloques se identifican por un número y un hash. Dos bloques que tengan el número 42 son diferentes si tienen diferentes hashes. Un bloque contiene también el hash del bloque padre (el número del padre no hace falta tenerlo, es el número del bloque hijo menos uno). El bloque génesis (el primer bloque) tiene número 0, y como hash padre tiene null. De esta manera simple, tengo todos los ingredientes para ir armando una blockchain, desde el bloque génesis en adelante, encadenando los bloques usando sus números y hashes.

Tengo una clase BlockChain (sí, prefiero usar mayúscula en la c). Hay un método para agregar un bloque, que puede devolver verdadero o falso. Sólo admite el bloque si su padre es el último bloque de la blockchain, controlando tanto número como hash esperado.

Pero existen otros nodos activos que envían otros bloques, que pueden ser agregados o no a la blockchain. ¿Cómo procesar esos bloques? Los bloques que no puedo agregar en la blockchain los agrego en otras cadenas alternativas, que llamé blockbranch:

En la segunda blockbranch de la figura, el bloque padre de su bloque 41 es todavía desconocido. Pero si llega ese bloque está todo listo para agregarlo al principio de la blockbranch. La primera blockbranch de la figura está ya conectada con la blockchain principal, compartiendo el bloque 40. Esa blockbranch no es blockchain porque tiene menos bloques que la principal. Ese es el algoritmo que elegí para decidir cuál es la blockchain: la cadena más larga obtenida, que comience desde el génesis.

Una blockbranch tienen uno o más bloques consecutivos. Esos bloques no forman parte de la blockchain actual. Pero una blockbranch puede unirse a un bloque de la blockchain o también de otra blockbranh, formando un árbol incipiente. Cada blockbranch es una proto-blockchain.

Cuando tengo suficientes bloques en una blockbranch, llegando a conectarse a otra que llegue hasta el bloque génesis, entonces esa rama es candidata a ser una blockchain. Supongamos que un nuevo bloque arriva al sistema:

El nuevo bloque es el padre del bloque 41 de la segunda blockbranch. Y resulta que su padre, un bloque 39, también es un bloque conocido, esta vez está en la blockchain principal. Entonces ahora, la segunda blockbranch ha llegado a completar una cadena de bloques desde el bloque génesis, hasta un bloque 43.

Si la rama de bloques es válida (si al aplicar los bloques al estado del final del bloque 39, se obtienen nuevos estados válidos, por ejemplo, si fuera una blockchain de criptomonedas: que en los nuevos bloques no hubiera transferencias inválidas), entonces la rama de bloques es válida. Si además, es más alta (tiene más bloques) que la blockchain principal, entonces la desplaza, y es promovida a ser blockchain, quedando:

El proceso de agregar bloques de esta manera, funciona aunque los bloques lleguen en orden diferente. Para manejar el crecimiento de la blockchain, y el formado y vigilancia de las blockbranches, y su promoción a mejor blockchain, tengo un objeto separado que llamé BlockProcessor, a cargo de toda esta orquestación. El procesador recibe nuevos bloques, y de a uno los va agregando a la blockchain, a una blockbranch, o a veces los rechaza (por ejemplo, cuando viene un bloque repetido que ya haya procesado; esto puede pasar, en el sistema final los bloques vienen de la red, y un mismo bloque puede ser enviado a nosotros desde distintos nodos). Puede detectar conexiones entre ramas y la cadena principal, y puede detectar la promoción de ramas a cadenas completas.

En el próximo post: detalles de un DSL (Domain Specific Language) que armé para diferentes escenarios de un block processor.

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Posted in Bitcoin, Blockchain, C#, Ethereum, Proyectos Open Source, Test-Driven Development | Leave a comment

Armando una Blockchain (1)

Siguiente Post

El mes pasado, febrero 2016, comencé a trabajar en el equipo de desarrollo de Rootstock, en un proyecto muy interesante que tiene “smart contracts” en una “blockchain” distribuida. En las semanas que pasaron, estudié las ideas e implementaciones de  Bitcoin, Ethereum, y criptomonedas. Estuve leyendo varios “papers”, libros, artículos y código. Mis enlaces:

http://delicious.com/ajlopez/bitcoin
http://delicious.com/ajlopez/ethereum
http://delicious.com/ajlopez/blockchain

Quisiera describir los elementos esenciales de una blockchain distribuida, y su importancia. Espero ir escribiendo código implementando estas ideas, de una manera simple, para captar el núcleo de estas implementaciones.

Una blockchain es una lista de bloques, comenzando por el primero, llamado bloque génesis:

Cada bloque tiene información. En las implementaciones de criptomonedas, se suele llamar a esa información, transacciones:

Una transacción describe, en esos dominios, una transferenca de criptomoneda, llámese bitcoin, ether o como quieran. Pero la esencia de la transacción es información que describe el cambio del estado del mundo. Por ejemplo, en Ethereum, el estado del mundo incluye el saldo actual de cada cuenta en el sistema. Una transferencia altera ese estado.

Hay un estado inicial luego de la aparición del bloque génesis, y luego, cada bloque, conteniendo cero o más transacciones, va alterando ese estado (usualmente un bloque también tiene una transacción de finalización del bloque, implícita):

Las transacciones deben ser válidas: no se permiten transacciones que transformen el estado del mundo de forma incorrecta. Un ejemplo de transacción inválida: aquella que saca fondos de una cuenta inexistente, o de una cuenta que no tiene el suficiente saldo.

El sistema no se ejecuta en un solo servidor, sino en una red de máquinas independientes, llamadas nodos, que corren lo que se llama el software cliente (este denominación, “cliente”, para mí es algo confusa, porque parece como que hay software servidor; pero no, los nodos son clientes de otros nodos).

Los nodos están conectados con algunos de los otros, no necesariamente con todos. Una red puede estar compuesta por cientos o miles de nodos conectados de esta manera.

Cuando una nueva transacción es ingresada al sistema (generalmente por la operación de algún usuario que quiere hacer un pago), esa transferencia es inyectada a un nodo, y éste se encarga de transmitirla a los demás nodos de la red, en principio a sus vecinos, pero éstos a su vez se encargarn de retransmitir la nueva transacción:

Algunos nodos especializados, teniendo todos los recursos para validad y ejecutar transacciones, agrupan a éstas en un bloque, que puede contener cero o más transacciones. En sistemas como Bitcoin hay incentivos económicos para que estos nodos generen nuevos bloques. Estos nodos especializados se llaman mineros. Y en Bitcoin y otros sistemas, ganan criptomoneda por minar nuevos bloques y por “fees” de las transacciones que colocan en un bloque.

Cuando un minero, digamos N2, produce un nuevo bloque, lo envía a sus nodos vecino, y eventualmente el bloque se reparte entre todos los nodos de la red:

Muchos nodos mantienen la blockchain completa, y al recibir un nuevo bloque, lo agregan a esa blockchain, siempre y cuando el bloque sea válido, y tenga un número inmediato al mejor bloque de la blockchain actual. A veces, a un nodo llegan varios bloques diferentes que compiten por agregarse a la blockchain:

Y hasta puede suceder que otra parte de la red tenga una blockchain diferente de la que tengan otros nodos:

En estos cosos, hay un algoritmo para alcanzar el consenso. Cuando el consenso se alcanza, la blockchain termina siendo la misma, y distribuida como copias en los nodos que alcanzaron el consenso. Eso es lo que hace que la blockchain se mantenga consistente y distribuida.

Hay varios detalles para discutir:

– ¿Cuándo un bloque es válido?
– ¿Cuándo una transacción es válida?
– ¿Cómo generar una transacción? Por ejemplo, en sistemas como Bitcoin, no cualquiera puede transferir fondos, sólos los dueños de las cuentas de donde salen los fondos. Hay que asegurarse que no cualquiera pueda transferir valores
– En caso de bloques y cadenas competidoras ¿cómo conseguir el consenso distribuido?
– ¿Cómo almacenar la blockchain en cada nodo?
– ¿Cómo almacenar el estado luego de la ejecución de las transacciones?
– ¿Cómo se descubren los nodos entre sí? ¿Cómo se transmite la información?

Quiero agregar código de ejemplo, con lo mínimo y esencial. Estoy escribiendo una librería en C#, usando  TDD (Test-Driven Development):

https://github.com/ajlopez/BlockchainSharp

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Posted in Bitcoin, Blockchain, C, C#, Ethereum, Proyectos Open Source | Leave a comment

Resoluciones del Nuevo Mes: Marzo 2016

Un nuevo mes comienza, tiempo de escribir las nuevas resoluciones. Pero primero, a revisar las del mes anterior.

– Mejorar AjGenesisNode-Express [pendiente]
– Trabajar en CrysJS [completo] ver repo
– Trabajar en CrysSharp [pendiente]
– Trabajar en Memolap [pendiente]
– Trabajar en SimpleMemolap [pendiente]
– Mejorar mis ejemplos de SimpleGA [pendiente]
– Mejorar SharpGo [completo] ver repo
– Mejorar Husky [pendiente]
– Trabajar en GoLin [pendiente]
– Mejorar ImmuO [completo] ver repo
– Más ejemplos de ReactJS [pendiente]
– Mejorar Aktores [pendiente]
– Mejorar ErlSharp [pendiente]

Fue un mes agitado, con cambio de trabajo profesional. Ahora estoy trabajando en un proyecto muy interesante relacionado con el proyecto Ethereum. Adicionalmente, estuve trabajando en:

– Mejorar RuScript [completo] ver repo
– Comenzar EthSharp, un nodo tipo Ethereum en C# [completo] ver repo
– Comenzar EthSharpVm, una máquina virtual Ethereum, implementada en C# [completo] ver repo
– Mejorar ElixirJS [completo] ver repo
– Mejorar SimpleForth [completo] ver repo
– Comenzar CrLisp [completo] ver repo

Mis nuevas resoluciones:

– Mejorar AjGenesisNode-Express
– Trabajar en CrysJS
– Trabajar en CrysSharp
– Mejorar mis ejemplos de SimpleGA
– Trabajar en SharpGo
– Trabajar en EthSharp

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Posted in C#, JavaScript, NodeJs, Proyectos Open Source | Leave a comment

Resoluciones del Nuevo Mes: Febrero 2016

De nuevo es tiempo de escribir las nuevas resoluciones, primero repaso de las de enero:

– Trabajar en mejorar los ejemplos de trader de SimpleGA [pendiente]
– Trabajar en SimpleDatabase [pendiente]
– Trabajar en SimpleMemolap [completo] ver repo
– Trabajar en Memolap [completo] ver repo
– Mejorar AjGenesisNode [pendiente]
– Mejorar SharpGo [completo] ver repo
– Mejorar Husky [completo] ver repo
– Trabajar en GoLin [completo] ver repo

También estuve trabajando en:

– Crear SRedux, una librería similar a Redux [completo] ver repo
– Crear ImmuO, objetos immutables en JavaScript [completo] ver repo
– Comenzar CrysSharp, lenguaje de programación Crystal implementando en C# [completo] ver repo
– Comenzar CrysJS, lenguaje de programación Crystal implementado JavaScript [completo] ver repo
– Agregar ejemplos ReactJS a los ejemplos de JavaScript [completo] ver repo
– Mejorar ElixirJS [completo] ver repo
– Crear ReduMan, manejador de reducers en JavaScript [completo] ver repo
– Crear RkStreams, streams reactivos en JavaScript [completo] ver repo

Mis nuevas resoluciones:

– Mejorar AjGenesisNode-Express
– Trabajar en CrysJS
– Trabajar en CrysSharp
– Trabajar en Memolap
– Trabajar en SimpleMemolap
– Mejorar mis ejemplos de SimpleGA
– Mejorar SharpGo
– Mejorar Husky
– Trabajar en GoLin
– Mejorar ImmuO
– Más ejemplos ReactJS
– Mejorar Aktores
– Mejorar ErlSharp

Me diviegto como logco 😉

Nos leemos!

Angel “Java” Lopez
@ajlopez

Posted in C#, JavaScript, NodeJs, Proyectos Open Source | Leave a comment

RkStreams, streams reactivos en JavaScript/NodeJS (1)

Esta vez no tengo un caso de uso concreto, pero es algo que es interesante de implementar usando simplicity pays, baby steps, y el flujo de trabajo de TDD (Test-Driven Development). No son como los streams nativos de NodeJS. En este proyecto:

https://github.com/ajlopez/RkStreams

Un stream es como un canal, por el que entran y salen simples objetos/valores JavaScript. Debe ser parecido a algunos conceptos de Redux (pero sin manejo de estado inmutable) y se debe parecer a los mailboxes del lenguaje Elm.

Lo interesante que la funcionalidad que logré implementar hasta ahora sale muy simple usando TDD. Es un buen ejercicio, y pueden ver siempre el historial de commits para ver cómo el proyecto va creciendo en capacidades de a poco, como respuesta a un nuevo test que se plantea, de pasar de “rojo” a “verde”.

Veamos un primer test, crear y usar un stream:

var rks = require('..');

exports['create and use stream'] = function (test) {
    test.async();
    
    var stream = rks.stream();
    
    stream.process(function (data) {
        test.ok(data);
        test.equal(data, 1);
        test.done();
    });
    
    stream.post(1);
};

Como es usual en mis proyectos, no expongo una “clase” de JavaScript, sino un método factoría .stream(). Luego el .post() permite enviar un objeto por el stream. Y el .process() permite tener funciones digamos subscriptoras, que procesan cada mensaje que llegue al stream. Esto permite separar la generación de eventos/objetos, de su proceso.

Pero los streams también puede producir otros streams. Un ejemplo clásico es transformar los objetos, con un .map(), que construye un nuevo stream:

exports['map stream'] = function (test) {
    test.async();
    
    var counter = 0;
    
    var stream = rks.stream();
    
    stream.map(function (x) { return x * 2; }).process(function (data) {
        counter++;
        
        test.ok(data);
        test.equal(data, counter * 2);
        
        if (data === 6)
            test.done();
    });
    
    stream.post(1);
    stream.post(2);
    stream.post(3);
};

O también podemos unir dos streams, con .merge(), de nuevo, devuelve un nuevo stream:

exports['post three messages to streams and merge'] = function (test) {
    test.async();
    
    var counter = 0;
    
    var stream1 = rks.stream();
    var stream2 = rks.stream();
    
    stream1.merge(stream2)
        .process(function (data) {
        counter++;
        
        test.ok(data);
        test.equal(data, counter);
        
        if (data === 3)
            test.done();
    });
    
    stream1.post(1);
    stream2.post(2);
    stream1.post(3);
};


O podemos crear un nuevo stream que sólo emita los objetos que cumplan con un predicado, usando .filter():

exports['filter stream'] = function (test) {
    test.async();
    
    var stream = rks.stream();
    
    stream
        .filter(function (x) { return x % 2 === 0})
        .filter(function (x) { return x % 5 === 0})
        .process(function (data) {
            test.ok(data);
            test.equal(data, 10);
            test.done();
        });
    
    for (var k = 1; k <= 10; k++)
        stream.post(k);
};

Tengo pendiente decidir el tratamiento de las excepciones en los filtros, mapeos y procesos. También quiero implementar un .branch() que permite que un stream se alimente de otro.

En próximos posts: esas nuevas funcionalidades, .process() selectivo, y ver cómo va quedando por dentro la implementación (a hoy, son unas pocas líneas de código).

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Posted in JavaScript, NodeJs, Programación Funcional, Programación Reactiva, RkStreams, Test-Driven Development | Comments Off on RkStreams, streams reactivos en JavaScript/NodeJS (1)