Testnet #4: Shielded Staking Is Here

In our last update, we announcedour first testnet, codenamed “Valetudo”, with an implementation of our MVP1milestone: multi-asset shielded transactions, and a basic, fully-trusting lightwallet protocol that does client-side scanning of the private chain state.

Today, we're excited to announce that shielded staking has come to the Cosmos,with our fourth testnet, codenamed “Thelxinoë”, after the fourth-smallest namedmoon of Jupiter.

The Thelxinoë testnet brings us partway to our MVP2 milestone: shielded stakingand delegation mechanics, providing privacy to delegators while retainingaccountability for validators.  This is a key part of our vision of a trulyprivate proof-of-stake network, and in this post, we'll walk through thechallenges involved in shielded staking, how our new staking design addressesthem, and give an update on our progress and next steps.

We're aiming to move to a weekly testnet cadence, so stay tuned for more updates!

The Challenge of Shielded Staking Rewards

Integrating privacy with proof of stake is a key goal for Penumbra.  Withoutprivate staking, holders of the staking token would have to choose betweenhelping to secure the network, participate in governance, and receive stakingrewards on the one hand, and maintaining privacy on the other hand.  This wouldput the project's goal, providing a shielded pool and DEX for the entire Cosmos,in conflict with the incentives of its stakeholders.

It's also critical that the staking system provide native, permissionless,non-custodial delegation, as in the design of the Cosmos SDK.  These propertiesshould be considered table stakes for new proof of stake deployments, but areunfortunately missing from many, most notably Eth2.  They're important toprevent winners-take-all dynamics by allowing all participants equal access tostaking, and to minimize the risk of re-centralization when these missingfeatures are inevitably provided by third parties.

We want a system that provides privacy to delegators, but accountability for thevalidators who participate in consensus.  However, the key challenge in buildingsuch a system is how to handle staking rewards.  Unlike a transparent chain,where all delegations are public, and the chain can simply credit delegators'accounts with staking rewards, if the delegations are private, the chain has noway to know the amount and duration of each delegation.

To sidestep this problem, Penumbra uses a new staking mechanism that eliminatesstaking rewards for delegators, while preserving the economic incentives forstaking.

How is this possible?  Rather than treating "unbonded" and "bonded" as differentstates of a single staking token, we record bonded stake using delegationtokens, which represent a share of a particular validator's delegation pool,similar to the way that LP shares represent shares of a liquidity pool.  Theexchange rate between staking tokens and delegation tokens prices in what wouldbe a staking reward in other systems.

Delegation Tokens

Each validator has a delegation pool, containing all the stake bonded to thatvalidator's behavior.  The size of the delegation pool for each validator ispart of the public chain state, and determines the validator's voting power.

Delegations are recorded using delegation tokens, which represent a share of avalidator's delegation pool.  These can be thought of as a first-class stakingderivative or liquid staking token, though we don't use those terms to avoidcarrying over assumptions from other system designs; we think "delegation token"is a better term.

Instead of tracking staking rewards directly, the chain tracks an exchange ratebetween the staking token and a validator's delegation token.  This exchangerate prices in the cumulative staking rewards since genesis.  When a userdelegates stake to a validator, they exchange their stake for delegation tokensat the current rate.  This discounts their share of the delegation pool for therewards from genesis up to their delegation, which they didn't earn.  Later,when they undelegate stake from that validator, they exchange their delegationtokens for stake, and get credited for the cumulative staking rewards sincegenesis.  Since they discounted their share on delegation, this netsout to the staking reward exactly over the period theydelegated, without requiring the chain to track that information!

How does this provide delegation privacy?  Because all delegations are fungiblewith each other, they can be recorded with a single delegation token, and thistoken is just another asset recorded in Penumbra's multi-asset shieldedpool.  To ensure that amounts are not revealed during (un)delegations,we'll use flow encryption to shield the amounts in each(un)delegation transaction, revealing only the aggregate flows into and out ofeach validator's delegation pool on epoch boundaries.

Validator Commission via Funding Streams

The exchange rate mechanism described above works for delegators, but we alsoneed a way to compensate validators for the cost of providing security to thenetwork.  In the Cosmos SDK, this is done using a commission parameter, whichdetermines a portion of the staking reward sent to the validator operator.

However, this mechanism is somewhat limiting, since it only allows commission tobe distributed directly to validator operators.  While some validators use theircommission to fund public goods for the ecosystem, that funding is generallyopaque and off-chain.  It would be more flexible if validators could dedicatesome portion of their commission to a DAO or other public goods mechanismtransparently and non-custodially.

To enable this, our design generalizes a single validator commission to a set offunding streams, each with their own address.  Validators can declare fundingstreams to addresses they don't directly control, and delegators can factorthose funding streams into their decisionmaking.

To exercise this functionality, we've added all of the addresses posted in the#testnet-faucet channel on Discord during the previous three testnets asfunding streams in the current testnet, so if you already posted your address,you should see your address receive rewards.

Slashing, Unbonding, and Quarantine

The exchange rate mechanism neatly solves the problem of shielding stakingrewards, and it also neatly handles slashing: to slash a malicious validator'sdelegation pool, the chain can adjust the exchange rate to price in the slashingpenalty.  The last essential component is an unbonding period, so that amalicious validator cannot misbehave, then withdraw their stake before they'reslashed.

This also poses a challenge for Penumbra, since all transactions are private bydefault and all value is privately recorded in a shielded pool.  Let's look atan undelegation transaction from the point of view of a user, and from the pointof view of the chain:

User's View           Chain's View
┌──────────────────┐ ┌──────────────────┐
│┌────────────────┐│ │┌────────────────┐│
││Spend           ││ ││Spend           ││
││                ││ ││                ││
││+100delegation_v││ ││+??? (shielded) ││
│├────────────────┤│ │├────────────────┤│
││Undelegate      ││ ││Undelegate      ││
││                ││ ││                ││
││Validator: v    ││ ││Validator: v    ││
││-100delegation_v││ ││-??? (shielded) ││
││+120penumbra    ││ ││+??? (shielded) ││
│├────────────────┤│ │├────────────────┤│
││Output          ││ ││Output          ││
││                ││ ││                ││
││-119.99penumbra ││ ││-??? (shielded) ││
│├────────────────┤│ │├────────────────┤│
││Fee             ││ ││Fee             ││
││                ││ ││                ││
││-0.01penumbra   ││ ││-0.01penumbra   ││
│└────────────────┘│ │└────────────────┘│
│                  │ │                  │
│Net: 0            │ │Net: 0 (zk proved)│
└──────────────────┘ └──────────────────┘

The transaction spends some delegations out of the shielded pool (unlinkablyfrom any previous transaction), exchanges them for staking tokens at the currentexchange rate (using flow encryption to shield the amounts in thisspecific transaction), and then creates a new output note in the shielded pool.

We want the user to be able to submit the transaction to the chain, and for thechain to record that it occurred, but still preserve the ability to slash thedelegation until the end of the unbonding period.  Because spends and outputscompletely unlinkable, if the chain adds the output with the staking tokens tothe shielded pool, it can never even identify them to slash them.

Instead, we hold any outputs from an undelegation transaction in a specialquarantine state, along with the nullifiers for the input notes that preventdouble-spending.  If the validator is slashed before the end of the unbondingperiod, we discard the quarantined notes, and remove the nullifiers from thespent set.  This unwinds the effect of the undelegation and allows the user toresubmit a new conversion of their delegation tokens with the post-slashingexchange rate.

This rule is simple, but it turns out to also enable "instant" redelegations, atleast up to slashing.  A redelegation just combines undelegation and delegationactions in a single transaction:

User's View             Chain's View
┌────────────────────┐ ┌──────────────────┐
│┌──────────────────┐│ │┌────────────────┐│
││Spend             ││ ││Spend           ││
││                  ││ ││                ││
││+100delegation_v  ││ ││+??? (shielded) ││
│├──────────────────┤│ │├────────────────┤│
││Undelegate        ││ ││Undelegate      ││
││                  ││ ││                ││
││Validator: v      ││ ││Validator: v    ││
││-100delegation_v  ││ ││-??? (shielded) ││
││+120penumbra      ││ ││+??? (shielded) ││
│├──────────────────┤│ │├────────────────┤│
││Delegate          ││ ││Delegate        ││
││                  ││ ││                ││
││Validator: w      ││ ││Validator: w    ││
││-119.99penumbra   ││ ││-??? (shielded) ││
││+97.84delegation_w││ ││+??? (shielded) ││
│├──────────────────┤│ │├────────────────┤│
││Output            ││ ││Output          ││
││                  ││ ││                ││
││-97.84delegation_w││ ││-??? (shielded) ││
│├──────────────────┤│ │├────────────────┤│
││Fee               ││ ││Fee             ││
││                  ││ ││                ││
││-0.01penumbra     ││ ││-0.01penumbra   ││
│└──────────────────┘│ │└────────────────┘│
│Net: 0              │ │Net: 0 (zk proved)│
└────────────────────┘ └──────────────────┘

Here, even though the present value of the two delegation tokens is the same,the amounts of each token might be slightly different, since the exchange rateprices in cumulative rewards, and the validators may have different commissions.

Now, what happens when we apply the quarantine rule?  The transaction isfinalized, and the output with the new delegation tokens is quarantined untilthe end of the unbonding period.  But the exchange rate is locked in when thetransaction is submitted, not when the unbonding period ends.  So, in theoptimistic case without slashing, the effect is as if the user had "instantly"redelegated their stake, even though they weren't able to access the newdelegation tokens during the unbonding period.  On the other hand, we stillprotect against rug-pulls from misbehaving validators, since it's not possibleto immediately redelegate to escape slashing.

Status and Next Steps

Thelxinoë implements the core economic mechanism for our staking design:per-validator delegation pools represented by delegation tokens, with theability to delegate and undelegate stake, and accounting for the stakingeconomics as part of the chain state.

This is most of the way to our MVP2 milestone.  What's left to implement is:

  • moving from immediate undelegation to an unbonding period, with correcttracking of quarantined undelegations;
  • the complete validator state machine, so validators can be declared, delegatedto, enter the consensus set, and exit the consensus set (either honorably, byunbonding, or dishonorably via slashing);
  • writing back the voting powers to Tendermint, so that the consensus setfollows the application state.

We've also started some preparatory work for our MVP3 milestone, IBC support,which enables Penumbra to act as a shielded pool for the entire Cosmosecosystem.  The public part of Penumbra's chain state will be recorded using theJellyfish Merkle Tree originally designed for Libra/Diem; ourjmt crate extracts the Diem implementation into a standalone,async-compatible implementation.  Thanks to Mark Zuckerberg and David Marcus forfunding the development of this technology and donating it to the community.  Toenable IBC, we've started working on adding support for JMT proofs to ICS23,which will also help enable IBC support between Cosmos chains and 0L(OpenLibra).

Using the Testnet

The testnet is only accessible by a command-line interface. Instructions on howto get started with it can be found onGithub. We don’t have an automatedfaucet set up, but we do have a dedicated discord channel (#testnet-faucet)where you can paste an address and have someone send you tokens, or send tokensto someone else in the discord.

If you posted your address in the discord during one of the previous threetestnets, we've added your address as one of the testnet validator's fundingstreams with 4 basis points of commission, so you should see your addressreceive rewards.

We’ve created a few different test assets to exercise the transaction functionality:

  • penumbra tokens, which can be used for paying fees;
  • gm and gn tokens, allowing you to send gm and gn to your friends;
  • tungsten_cube tokens, a fan favorite;
  • pizza tokens, representing a tasty and nutritious snack;
  • nala tokens, since no blockchain is complete without a dog token.

To be very explicit: this is not an incentivized testnet. These tokens have novalue whatsoever, no purpose other than playing with our unfinished software,and we’ll be shutting down the testnet as soon as next week. In the meantime,though, if you’re interested in giving it a spin, why not try it out?

   Discord