Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added new gas mechanics design. #1411

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions design/gas/Design_gas.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Obscuro Gas Design

## Overview

The revenue generation mechanism for Obscuro hinges on the collection of gas fees. Notably, as Obscuro operates as a layer 2 protocol, the cost of operations surpasses that of layer 1, since it has to cover layer 1 gas costs in addition to its operational expenses. Unlike layer 1 miners, who only shoulder operational costs, there's no expenditure prerequisite for block publication on Obscuro except for the static cost of stake.
StefanIliev545 marked this conversation as resolved.
Show resolved Hide resolved

The gas mechanics of a protocol normally have the following functions:
1) Revenue for node operators.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Revenue for node operators.

Has not been discussed (just in case it was missed :) )

2) Congestion management and prevention of denial of service.
3) Price discovery mechanism for transactions.

## Arbitrum Gas Mechanics

Arbitrum does not describe how their gas mechanics work and how would price change with network congestion. It is implied in [this](https://medium.com/offchainlabs/understanding-arbitrum-2-dimensional-fees-fd1d582596c9) article that there is indeed a mechanism that increases the L2 cost, but their public documentation seems to just call the gas price unit `ArbGas` without elaborating how its derived. It's possible that it is actually static and what is implied in the article is that the L1 price influenced the change in the L2 gas cost.

## Optimism Gas Mechanics

Optimism is EIP-1559 compliant and has a [public dashboard](https://public-grafana.optimism.io/d/9hkhMxn7z/public-dashboard?orgId=1&refresh=5m) which showcases gas prices for both L1 and L2. During time of writing, the gas dashboard clearly showed different spikes between L1 prices and L2 prices. They do not elaborate however when is the base fee modified, presumably its at the time of a rollup as they have no concept of batches in their current live version. They mention that the parameters of EIP-1559 are different, presumably the gas fee increase/decrease params. Optimism bedrock should however introduce blocks and those parameters should change.

### Initial Bootstrapping of Network Gas

Similar to other layer 2 protocols, Obscuro seeks to leverage Ethereum for gas usage. To facilitate this, Ethereum must first be bridged over to Obscuro. Although the bridge typically operates with a relayer, relaying a message incurs a gas cost. Hence, to bootstrap the entire layer 2 protocol, including relayers and bridges, cross-chain messages concerning Ethereum depositing into an account will be automatically executed on layer 2 at no cost and without the need for relaying. This ensures no additional transactions that necessitate publishing to layer 1.


### Types of Transactions

Ethereum has developed to accommodate several [transaction types](https://docs.infura.io/networks/ethereum/concepts/transaction-types):
1) Regular transactions - they work based on a gas auction.
2) Access list transactions - same as previous ones, but they also announce what storage access they are supposed to perform when executed.
3) EIP-1559 - the new transactions that burn the gas fee and work with tips in order to achieve a fair system.

Usually layer 2's support EIP-1559 so there is a pending question of what we would need to support. Normally all support EIP-1559, but not all support gas auction (or mention if they do). As most wallets have moved over to EIP-1559 it is preferable to start with support for it and add the support for the gas auction later on after everything else is finished.
Note that Binance for example still uses Type 1 transactions and has not migrated to EIP-1559.

## Requirements

1. Ethereum must be used for gas operations and bridged from the layer 1 protocol.
2. Bridged gas should automatically deposit into the respective addresses.
3. Gas-consuming transactions should include a layer 1 cost component for calldata publishing and a layer 2 component that covers execution costs and prevents endless transaction execution.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't the l2 gas component implemnet the eip 1559 as well? To regulate the congestion on the L2?
If batches are 50% full, the l2 base fee increases, etc

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per the discord conversation, we need to address what it means to have batches full which is currently not a concept. I'll update the design with this.

4. L2 gas price should be configurable. Furthermore it should support being free whilst still not allowing non halting execution.
5. The gas mechanics need to prevent denial of service attacks.
6. EIP-1559 transactions should have their base fee + tip deposited to the sequencer without any ETH being burned.

StefanIliev545 marked this conversation as resolved.
Show resolved Hide resolved
## Gas Cost Display

Metamask can disassemble the cost components for layer 1 and layer 2 for specific transactions on Optimism, such as token balance approvals. However, it remains unclear how they achieve this as it's neither fully documented nor supports all transactions.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how can we find out? Is it based on the chainId?
Maybe we can ask them?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bhav will get in touch to get the requirements from their dev team



## Design for Gas Deposit

Given that Ethereum as a currency operates on the layer 1 protocol, it needs to be bridged to Obscuro for usage. This transition mechanism will be facilitated by the standard Obscuro bridge. The deposited value will produce a cross-chain message indicating the Ethereum recipient through the bridge smart contract.

```EthereumDeposited(address receiver, uint256 amount)```

The enclave will automatically pick up this message, along with other cross-chain messages, but it will be treated specially. Upon detection, the enclave will increase the balance of the receiver account by the amount specified in the message. This automatic relaying is needed in order to avoid the chicken and egg problem one would have initially where no relayer has any gas to relay the gas deposit messages. It would also ensure relayers who run out of gas can easily recharge without relying on other relayers if we were to use a different bootstrap mechanism. Note that those deposits will not call the fallback function of the address if it is a smart contract and any deposits to such contracts would later on need a message relayed to verify the message as they would normally.

## Gas Estimation
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't 100% correct, and makes things confusing.

Gas estimation is how much processing power it takes to execute the transaction.
Which is used for network congestion throttling.
Since :

  • The rollup is not executed
  • We're not accounting for rollup compression costs
  • Once a tx is minted into a batch it's "soft-final"
  • We don't have a finality mechanism that allows users to bump their txs to be rolled up faster

I don't believe there is a point in changing how the gas estimation for a given transaction is done. The binary search tree done in geth should be enough, and I don't see the need to add the L1 calldata cost.

My suggestion would be to leave the gas estimation as geth and move additional payout to the gas price.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gas estimation needs to reflect what the user will actually pay.


When an RPC call for gas estimation is made to Obscuro, the returned estimate should include the expected layer 1 calldata cost alongside the usual execution-based gas estimation. This can be achieved by taking an estimation for layer 1 minFee per gas, determining the calldata cost of the transaction, and adding this to the standard gas estimate.

`Gas estimate = L1_gas_fee * calldata_gas + estimated_l2_gas`

## Gas Expenditure

Before executing a transaction at Obscuro, we must automatically deduct the layer 1 costs for the transaction from the sender's balance. This can be done directly through the stateDB before processing. Ideally, the remaining balance will be refunded, simulating a scenario where the gas limit has been spent. However, potential overruns of execution costs could result in transactions exceeding their set gas limit.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why deduct the layer 1 costs for the transaction from the sender's balance ?

What if the gas price was bumped for a given transaction? Such that :

  • gas_price = l2_current_gasPrice + projected_number_txs_in_a_rollup / l1_projected_gasPrice

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This calculation makes it so transactions that spend more gas on the L2 to pay for more L1 fees, while value transfers will pay little in L1 fees. It's not really a competitive solution with other rollups. We'd have some users subsidizing others.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might be missing somthing, can you explain a bit more about how is one user subsidizing others?
The lowest possible transaction is a value transfer, which has a fixed L2 gas cos, which will potentially be a fixed L1 Rollup cost, so it should pay a smaller L1 fee than a contract creation or other transactions right ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Value transfer should pay less for L1 cost than transactions with encoded calldata, correct. But it should still pay its full L1 gas price. If I do a transaction to say a smart contract that has a fallback (so no calldata) and in this contract you have a for loop er whatever, the calldata is pretty much the same as it would be for a value transfer, yet because L1 fees are factored in the gas price each iteration of the loop would be subsidizing L1 costs that are completely irrelevant to the computation.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, because the gas limit of that said transaction is higher than the value transfer.
So let's say there's a Quirky Tx that does a call on a contract which does a for loop (spins a while).

gasPrice: ( L2Gasprice + L1Gasprice)
Tx A: Value transfer - tx rollup size 10 - gas limit 21 000 - Final gas cost 21 000 * gasPrice
Tx B: Deploy Contract - tx rollup size 3000 - gas limit 120 000 - Final gas cost 120 000 * gasPrice
Tx C: Quirky Tx - tx rollup size 40 - gas limit 500 000 - Final gas cost 500 000 * gasPrice

The rollup size does not matter for the gas price nor for the final gas paid by the user.
Saying that tx A and C are subsidizing Tx B doesn't make a lot of sense because they are paying network congestion on the L2.

That being said, if you want to figure out a way that you can adjust the L1GasPrice component based on the potential tx rollup size, I think that's a good idea, but perhaps not needed for a first iteration imo.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's say we have a mechanism to estimate the L1 eth gas cost.
The following happens:

  1. Obscuro user submits TX1 (size=1kb) and the L2 execution cost is 1Million gas.
  2. Tx1 enters the enclave which will do the following:
    a. Check that the user has enough balance to pay for size(Tx1) * estimated_publishing cost. If yes, deduct that amount. Also, record this amount, in case it needs to be payed back if the tx is not included.
    b. Check the user has the minium gas required for Obscuro. Deduct that
    c. Start executing, until the tx finishes, or the user runs out of gas.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the initial approach I was thinking about as it is most intuitive to implement, but the problem with it is that transactions will result in spending more ETH than authorised when signed. When a user signs there is an agreement over the total gas cost that can be deducted from the balance + the total value being sent in the transaction; Deducting externally of the gas will result in higher than authorized "total" gas spend.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but why do you have to deduct more than authorised?

Obscuro user submits TX1 (size=1kb) and the L2 execution cost is 1Million gas.

Tx1 enters the enclave which will do the following:

a. Check that the user has enough balance to pay for size(Tx1) * estimated_publishing cost. Also if the tx is authorised to spend that. If yes, deduct that amount. Also, record this amount, in case it needs to be payed back if the tx is not included.
b. Check the user has the minium gas required for Obscuro. Deduct that
c. Start executing, until the tx finishes, or the user runs out of gas.


The best approach would be to both decrease the balance and reduce the transaction's gas limit, assuming that layer 1 prices will be factored into this gas limit, given that the limit is set based on the eth_estimateGas call.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the key element of the design.
Needs to be elaborated on a bit more



## Monitoring and Adjusting the L1 Fee

In order to pay for rollups without losing money, Obscuro needs to collect sufficient gas fees for the L1 cost including any differences caused due to time. EIP-1559 made the gas fee predictable. With each block a miner might choose to increase or reduce it by a % of the previous block. This means we can implement a prediction mechanism that prices the worst case scenario by increasing the current L1 gas cost with the required percentage based on how many blocks will the L1 produce until we hit our rollup duration limit.

It's important to note that Optimism has chosen not to track L1 prices precisely and impose a limit on how much transaction fees can be affected. They initially had a 10% overcharge on the l1 gas cost to cover for potential spikes, but have now migrated to a model they don't really explain in their docs.

This leaves us with two options:
1) Attempt to precisely estimate gas fees and refund anything overcharged when the rollup is published
2) Do a simple overcharge and follow what Optimism have done as this model has proven quite successful for them revenue wise.


## Sequencer Compensation

Upon the production of a batch, all transactions enclosed within it would have made payments for gas. The aggregate sum, encompassing both layer 1 and layer 2 costs, will subsequently be debited to the address denoted as coinbase within the batch. It would be more practical for this address to be configurable. The reason being that the sequencer's address is derived from a key that must be safeguarded, and implementing any logic for fund transfer from it would necessitate code development.

This entire logic can happen in the `evm_facade.go`.

## Batch gas limit

In order to prevent denial of service attacks we need to have a batch gas limit. This would lend itself well to Obscuro being EIP-1559 complaint making us able to dynamically price L2 fees based on congestion. For the initial version of the gas mechanics we can use a fixed L2 gas price and later on migrate to EIP-1559 compliancy. Taking cue from Optimism's approach to modifying the parameters, we should divide the parameters for Obscuro proportionally to L1 block creation time vs Obscuro L2 batch creation time. This should yield approximately identical behaviour.