Ethereum’s Issuance: uncleReward

Published on: Aug 15, 2020 Last edited: Jan 8, 2023

Second in a series about issuance

This the second in a series of two articles detailing Ethereum’s issuance. Read the first part, which discusses the blockReward calculation. Also, see the code base for the actual code. This article discusses the uncleReward.

Uncle Reward

Previously, we looked at the ungrammatical second sentence in Section 11.3 of Ethereum’s Yellow Paper. In the first article, we discussed the first half of that sentence concerning blockReward. In this article we discuss the remaining half of that sentence (shown below) which details the uncleReward.

It would be more accurate for the Yellow Paper to say that the “beneficiary of each ommer gets rewarded…” as there may be more than one uncle in the block, each with a different miner. We call this reward the uncleReward.

The calculation of the uncleReward is a function of the blockNumber in which it appears, the uncle’s own blockNumber, and the baseReward from the previous article. A block “becomes an uncle” when it shows up in the uncle list of a canonical block.

The uncleReward is calculated from the block’s baseReward reduced by 1/8 for each block the uncle is distant from the current block. If an uncle is more than six blocks old, it is not rewarded

Small Detour

Before we proceed, let’s take a small detour to look at the fourth sentence of Section 11.3, the only sentence we haven’t looked at yet. This sentence informs the calculation of minerReward.

This simplifies our concerns. It means we don’t have to keep track of previously applied rewards. The winner of a blockReward may also win one or more uncleRewards in the same block. Furthermore, a single miner may win both uncleRewards in the same block.

Back to the Main Line…

The uncleReward is described by the following set of three unnecessarily-complicated equations (163, 164, and 165):

We will look at each one separately. Starting with Equation 163:

where…

Translating Equation 163 into English, it says “For each uncle in the block’s uncle list (if any), the account of the uncle’s miner either (a) remains empty if it was previously empty and the uncleReward is zero, or (b) the account transitions to a new state (called a-prime) as per Equation 164”:

where…

This translates to English as, “The state of the account of the uncle’s miner after the block, a-prime, is the same as it was prior to the block except for the fact that balance has increased by the value R (the uncleReward).

And finally, Equation 165 defines the uncleReward:

where…

Translating this final bit to English: “The uncleReward is the baseReward lessened by 1/8 for each block that the uncle is distant from the present block.”

Note that the uncle’s blockNumber will always be less than the block’s blockNumber, making the value in the innermost parentheses always negative, and thereby lowering the uncleReward for each block distant from the front of the chain.

In Code

All of the above mumbo-jumbo fits nicely into this TrueBlocks code:

These calculations, at least to me, are much easier when written in code than they are in the Yellow Paper .

Note that getUncleReward needs to be called for each uncle in the block; therefore, we must first call getUncleCount, and spin to query for each uncle block. Then, we can extract the uncle’s block number, and calculate uncleReward.

We accumulate the rewards for the uncles and return that value to the caller:

Rolling it Up

We’ve shown that the blockReward and the uncleReward are not that complicated, and that both are functions of blockNumber and nUncles.

Until now, we’ve shown this calculation for individual blocks. The only thing left to do is to roll through each block in the chain, accumulating the results for presentation.

We use a C++ accumulator class we call CReconciliation. The name implies an additional feature that we will discuss in the README of the code base where we ‘reconcile’ the expected or modeled values with actual account balances directly from the chain.

There have been other proposed scripts to the Crypto Twitter uproar. Those scripts only model the behavior of the chain. They do not validate or audit the behavior. We explain this auditing process in the README.

For now, we conclude this article with code that processes the rewards for each block.

forEvery…Thing…

The following code shows an excellent feature of TrueBlocks.

TrueBlocks provides many functions that start with forEvery, such as forEveryBlock, forEveryAddressInBlock, forEveryTransactionInBlock, forEveryIndexFile, etc.

These functions are similar in nature to Javascript’s map and reduce. One sends an arbitrary function and arbitrary data pointer to each block in the chain (or each transaction, or each address, or whatever) and allows the function to be applied to the data.

This tends to make the topmost code of a TrueBlocks app very minimal:

One need only define the function calcRewards, which we’ve done throughout these two articles.

The above code spins through each block, accumulating, auditing, and presenting the data for that block, and then reports the results of the accumulated data to the screen.

One Final Thought

Here, I wish to interject my own personal opinion: the Yellow Paper is stupidly over-complicated. The code that generates the Ether Supply is, in the end, trivial. For some ungodly reason, the specification wildly over-complicates it. I suppose that’s the nature of engineers with a Ph.D.

Support Our Work

I wish to thank Meriam Zandi for her help in this article.

Help us continue our work. Visit our GitCoin grant page here: https://gitcoin.co/grants/184/trueblocks, and donate today.

Or, if you’d rather not expose yourself to scrutiny, and you’d still like to donate, send ETH to 0xf503017d7baf7fbc0fff7492b751025c6a78179b.

Also, Read

Edit this page on GitHub