Facebook’s proposed currency is technically sound, but should you trust it?

You can probably trust Libra’s technical design, but whether you can trust Facebook is still unclear.

Dapper Labs
Dapper Labs
10 min readJun 21, 2019

--

Well, it’s true.

Facebook needs you to trust Libra for the currency to succeed, which is probably why Facebook itself is largely absent from most of Libra’s technical documentation.

Dieter Shirley, the primary creator of ERC-721 (the non-fungible token standard), co-creator of CryptoKitties, and co-founder of Dapper Labs, reviewed Libra’s white paper and shared his opinion with the team yesterday.

We thought you might appreciate his technical analysis as well. There’s a summary at the bottom if you want the short version!

Libra’s consensus algorithm is HotStuff

A consensus algorithm is a process used to achieve agreement on data modifications in a system of distributed actors, like a blockchain. The actors that participate in maintaining the distributed system are often referred to as ‘validator’ nodes.

Libra’s consensus algorithm is HotStuff. The founding principal researcher at VMware Research, Dr. Dahlia Malkhi, was an author on the HotStuff paper and is listed as an author of the Libra paper.

I always think of HotStuff as a pipelined version of Tendermint (but to be fair, the HotStuff paper actually introduces a non-pipelined version first — I’ll go into that in a little bit).

The original version of Tendermint was a three-round consensus protocol, where the whole network would go through three different voting phases before a block was considered finalized. You can think of these three rounds as:

  1. “Acknowledgement”: I’ve seen this block and agree it is a valid contender as the next block in the chain
  2. “Pledge”: I have seen that 2/3rds of participants have acknowledged this block. I pledge to choose this block as the next block in the chain unless I see 2/3rds of people tell me otherwise
  3. “Commitment”: I have seen 2/3rds of participants “pledge” for this block, so there is agreement that this is the next block — no take-backs!.

HotStuff (as I understand it!) uses the same three stages of agreement but assumes that the vast majority of the time, a proposed block will be acknowledged, pledged for and finally committed. In other words, we assume that only a small minority is actively trying to undermine consensus.

So, HotStuff pipelines this process (kind of like an assembly line). The acknowledgment of block 6 is also a vote for block 5 and a commitment for block 4. And when a validator sees a proposal for block 7, it will have seen everyone else’s acknowledgment of block 6, so it can pledge for 6, and it will have seen everyone’s pledge for block 5 so can publish a commitment for 5.

The recovery case when someone is trying to attack the network in HotStuff makes all of the above more complicated, but it can be shown that:

  • HotStuff is at least as safe as Tendermint when it’s under attack
  • HotStuff is at least as fast as Tendermint when it’s under attack, but
  • HotStuff could be something like three times as fast as Tendermint when not under attack.

There is one crucial extension of HotStuff over Tendermint that merits clarification: Both algorithms designate one validator as a temporary “leader”, which might change from block to block, who proposes the next candidate block. In Tendermint, every validator sends its vote to every other validator. For a system with N validators, O(N²) messages are sent over the wire. In contrast, the non-leader validators in HotStuff only send their vote to the leader, dramatically reducing the overall network traffic. This additional optimization allows HotStuff to run even faster.

Interestingly enough, Tendermint has since been updated to only require two rounds–the commitment step is no longer explicit–but HotStuff still uses three rounds.

LibraBFT is a variant of HotStuff (which isn’t surprising, since HotStuff was designed to have flexible parameters for different environments), and it seems that Dr. Malkhi had a hand in designing it.

In my opinion, HotStuff is a good approach and is (nearly) as easy to understand as Tendermint while being significantly more efficient under normal conditions.

Libra’s scaling solution is to restrict access to very powerful computers

Libra’s scaling solution is similar to the approach EOS and Tron have taken, both of which received a fair amount of criticism as a result of their approach (among other things).

EOS and Tron use delegated proof of stake (DPoS) to choose the small list of validators used to run the chain’s consensus algorithm. DPoS is more or less a protocol for voting nodes into power. Everyone who wants to participate in consensus as a validator has to put up a slashable stake, but the validators that are chosen are the ones that get the most votes from the users of the network. The amount of voting power you have is proportional to your on-chain wealth: If I have twice as many tokens as you, I get twice as much voting power.

The voters themselves do not put their money at stake, which dramatically limits the total security of this system. It also seems like buying votes is rampant in these systems (e.g. “vote for me to become a validator, and I’ll give you $5!”)

Libra does not appear to use delegated proof of stake.

As I understand it, Libra is specifically whitelisting node operators, and those node operators must demonstrate three things:

  • Access to sufficiently powerful hardware to keep up with the network
  • A public reputation that pleases the Libra governance board
  • $10M

Once you are on the list, your validator node has exactly the same voting power in the consensus algorithm as any other operator’s validator node.

The “reputation” part is how Libra solves Sybil-resistance (i.e. how Libra defends against an attack where one participant pretends to be many independent participants). I can’t have twice as much power as you in the consensus algorithm, because I would need to control two nodes to do so. It doesn’t matter if I’m willing to put in $20M or even $100M, the board appears to be committed to ensuring that each node is run by independent entities (this seems like a pretty good idea to me!).

What is unclear is how Libra will be able to meet their promise to transition all this to a fully decentralized system. This architecture is unlikely to scale beyond 1000 nodes. At the current buy-in of $10M, that would mean you could buy 51% of the network for $5.1B. That’s a lot of money, but it’s also the kind of money that many, many large corporations and government entities have access to, and it’s all that is needed to take over the network completely.

Fun fact: You’d need just $3.4B to destabilize or halt the network.

Libra’s programming environment is currently half-baked but incorporates some good ideas

Developer adoption will expedite or hinder Libra’s success, so a quality programming environment is crucial. Libra’s programming environment is new, incorporates some good ideas, and is far from complete.

Libra’s programming language, Move, has Rust-inspired syntax (which I would argue is the least appealing part of Rust!), and heavily depends on explicit ownership of data objects.

The approach to ownership is interesting: Libra uses a technique called Linear Typing that requires certain objects must exist in exactly one place at any given time. As a result, you can’t make a copy of it (you can only move it), and you can’t discard it. This seems like a great idea for digital assets: the static typing mechanism can ensure that all code never duplicates or loses assets, either intentionally or accidentally. This approach to ownership is a different way of thinking about asset storage on a blockchain, that could unlock some pretty powerful use cases.

Ethereum’s approach to ownership is that every token is tracked like a bank balance. You can go to the smart contract controlling that token and say “I want to give 15 coins to Mary.” From there, the smart contract will decrease my balance by 15 coins, and increase Mary’s balance by 15 coins. However, I can’t go to the smart contract and say “please give me fifteen tokens”, and then store those tokens somewhere else.

Ethereum gives a lot of flexibility to smart contracts by allowing them to also have “bank accounts”, which empowers a lot of interesting use cases. But Ethereum’s approach has some limitations, as both the Cheeze Wizards and CryptoKitties smart contracts have shown us. Take the CryptoKitties birthing fee as an example: all the outstanding birthing fees for all pregnant Kitties are in the CryptoKitties smart contract “bank account”. But that’s just a single pool of tokens, and there’s no clear way to audit which token is associated with which pregnant Kitty. We solved this for CryptoKitties, but the logic that was needed isn’t as clear as would be ideal.

With the Move model, we could literally store the birthing fee inside the cat itself. For those of you who know about ERC-998, it might seem like Composable Tokens are Ethereum’s answer to this issue, but the Move model is much more powerful than ERC-998, much easier to understand, and far less likely to introduce errors.

Unfortunately, this technique can only work on atomic objects, which means it’s annoying to use it for coins! I can create a “purse” that consists of 10 coins, and the type system will ensure that I don’t drop that purse and don’t make a copy of that purse. But it won’t let me split that purse of 10 coins into two purses of six coins and four coins each. This means I can’t actually buy anything with that purse unless I want to pay exactly 10 coins for it!

You could apply the Linear Typing model to the coins themselves, one object per coin — but that means that if you have 100 coins, you literally need to use up 100 memory slots to store them, and you still wouldn’t be able to buy something for half a coin.

It’s worth noting that Linear Types are excellent for non-fungible tokens (NFTs), but I couldn’t see a single reference to NFTs in any of the documentation I went through. But who knows, maybe I’m overly biased with a fondness for NFTs…

Libra’s solution to the “groups of tokens” problem is to have the smart contract that controls the token be allowed to “break” the rules for Linear Types — in other words, the token contract can create or destroy “purses” at will. Ironically enough, this completely undermines the safety guarantees, and because the syntax for creating and destroying affine objects is completely crazypants; it seems much more likely to introduce errors than suppress them!

For some reason, they’ve decided to apply the syntax for managing “resource” objects (i.e. Linearly Typed objects) to all types. So, whenever you access a variable, you must explicitly indicate if you are making a copy of that object, or are moving that object.

Here’s a sample line of code from Cheeze Wizards:

Here’s what that does to the sample line of code:

Here is an example of creating a “purse” object from their sample docs:

I believe the same thing could be expressed as follows (assuming the existence of Linear Types, but otherwise using Solidity syntax):

I encourage technical-minded readers not to simply gloss over the length of the Move example, but to really examine it to see how long it takes you to figure out what is even happening there. It took me a good five minutes.

Hopefully, they will take some time over the next couple of years to streamline some of this. After all, they don’t plan on letting anyone else write Move code any time soon.

The TL;DR version of Dieter’s technical analysis

  • Libra’s consensus algorithm is a good choice: relatively easy to understand while being significantly more efficient than similar solutions
  • Libra does not appear to use delegated proof of stake
  • Libra protects itself from Sybil attacks by having each node run by independent entities, enforcing this via the Libra governance board
  • How Libra will fulfill the promise of becoming a “fully decentralized system” is unclear
  • Libra’s programming language, Move, is powerful, but not especially elegant
  • Libra’s approach to ownership is a different way of thinking about asset storage on a blockchain. Using a technique called Linear Typing, it requires that certain objects must exist in exactly one place at any given time
  • Linear Types would be excellent for NFTs, but Libra doesn’t seem to have any interest in supporting NFTs
  • Libra’s solution to “groups of tokens” problem is to have the smart contract that controls the token be allowed to “break” the rules for Linear Types. This seems to undermine the safety guarantees and, due to the syntax for creating and destroying affine objects, seems more likely to introduce errors than suppress them.

Want to learn more about Libra from other folks in the industry?

Philippe Castonguay’s annotation of Libra’s white paper is a good paragraph-by-paragraph walkthrough.

If you’re interested in what Libra means in non-technical terms, this tweet thread from Nathaniel Whittemore is an excellent resource to start with:

How do you feel about Libra?

Let us know in the comments below!

And if you want to stay up-to-date on the future of decentralization, follow Dapper Labs on Twitter.

--

--

Dapper Labs
Dapper Labs

The serious business of fun and games on the blockchain