Resoluciones del Nuevo Mes: Marzo 2017

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

Profesión

February 19th, 2017

El título de este post está inspirado en un relato de Isaac Asimov, “Profession”. Más información en:

https://en.wikipedia.org/wiki/Profession_(novella)

Pueden leerla en:

http://www.inf.ufpr.br/renato/profession.html

Transcurre en el siglo LXVI (sesenta y seis), cuando la humanidad todavía ocupa la Tierra como planeta central, pero donde la actividad excitante está en los Mundos Exteriores. Los jóvenes se educan con “cintas” donde van aprendiendo sobre temas, antes de llegar a la “Olimpíada”, una competencia donde poner a prueba sus conocimientos, y son elegidos entocnes por distintos empleadores de los Mundos Exteriores, en base a su resultado.

George quiere ser programador de computadores, pero se le rechaza la oportunidad de estudiar y especializarse, aduciendo que su mente no es adecuada. Queda internado en un lugar, la Casa. Mientras, un compañero de estudios, estudia con la “cinta” y llega a la “Olimpíada”. George se escapa de la Casa, y al llegar a la ciudad de la “Olimpíada” se encuentra con este compañero, que se lamenta de no haber obtenido el mejor empleo posible, porque su “cinta” estaba desactualizada, y no trataba de los últimos modelos del espectrógrafo Beechman.

Al final, George es encontrado (en realidad, siempre lo vigilaron) y luego de algunos pasos más, se le revela que fue apartado y ahora aprobado, para ser parte de otro grupo, desconocido. La Casa no es un lugar para inadaptados mentales, es un Instituto de Altos Estudios, donde la gente creativa se dedica a crear, a mejorar el conocimiento de la sociedad, no solo a aprender “cintas”. Alguien llamado Beechman tuvo que ser el inventor del espectrógrafo Beechman, y no estudió eso de una “cinta”.

Siempre me impresionó este relato, que habré leido hace unas décadas en el siglo pasado. En los ochenta, me encontré trabajando como pasante en una sucursal en Buenos Aires de una multinacional. En un piso, estaba el especialista en el Sistema Operativo X17, digamos. Sabía todo de eso, cómo instalar, que instalar, cómo corregir tal cosa; era el especialista preferido del tema. Estaba siempre ocupado, y reclamado desde otros paises incluso. Pero no sabía mucho más. Había entrado en el camino de la especialización.

No digo que “esté mal”, pero no era eso lo que yo quería. Antes y después, en otros ámbitos, volví a encontrar ese “síndrome” de estudiar algo especializado. Desde entonces, he tratado de estudiar algo concreto pero siempre teniendo en el panorama el paisaje general, los fundamentos de algo, más que los detalles circunstanciales del momento. Además, nuestra profesión está signada por el cambio permanente, así que veo interesante tener siempre en vista el aspecto general de algo, más allá de las “technicalities” del framework, lenguaje o librería de moda.

De ahí que rara vez me especialicé en algo, con la SuperLibrary 17.2, o el MegaFramework MVC 18.2. Prefiero entender las fuerzas, contexto, casos de uso de esa librería, antes que los métodos detallados. Prefieron conocer por qué adoptamos MVC en estos tiempos, o modelos similares, y luego ver de aplicar eso en cada caso.

Hay un caso concreto actual, del camino estudio algo especializado, sin ver lo general. Lo noto en “machine learning”. Muchos quieren aprender TensorFlow o algún framework en particular de redes neuronales, sin tomarse el trabajo de aprender los fundamentos de los distintos “approaches” que hoy tenemos en “machine learning”. Hay que estudiar algoritmos genéticos, redes neuronales, árboles de decisión, distintos algoritmos de clasificación, y hasta recordar los sistemas expertos y la historia de la “inteligencia artificial”, para realmente comenzar a entender y poder tomar decisiones y extender todo lo que hay para hacer en “machine learning”.

Nos leemos!

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

 

 

Muerte a Spring

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

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

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

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

Armando una Blockchain (15)

December 3rd, 2016

Anterior Post

Siempre aparecen temas interesantes para encarar y resolver, en mis implementaciones de blockchain abiertas (C#, JavaScript/NodeJS); una es la comunicación ENTRE nodos. Los nodos tiene que intercambiar datos como nuevos bloques, nuevas transacciones, mensajes de estado y sincronización…. Y también, un nodo que comienza a ejecutar o que está ejecutando desde hace varios días, debe saber descubrir qué otros nodos como él están disponibles en ese momento. Ese proceso tiene un nombre: “peer discovery”, descubrimiento de pares.

Me gustaría escribir hoy algunas ideas:

– Cada nodo tiene un id de nodo, y un id de red en la que trabaja, de esa manera, los demás nodos lo identifican (id de node) y saben si trabaja en la misma red que ellos (id de red).

– Un nodo puede tener una lista preconfigurada (“hardcodeada”) de nodos con los cuales comunicarse, como pares iniciales

– Pero también puede tener otra lista: una lista de nodos especiales en la red, que CONOCEN a otros nodos de la red. Como que mantienen un registro (“registry”) de los nodos disponibles. Estos nodos especiales se van informando dinámicamente de los nodos que existen activos, y los van propagando a otros nodos registro. Un nodo normal se comunica periódicamente con nodos registro, y de esa forma va consiguiendo una lista de pares disponible. Los nodos registros no son nodoso de trabajo ni pares. Puede que en vez de estar identificados por un número de IP, estén referenciados por nombres de máquina, bajo control de servidores de nombre DNS que estén bajo control de la red. Eso permite cambiar su máquina física sin cambiar la configuración de los nodos originales.

Cuando un nuevo nodo comienza a ejecutar, comunica su existencia a su lista de nodos registro, y activamente les pide a éstos cuáles son los pares disponibles para trabajar. Cada nodo de trabajo tiene configurado un número de MAXIMA cantidad de pares activos a contactar.

Cuando uno de esos activos se cae, o se ve que no es alcanzable, el nodo original trata de conectarse con otros nodos activos que va descubriendo con el tiempo desde los nodos registro.

No es objetivo conseguir uan buena distribución de conexiones, pero se podría ir clasificiando los nodos conocidos en zonas arbitrarias (por ejemplo, la zona es el múdulo de id de nodo por 16). Cuando un nodo de la zona 2 pide nodos pares, se le podría entregar PREFERENTEMENTE nodos de la zona 1 y zona 3. Pero hay que demostrar que esto permite una mejor distribución de los mensajes. No es un caso de uso en el que haría énfasis por ahora. Podría ser más importante impedir que un nodo cualquiera, al interrogar a los nodos registro, consiguiera fácilmente la lista de TODOS los nodos de la red.

Como de costumbre, me gustaría pasar estas ideas a código, siguiendo simplicidad, casos de usos, y TDD.

Nos leemos!

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

MultiMoneda En Ethererum/RSK (1)

November 29th, 2016

En mi serie de posts sobre conexión de blockchains, estoy escribiendo sobre el intercambio (de valor, uno a uno, sin cambio de valor) entre dos blockchains populares y heterogéneas (Bitcoin y Ethereum/RSK). Soy miembre del equipo de desarrollo de @RSKSmart, pero esos posts son opiniones personales: hay código adicional en el proyecto todavía no publicado.

Otro camino a explorar, es tener, en LA MISMA BLOCKCHAIN, varias cripto monedas. Pienso que puede hacerse de forma simple extendiendo Ethereum/RSK.

En Ethereum, hay cuentas con estado, y en el estado de la cuenta está el balance de esa cuenta. Hay una única moneda “asumida, el Ether. Pero pienso que este modelo puede ser extendido.

Cada cuenta puede tener una moneda. La cripomoneda asumida es el Ether, pero algunas cuentas podrían ser creadas con OTRA criptomoneda como moneda asumida. De este forma, tendrías una partición de cuentas. Una cuenta con moneda X puede transferir y recibir valor de otra cuenta de la MISMA MONEDA X. De esta manera, las nuevas cuentas podría reaprovecha, apalancar, toda la infraestructura de cuentas y transferencias original, pero para una moneda diferente, sin necesidad de armar una blockchain por separada.

En los próximos post, quiero escribir sobre:

– Cómo definir una nueva moneda
– Cómo crear una cuenta con una nueva moneda asociada
– Cómo transferir entre cuentas con la misma moneda
– Cómo transferir entre cuentas con diferentes monedas

Nos leemos!

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

Conectando Blockchains (6)

November 27th, 2016

Anterior Post

BitCoin es la blockchain más conocida. Ethereum es el “new kid on the block”, y tiene similitudes y diferencias con la BitCoin. En principio, Ethereum tiene nodos ejecutando, que intercambian transacciones, bloques, y van formando una blockchain por consenso distribuido:

El conseso se basa en un “proof of work” en cada bloque agregado a la blockchain, de manera parecida a como se hace en BitCoin. Pero ahí acaban las similitudes. La estructura interna de una transacción, el estado del mundo que se guarda al final de cada bloque, son diferentes. Por ejemplo, en Ethereum hay cuentas,  y se mantiene en su estado el saldo, mientras que en BitCoin se manejan “unspent outputs”, en vez de saldo.

Pero la principal diferencia es que en Ethereum, cada cuenta puede tener un contrato inteligente. Cada nodo de Ethereum corre una Virtual Machine que puede ejecutar esos contratos inteligentes. Cada transferencia puede (o no) ejecutar un método del contrato inteligente asociado a la cuenta destino de la transacción. Esto abre la posibilidad de todo un nuevo mundo de casos de uso.

El tener contratos inteligentes en Ethererum/RSK, es una de las motivaciones para intentar la comunicación bidireccional de estas dos blockchains. BitCoin es limitado en la ejecución de scripts, y los contratos inteligentes son un nuevo mundo a explorar.

Nos leemos!

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

Conectando Blockchains (5)

November 17th, 2016

Anterior Post
Siguiente Post

El caso de uso que tengo en mente es conectar blockchains heterogéneas: BitCoin y Ethereum/RSK:

El principal problema es que ambas blockchains son muy diferentes La solución del primer caso de uso (transferir de BitCoin a Ethereum/RSK) será muy diferente a la solución del segundo caso de uso (transferir desde Ethereum/RSK a BitCoin).

Y la diferencia clave es que Ethereum/RSK tiene contratos inteligentes (hasta admite contratos nativos precompilados, si se necesita mayores capacidades). La otra diferencia es el formato de las transacciones: BitCoin usa Unspent Outputs mientras Ethereum se basa en mantener balances por cuenta.

Pero elijo estos casos de usos porque son interesantes y no triviales, a discutir en los próximos posts.

Nos leemos!

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