This will be a shorter update since it’s only been two weeks since the last update. The big news is that mana the Ethereum client I’ve been working on with PoA Network for the past few months will be getting support from two new organizations: Compound and Consensys! Here’s a blog post about it from PoA Network. With the added resources and connections this will provide I’m confident we’ll be able to achieve our goal of building a first class client that can compete with Geth and Parity. In the next few weeks a few more developers will be added to the project. Currently my plan is to step back into an advisory type roll on that project and work on Ellipticoin full time!
Got the blacksmith node to “watch” the staking contract.
For the blacksmith node to function it’ll have to watch the staking contract on the parent chain (Ethereum). Every time block is mined on the parent chain we’ll call
winneron the staking contract. If the node calling it is the winner they’ll process a block of transactions, broadcast that block to the network and call the staking contract to collect their reward. To get this to work I needed a way to be notified of new blocks being mined on Ethereum. I opened a PR on Ethereumex to add WebSocket support but decided to close it because fully supporting WebSockets in Ethereumex would take a significant amount of time and there’s too much to do on Ellipticoin right now. My branch solves the problem I needed to solve though. The node can now successfully subscribe to a channel over a WebSocket to Infura and listen for new blocks. When a new block arrives it calls
winneron the staking contract. The next step will be to forge a block and notify it’s peers if it’s the winner. Before doing that I needed to do more work on block forging.
Started modeling block data
To start blocks have the following attributes:
- parent: the parent block
- number: the block number
- total_burned: the total number of tokens (DAI) burned on this chain
- changeset_hash: a hash of all the writes made by this block. (See the following section on the changeset hash)
- block_hash: this is a hash of all the other values. This can act as a global identifier for blocks
Using real models and a relational database to store block data has been much more intuitive than storing everything in an on disk in a key value store like Etheruem and Bitcoin do. I think it will also make the code more clear and make it easier to query data about the chain.
When transactions are posted to a Blacksmith node Elixir pushes them into a queue is Redis. This is the equivalent of the mempool in Bitcoin and Ethereum. When it’s time to mine a block Elixir has to tell Rust to start processing transactions. Originally I thought I would do that through a nif but it turns out that nifs disrupt the scheduling of other processes. Since transaction processing was going to run for two full seconds I wanted to find a better way. Enter Redis PubSub! Now when it’s time to process some transactions we can call Redis.publish(@channel, [“proccess_transactions”, duration]) from Elixir. On the other end Rust is subscribed to that channel and can receive the message. It then processes transactions for the specified amount of time and then publishes back to the channel when it’s done. Elixir then picks up on this message and sends it to the appropriate process. Using Redis PubSub over nifs will keep BEAM from blocking allow for richer communication between Rust an Elixir
Protocol thoughts and updates
I’ve been thinking a lot about how networking will work in Ellipticoin. Devp2p, Ethereum’s networking protocol, is probably the most complicated part of Ethereum. I want the networking code in Ellipticoin to be as simple as possible. To start it’s going to work a lot like a modern RESTful JSON api but with CBOR instead of JSON. This way payloads will be smaller and deterministic so they can be signed. All messages will be broadcast directly to all other nodes. If this starts to be problematic we can switch to CBOR over libp2p.
Added the changeset hash
Ethereum stores state in a Merkle Patricia tree. This means that every state update needs to walk the tree to a leaf node and update each node along the way. This adds a lot of complexity to the protocol and ends up being a bottleneck in processing Ethereum transactions. Ellipticoin won’t store state in a Merkle tree or a Merkle-Patricia tree 😮. Instead, each time a write is made the value that was written and the key it was written to are appended to a string of bytes. When a block is forged a hash is taken of this string. Other nodes can then run the transactions themselves and verify that they get the same resulting hash. This means that instead of having to run the hashing algorithm multiple times for each individual state update you only have to run it once per block! This speeds things up and make implementation much simpler. The downside is you won’t be able to run Ellipticoin light clients. This shouldn’t be a problem though because if you don’t want to run a full node you can still verify the final changeset hash because it will be submitted to the parent chain (Ethereum).
Thinking about the signature chain
When submitting a block to the chain a blacksmith will sign the following message (<> means concat):
block number <> changeset_hash <> last_signature_in_signature_chain
If a blacksmith signs two messages with the same
last_signature_in_signature_chainwith a different
changeset_hashtheir stake will be slashed. This is the equivalent of slashing in PoS algorithms and solves the nothing at stake problem.
Thanks for reading!
If you have any questions or comments on any of this swing by the Ellipticoin Telegram room and say hello!