# Client-compatible "eth_totalSupply" Fetch the total ETH supply from any Ethereum client pair (EL-CL). ## Motivation Currently, there is not a standardized way to fetch the total ETH in circulation. In order to provide more transparency and ease of use to the ecosystem, we propose a standardized JSON-RPC method to address this. ## Project description This project aims to create a standardized JSON-RPC API that is compatible across clients in order to get the total ETH in circulation at a given block number. #### Example ``` curl https://.../ \ --header 'Content-Type: application/json' \ --data '{ "method": "eth_totalSupply", "params":["block_number (default:'latest')"], "id": 1, "jsonrpc": "2.0" }' ``` **result** ``` {"jsonrpc":"2.0","id":1,"result":"0x7270E00"} ``` Every Ethereum client pair that implements this, will be able to return the total ETH at a given block. ## Specification In order to get the total ETH supply, it is necessary to independently get the total ETH in the EL and CL as they have separate accountings. We can represent the total ETH supply as: ``` supply = EVM balances + beacon chain balances - beacon chain deposits ``` ***There are two main ways to get the total ETH supply (Execution Layer).*** #### 1. Supply delta per block The idea here is to create a hook that stores the supply delta of each block every time a new block is appended to the chain. Geth already has a [live tracer](https://github.com/ethereum/go-ethereum/pull/29347) implemented that does this. **Example output geth tracer** ``` {"delta":320000001000000000000000000,"reward":0,"withdrawals":0,"burn":0,"blockNumber":0,"hash":"0x25a5cc106eea7138acab33231d7160d69cb777ee0c2c553fcddf5138993e6dd9","parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000"} {"delta":2000000000000000000,"reward":2000000000000000000,"withdrawals":0,"burn":0,"blockNumber":1,"hash":"0x696d95da6726a67afd5be2a37d3883e9be8008491b30d5bd1069ea5922fa2a41","parentHash":"0x25a5cc106eea7138acab33231d7160d69cb777ee0c2c553fcddf5138993e6dd9"} {"delta":2000000000000000000,"reward":2000000000000000000,"withdrawals":0,"burn":0,"blockNumber":2,"hash":"0x89b977ffab1052f5f6f778e4680354a8a1a1e0f623db9b2f20beba9f36f68721","parentHash":"0x696d95da6726a67afd5be2a37d3883e9be8008491b30d5bd1069ea5922fa2a41"} {"delta":2000000000000000000,"reward":2000000000000000000,"withdrawals":0,"burn":0,"blockNumber":3,"hash":"0x1970908e724ac37efbb0b3bf9f77ebdf04e1ccb3f9da1463bec00252cb3a701f","parentHash":"0x89b977ffab1052f5f6f778e4680354a8a1a1e0f623db9b2f20beba9f36f68721"} ``` **It can also be done with Reth ExEx*** #### 2. Iterate over all Ethereum accounts For this option, we need to iterate over the state trie and sum up the balances. This option is very computationally expensive and it adds a lot of extra work to the node. ### Consensus Layer supply In order to get the ETH from the consensus layer, we just iterate and sum up the validators' balances. ### Simplified Pipeline 1. A user calls "eth_totalSupply (blockN)" using the standard Ethereum JSON-RPC. 2. Once the node receives the command, two sepparate threads are open: 1. get the ETH supply from the consensus layer at block N, 2. get the ETH supply from the execution layer at block N. Sum up all the balances from the delta supply tracer, cache the result so hard work is done only once. 3. Once we have the ETH supply from both layers, we sum them up and subtract the deposits. 4. Return the result to the user. ### Optional flag Due to the fact that this will bring additional constrains to the node, the flag will be optional*. ``` geth .. --totalSupply true ``` ``` reth node --full --totalSupply true ``` *If the additional resources are significant ## Possible challenges - Compare computer resource usage with and without the --totalSupply flag in order to objectively measure how much extra work is put into the node. 1. Memory Usage 2. Disk I/O 3. CPU This is an important point to optimize, aiming to minimize the additional resources required for the nodes as much as possible. - Burden on Node. Optimize the implementation as much as possible so the node d ## Goal of the project To have it implemented in at least one client pair (EL-CL). Once implemented, a user will be able to call the eth_totalSupply api and get the correct result. ### Mentors Sina from the Geth team has been very helpful. ## Resources [geth-live-tracer](https://github.com/ethereum/go-ethereum/pull/29347) [eth-total-supply](https://github.com/lastmjs/eth-total-supply)