Making “free gas” work for validators and delegators

Let’s assume a generic Proof of Stake protocol where validators take turns proposing blocks. The number of blocks proposed by a validator is directly proportional to (or a linear function of) his weight:

  • Alice staked X tokens, and Bob staked 2X tokens.
  • → Alice proposes Y blocks per unit time, and Bob proposes 2Y blocks per unit time.

Moreover, number of transactions included on average is calculated by multiplying with weight:

  • Network processed 10m txs last month. Alice’s weight is 5%.
  • → Alice included 10m * 5% = 500k txs last month

Let’s assume that the transaction fee distribution scheme in this protocol is proposer-gets-all, that is, the block proposer receives the fees attached to transactions that he included in the block.

Alice, as a validator, can get free gas. She signs some transactions, but doesn’t publish them. Instead, when it’s her turn to propose a block, she just includes them. Since it’s Alice collecting the transaction fees, she essentially pays herself for the transaction, getting free gas.

Alice can be a dapp developer, paying for the usage of the dapp’s users. Given her weight, she would have the right to include weight * total_tps many transactions per second. If the number of users increases and she needs more throughput, she simply increases her weight by staking more.

Moreover, delegators can also get free gas with implicit agreements. Let’s assume Dan, a dapp developer, also wants to get free gas, but he doesn’t want to become a validator.

Dan can simply delegate tokens to Alice, increasing her weight and throughput allocation. Dan enters an agreement with Alice: Dan will share his transactions only with Alice. Then, when Alice includes them, she will relay the tx fees back to Dan, after getting a commission. As a result, Dan gets highly discounted or free gas without becoming a validator, depending on Alice’s commission rate.

It’s easy to see what’s happening here: Alice and Dan are converting their OPEX into CAPEX. Instead of paying for their users’ transactions regularly, they make a one time investment to cover their users’ expenses.

Well, “one time” considering your demand for transaction stays the same. If Alice or Dan has a growing user base, however, their path may look like this:

  1. Develop a dapp. Make initial investment: delegate 100 users’ throughput worth of tokens.
  2. You found product-market fit and now have 10x more users.
  3. Top-up delegation 10x to offset increased demand.
  4. Repeat.

Still, with this model, one doesn’t have to pay for gas, AND one can receive issuance rewards on top of it.

However, a problem becomes apparent. Alice has to wait until it’s her turn to propose, in order to include transactions. Also, Dan has to wait until it’s the validator’s turn whom he delegated to.

Say that Alice has 1% weight. Then, Alice can propose every 1 in 100 blocks, and the time to finality has increased 100-fold. Alice has to wait for a long time, if a subsequent transaction depends on the inclusion of a preceding transaction.

A possible alternative for getting free gas could be to make validators exempt of paying fees for transactions, i.e. allow them to get zero gas price. However, in such a scenario, there is no incentive for a validator to include another validator’s transaction, since they could be filling the same block space with a regular user’s paying transactions.

To solve this problem, I propose an instrument called Inclusion Bond, or IB for short. With an IB, Alice and Bob can include each other’s transactions, and eventually have their respective transaction fees routed back to them. Here is a simple example:

  1. Alice publishes her transaction.
  2. It’s Bob’s turn, and he includes it immediately. Transaction fee is calculated as F.
  3. However, Bob doesn’t receive the transaction fee. Instead, an IB is created, within which the fee is locked.
    • Alice owes Bob transaction inclusion worth of F tokens.
    • Neither Alice nor Bob can use the tokens, until Alice settles the IB by including one of Bob’s transactions.
  4. The IB sits for a while. Then, Bob publishes a tx, and Alice includes it. Resulting fee is G tokens. Depending on the amount, we have 3 options:
    • Case G < F (Bob spends less than Alice): Bob immediately receives back the G tokens which he has just paid. G tokens are released from the IB, and returned to Alice. The IB has F - G outstanding.
    • Case G = F (Bob spends the same amount as Alice): Bob immediately receives back G = F tokens which he has just paid. All G = F tokens are released from the bond, and returned to Alice. The IB is settled.
    • Case G > F (Bob spends more than Alice): Bob immediately receives back F (a portion of) the tokens which he has just paid. All F tokens are released from the bond, and returned to Alice. While the IB is settled, a new one is created, where Bob owes Alice an inclusion worth of G - F tokens.

IB’s are opt-in, that is, if a validator is OK with generating an IB, he can set a flag in the transaction header.

  • 0: IB not allowed. Proposer directly receives the resulting fee.
  • 1: IB allowed, but not enforced. Proposer can choose to receive the fee directly, or create an IB.
  • 2: IB enforced. If the proposer chooses to include, he won’t be able to receive the fee directly, and an IB will be created.

Validators generate IBs based on their own throughput allocation. At any given time, a validator is expected to have many outstanding IBs with most other validators, where they keep track of each other’s throughput allocation and outstanding IBs. If Bob sees that Alice’s outstanding IBs are close to her throughput allocation, then Bob does not enter into any more IBs with Alice, because there is a high chance she will not be able to return the favor.

Also, there is a certain lag until a tx fee is relayed back to its originator, since Alice has to wait until Bob publishes a transaction, for the IB to be settled.

IBs function similarly with delegators:

  1. Dan specifies Alice as the issuer of the IB in his tx header.
  2. Bob includes Alice’s tx, generating an IB between Alice and Bob.
  3. Later, Alice includes one of Bob’s tx, settling the IB and receiving the tx fee back.
  4. Alice takes a commission and relays the rest of the back to Dan.

Caveat: While inter-validator agreements are enforced by the protocol, validator-delegator agreements do not have to be. Alice can track whether Dan’s delegation is enough to cover the tx fee, and not relay the fee if it’s not.

To summarize, IBs allow validators to keep an account of inclusion of each other’s transactions. The fee is locked up until the favor is returned, so the issuer has an incentive to include the holder’s transaction to receive the fee back. In a functioning system, validators keep track of IBs: They favor the txs of validators who have returned the favor in the past, and refrain from including the txs of validators that don’t return the favor.

(This work was presented in a community call, click here to see the video.)

This research was conducted at CasperLabs, where we are building the truly decentralized, scalable, next generation Proof-of-Stake network.