Skip to content
Draft
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
2 changes: 2 additions & 0 deletions l1-contracts/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,5 @@ gas_benchmark.diff
/bench-out

/coverage

.solidity-language-server/
8 changes: 4 additions & 4 deletions l1-contracts/gas_benchmark.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,21 @@
| Function | Avg Gas | Max Gas | Calldata Size | Calldata Gas |
|----------------------|---------|-----------|---------------|--------------|
| propose | 199,366 | 225,550 | 996 | 15,936 |
| submitEpochRootProof | 991,032 | 1,029,525 | 14,148 | 226,368 |
| submitEpochRootProof | 994,761 | 1,033,254 | 14,148 | 226,368 |
| setupEpoch | 32,042 | 113,837 | - | - |

**Avg Gas Cost per Second**: 3,643.2 gas/second
**Avg Gas Cost per Second**: 3,646.4 gas/second
*Epoch duration*: 0h 38m 24s

## Validators

| Function | Avg Gas | Max Gas | Calldata Size | Calldata Gas |
|----------------------|-----------|-----------|---------------|--------------|
| propose | 327,774 | 355,591 | 4,516 | 72,256 |
| submitEpochRootProof | 1,572,081 | 1,669,921 | 16,644 | 266,304 |
| submitEpochRootProof | 1,575,811 | 1,673,651 | 16,644 | 266,304 |
| aggregate3 | 376,665 | 390,039 | - | - |
| setupEpoch | 46,504 | 547,670 | - | - |

**Avg Gas Cost per Second**: 5,937.3 gas/second
**Avg Gas Cost per Second**: 5,940.5 gas/second
*Epoch duration*: 0h 38m 24s

16 changes: 8 additions & 8 deletions l1-contracts/gas_benchmark_results.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
},
"submitEpochRootProof": {
"calls": 4,
"min": 972329,
"mean": 991032,
"median": 981138,
"max": 1029525,
"min": 976058,
"mean": 994761,
"median": 984867,
"max": 1033254,
"calldata_size": 14148,
"calldata_gas": 226368
}
Expand All @@ -45,10 +45,10 @@
},
"submitEpochRootProof": {
"calls": 4,
"min": 1460323,
"mean": 1572081,
"median": 1579041,
"max": 1669921,
"min": 1464053,
"mean": 1575811,
"median": 1582771,
"max": 1673651,
"calldata_size": 16644,
"calldata_gas": 266304
},
Expand Down
70 changes: 49 additions & 21 deletions l1-contracts/partial_epoch_proof_gas_report.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,71 @@
"contract": "test/RollupWithPreheating.sol:RollupWithPreheating",
"deployment": {
"gas": 0,
"size": 42950
"size": 43893
},
"functions": {
"gasReportSubmit16Checkpoints((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": {
"calls": 1,
"min": 1291434,
"mean": 1291434,
"median": 1291434,
"max": 1291434
"min": 1301116,
"mean": 1301116,
"median": 1301116,
"max": 1301116
},
"gasReportSubmit16CheckpointsWithTwoOverrides((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": {
"calls": 1,
"min": 1466779,
"mean": 1466779,
"median": 1466779,
"max": 1466779
},
"gasReportSubmit1Checkpoint((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": {
"calls": 1,
"min": 661209,
"mean": 661209,
"median": 661209,
"max": 661209
"min": 664809,
"mean": 664809,
"median": 664809,
"max": 664809
},
"gasReportSubmit1CheckpointWithTwoOverrides((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": {
"calls": 1,
"min": 691596,
"mean": 691596,
"median": 691596,
"max": 691596
},
"gasReportSubmit32Checkpoints((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": {
"calls": 1,
"min": 1805036,
"mean": 1805036,
"median": 1805036,
"max": 1805036
"min": 1821204,
"mean": 1821204,
"median": 1821204,
"max": 1821204
},
"gasReportSubmit32CheckpointsWithTwoOverrides((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": {
"calls": 1,
"min": 2079915,
"mean": 2079915,
"median": 2079915,
"max": 2079915
},
"gasReportSubmit8Checkpoints((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": {
"calls": 1,
"min": 980313,
"mean": 980313,
"median": 980313,
"max": 980313
"min": 986773,
"mean": 986773,
"median": 986773,
"max": 986773
},
"gasReportSubmit8CheckpointsWithTwoOverrides((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": {
"calls": 1,
"min": 1083754,
"mean": 1083754,
"median": 1083754,
"max": 1083754
},
"gasReportSubmit8MoreCheckpoints((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": {
"calls": 1,
"min": 988027,
"mean": 988027,
"median": 988027,
"max": 988027
"min": 994477,
"mean": 994477,
"median": 994477,
"max": 994477
}
}
}
Expand Down
16 changes: 10 additions & 6 deletions l1-contracts/partial_epoch_proof_gas_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@

| Proof submission | Gas |
|---|---:|
| 1 Checkpoint | 661,209 |
| 8 Checkpoints | 980,313 |
| 8 More Checkpoints | 988,027 |
| 16 Checkpoints | 1,291,434 |
| 32 Checkpoints | 1,805,036 |
| 1 Checkpoint | 664,809 |
| 1 Checkpoint With Two Overrides | 691,596 |
| 8 Checkpoints | 986,773 |
| 8 Checkpoints With Two Overrides | 1,083,754 |
| 8 More Checkpoints | 994,477 |
| 16 Checkpoints | 1,301,116 |
| 16 Checkpoints With Two Overrides | 1,466,779 |
| 32 Checkpoints | 1,821,204 |
| 32 Checkpoints With Two Overrides | 2,079,915 |

Uses the mock epoch proof verifier.
_Uses the mock epoch proof verifier._
22 changes: 21 additions & 1 deletion l1-contracts/script/deploy/RollupConfiguration.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ import {CheatDepositArgs} from "@aztec/mock/MultiAdder.sol";
import {IRewardDistributor} from "@aztec/governance/interfaces/IRewardDistributor.sol";
import {IBoosterCore} from "@aztec/core/reward-boost/RewardBooster.sol";
import {EthValue, EthPerFeeAssetE12} from "@aztec/core/libraries/rollup/FeeLib.sol";
import {GenesisState, RollupConfigInput} from "@aztec/core/interfaces/IRollup.sol";
import {GenesisState, RegistryRewardOverride, RollupConfigInput} from "@aztec/core/interfaces/IRollup.sol";
import {RewardBoostConfig} from "@aztec/core/reward-boost/RewardBooster.sol";
import {StakingQueueConfig} from "@aztec/core/libraries/compressed-data/StakingQueueConfig.sol";
import {RewardConfig, Bps} from "@aztec/core/libraries/rollup/RewardLib.sol";
import {SafeCast} from "@oz/utils/math/SafeCast.sol";

interface IRollupConfiguration {
function loadConfig() external;
Expand All @@ -28,6 +29,7 @@ interface IRollupConfiguration {

contract RollupConfiguration is IRollupConfiguration, Test {
using stdJson for string;
using SafeCast for uint256;

// Storage for loaded config
string public networkName;
Expand Down Expand Up @@ -127,6 +129,24 @@ contract RollupConfiguration is IRollupConfiguration, Test {
config.version = 0; // Computed below
config.provingCostPerMana = EthValue.wrap(vm.envUint("AZTEC_PROVING_COST_PER_MANA"));
config.initialEthPerFeeAsset = EthPerFeeAssetE12.wrap(vm.envUint("AZTEC_INITIAL_ETH_PER_FEE_ASSET"));
config.registryRewardOverrides[0] = _getRegistryRewardOverride("AZTEC_REGISTRY_REWARD_OVERRIDE_0");
config.registryRewardOverrides[1] = _getRegistryRewardOverride("AZTEC_REGISTRY_REWARD_OVERRIDE_1");
}

function _getRegistryRewardOverride(string memory _envName)
internal
view
returns (RegistryRewardOverride memory registryRewardOverride)
{
string memory value = vm.envOr(_envName, string(""));
if (bytes(value).length == 0) {
return registryRewardOverride;
}

string[] memory fields = vm.split(value, ",");
require(fields.length == 2, "Invalid registry reward override");
registryRewardOverride.registry = vm.parseAddress(fields[0]);
registryRewardOverride.sequencerReward = vm.parseUint(fields[1]).toUint96();
}

/// @notice Compute rollup config version by hashing config + genesis state
Expand Down
2 changes: 2 additions & 0 deletions l1-contracts/scripts/network-defaults.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
"AZTEC_MANA_TARGET": 100000000,
"AZTEC_PROVING_COST_PER_MANA": 100,
"AZTEC_INITIAL_ETH_PER_FEE_ASSET": 10000000,
"AZTEC_REGISTRY_REWARD_OVERRIDE_0": "",
"AZTEC_REGISTRY_REWARD_OVERRIDE_1": "",
"AZTEC_SLASHER_ENABLED": true,
"AZTEC_SLASHING_ROUND_SIZE_IN_EPOCHS": 4,
"AZTEC_SLASHING_QUORUM": 65,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def render(input_path: Path, output_path: Path) -> None:
lines.extend(
[
"",
"_Uses the mock epoch proof verifier; real ZK verification and top-level transaction calldata gas are not included._",
"_Uses the mock epoch proof verifier._",
"",
]
)
Expand Down
8 changes: 6 additions & 2 deletions l1-contracts/src/core/Rollup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -612,8 +612,12 @@ contract Rollup is IStaking, IValidatorSelection, IRollup, RollupCore {
return StakingLib.LEGACY_SLASHER_DRAIN_WINDOW;
}

function getBurnAddress() external pure override(IRollup) returns (address) {
return address(bytes20("CUAUHXICALLI"));
function getProtocolFeeRecipient() external view override(IRollup) returns (address) {
return RewardExtLib.getProtocolFeeRecipient();
}

function getProtocolFeeMargin() external view override(IRollup) returns (uint16) {
return RewardExtLib.getProtocolFeeMargin();
}

/**
Expand Down
61 changes: 58 additions & 3 deletions l1-contracts/src/core/RollupCore.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import {
IRollupCore,
RollupStore,
SubmitEpochRootProofArgs,
RollupConfigInput
RollupConfigInput,
MAX_REGISTRY_REWARD_OVERRIDES,
RegistryRewardOverride
} from "@aztec/core/interfaces/IRollup.sol";
import {IVerifier} from "@aztec/core/interfaces/IVerifier.sol";
import {IStakingCore} from "@aztec/core/interfaces/IStaking.sol";
Expand Down Expand Up @@ -189,6 +191,11 @@ contract RollupCore is EIP712("Aztec Rollup", "1"), Ownable, IStakingCore, IVali
*/
uint256 public immutable L1_BLOCK_AT_GENESIS;

address internal immutable REGISTRY_REWARD_OVERRIDE_0_REGISTRY;
uint96 internal immutable REGISTRY_REWARD_OVERRIDE_0_SEQUENCER_REWARD;
address internal immutable REGISTRY_REWARD_OVERRIDE_1_REGISTRY;
uint96 internal immutable REGISTRY_REWARD_OVERRIDE_1_SEQUENCER_REWARD;

/**
* @dev Storage gap to ensure checkBlob is in its own storage slot
*/
Expand Down Expand Up @@ -233,6 +240,13 @@ contract RollupCore is EIP712("Aztec Rollup", "1"), Ownable, IStakingCore, IVali
Errors.Staking__ExitDelayAboveSlasherDelay(_config.exitDelaySeconds, StakingLib.SLASHER_EXECUTION_DELAY)
);

// We can only figure out if the epoch is full once it closes,
// so we need to allow proofs to be accepted in a later epoch
require(
_config.aztecProofSubmissionEpochs > 0,
Errors.Rollup__InvalidProofSubmissionEpochs(1, _config.aztecProofSubmissionEpochs)
);

TimeLib.initialize(
block.timestamp,
_config.aztecSlotDuration,
Expand All @@ -256,6 +270,10 @@ contract RollupCore is EIP712("Aztec Rollup", "1"), Ownable, IStakingCore, IVali
);

_initializeRewards(_config);
REGISTRY_REWARD_OVERRIDE_0_REGISTRY = _config.registryRewardOverrides[0].registry;
REGISTRY_REWARD_OVERRIDE_0_SEQUENCER_REWARD = _config.registryRewardOverrides[0].sequencerReward;
REGISTRY_REWARD_OVERRIDE_1_REGISTRY = _config.registryRewardOverrides[1].registry;
REGISTRY_REWARD_OVERRIDE_1_SEQUENCER_REWARD = _config.registryRewardOverrides[1].sequencerReward;

L1_BLOCK_AT_GENESIS = block.number;

Expand Down Expand Up @@ -325,6 +343,30 @@ contract RollupCore is EIP712("Aztec Rollup", "1"), Ownable, IStakingCore, IVali
FeeLib.updateProvingCostPerMana(_provingCostPerMana);
}

/**
* @notice Updates the protocol fee margin applied on top of operator cost in the mana base fee
* @dev Only callable by owner. Increases are rate-limited (30-day cooldown, x3/2 step on the fee
* multiplier); decreases are immediate. Setting the current value is a no-op and emits no
* event.
* @param _protocolFeeMarginBps The new margin in basis points
*/
function setProtocolFeeMargin(uint16 _protocolFeeMarginBps) external override(IRollupCore) onlyOwner {
(bool changed, uint16 oldBps) = RewardExtLib.updateProtocolFeeMargin(_protocolFeeMarginBps);
if (changed) {
emit IRollupCore.ProtocolFeeMarginUpdated(oldBps, _protocolFeeMarginBps);
}
}

/**
* @notice Updates the recipient of the protocol fee tranche of the reward waterfall
* @dev Only callable by owner. Rejects the zero address.
* @param _recipient The new protocol fee recipient
*/
function setProtocolFeeRecipient(address _recipient) external override(IRollupCore) onlyOwner {
address oldRecipient = RewardExtLib.updateProtocolFeeRecipient(_recipient);
emit IRollupCore.ProtocolFeeRecipientUpdated(oldRecipient, _recipient);
}

/**
* @notice Updates the configuration for the staking entry queue
* @dev Only callable by owner. Controls how validators enter the active set.
Expand Down Expand Up @@ -470,7 +512,7 @@ contract RollupCore is EIP712("Aztec Rollup", "1"), Ownable, IStakingCore, IVali
* @param _args Contains the epoch range, public inputs, fees, attestations, and the ZK proof
*/
function submitEpochRootProof(SubmitEpochRootProofArgs calldata _args) external override(IRollupCore) {
EpochProofExtLib.submitEpochRootProof(_args);
EpochProofExtLib.submitEpochRootProof(_args, _getRegistryRewardOverrides());
}

/**
Expand Down Expand Up @@ -607,7 +649,7 @@ contract RollupCore is EIP712("Aztec Rollup", "1"), Ownable, IStakingCore, IVali
}

// Constructor-only writer; post-deployment updates go through {setRewardConfig}.
RewardExtLib.initializeConfig(rewardConfig);
RewardExtLib.initializeConfig(rewardConfig, _config.registryRewardOverrides);
}

function _initializeStore(
Expand All @@ -629,4 +671,17 @@ contract RollupCore is EIP712("Aztec Rollup", "1"), Ownable, IStakingCore, IVali
rollupStore.config.outbox = IOutbox(address(new Outbox(address(this), _config.version)));
rollupStore.config.feeAssetPortal = IFeeJuicePortal(inbox.getFeeAssetPortal());
}

function _getRegistryRewardOverrides()
internal
view
returns (RegistryRewardOverride[MAX_REGISTRY_REWARD_OVERRIDES] memory overrides)
{
overrides[0] = RegistryRewardOverride({
registry: REGISTRY_REWARD_OVERRIDE_0_REGISTRY, sequencerReward: REGISTRY_REWARD_OVERRIDE_0_SEQUENCER_REWARD
});
overrides[1] = RegistryRewardOverride({
registry: REGISTRY_REWARD_OVERRIDE_1_REGISTRY, sequencerReward: REGISTRY_REWARD_OVERRIDE_1_SEQUENCER_REWARD
});
}
}
Loading
Loading