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

feat: sum transaction fees and pay on l1 #6522

Merged
merged 6 commits into from
May 20, 2024
Merged
Show file tree
Hide file tree
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
22 changes: 11 additions & 11 deletions barretenberg/cpp/pil/avm/constants.pil
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,22 @@ namespace constants(256);
pol PORTAL_SELECTOR = 2;

// NOTE: constant expression evaluation does not seem to be supported yet in pil
// pol START_GLOBAL_VARIABLES = CALL_CONTEXT_LENGTH + HEADER_LENGTH = 6 + 22 = 28
// pol START_GLOBAL_VARIABLES = CALL_CONTEXT_LENGTH + HEADER_LENGTH = 6 + 23 = 29

// Global Variables
pol CHAIN_ID_SELECTOR = 28;
pol VERSION_SELECTOR = 29;
pol BLOCK_NUMBER_SELECTOR = 30;
pol TIMESTAMP_SELECTOR = 31;
pol COINBASE_SELECTOR = 32;
pol CHAIN_ID_SELECTOR = 29;
pol VERSION_SELECTOR = 30;
pol BLOCK_NUMBER_SELECTOR = 31;
pol TIMESTAMP_SELECTOR = 32;
pol COINBASE_SELECTOR = 33;

pol END_GLOBAL_VARIABLES = 28 + 8; // We only use the first 5 of 8 global variables for now
pol END_GLOBAL_VARIABLES = 29 + 8; // We only use the first 5 of 8 global variables for now

pol START_SIDE_EFFECT_COUNTER = 36;
pol START_SIDE_EFFECT_COUNTER = 37;
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@Maddiaa0 I was confused about why over in #6457 some fields were bumped by two, so just wanted your eyes to make sure this doesn't need a similar operation. If it does, could you explain why?


// Gas
pol FEE_PER_DA_GAS_SELECTOR = 37;
pol FEE_PER_L2_GAS_SELECTOR = 38;
pol FEE_PER_DA_GAS_SELECTOR = 38;
pol FEE_PER_L2_GAS_SELECTOR = 39;

pol TRANSACTION_FEE_SELECTOR = 39;
pol TRANSACTION_FEE_SELECTOR = 40;

Original file line number Diff line number Diff line change
Expand Up @@ -915,63 +915,63 @@ template <typename FF_> class avm_mainImpl {
{
Avm_DECLARE_VIEWS(83);

auto tmp = (avm_main_sel_op_fee_per_da_gas * (avm_kernel_kernel_sel - FF(37)));
auto tmp = (avm_main_sel_op_fee_per_da_gas * (avm_kernel_kernel_sel - FF(38)));
tmp *= scaling_factor;
std::get<83>(evals) += tmp;
}
// Contribution 84
{
Avm_DECLARE_VIEWS(84);

auto tmp = (avm_main_sel_op_fee_per_l2_gas * (avm_kernel_kernel_sel - FF(38)));
auto tmp = (avm_main_sel_op_fee_per_l2_gas * (avm_kernel_kernel_sel - FF(39)));
tmp *= scaling_factor;
std::get<84>(evals) += tmp;
}
// Contribution 85
{
Avm_DECLARE_VIEWS(85);

auto tmp = (avm_main_sel_op_transaction_fee * (avm_kernel_kernel_sel - FF(39)));
auto tmp = (avm_main_sel_op_transaction_fee * (avm_kernel_kernel_sel - FF(40)));
tmp *= scaling_factor;
std::get<85>(evals) += tmp;
}
// Contribution 86
{
Avm_DECLARE_VIEWS(86);

auto tmp = (avm_main_sel_op_chain_id * (avm_kernel_kernel_sel - FF(28)));
auto tmp = (avm_main_sel_op_chain_id * (avm_kernel_kernel_sel - FF(29)));
tmp *= scaling_factor;
std::get<86>(evals) += tmp;
}
// Contribution 87
{
Avm_DECLARE_VIEWS(87);

auto tmp = (avm_main_sel_op_version * (avm_kernel_kernel_sel - FF(29)));
auto tmp = (avm_main_sel_op_version * (avm_kernel_kernel_sel - FF(30)));
tmp *= scaling_factor;
std::get<87>(evals) += tmp;
}
// Contribution 88
{
Avm_DECLARE_VIEWS(88);

auto tmp = (avm_main_sel_op_block_number * (avm_kernel_kernel_sel - FF(30)));
auto tmp = (avm_main_sel_op_block_number * (avm_kernel_kernel_sel - FF(31)));
tmp *= scaling_factor;
std::get<88>(evals) += tmp;
}
// Contribution 89
{
Avm_DECLARE_VIEWS(89);

auto tmp = (avm_main_sel_op_coinbase * (avm_kernel_kernel_sel - FF(32)));
auto tmp = (avm_main_sel_op_coinbase * (avm_kernel_kernel_sel - FF(33)));
tmp *= scaling_factor;
std::get<89>(evals) += tmp;
}
// Contribution 90
{
Avm_DECLARE_VIEWS(90);

auto tmp = (avm_main_sel_op_timestamp * (avm_kernel_kernel_sel - FF(31)));
auto tmp = (avm_main_sel_op_timestamp * (avm_kernel_kernel_sel - FF(32)));
tmp *= scaling_factor;
std::get<90>(evals) += tmp;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,9 @@ const size_t ROLLUP_VALIDATION_REQUESTS_LENGTH = MAX_BLOCK_NUMBER_LENGTH;
const size_t STATE_REFERENCE_LENGTH = APPEND_ONLY_TREE_SNAPSHOT_LENGTH + PARTIAL_STATE_REFERENCE_LENGTH;
const size_t TX_CONTEXT_LENGTH = 2 + GAS_SETTINGS_LENGTH;
const size_t TX_REQUEST_LENGTH = 2 + TX_CONTEXT_LENGTH + FUNCTION_DATA_LENGTH;
const size_t HEADER_LENGTH =
APPEND_ONLY_TREE_SNAPSHOT_LENGTH + CONTENT_COMMITMENT_LENGTH + STATE_REFERENCE_LENGTH + GLOBAL_VARIABLES_LENGTH;
const size_t TOTAL_FEES_LENGTH = 1;
const size_t HEADER_LENGTH = APPEND_ONLY_TREE_SNAPSHOT_LENGTH + CONTENT_COMMITMENT_LENGTH + STATE_REFERENCE_LENGTH +
GLOBAL_VARIABLES_LENGTH + TOTAL_FEES_LENGTH;
const size_t PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH =
CALL_CONTEXT_LENGTH + 4 + MAX_BLOCK_NUMBER_LENGTH + (READ_REQUEST_LENGTH * MAX_NOTE_HASH_READ_REQUESTS_PER_CALL) +
(READ_REQUEST_LENGTH * MAX_NULLIFIER_READ_REQUESTS_PER_CALL) +
Expand Down Expand Up @@ -172,7 +173,7 @@ const size_t KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = ROLLUP_VALIDATION_REQUESTS_LE
PARTIAL_STATE_REFERENCE_LENGTH + 1 + AZTEC_ADDRESS_LENGTH;
const size_t CONSTANT_ROLLUP_DATA_LENGTH = APPEND_ONLY_TREE_SNAPSHOT_LENGTH + 4 + GLOBAL_VARIABLES_LENGTH;
const size_t BASE_OR_MERGE_PUBLIC_INPUTS_LENGTH =
CONSTANT_ROLLUP_DATA_LENGTH + PARTIAL_STATE_REFERENCE_LENGTH + PARTIAL_STATE_REFERENCE_LENGTH + 4;
CONSTANT_ROLLUP_DATA_LENGTH + PARTIAL_STATE_REFERENCE_LENGTH + PARTIAL_STATE_REFERENCE_LENGTH + 5;
const size_t ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_LENGTH = 2 + FUNCTION_DATA_LENGTH + CALL_CONTEXT_LENGTH;
const size_t GET_NOTES_ORACLE_RETURN_LENGTH = 674;
const size_t NOTE_HASHES_NUM_BYTES_PER_BASE_ROLLUP = 2048;
Expand Down
5 changes: 4 additions & 1 deletion docs/docs/protocol-specs/gas-and-fees/kernel-tracking.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ CombinedConstantData --> TxContext

class Header {
+GlobalVariables global_variables
+Fr total_fees
}
Header --> GlobalVariables

Expand Down Expand Up @@ -538,10 +539,12 @@ The interplay between these two `revert_code`s is as follows:
| 1 | 1 | 3 |
| 2 or 3 | (any) | (unchanged) |

## Base Rollup Kernel Circuit
## Rollup Kernel Circuits

The base rollup kernel circuit takes in a `KernelData`, which contains a `KernelCircuitPublicInputs`, which it uses to compute the `transaction_fee`.

Additionally, it verifies that the max fees per gas specified by the user are greater than the current block's fees per gas. It also verifies the `constant_data.global_variables.gas_fees` are correct.

After the public data writes specific to this transaction have been processed, and a new tree root is produced, the kernel circuit injects an additional public data write based upon that root which deducts the transaction fee from the `fee_payer`'s balance.

The calculated trasaction fee is set as output on the base rollup as `accumulated_fees`. Each subsequent merge rollup circuit sums this value from both of its inputs. The root rollup circuit then uses this value to set the `total_fees` in the `Header`.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ The block header contains a `GlobalVariables`, which contains a `GasFees` object
- `feePerDaGas`: The fee in [FPA](./fee-payment-asset.md) per unit of DA gas consumed for transactions in the block.
- `feePerL2Gas`: The fee in FPA per unit of L2 gas consumed for transactions in the block.

`GlobalVariables` also includes a `coinbase` field, which is the L1 address that receives the fees.

The block header also contains a `totalFees` field, which is the total fees collected in the block in FPA.

## Updating the `GasFees` Object

Presently, the `feePerDaGas` and `feePerL2Gas` are fixed at `1` FPA per unit of DA gas and L2 gas consumed, respectively.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,12 @@ These are held in the L2 blocks `Header`
classDiagram
class Header {
+GlobalVariables globalVariables
+Fr totalFees
}

class GlobalVariables {
+GasFees gasFees
+EthAddress coinbase
}

class GasFees {
Expand All @@ -97,6 +99,10 @@ A transaction cannot be executed if the `maxFeesPerGas` is less than the `feePer

The `feePerGas` is presently held constant at `1` for both dimensions, but may be updated in future protocol versions.

`totalFees` is the total fees collected in the block in FPA.

`coinbase` is the L1 address that receives the fees.

## Transaction Fee

The transaction fee is calculated as:
Expand Down
1 change: 1 addition & 0 deletions docs/docs/protocol-specs/rollup-circuits/base-rollup.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class Header {
content_commitment: ContentCommitment
state: StateReference
global_variables: GlobalVariables
total_fees: Fr
}
Header *.. Body : txs_hash
Header *-- ContentCommitment: content_commitment
Expand Down
1 change: 1 addition & 0 deletions docs/docs/protocol-specs/rollup-circuits/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ class Header {
content_commitment: ContentCommitment
state: StateReference
global_variables: GlobalVariables
total_fees: Fr
}
Header *.. Body : txs_hash
Header *-- ContentCommitment: content_commitment
Expand Down
1 change: 1 addition & 0 deletions docs/docs/protocol-specs/rollup-circuits/root-rollup.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class Header {
content_commitment: ContentCommitment
state: StateReference
global_variables: GlobalVariables
total_fees: Fr
}
Header *.. Body : txs_hash
Header *-- ContentCommitment: content_commitment
Expand Down
1 change: 1 addition & 0 deletions docs/docs/protocol-specs/state/archive.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ class Header {
body_hash: Fr[2]
state: StateReference
global_variables: GlobalVariables
total_fees: Fr
}
Header *.. Body : body_hash
Header *-- StateReference : state
Expand Down
1 change: 1 addition & 0 deletions docs/docs/protocol-specs/state/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ class Header {
content_commitment: ContentCommitment
state: StateReference
global_variables: GlobalVariables
total_fees: Fr
}
Header *.. Body : txs_hash
Header *-- ContentCommitment: content_commitment
Expand Down
6 changes: 3 additions & 3 deletions l1-contracts/src/core/Rollup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,9 @@ contract Rollup is IRollup {
header.globalVariables.blockNumber, header.contentCommitment.outHash, l2ToL1TreeHeight
);

// pay the coinbase 1 gas token if it is not empty
if (header.globalVariables.coinbase != address(0)) {
GAS_TOKEN.transfer(address(header.globalVariables.coinbase), 1);
// pay the coinbase 1 gas token if it is not empty and header.totalFees is not zero
if (header.globalVariables.coinbase != address(0) && header.totalFees > 0) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should we pay if totalFees is not zero and throw if coinbase is empty?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, and there are comments around the codebase saying that coinbase should not be allowed to be undefined when we are in production. Not all the tests set coinbase yet. So I added #6539

Copy link
Collaborator

Choose a reason for hiding this comment

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

Cool! The rest looks good to me 😃

GAS_TOKEN.transfer(address(header.globalVariables.coinbase), header.totalFees);
}

emit L2BlockProcessed(header.globalVariables.blockNumber);
Expand Down
5 changes: 3 additions & 2 deletions l1-contracts/src/core/libraries/ConstantsGen.sol
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,9 @@ library Constants {
APPEND_ONLY_TREE_SNAPSHOT_LENGTH + PARTIAL_STATE_REFERENCE_LENGTH;
uint256 internal constant TX_CONTEXT_LENGTH = 2 + GAS_SETTINGS_LENGTH;
uint256 internal constant TX_REQUEST_LENGTH = 2 + TX_CONTEXT_LENGTH + FUNCTION_DATA_LENGTH;
uint256 internal constant TOTAL_FEES_LENGTH = 1;
uint256 internal constant HEADER_LENGTH = APPEND_ONLY_TREE_SNAPSHOT_LENGTH
+ CONTENT_COMMITMENT_LENGTH + STATE_REFERENCE_LENGTH + GLOBAL_VARIABLES_LENGTH;
+ CONTENT_COMMITMENT_LENGTH + STATE_REFERENCE_LENGTH + GLOBAL_VARIABLES_LENGTH + TOTAL_FEES_LENGTH;
uint256 internal constant PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = CALL_CONTEXT_LENGTH + 4
+ MAX_BLOCK_NUMBER_LENGTH + (READ_REQUEST_LENGTH * MAX_NOTE_HASH_READ_REQUESTS_PER_CALL)
+ (READ_REQUEST_LENGTH * MAX_NULLIFIER_READ_REQUESTS_PER_CALL)
Expand Down Expand Up @@ -211,7 +212,7 @@ library Constants {
uint256 internal constant CONSTANT_ROLLUP_DATA_LENGTH =
APPEND_ONLY_TREE_SNAPSHOT_LENGTH + 4 + GLOBAL_VARIABLES_LENGTH;
uint256 internal constant BASE_OR_MERGE_PUBLIC_INPUTS_LENGTH = CONSTANT_ROLLUP_DATA_LENGTH
+ PARTIAL_STATE_REFERENCE_LENGTH + PARTIAL_STATE_REFERENCE_LENGTH + 4;
+ PARTIAL_STATE_REFERENCE_LENGTH + PARTIAL_STATE_REFERENCE_LENGTH + 5;
uint256 internal constant ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_LENGTH =
2 + FUNCTION_DATA_LENGTH + CALL_CONTEXT_LENGTH;
uint256 internal constant GET_NOTES_ORACLE_RETURN_LENGTH = 674;
Expand Down
7 changes: 6 additions & 1 deletion l1-contracts/src/core/libraries/HeaderLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import {Hash} from "./Hash.sol";
* | 0x0208 | 0x20 | gasFees.feePerL2Gas
* | | | }
* | | | }
* | 0x0228 | 0x20 | total_fees
* | --- | --- | ---
*/
library HeaderLib {
Expand Down Expand Up @@ -100,9 +101,10 @@ library HeaderLib {
ContentCommitment contentCommitment;
StateReference stateReference;
GlobalVariables globalVariables;
uint256 totalFees;
}

uint256 private constant HEADER_LENGTH = 0x228; // Header byte length
uint256 private constant HEADER_LENGTH = 0x248; // Header byte length

/**
* @notice Validates the header
Expand Down Expand Up @@ -190,6 +192,9 @@ library HeaderLib {
header.globalVariables.gasFees.feePerDaGas = uint256(bytes32(_header[0x01e8:0x0208]));
header.globalVariables.gasFees.feePerL2Gas = uint256(bytes32(_header[0x0208:0x0228]));

// Reading totalFees
header.totalFees = uint256(bytes32(_header[0x0228:0x0248]));

return header;
}
}
12 changes: 6 additions & 6 deletions l1-contracts/test/fixtures/empty_block_0.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"l2ToL1Messages": []
},
"block": {
"archive": "0x0ed815d35918f1aabf391fa174a1d95476da157e40b7fc581b2c8f4cfd23e6b3",
"archive": "0x1457164d01299b0097706a5b0e8735720280e2937d369b2bee07ba987fd6846e",
"body": "0x00000000",
"txsEffectsHash": "0x002676dbd818b1ba16e11597cb5c07b06aa7771127b02a77d0c3a6039bb9fef1",
"decodedHeader": {
Expand All @@ -23,16 +23,16 @@
"chainId": 31337,
"timestamp": 0,
"version": 1,
"coinbase": "0xbe70f89d75a00bd140342ebc63beb517cf9735bc",
"feeRecipient": "0x08eb6120958820f4b4fd61a9bcaa32c33349663034e1db315ba57c67d155b172",
"coinbase": "0x13def1c0178621c029040272730bb660031f3d51",
"feeRecipient": "0x2193c536a292e81634f7f77e7c9f3fdc7a197d396bfda81fdc0112e0b2bc9bb6",
"gasFees": {
"feePerDaGas": 0,
"feePerL2Gas": 0
}
},
"lastArchive": {
"nextAvailableLeafIndex": 1,
"root": "0x067a48e3140b6f15d71751ededfa0cccde3d436bb71aa7fec226b0bfe51dc5cf"
"root": "0x05b0b6df52f1d47d0406318558052c89a174fbc9d615def82b3cc9ccc1937db8"
},
"stateReference": {
"l1ToL2MessageTree": {
Expand All @@ -55,8 +55,8 @@
}
}
},
"header": "0x067a48e3140b6f15d71751ededfa0cccde3d436bb71aa7fec226b0bfe51dc5cf000000010000000000000000000000000000000000000000000000000000000000000001002676dbd818b1ba16e11597cb5c07b06aa7771127b02a77d0c3a6039bb9fef100089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c0007638bb56b6dda2b64b8f76841114ac3a87a1820030e2e16772c4d294879c31864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f800000001016642d9ccd8346c403aa4c3fa451178b22534a27035cdaa6ec34ae53b29c50cb000000800bcfa3e9f1a8922ee92c6dc964d6595907c1804a86753774322b468f69d4f278000001000572c8db882674dd026b8877fbba1b700a4407da3ae9ce5fa43215a28163362b000000800000000000000000000000000000000000000000000000000000000000007a69000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000be70f89d75a00bd140342ebc63beb517cf9735bc08eb6120958820f4b4fd61a9bcaa32c33349663034e1db315ba57c67d155b17200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"publicInputsHash": "0x00e9c95b88dbc49351e6a0a9b660918147d3c69410df4fba105c047a4f253a47",
"header": "0x05b0b6df52f1d47d0406318558052c89a174fbc9d615def82b3cc9ccc1937db8000000010000000000000000000000000000000000000000000000000000000000000001002676dbd818b1ba16e11597cb5c07b06aa7771127b02a77d0c3a6039bb9fef100089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c0007638bb56b6dda2b64b8f76841114ac3a87a1820030e2e16772c4d294879c31864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f800000001016642d9ccd8346c403aa4c3fa451178b22534a27035cdaa6ec34ae53b29c50cb000000800bcfa3e9f1a8922ee92c6dc964d6595907c1804a86753774322b468f69d4f278000001000572c8db882674dd026b8877fbba1b700a4407da3ae9ce5fa43215a28163362b000000800000000000000000000000000000000000000000000000000000000000007a6900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000013def1c0178621c029040272730bb660031f3d512193c536a292e81634f7f77e7c9f3fdc7a197d396bfda81fdc0112e0b2bc9bb6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"publicInputsHash": "0x004fa9f8a995305c2569a378b91e45d14f9a6b7d9ba0ca19e0ac0e4ea79123fb",
"numTxs": 0
}
}
Loading
Loading