Armando una Blockchain (3)

Published on Author lopezLeave a comment

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

Leave a Reply

Your email address will not be published. Required fields are marked *