Archive for the 'Proyectos Open Source' Category

Ejecutando un Nodo Ethereum/RSK

Monday, June 12th, 2017

La testnet pública de RSK fue lanzada, y el código principal fue abierto. Si no conoce a RSK, visitar:

http://rsk.co/

Técnicamente, es un fork de Ethereum, de la versión Java, con un 2-way peg contra Bitcoin, y con capacidades de merge-mining. Pueden correr su propio nodo, en solitario, o en su propia red, o pueden ejecutar nodos uniéndose a la testnet pública. Hay instrucciones de como hacerlo en el wiki del proyecto:

https://github.com/rsksmart/rskj/wiki

En este post, quiero describir mi flujo de trabajo para compilar, configurar y ejecutar un nodo, pudiendo así hacer experimentos, probar ideas de implementación distintas (nota: actualmente soy miembro del equipo de desarrollo de RSK, pero esta descripción en este posts, es una descripción personal de lo que uso). Primero, bajarse el código fuente de:

https://github.com/rsksmart/rskj

Actualmente, la versión que se usa en testnet, está en el branch Ginger:

https://github.com/rsksmart/rskj/tree/ginger

También pueden clonarse el repositorio y modificarlo en el suyo propio. Para compilar, se puede usar el IntelliJ Idea Community edition, o usar el comando de línea:

.\gradlew build shadow -x testnet

(usualmente trabajo con Windows; en Linux, Max, cambiar la barra invertida por la barra normal /). Más detalles en:

https://github.com/rsksmart/rskj/wiki/Compile-and-run-a-RSK-node-locally

La opción shadow es para armar un archivo jar que tenga todas las dependencias. La opción –x test permite saltear la ejecución de los tests durante la tarea de build. El comando genera un archivo jar en un subdirectorio. Ejecutar:


cd rskj-core\build\libs
java -Drsk.conf.file=<path> -cp rskj-core-0.2.0-GINGER-all.jar co.rsk.Start

Eso lanza al nodo. ¿Cuál es el archivo de configuración a usar? Más info en:

https://github.com/rsksmart/rskj/wiki/How-to-initialize-RSK-node-configuration-file-settings

Hay un archivo de configuración de ejemplo en:

https://github.com/rsksmart/rskj/blob/master/rskj-core/src/main/resources/config/rsk-sample.conf

Una de las cosas que hay que hacer, es que cada instancia de nodo que queremos lanzar tenga su id de nodo. Para generar el id de nodo y una clave privada asociada, ejecutar primero el comando de línea:


java -cp rskj-core-0.2.0-GINGER-all.jar co.rsk.GenNodeKeyId

Vuelva un JSON en consola. Hay que copiar de los datos que vuelta, la clave privada en el archivo de configuración, y opcionalmente, el id de nodo:


# Private key of the peer
nodeId = 66cf57...
privateKey = 46f850...

Sólo es mandatorio el privateKey para ejecutar el nodo, pero puede copiar el id de nodo para mantener una referencia. La otra línea a definir es el llamado secreto coinbase:


# this string is computed
# to be eventually the address
# that get the miner reward
coinbase.secret = mytreasure

Puede poner una palabra arbitraria.

Para permitir el CORS (Cross-Origin Resource Sharing) para exponer el estado del nodo por JSON RPC (Remote Procedure Call), hay que modificar la propiedad cors:


rpc {
enabled = true # you can disable rpc
port = 4444

cors = "*.rsk.co" # you can put "localhost here"

La capacidad de RPC es solamente usada para consultar al nodo, y enviar transferencias desde un cliente, pero desabilitarla no interfiere con el proceso normal del nodo. ¿Cómo hacemos que el nodo se conecte a la red testnet pública? Hay definidos nodos de bootstrap:


peer {
discovery = {
# if peer discovery is off
# the peer window will show
# only what retrieved by active
# peer [true/false]
enabled = true
# List of the peers to start
# the search of the online peers
# values: [ip:port]
ip.list = [
"bootstrap01.testnet.rsk.co:50505",
"bootstrap02.testnet.rsk.co:50505",
"bootstrap03.testnet.rsk.co:50505",
"bootstrap04.testnet.rsk.co:50505"
]

para usar como puntos de partida en lo que se llama el proceso de descubrimiento de pares, peer discovery. Se puede desabilitar, por ejemplo, si quiere usar el nodo para su propia red, o quiere poner en otro lugar de la configuración (ver más abajo) a qué nodos explícitos quiere conectarse al principio.

Si quiere ejecutar VARIOS nodos locales, debe tener entonces VARIOS archivos de configuración. En estos archivos, ajustar las propiedas siguientes, para que los nodos no se pisen entre sí:

# Peer for server to listen for incoming connections
# 50505 for testnet
listen.port = 50505 # ie to 50506

y también la ya mencionada:


rpc {
enabled = true
port = 4444 # ie to 4445

También, cambiar el directorio de database, donde cada nodo graba los bloques, el estado, etc, sus datos de funcionamiento en archivos. Adicionalmente, pueden poner su propio id de red, para que sus nodos sólo se entiendan entre ellos:


# Network id
networkId = 777 # ie to 42

También puede especificar directamente a qué nodos conectarse. Debe conocer entonces la IP o nombre de máquina, el port del otro nodo, y el id: el otro nodo no aceptará conexiones de quien no conozca su id de nodo:


# Boot node list
# Use to connect to specific nodes
active = [
#{
# ip = 11.22.33.44
# port = 50505
# nodeId = e437a483...
#}
]

En el ejemplo, la propiedad ip está puesta con números, pero puede ponerse el nombre de máquina directamente.

Si quieren que su nodo mine bloques, pueden cambiar estas propiedades a verdadero:


# miner options
miner {
server.enabled = false # change to true
client.enabled = false # change to true

Si sólo cambia la propiedad server.enabled a verdadero, dejando client.enabled en false, podrá minar apoyándose en merge mining con software y hardware de minería, pero esa característica está más allá del alcance de este post.

¿Alguna duda? Siempre pueden visitar, preguntar o comentar en el canal de gitter de RSK Java:

https://gitter.im/rsksmart/rskj

Interesados? RSK busca desarrolladores, ver los tweets:

https://twitter.com/RSKsmart/status/872169805515718657


Nos leemos!

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

Resoluciones del Nuevo Mes: Junio 2017

Wednesday, June 7th, 2017

Un nuevo mes comienza, y es tiempo de escribir las resoluciones mensuales. Como siempre, primero un repaso de las del mes anterior:

– Continuar RskSharp [pendiente]
– Continuar SimpleBlockchain [completo] ver repo
– Continuar BlockchainSharp [pendiente]
– Continuar ChineseP [pendiente]
– Continuar TensorSharp [pendiente]
– Continuar RSharp [completo] ver repo

I also worked on:

– Mejorar AjDrawJS [completo] ver repo
– Mejorar AjTalkJS [completo] ver repo
– Mejorar SimpleForth [completo] ver repo
– Mejorar ClojJS Clojure in JavaScript [completo] ver repo
– Ejemplo adicional para SimpleGA, algoritmos genéticos [completo] ver repo
– Experimentos con RSKJ fork [completo] ver repo
– Creaar wordie, lenguaje de programación en inglés [completo] ver repo
– Creaar domie, un DOM para tests en JavaScript [completo] ver repo
– Crear vyu, un framework a la vue.js [completo] ver repo

Mis nuevas resoluciones:

– Continuar RskSharp
– Continuar SimpleBlockchain
– Continuar BlockchainSharp
– Continuar ChineseP
– Continuar TensorSharp
– Continuar RSharp
– Experimentar con RSKJ fork
– Continuar Vyu
– Continuar Domie
– Continuar Wordie

Nos leemos!

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

Lanzando la TestNet RSK

Tuesday, May 23rd, 2017

El proyecto arrancó en 2015, y yo estoy participando en el equipo de desarrollo desde hace algo más de un año. Ayer se lanzó la TestNet pública, en medio de la conferencia Consensus 2017:

http://www.coindesk.com/events/consensus-2017/

Ver instrucciones para participar en la prueba:

https://github.com/rsksmart/rskj/wiki

El repositorio de código principal en:

https://github.com/rsksmart/rskj

Pueden observar el estado de la testnet en:

http://stats.rsk.co/

El gran tema del proyecto es correr una red Ethereum, pero separada, que permita la ejecución de “smart contracts”, usando bitcoins, transferidos a cuentas de la red RSK. Un usuario que tenga bitcoins puede transferir ese valor a la red RSK para que pueda aplicarlos en la ejecución de “smart contracts”.

Si el mundo de contratos inteligentes es nuevo para Uds., comenzar estudiando:

https://www.ethereum.org/

Si quieren saber cómo programar una blockchain (usando TDD por supuesto 🙂 estoy escribiendo en:

http://blogs.msmvps.com/lopez/category/blockchain/

Espero poder escribir más en detalle sobre las ideas de este proyecto.

Nos leemos!

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

Resoluciones del Nuevo Mes: Mayo 2017

Tuesday, May 9th, 2017

Como pasa el año, tiempo de escribir las nuevas resoluciones, veamos el resultado de las anteriores:

– Continuar RskSharp [completo] ver repo
– Continuar SimpleBlockchain [completo] ver repo
– Continuar Solidity Compiler [pendiente]
– Continuar ChineseP [completo] ver repo
– Continuar TensorSharp [completo] ver repo
– Continuar RSharp [completo] ver repo
– Continuar SimpleForth [pendiente]

Además, estuve trabajando en:

– Continuar BlockchainSharp [completo] ver repo
– Comenzar Neurum, redes neuronales en C# [completo] ver repo
– Comenzar AjTalkJS, intérprete Smalltalk en JavaScript [completo] ver repo
– Comenzar SimpleProlog, intérprete Prolog en JavaScript [completo] ver repo
– Comenzar AjDrawJS [completo] ver repo

Resoluciones del nuevo mes:

– Continuar RskSharp
– Continuar SimpleBlockchain
– Continuar BlockchainSharp
– Continuar ChineseP
– Continuar TensorSharp
– Continuar RSharp

Nos leemos!

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

Resoluciones del Nuevo Mes: Abril 2017

Friday, April 7th, 2017

Un nuevo comienza, ya pasó el verano, estamos en otoño por estos lares. Tiempo de escribir mis resoluciones mensuales, pero primero un repaso de las del mes anterior:

– Continuar RskSharp [complete] ver repo
– Continuar SimpleBlockchain [pending]
– Continuar Solidity Compiler [complete] ver repo
– Continuar ChineseP [pending]
– Continuar TensorSharp [complete] ver repo

Además estuve trabajando en:

– Mejorar SimpleProlog [completo] ver repo
– Continuar RSharp [completo] ver repo
– Mejorar AjDrawJS [completo] ver repo
– Mejorar SimpleForth [completo] ver repo

Mis resoluciones del nuevo mes son:

– Continuar RskSharp
– Continuar SimpleBlockchain
– Continuar Solidity Compiler
– Continuar ChineseP
– Continuar TensorSharp
– Continuar RSharp
– Continuar SimpleForth

Nos leemos!

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

Resoluciones del Nuevo Mes: Marzo 2017

Wednesday, March 8th, 2017

Un nuevo mes comienza y es tiempo de escribir mis resoluciones. Primero, una revisión de las de febrero:

– Mejorar SharpGo [completo] ver repo
– Mejorar BlockchainSharp [pendiente]
– Mejorar SimpleBlockchain [completo] ver repo
– Continuar Solidity Compiler [completo] ver repo
– Continuar ChineseP [pendiente]
– Mejorar ErlSharp [completo] ver repo

Además estuve trabajando en:

– Comenzar RskSharp [completo] ver repo
– Comenzar TensorSharp [completo] ver repo
– Mejorar AjDrawJs [completo] ver repo
– Mejorar SimpleForth [completo] ver repo
– Mejorar CrysSharp [completo] ver repo
– Nuevo ejemplo Bitcoin en SimpleGA [completo] ver repo
– Mejorar Husky, mi intérprete Haskell [completo] ver repo
– Mejorar SimpleLisp [completo] ver repo
– Mejorar CrysJS [completo] ver repo

Mis nuevas resoluciones:

– Continuar RskSharp
– Continuar SimpleBlockchain
– Continuar Solidity Compiler
– Continuar ChineseP
– Continuar TensorSharp

Nos leemos!

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

Muerte a Spring

Tuesday, February 7th, 2017

En el título me refiero al Spring Framework de Java. Pero no se tome al pie de la letra ese título. La idea del post es mostrar que podemos usar mal algo, como una librería, cuando el contexto y los casos de usos no son los adecuados. Muchas veces, como programadores, usamos lo que conocemos, pero no siempre es el camino más adecuado a tomar dado los casos de uso que tenemos entre manos. Es por eso que muchas veces hago énfasis en tener en cuenta los casos de uso y el contexto.

Spring Framework nació en este siglo de la mano de Rod Johnson para poner orden en el desarrollo de un proyecto Java. Una de sus primeras “features” es permitir configurar un grafo de objetos desde un archivo o declaración XML. Eso permitía, hasta en deployment, configurar la conducta de nuestra aplicación, por ejemplo, cambiar el objeto concreto de persistencia, para pasar de usar Oracle a usar otra base de datos. Con el tiempo, esa capacidad de configuración se extendió al uso o no de otros frameworks, por ejemplo, de ORMs como Hibernate.

Pero había que mantener esos archivos XML de configuración. No recuerdo qué framework permitió declarar en atributos la relación entre los objetos, y Spring adoptó con el tiempo esa estrategia también.

Hoy quiero apuntar a código real, de un proyecto de código abierto, que comencé a conocer en @RSKSmart hace un año: la implementación en Java de Ethereum:

https://github.com/ethereum/ethereumj

Es un servidor que ejecuta en una red de servidores similares. implementando una blockchain con smart contracts. Hay implementaciones en otros lenguajes, como Go y Python. Al arrancar, levanta un conjunto de objetos, algunos apuntan a otros, y comienza a funcionar. Pero veamos, como ejemplo, un objeto de los que levanta, el WorldManager:

https://github.com/ethereum/ethereumj/blob/develop/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java

Veamos parte del código inicial:

 @Autowired
private PeerClient activePeer;

@Autowired
private ChannelManager channelManager;

@Autowired
private AdminInfo adminInfo;

@Autowired
private NodeManager nodeManager;

@Autowired
private SyncManager syncManager;

@Autowired
private FastSyncManager fastSyncManager;

@Autowired
private SyncPool pool;

@Autowired
private PendingState pendingState;

@Autowired
private UDPListener discoveryUdpListener;

@Autowired
private EventDispatchThread eventDispatchThread;

@Autowired
private DbFlushManager dbFlushManager;
    
@Autowired
private ApplicationContext ctx;

y además usando @Autowired en el constructor:

@Autowired
public WorldManager(final SystemProperties config, final Repository repository,
                    final EthereumListener listener, final Blockchain blockchain,
                    final BlockStore blockStore) {
    this.listener = listener;
    this.blockchain = blockchain;
    this.repository = repository;
    this.blockStore = blockStore;
    this.config = config;
    loadBlockchain();
}

En total, más de una docena de objetos referenciados y creados al principio de la vida de WorldManager. Además, muchos de esos objetos tienen en su implementación más @Autowired. Prácticamente todos estos objetos terminan siendo “singletons”, creados al y relacionados al principio, y nada más. Pero muchos terminan siendo entonces objetos globales, con un estado mutable, que dificulta muchas veces su uso adecuado. En un objeto podemos tener acceso entonces al objeto “global” K, pero cualquier otro código puede alterar el estado de K mientras lo estamos usando. Es notable ese caso en el uso de BlockchainImpl y de Repository, pero eso daría para tema de otro post.

Veamos también la implementación de la interface Ethereum:

https://github.com/ethereum/ethereumj/blob/develop/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java

Vemos ahí:

@Autowired
WorldManager worldManager;

@Autowired
AdminInfo adminInfo;

@Autowired
ChannelManager channelManager;

@Autowired
ApplicationContext ctx;

@Autowired
BlockLoader blockLoader;

@Autowired
ProgramInvokeFactory programInvokeFactory;

@Autowired
Whisper whisper;

@Autowired
PendingState pendingState;

@Autowired
SyncManager syncManager;

@Autowired
CommonConfig commonConfig = CommonConfig.getDefault();

más objetos referenciados mágicamente con @Autowired. Y de nuevo más en el constructor:

@Autowired
public EthereumImpl(final SystemProperties config, final CompositeEthereumListener compositeEthereumListener) {
    this.compositeEthereumListener = compositeEthereumListener;
    this.config = config;
    System.out.println();
    this.compositeEthereumListener.addListener(gasPriceTracker);
    gLogger.info("EthereumJ node started: enode://" + Hex.toHexString(config.nodeId()) + "@" + config.externalIp() + ":" + config.listenPort());
}


Recordemos que @Autowired es una anotación de Spring que, cuando es el encargado de construir el objeto, completa automáticamente estas referencias anotadas con autowired, con objetos QUE NO SABEMOS cuáles son así viendo el código de arriba, desperdigados por todo el resto del proyecto como beans que cumplen con lo que pide el autowired.

Y notemos que el EthereumImpl, con todos sus objetos referenciados automáticamente, para colmo referencia a un WorldManager. Ambas implementaciones terminan referenciando muchos objetos. Esto tiene toda la facha de “code smell”.

Alguien podría decir: “pero seguramente es necesario, porque el sistema es complejo y tiene muchas relaciones…”. Despues de haber estado un año trabajando sobre este código, usándolo como base, les puedo asegurar que bien se podría implementar mucho más fácil. Lo que sospecho que pasó: el @Autowired es un camino de ida, y cada vez fue más fácil agregar un campo autowired a uno de los objetos ya existentes, que sentarse a pensar cómo armar un grafo de objetos inicial, donde a cada objeto se le inyecte sus colaboradores APROPIADOS. De hecho, es prácticamente el único uso de Spring en el proyecto: armar el grafo inicial. No hay “lifecycle” de objetos ni nada más. Tranquilamente se puede armar un grafo de objetos más armónico, con un código propio. Además, sería más fácil de escribir tests, donde por código, queda explícito que objetos usa cada objeto para funcionar.

He dejado de lado algunos otros temas, como el uso de @PostInit para completar el estado de un objeto, luego de construirlo, y el armado de los listeners: ¿cuándo un objeto comienza a escuchar los eventos de otro? Toda esta conducta queda desperdigada en anotaciones y código separado, y prácticamente sin tests. Y un @Autowired mal resuelto puede detectarse recién con la ejecución del servidor. El proyecto original es muy interesante, y tiene otras cualidades. Pero hoy le tocó el turno a esto que veo como anti patrón, y un claro ejemplo de abandonar lo simple (crear el grafo nosotros) por lo fácil (que lo haga Spring).

En definitiva, el ABUSO de @Autowired ha derivado en la existencia de dos objetos “bolsa de gatos”, objetos “God”. Spring Framework es una gran herramienta, pero como toda herramienta, hay que usarla adecuadamente y respetando el contexto. Espero que en el proyecto en el que estoy trabajando, podamos erradicar esta complejidad y conseguir una implementación más simple. No repitan esto en su casa! 😉

Nos leemos!

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

Resoluciones del Nuevo Mes: Febrero 2017

Monday, February 6th, 2017

El segundo mes del año comienza, es tiempo de escribir mis resoluciones, pero antes, un repaso de las de enero:

– Mejorar CrysSharp [pendiente]
– Mejorar SharpGo [completo] ver repo 
– Mejorar BlockchainSharp [completo] ver repo
– Mejorar SimpleBlockchain [pendiente]
– Continuar Solidity Compiler [completo] ver repo
– Mejorar ChineseP [pendiente]
– Continuar PegSharp [pendiente]

También estuve agregando una mejora menor en ErlSharp ver repo.

Mis resoluciones para febrero:

– Mejorar SharpGo 
– Mejorar BlockchainSharp
– Mejorar SimpleBlockchain
– Mejorar Solidity Compiler
– Mejorar ChineseP
– Mejorar ErlSharp

Nos leemos!

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

Resoluciones del Nuevo Mes: Enero 2017

Wednesday, January 11th, 2017

Comenzó un nuevo año, yo sigo con resoluciones públicas mensuales, tiempo de escribirlas, pero antes a repasar las de diciembre:

– Mejorar CrysSharp [pendiente
– Mejorar SharpGo  [complete] see repo
– Mejorar BlockchainSharp [pendiente]
– Mejorar SimpleBlockchain [pendiente]
– Continuar Solidity Compiler [completo] see repo
– Continuar ChineseP [pendiente]
– Continuar PegSharp [pendiente]

He tenido temas personales, de salud, para atender, pero ahora estoy en una mejor posición para volver al ruedo.

Mis resoluciones de enero son:

– Mejorar CrysSharp
– Mejorar SharpGo 
– Mejorar BlockchainSharp
– Mejorar SimpleBlockchain
– Continuar Solidity Compiler
– Continuar ChineseP
– Continuar PegSharp

Nos leemos!

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

Resoluciones del Nuevo Mes: Diciembre 2016

Friday, December 9th, 2016

Y llegamos al fin de año. Tiempo de revisar las resoluciones de noviembre:

– Mejorar CrysSharp [pendiente]
– Mejorar SharpGo [pendiente] ver repo
– Mejorar BlockchainSharp [pendiente]
– Mejorar SimpleBlockchain [pendiente]
– Mejorar Solidity Compiler [pendiente] see repo
– Continuar ChineseP [pendiente]
– Continuar PegSharp [pendiente] see repo

Mis resoluciones para el nuevo mes de diciembre:

– Mejorar CrysSharp
– Mejorar SharpGo
– Mejorar BlockchainSharp
– Mejorar SimpleBlockchain
– Mejorar Solidity Compiler
– Mejorar ChineseP
– Mejorar PegSharp

Nos leemos!

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