{ "cells": [ { "cell_type": "code", "execution_count": 1, "id": "7ef1cd69-3e8e-4190-9ea9-61679006b43d", "metadata": { "tags": [] }, "outputs": [], "source": [ "%config InlineBackend.figure_format = 'svg'\n", "\n", "import os, sys\n", "sys.path.insert(1, os.path.realpath(os.path.pardir))\n", "# You may remove the two lines above if you have installed abm1559 from pypi\n", "\n", "from typing import Sequence, Dict, Tuple\n", "\n", "from abm1559.utils import constants\n", "gamma = 500000\n", "constants[\"SIMPLE_TRANSACTION_GAS\"] = gamma\n", "\n", "from abm1559.config import rng\n", "\n", "from abm1559.txs import Tx1559\n", "\n", "from abm1559.txpool import TxPool\n", "\n", "from abm1559.users import User1559\n", "\n", "from abm1559.userpool import UserPool\n", "\n", "from abm1559.chain import (\n", " Chain,\n", " Block1559,\n", ")\n", "\n", "from abm1559.simulator import (\n", " spawn_poisson_demand,\n", ")\n", "\n", "import matplotlib.pyplot as plt\n", "import pandas as pd\n", "pd.set_option('display.max_rows', 1000)\n", "import numpy as np\n", "import seaborn as sns\n", "from tqdm.notebook import tqdm\n", "from itertools import product\n", "\n", "# x | x | x | x | too late\n", "# 0 1 2 3 4\n", "\n", "class UserSharded(User1559):\n", " def __init__(self, wakeup_block, **kwargs):\n", " super().__init__(wakeup_block, **kwargs)\n", " rng = kwargs[\"rng\"]\n", " window_size = kwargs[\"window_size\"]\n", " self.publishing_time = rng.choice(range(window_size+1))\n", " self.inclusion_time = -1\n", " \n", " def publish(self, env):\n", " current_block = env[\"current_block\"]\n", " window_size = env[\"window_size\"]\n", " if self.inclusion_time == -1:\n", " return False\n", " if current_block - self.inclusion_time >= window_size:\n", " return False\n", " if current_block - self.inclusion_time == self.publishing_time:\n", "# print(f\"User waking up at {self.wakeup_block} publishing after {self.publishing_time} blocks at block {current_block}\")\n", " return True\n", " return False\n", " \n", " def create_transaction(self, env):\n", " tx_params = self.decide_parameters(env)\n", "\n", " tx = TxSharded(\n", " sender = self.pub_key,\n", " tx_params = tx_params,\n", " )\n", "\n", " return tx\n", " \n", "class UserShardedHonest(UserSharded):\n", " def __init__(self, wakeup_block, **kwargs):\n", " super().__init__(wakeup_block, **kwargs)\n", " self.publishing_time = 0\n", "\n", "class TxSharded(Tx1559):\n", " \"\"\"\n", " Inherits from :py:class:`abm1559.txs.Transaction`. A 1559-type transaction.\n", " \"\"\"\n", "\n", " def __init__(self, sender, tx_params, **kwargs):\n", " super().__init__(sender, tx_params, **kwargs)\n", " self.blob_published = False\n", " \n", " def publish_blob(self):\n", " self.blob_published = True\n", " \n", " def __str__(self):\n", " return f\"Sharded Transaction {self.tx_hash.hex()}: max_fee {self.max_fee}, gas_premium {self.gas_premium}, gas_used {self.gas_used}, blob_published {self.blob_published}\"\n", " \n", "MAX_TX_POOL = 500\n", "MIN_PREMIUM = 1e9\n", "\n", "class TxPoolLimit(TxPool):\n", " \n", " def __init__(self, max_txs=MAX_TX_POOL, min_premium=MIN_PREMIUM, **kwargs):\n", " super().__init__(**kwargs)\n", " self.max_txs = max_txs\n", " self.min_premium = MIN_PREMIUM\n", " \n", " def add_txs(self, txs: Sequence[Tx1559], env: dict) -> Sequence[Tx1559]:\n", " for tx in txs:\n", " self.txs[tx.tx_hash] = tx\n", " \n", " if self.pool_length() > self.max_txs:\n", " sorted_txs = sorted(self.txs.values(), key = lambda tx: -tx.tip(env))\n", " self.empty_pool()\n", " self.add_txs(sorted_txs[0:self.max_txs], env)\n", " return sorted_txs[self.max_txs:]\n", " \n", " return []\n", "\n", "class TxPool1559(TxPoolLimit):\n", " \n", " def select_transactions(self, env, user_pool=None, rng=rng) -> Sequence[Tx1559]:\n", " # Miner side\n", " max_tx_in_block = int(constants[\"MAX_GAS_EIP1559\"] / constants[\"SIMPLE_TRANSACTION_GAS\"])\n", "\n", " valid_txs = [tx for tx in self.txs.values() if tx.is_valid(env) and tx.tip(env) >= self.min_premium]\n", " rng.shuffle(valid_txs)\n", "\n", " sorted_valid_demand = sorted(\n", " valid_txs,\n", " key = lambda tx: -tx.tip(env)\n", " )\n", " selected_txs = sorted_valid_demand[0:max_tx_in_block]\n", "\n", " return selected_txs\n", " \n", "def update_basefee_sharded(chain: Chain, basefee: int, window_size: int) -> int:\n", " \"\"\"\n", " Basefee update rule\n", "\n", " Args:\n", " block (Block): The previous block\n", " basefee (int): The current basefee\n", "\n", " Returns:\n", " int: The new basefee\n", " \"\"\"\n", " \n", " head = chain.current_head\n", " adjustment_quotient = constants[\"BASEFEE_MAX_CHANGE_DENOMINATOR\"] * window_size\n", " new_basefee = basefee\n", " \n", " for w in range(window_size):\n", " block = chain.blocks[head]\n", " gas_used = sum([tx.gas_used for tx in block.txs if tx.blob_published])\n", "# print(f\"Gas used by block head - {w} (height {len(chain.blocks) - w - 1}): {gas_used}\")\n", " if gas_used == constants[\"TARGET_GAS_USED\"]:\n", " pass\n", " elif gas_used > constants[\"TARGET_GAS_USED\"]:\n", " gas_delta = gas_used - constants[\"TARGET_GAS_USED\"]\n", " fee_delta = max(new_basefee * gas_delta // constants[\"TARGET_GAS_USED\"] // adjustment_quotient, 1)\n", " new_basefee = new_basefee + fee_delta\n", " else:\n", " gas_delta = constants[\"TARGET_GAS_USED\"] - gas_used\n", " fee_delta = new_basefee * gas_delta // constants[\"TARGET_GAS_USED\"] // adjustment_quotient\n", " new_basefee = new_basefee - fee_delta\n", " head = block.parent_hash\n", " if head == b'\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00':\n", " break\n", " \n", " return new_basefee\n", "\n", "def update_basefee_delayed(chain: Chain, basefee: int, window_size: int) -> int:\n", " \"\"\"\n", " Basefee update rule\n", "\n", " Args:\n", " block (Block): The previous block\n", " basefee (int): The current basefee\n", "\n", " Returns:\n", " int: The new basefee\n", " \"\"\"\n", " \n", " head = chain.current_head\n", " adjustment_quotient = 4 * constants[\"BASEFEE_MAX_CHANGE_DENOMINATOR\"]\n", " new_basefee = basefee\n", " \n", " for w in range(window_size):\n", " block = chain.blocks[head]\n", " head = block.parent_hash\n", " if head == b'\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00':\n", " break\n", " \n", " gas_used = sum([tx.gas_used for tx in block.txs if tx.blob_published])\n", " if gas_used == constants[\"TARGET_GAS_USED\"]:\n", " pass\n", " elif gas_used > constants[\"TARGET_GAS_USED\"]:\n", " gas_delta = gas_used - constants[\"TARGET_GAS_USED\"]\n", " fee_delta = max(new_basefee * gas_delta // constants[\"TARGET_GAS_USED\"] // adjustment_quotient, 1)\n", " new_basefee += fee_delta\n", " else:\n", " gas_delta = constants[\"TARGET_GAS_USED\"] - gas_used\n", " fee_delta = new_basefee * gas_delta // constants[\"TARGET_GAS_USED\"] // adjustment_quotient\n", " new_basefee -= fee_delta\n", " \n", " return new_basefee\n", "\n", "def simulate_sharded(\n", " demand_scenario, txpool, UserClass,\n", " window_size = 4, extra_metrics = None, rng = rng, silent=False,\n", " basefee_update_fn = update_basefee_sharded\n", "):\n", " # Instantiate a couple of things\n", " chain = Chain()\n", " metrics = []\n", " user_pool = UserPool()\n", " \n", " # `env` is the \"environment\" of the simulation\n", " env = {\n", " \"basefee\": 1 * 1e9,\n", " \"current_block\": None,\n", " \"window_size\": window_size,\n", " }\n", "\n", " for t in tqdm(range(len(demand_scenario)), disable=silent, desc=\"simulation loop\", leave=False):\n", " \n", " # Sets current block\n", " env[\"current_block\"] = t\n", " \n", " # Reset the random number generator with new seed to generate users with same values across runs\n", " rng = np.random.default_rng((2 ** t) * (3 ** 1))\n", " \n", " ### SIMULATION ###\n", "\n", " # We return some demand which on expectation yields `demand_scenario[t]` new users per round\n", " users = spawn_poisson_demand(t, demand_scenario[t], UserClass, rng=rng, window_size = window_size)\n", " \n", " # Add new users to the pool\n", " # We query each new user with the current basefee value\n", " # Users either return a transaction or None if they prefer to balk\n", " decided_txs = user_pool.decide_transactions(users, env)\n", "\n", " # New transactions are added to the transaction pool\n", " # `evicted_txs` holds the transactions removed from the pool for lack of space\n", " pool_limit_evicted_txs = txpool.add_txs(decided_txs, env)\n", "\n", " # The best valid transactions are taken out of the pool for inclusion\n", " selected_txs = txpool.select_transactions(env, rng = rng)\n", " \n", " txpool.remove_txs([tx.tx_hash for tx in selected_txs])\n", "\n", " # We create a block with these transactions\n", " block = Block1559(\n", " txs = selected_txs, parent_hash = chain.current_head,\n", " height = t, basefee = env[\"basefee\"]\n", " )\n", " \n", " # The block is added to the chain\n", " chain.add_block(block)\n", " \n", " # We ask publishers in blocks head:head-window_size if they want to publish\n", " head = chain.current_head\n", " \n", " # Set inclusion time\n", " for user in [user_pool.users[tx.sender] for tx in chain.blocks[chain.current_head].txs]:\n", " user.inclusion_time = env[\"current_block\"]\n", " \n", " for w in range(window_size):\n", " block = chain.blocks[head]\n", " for tx in block.txs:\n", " sender = tx.sender\n", " if user_pool.users[sender].publish(env):\n", " tx.publish_blob()\n", " head = block.parent_hash\n", " if head == b'\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00':\n", " break\n", " \n", " ### METRICS ### \n", " row_metrics = {\n", " \"block\": t,\n", " \"users\": len(users),\n", " \"decided_txs\": len(decided_txs),\n", " \"pool_limit_evictions\": len(pool_limit_evicted_txs),\n", " \"included_txs\": len(selected_txs),\n", " \"basefee\": env[\"basefee\"] / 1e9, # to Gwei\n", " \"pool_length\": txpool.pool_length(),\n", " \"gas_used\": block.gas_used(),\n", " }\n", " \n", " if not extra_metrics is None:\n", " row_metrics = {\n", " **row_metrics,\n", " **extra_metrics(env, users, user_pool, txpool),\n", " }\n", " \n", " metrics.append(row_metrics)\n", " \n", " # Finally, basefee is updated and a new round starts\n", " env[\"basefee\"] = basefee_update_fn(chain, env[\"basefee\"], env[\"window_size\"])\n", "\n", " return (pd.DataFrame(metrics), user_pool, chain)" ] }, { "cell_type": "code", "execution_count": 2, "id": "300842d9-3b22-44a4-acf1-4663c4fe472d", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "", "version_major": 2, "version_minor": 0 }, "text/plain": [ "simulation loop: 0%| | 0/2000 [00:00 blob is published right away, counts in the very next basefee update.\n", " - Delay = 4 => User publishes their blob too late, the blob is never counted in any basefee update, counted as missing.\n", " \n", "## Rolling-window basefee\n", "\n", "We update basefee according to the multiplicative formula in the [note](https://notes.ethereum.org/@barnabe/Bk1zeDimK).\n", "\n", "### Simulation with late users\n", "\n", "In this simulation, the blob delay is drawn randomly among integers 0 to 4 (inclusive). This is the average block size we record. Note that the target is 12.5M, so the average block size plotted below in orange is way above." ] }, { "cell_type": "code", "execution_count": 3, "id": "9010a1b6-c9cc-44e0-a128-a37cb5246e31", "metadata": {}, "outputs": [], "source": [ "def running_average(chain, head, window_size):\n", " total_used = 0\n", " count = 0\n", " for i in range(window_size):\n", " block = chain.blocks[head]\n", " total_used += sum([tx.gas_used for tx in block.txs if tx.blob_published])\n", " count += 1\n", " head = block.parent_hash\n", " if head == b'\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00':\n", " break\n", " return total_used / float(count)\n", "\n", "def get_ma_df(chain, window_size=20):\n", " head = chain.current_head\n", " avgs = []\n", " for i in range(len(chain.blocks)):\n", " avgs = [running_average(chain, head, window_size)] + avgs\n", " block = chain.blocks[head]\n", " head = block.parent_hash\n", " return pd.DataFrame({ \"avg_gas_used\": avgs, \"block\": list(range(len(chain.blocks))) })" ] }, { "cell_type": "code", "execution_count": 4, "id": "0105018f-a7e2-428c-ae7d-3103acce3475", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", " \n", " 2021-10-19T16:42:22.263642\n", " image/svg+xml\n", " \n", " \n", " Matplotlib v3.4.2, https://matplotlib.org/\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n" ], "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "get_ma_df(chain).plot(\"block\", \"avg_gas_used\", style={\"avg_gas_used\": 'orange'})" ] }, { "cell_type": "markdown", "id": "072ebf9f-1311-494f-b671-398fabcdc8c4", "metadata": {}, "source": [ "Comparing basefee (plotted in blue below) with later plots, we see that basefee is too low, i.e., the supply of blob space is underpriced, hence the blocks are too large." ] }, { "cell_type": "code", "execution_count": 5, "id": "aed7bbe2-538c-4e0e-85b9-5c6fa62375ad", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", " \n", " 2021-10-19T16:42:22.432561\n", " image/svg+xml\n", " \n", " \n", " Matplotlib v3.4.2, https://matplotlib.org/\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n" ], "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "df.plot(\"block\", \"basefee\")" ] }, { "cell_type": "markdown", "id": "cb8e4f78-da9f-4871-869d-0c2acf71b702", "metadata": {}, "source": [ "The rolling window cannot target the correct average block size. Since blobs may be published later, either the gas used is currently correct, or underestimated. This implies that basefee is \"too low\" and over time too many blobs get in." ] }, { "cell_type": "markdown", "id": "050275a3-c7bf-401f-aa79-a120eacd830b", "metadata": {}, "source": [ "### Simulation with early users\n", "\n", "We redo the simulation with honest sharded users: always publish their blob with delay 0, basefee updates always done with the \"correct\" block size." ] }, { "cell_type": "code", "execution_count": 6, "id": "b681481b-9a82-45fc-9961-53f14f7283c9", "metadata": { "tags": [] }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "", "version_major": 2, "version_minor": 0 }, "text/plain": [ "simulation loop: 0%| | 0/2000 [00:00" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", " \n", " 2021-10-19T16:42:42.560665\n", " image/svg+xml\n", " \n", " \n", " Matplotlib v3.4.2, https://matplotlib.org/\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n" ], "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "get_ma_df(chain).plot(\"block\", \"avg_gas_used\", style={\"avg_gas_used\": 'orange'})" ] }, { "cell_type": "markdown", "id": "b65091f2-6d2e-4aa2-8985-6194b6bf014d", "metadata": {}, "source": [ "Basefee follows, stabilising at a level that prices accurately the demand." ] }, { "cell_type": "code", "execution_count": 8, "id": "a289a2d3-0f43-4769-894a-f84300d769fc", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", " \n", " 2021-10-19T16:42:42.734295\n", " image/svg+xml\n", " \n", " \n", " Matplotlib v3.4.2, https://matplotlib.org/\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n" ], "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "df.plot(\"block\", \"basefee\")" ] }, { "cell_type": "markdown", "id": "a3de7167-dc53-416d-916b-2665486d9423", "metadata": {}, "source": [ "## Delayed accounting basefee\n", "\n", "In this version, we do not apply the rolling window update to basefee, but the usual basefee update, except with a lag of `window_size` blocks." ] }, { "cell_type": "code", "execution_count": 9, "id": "ab018c74-e3ad-4565-a1d8-9528a6ecb658", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "", "version_major": 2, "version_minor": 0 }, "text/plain": [ "simulation loop: 0%| | 0/2000 [00:00" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", " \n", " 2021-10-19T16:43:03.212446\n", " image/svg+xml\n", " \n", " \n", " Matplotlib v3.4.2, https://matplotlib.org/\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n" ], "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "get_ma_df(chain).plot(\"block\", \"avg_gas_used\", style={\"avg_gas_used\": 'orange'})" ] }, { "cell_type": "markdown", "id": "2a240474-0d0b-4f50-afde-1e196d6d112f", "metadata": {}, "source": [ "Here too basefee stabilises:" ] }, { "cell_type": "code", "execution_count": 11, "id": "2d734217-2a88-4d4f-8c44-d5958582450f", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", " \n", " 2021-10-19T16:43:03.378496\n", " image/svg+xml\n", " \n", " \n", " Matplotlib v3.4.2, https://matplotlib.org/\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n" ], "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "df.plot(\"block\", \"basefee\")" ] }, { "cell_type": "raw", "id": "ff9c0ed1-737c-4e0a-954a-ecd269c52545", "metadata": {}, "source": [ "EIP-1559 fee market for shards" ] }, { "cell_type": "raw", "id": "f88cac89-1cc3-4b8d-8cae-210ab620bc84", "metadata": {}, "source": [ "Looking at the rolling window adjustment and delayed accounting for basefee" ] }, { "cell_type": "raw", "id": "be769112-8ce3-41ca-953d-1c7e01a4954a", "metadata": {}, "source": [ "// References + footnotes\n", "\n", "// Authors\n", "let authorData = [\"barnabe\"];" ] }, { "cell_type": "raw", "id": "ef5286e1-e844-426c-b7bd-602d679b4de1", "metadata": {}, "source": [] } ], "metadata": { "date": "12/10/2021", "desc": "Looking at basefee update rules for shards", "image": "https://ethereum.github.io/rig/static/rig.png", "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.7" }, "path": "notebooks/sharding.html", "repo": "abm1559", "title": "Sharding EIP-1559" }, "nbformat": 4, "nbformat_minor": 5 }