Skip to content

Commit

Permalink
refactor: proving cost in fee header (#12048)
Browse files Browse the repository at this point in the history
  • Loading branch information
LHerskind authored Feb 26, 2025
1 parent f887efc commit 5da66c8
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 31 deletions.
2 changes: 1 addition & 1 deletion l1-contracts/src/core/Rollup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
EnumerableSet
} from "@aztec/core/interfaces/IStaking.sol";
import {IValidatorSelection} from "@aztec/core/interfaces/IValidatorSelection.sol";
import {FeeAssetValue} from "@aztec/core/libraries/RollupLibs/FeeMath.sol";

// We allow the unused imports here as they make it much simpler to import the Rollup later
// solhint-disable no-unused-import
Expand Down Expand Up @@ -39,7 +40,6 @@ import {
EpochRewards,
FeeAssetPerEthE9,
EthValue,
FeeAssetValue,
PriceLib
} from "./RollupCore.sol";
// solhint-enable no-unused-import
Expand Down
51 changes: 25 additions & 26 deletions l1-contracts/src/core/RollupCore.sol
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,7 @@ import {
ValidateHeaderArgs,
Header
} from "@aztec/core/libraries/RollupLibs/ExtRollupLib.sol";
import {
EthValue,
FeeAssetValue,
FeeAssetPerEthE9,
PriceLib
} from "@aztec/core/libraries/RollupLibs/FeeMath.sol";
import {EthValue, FeeAssetPerEthE9, PriceLib} from "@aztec/core/libraries/RollupLibs/FeeMath.sol";
import {IntRollupLib} from "@aztec/core/libraries/RollupLibs/IntRollupLib.sol";
import {ProposeArgs, ProposeLib} from "@aztec/core/libraries/RollupLibs/ProposeLib.sol";
import {StakingLib} from "@aztec/core/libraries/staking/StakingLib.sol";
Expand Down Expand Up @@ -175,7 +170,13 @@ contract RollupCore is

// Genesis block
rollupStore.blocks[0] = BlockLog({
feeHeader: FeeHeader({excessMana: 0, feeAssetPriceNumerator: 0, manaUsed: 0, congestionCost: 0}),
feeHeader: FeeHeader({
excessMana: 0,
feeAssetPriceNumerator: 0,
manaUsed: 0,
congestionCost: 0,
provingCost: 0
}),
archive: _genesisArchiveRoot,
blockHash: _genesisBlockHash,
slotNumber: Slot.wrap(0)
Expand Down Expand Up @@ -424,18 +425,7 @@ contract RollupCore is
interim.totalBurn += interim.burn;

// Compute the proving fee in the fee asset
{
// @todo likely better for us to store this if we can pack it better
interim.feeAssetPrice = IntRollupLib.getFeeAssetPerEth(
rollupStore.blocks[_args.start + i - 1].feeHeader.feeAssetPriceNumerator
);
}
interim.proverFee = Math.min(
feeHeader.manaUsed
* FeeAssetValue.unwrap(rollupStore.provingCostPerMana.toFeeAsset(interim.feeAssetPrice)),
interim.fee
);

interim.proverFee = Math.min(feeHeader.manaUsed * feeHeader.provingCost, interim.fee);
interim.fee -= interim.proverFee;

er.rewards += interim.proverFee;
Expand Down Expand Up @@ -498,6 +488,11 @@ contract RollupCore is
// Decode and validate header
Header memory header = ExtRollupLib.decodeHeader(_args.header);

// @todo As part of a refactor of the core for propose and submit, we should
// be able to set it up such that we don't need compute the fee components
// unless needed.
// Would be part of joining the header validation.

setupEpoch();
ManaBaseFeeComponents memory components =
getManaBaseFeeComponentsAt(Timestamp.wrap(block.timestamp), true);
Expand All @@ -515,7 +510,9 @@ contract RollupCore is
uint256 blockNumber = ++rollupStore.tips.pendingBlockNumber;

{
rollupStore.blocks[blockNumber] = _toBlockLog(_args, blockNumber, components.congestionCost);
// @note The components are measured in the fee asset.
rollupStore.blocks[blockNumber] =
_toBlockLog(_args, blockNumber, components.congestionCost, components.provingCost);
}

rollupStore.blobPublicInputsHashes[blockNumber] = blobPublicInputsHash;
Expand Down Expand Up @@ -729,11 +726,12 @@ contract RollupCore is
}

// Helper to avoid stack too deep
function _toBlockLog(ProposeArgs calldata _args, uint256 _blockNumber, uint256 _congestionCost)
internal
view
returns (BlockLog memory)
{
function _toBlockLog(
ProposeArgs calldata _args,
uint256 _blockNumber,
uint256 _congestionCost,
uint256 _provingCost
) internal view returns (BlockLog memory) {
FeeHeader memory parentFeeHeader = rollupStore.blocks[_blockNumber - 1].feeHeader;
return BlockLog({
archive: _args.archive,
Expand All @@ -745,7 +743,8 @@ contract RollupCore is
_args.oracleInput.feeAssetPriceModifier
),
manaUsed: uint256(bytes32(_args.header[0x0268:0x0288])),
congestionCost: _congestionCost
congestionCost: _congestionCost,
provingCost: _provingCost
})
});
}
Expand Down
3 changes: 2 additions & 1 deletion l1-contracts/src/core/libraries/RollupLibs/FeeMath.sol
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,10 @@ struct ManaBaseFeeComponents {

struct FeeHeader {
uint256 excessMana;
uint256 feeAssetPriceNumerator;
uint256 manaUsed;
uint256 feeAssetPriceNumerator;
uint256 congestionCost;
uint256 provingCost;
}

struct L1FeeData {
Expand Down
22 changes: 22 additions & 0 deletions l1-contracts/test/Rollup.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,28 @@ contract RollupTest is RollupBase {
rollup.propose(args, signatures, data.body, data.blobInputs);
}

function testProvingFeeUpdates() public setUpFor("mixed_block_1") {
rollup.setProvingCostPerMana(EthValue.wrap(1000));
_proposeBlock("mixed_block_1", 1, 1e6);

rollup.setProvingCostPerMana(EthValue.wrap(2000));
_proposeBlock("mixed_block_2", 2, 1e6);

// At this point in time, we have had different proving costs for the two blocks. When we prove them
// in the same epoch, we want to see that the correct fee is taken for each block.
_proveBlocks("mixed_block_", 1, 2, address(this));

// 1e6 mana at 1000 and 2000 cost per manage multiplied by 10 for the price conversion to fee asset.
uint256 provingFees = 1e6 * (1000 + 2000) * 10;
uint256 expectedProverRewards = rewardDistributor.BLOCK_REWARD() / 2 * 2 + provingFees;

assertEq(
rollup.getCollectiveProverRewardsForEpoch(Epoch.wrap(0)),
expectedProverRewards,
"invalid prover rewards"
);
}

struct TestBlockFeeStruct {
EthValue provingCostPerManaInEth;
FeeAssetValue provingCostPerManaInFeeAsset;
Expand Down
5 changes: 3 additions & 2 deletions l1-contracts/test/fees/MinimalFeeModel.sol
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ contract MinimalFeeModel {
EthValue public provingCost = EthValue.wrap(100);

constructor(uint256 _slotDuration, uint256 _epochDuration) {
feeHeaders[0] = FeeHeader(0, 0, 0, 0);
feeHeaders[0] = FeeHeader(0, 0, 0, 0, 0);

l1BaseFees.pre = L1FeesModel({base_fee: 1 gwei, blob_fee: 1});
l1BaseFees.post = L1FeesModel({base_fee: block.basefee, blob_fee: _getBlobBaseFee()});
Expand Down Expand Up @@ -127,7 +127,8 @@ contract MinimalFeeModel {
),
manaUsed: _manaUsed,
excessMana: excessMana,
congestionCost: 0
congestionCost: 0,
provingCost: 0
});
}

Expand Down
2 changes: 1 addition & 1 deletion yarn-project/aztec.js/src/api/ethereum/cheat_codes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ export class RollupCheatCodes {

const tipsAfter = await this.getTips();
this.logger.info(
`Proven tip moved: ${tipsBefore.proven} -> ${tipsAfter.proven}. Pending tip moved: ${tipsBefore.pending} -> ${tipsAfter.pending}`,
`Proven tip moved: ${tipsBefore.proven} -> ${tipsAfter.proven}. Pending tip: ${tipsAfter.pending}.`,
);
}

Expand Down

2 comments on commit 5da66c8

@AztecBot
Copy link
Collaborator

Choose a reason for hiding this comment

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

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'C++ Benchmark'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.05.

Benchmark suite Current: 5da66c8 Previous: f887efc Ratio
wasmconstruct_proof_ultrahonk_power_of_2/20 11103.012053 ms/iter 10217.298942 ms/iter 1.09

This comment was automatically generated by workflow using github-action-benchmark.

CC: @ludamad @codygunton

@AztecBot
Copy link
Collaborator

Choose a reason for hiding this comment

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

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'P2P Testbench'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.05.

Benchmark suite Current: 5da66c8 Previous: f887efc Ratio
degree-1-strict - maxDelay 524 ms 271 ms 1.93
degree-1-strict - averageDelay 315.25 ms 188.5 ms 1.67
degree-1-strict - medianDelay 425 ms 222 ms 1.91
normal-degree-100-nodes - minDelay 1246 ms 221 ms 5.64
normal-degree-100-nodes - maxDelay 1246 ms 535 ms 2.33
normal-degree-100-nodes - averageDelay 1246 ms 374.43 ms 3.33
normal-degree-100-nodes - medianDelay 1246 ms 422 ms 2.95
normal-degree-50-nodes - minDelay 226 ms 178 ms 1.27
normal-degree-50-nodes - maxDelay 6769 ms 5279 ms 1.28
normal-degree-50-nodes - averageDelay 2255.8 ms 1864.29 ms 1.21
normal-degree-50-nodes - medianDelay 1136 ms 873 ms 1.30

This comment was automatically generated by workflow using github-action-benchmark.

CC: @Maddiaa0

Please sign in to comment.