I was chatting to another code-monkey1 recently about Astris which is a piece of software I wrote as part of the final project of the Information Security MSc I completed last year.
I made it sound like a failure, and me sound like a really bad software engineer. This post is the result of me reflecting on that conversation and the way I framed certain aspects and how I should have framed them.
Astris the software didn’t work as intended:
I made out that the reasons for this were:
None of that actually false, but I do believe it paints the whole project in a negative light.
The MSc project aim was to create a new e-voting protocol and implement a software proof-of-concept to show viability.
Astris, the software, was an opportunity for me to learn about building peer-to-peer systems. These are quite different from the usual distributed systems I have dealt with where each part of a service is the master of its own realm. In a P2P scenario, every node in the service is the master of its own data and has to convince and be convinced by every other node of the validity of its own data.
I made the simplest possible protocol for P2P communication, and it turned out in hindsight that that was only barely suitable for the task in hand. This is where the blockchain consensus became tricky to manage and the tight timescale of the project meant that I could not go back and fix it, and instead the limitations and learnings were reported in the final project.
This was a failing of the project and a bad design decision, but as a first foray into P2P I am not completely surprised that I didn’t get it correct first time, but pleased with the opportunity to learn.
The fact that I choose a direct RPC style node-to-node communication was for a reasonable reason, in that I wanted that same RPC to be able to send a block into the network from a “thin client”.
The consensus mechanism, which validates new blocks and picks “the one true chain”, was severely broken. The validation had no checkpointing and had to walk the entire chain. That meant if a client suggested a chain starting at a block that wasn’t the head of the chain, it would have to validate from the very beginning. On a large chain, that might take hours, just to discover that a block was invalid and the proposed chain should be discarded. I did make the start of implementing a version of the the validation with checkpointing, but did not have the time to work on it, and as a proof-of-concept, correct functionality in the happy-path (which I could ensure was followed in the simulated elections) was the most important factor. I believe that the way I have implemented it, it would be very susceptible to denial-of-service attacks, but mitigation was too time-expensive.
The second factor of the UX not being suitable for a layman user was also something that came out later on. Each node interacting with the election (i.e. with the blockchain for that election) needed a full copy of the chain or they would have to trust a different node that did have the full chain. I didn’t want the user to have to trust a 3rd party, but a long chain can take hours to validate on a client so there is definitely a conflict of interest.
My software didn’t directly address this, except that the API allowed a client to send a block to a full node, not requiring the full chain on the client. As the user would be able to choose whichever full node they wanted to and therefore have a measure of trust in their own choice this was not such a problem.
In my head the fact that the user doesn’t have a full node on the client side felt like a failure, but in hindsight I don’t believe that should be too much of a problem.
There are still factors of trust here like, where the client came from and does it really not send my plaintext ballot to some third party - but that is a supply-chain issue and out-of-scope for the project.
I had hoped to be able to build nice web-interfaces for all the interactions, but alas time was against me here. I don’t think that would have helped resolve the issues discussed here as they affect the inter-node communication at a lower level than whether the user hit a web-interface or a cli-interface.
Yes, on writing the software I discovered that some of the choices I had made were, shall we say, sub-optimal. But those parts of the software were those where I was dealing with a specific technology for the first time. In an effort to simplify things for myself and produce a functional proof-of-concept, I had to make some guesses and “worse is better” type choices, rather than spend the extra time I didn’t have.
The areas of the code base that shine however where the ones where I had a good handle on the details, such as the actual e-voting protocol itself and the chain validation and cryptography. These were the areas I spent most of my time budget on the research and implementation thereof. They worked well, efficiently and supported the project outcomes.
I shouldn’t be so harsh on myself. The project didn’t come out gold-plated. There are many areas I am not pleased with. However, did it achieve the goals I needed it to?
Also, think about what you are saying when talking to people. I was just blathering really and all my neuroses came out with it. Had I taken the time to stop and think I might have been able to be more able to explain the objectives and highlight that the shortcomings were just perfectionisms and had I focussed on them during the project, I would not have been able to achieve the objectives I set out for myself.
The report2 gained me a pass and an overall “distinction” in the master, so it cannot have been all bad ;)
. Perhaps I will have the time and motivation to correct some of the items discussed here, but even if not, the report and the implementation were both a valuable learning experience.