Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
b3bfb3c7
Commit
b3bfb3c7
authored
Mar 09, 2023
by
Mark Tyneway
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
resource-metering: change params
parent
4f96e19c
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
70 additions
and
90 deletions
+70
-90
.gas-snapshot
packages/contracts-bedrock/.gas-snapshot
+7
-9
ResourceMetering.sol
packages/contracts-bedrock/contracts/L1/ResourceMetering.sol
+11
-9
BenchmarkTest.t.sol
...ages/contracts-bedrock/contracts/test/BenchmarkTest.t.sol
+3
-3
ResourceMetering.t.sol
...s/contracts-bedrock/contracts/test/ResourceMetering.t.sol
+47
-67
foundry.toml
packages/contracts-bedrock/foundry.toml
+1
-1
package.json
packages/contracts-bedrock/package.json
+1
-1
No files found.
packages/contracts-bedrock/.gas-snapshot
View file @
b3bfb3c7
...
...
@@ -397,17 +397,15 @@ RLPWriter_writeUint_Test:test_writeUint_smallint_succeeds() (gas: 7280)
RLPWriter_writeUint_Test:test_writeUint_zero_succeeds() (gas: 7749)
ResolvedDelegateProxy_Test:test_fallback_addressManagerNotSet_reverts() (gas: 605906)
ResolvedDelegateProxy_Test:test_fallback_delegateCallBar_reverts() (gas: 24783)
ResourceMeteringCustom_Test:test_meter_generateArtifact_succeeds() (gas: 1042150946)
ResourceMetering_Test:test_meter_initialBaseFee_succeeds() (gas: 7245)
ResourceMetering_Test:test_meter_initialBaseFee_succeeds() (gas: 7025)
ResourceMetering_Test:test_meter_initialResourceParams_succeeds() (gas: 8983)
ResourceMetering_Test:test_meter_minBaseFeeLessThanMaxBaseFee_succeeds() (gas: 6
420
)
ResourceMetering_Test:test_meter_updateNoGasDelta_succeeds() (gas:
2008226
)
ResourceMetering_Test:test_meter_updateOneEmptyBlock_succeeds() (gas: 18
645
)
ResourceMetering_Test:test_meter_minBaseFeeLessThanMaxBaseFee_succeeds() (gas: 6
194
)
ResourceMetering_Test:test_meter_updateNoGasDelta_succeeds() (gas:
4008242
)
ResourceMetering_Test:test_meter_updateOneEmptyBlock_succeeds() (gas: 18
441
)
ResourceMetering_Test:test_meter_updateParamsNoChange_succeeds() (gas: 14005)
ResourceMetering_Test:test_meter_updateTenEmptyBlocks_succeeds() (gas: 21651)
ResourceMetering_Test:test_meter_updateTwoEmptyBlocks_succeeds() (gas: 21607)
ResourceMetering_Test:test_meter_useMaxWithMaxBaseFee_succeeds() (gas: 29466331)
ResourceMetering_Test:test_meter_useMax_succeeds() (gas: 8017710)
ResourceMetering_Test:test_meter_updateTenEmptyBlocks_succeeds() (gas: 21243)
ResourceMetering_Test:test_meter_updateTwoEmptyBlocks_succeeds() (gas: 21199)
ResourceMetering_Test:test_meter_useMax_succeeds() (gas: 20017420)
ResourceMetering_Test:test_meter_useMoreThanMax_reverts() (gas: 16142)
SafeCall_call_Test:test_callWithMinGas_noLeakageHigh_succeeds() (gas: 2075873614)
SafeCall_call_Test:test_callWithMinGas_noLeakageLow_succeeds() (gas: 753665282)
...
...
packages/contracts-bedrock/contracts/L1/ResourceMetering.sol
View file @
b3bfb3c7
...
...
@@ -29,13 +29,14 @@ abstract contract ResourceMetering is Initializable {
/**
* @notice Maximum amount of the resource that can be used within this block.
* This value cannot be larger than the L2 block gas limit.
*/
int256 public constant MAX_RESOURCE_LIMIT =
8
_000_000;
int256 public constant MAX_RESOURCE_LIMIT =
20
_000_000;
/**
* @notice Along with the resource limit, determines the target resource limit.
*/
int256 public constant ELASTICITY_MULTIPLIER =
4
;
int256 public constant ELASTICITY_MULTIPLIER =
5
;
/**
* @notice Target amount of the resource that should be used within this block.
...
...
@@ -50,22 +51,21 @@ abstract contract ResourceMetering is Initializable {
/**
* @notice Minimum base fee value, cannot go lower than this.
*/
int256 public constant MINIMUM_BASE_FEE = 1
0_000
;
int256 public constant MINIMUM_BASE_FEE = 1
gwei
;
/**
* @notice Maximum base fee value, cannot go higher than this.
* This value must be small enough to allow a user to request the
* MAX_RESOURCE_LIMIT when the base fee is at its max value.
* Setting this value too large can result in more gas being
* consumed than the L1 block gas limit.
* It is possible for the MAXIMUM_BASE_FEE to raise to a value
* that is so large it will consume the entire gas limit of
* an L1 block.
*/
int256 public constant MAXIMUM_BASE_FEE = int256(uint256((type(uint
32).max / 7) * 6
));
int256 public constant MAXIMUM_BASE_FEE = int256(uint256((type(uint
128).max)
));
/**
* @notice Initial base fee value. This value must be smaller than the
* MAXIMUM_BASE_FEE.
*/
uint128 public constant INITIAL_BASE_FEE = 1
_000_000_000
;
uint128 public constant INITIAL_BASE_FEE = 1
gwei
;
/**
* @notice EIP-1559 style gas parameters.
...
...
@@ -89,10 +89,12 @@ abstract contract ResourceMetering is Initializable {
// Run the underlying function.
_;
// Run the metering function.
_metered(_amount, initialGas);
}
/**
* @notice An internal function that holds all of the logic for metering a resource.
*
* @param _amount Amount of the resource requested.
...
...
packages/contracts-bedrock/contracts/test/BenchmarkTest.t.sol
View file @
b3bfb3c7
...
...
@@ -32,7 +32,7 @@ contract SetPrevBaseFee_Test is Portal_Initializer {
// In order to achieve this we make no assertions, and handle everything else in the setUp()
// function.
contract GasBenchMark_OptimismPortal is Portal_Initializer {
uint128 INITIAL_BASE_FEE;
uint128
internal
INITIAL_BASE_FEE;
// Reusable default values for a test withdrawal
Types.WithdrawalTransaction _defaultTx;
...
...
@@ -124,7 +124,7 @@ contract GasBenchMark_OptimismPortal is Portal_Initializer {
}
contract GasBenchMark_L1CrossDomainMessenger is Messenger_Initializer {
uint128 INITIAL_BASE_FEE;
uint128
internal
INITIAL_BASE_FEE;
function setUp() public virtual override {
super.setUp();
...
...
@@ -153,7 +153,7 @@ contract GasBenchMark_L1CrossDomainMessenger is Messenger_Initializer {
}
contract GasBenchMark_L1StandardBridge_Deposit is Bridge_Initializer {
uint128 INITIAL_BASE_FEE;
uint128
internal
INITIAL_BASE_FEE;
function setUp() public virtual override {
super.setUp();
...
...
packages/contracts-bedrock/contracts/test/ResourceMetering.t.sol
View file @
b3bfb3c7
...
...
@@ -46,8 +46,8 @@ contract ResourceMetering_Test is Test {
uint256 max = uint256(meter.MAXIMUM_BASE_FEE());
uint256 min = uint256(meter.MINIMUM_BASE_FEE());
uint256 initial = uint256(meter.INITIAL_BASE_FEE());
assertTrue(max > initial);
assertTrue(min < initial);
assertTrue(max >
=
initial);
assertTrue(min <
=
initial);
}
/**
...
...
@@ -83,8 +83,7 @@ contract ResourceMetering_Test is Test {
meter.use(0);
(uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();
// Base fee decreases by 12.5%
assertEq(prevBaseFee, 875000000);
assertEq(prevBaseFee, 1 gwei);
assertEq(prevBoughtGas, 0);
assertEq(prevBlockNum, initialBlockNum + 1);
}
...
...
@@ -94,7 +93,7 @@ contract ResourceMetering_Test is Test {
meter.use(0);
(uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();
assertEq(prevBaseFee,
765624999
);
assertEq(prevBaseFee,
1 gwei
);
assertEq(prevBoughtGas, 0);
assertEq(prevBlockNum, initialBlockNum + 2);
}
...
...
@@ -104,7 +103,7 @@ contract ResourceMetering_Test is Test {
meter.use(0);
(uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();
assertEq(prevBaseFee,
263075576
);
assertEq(prevBaseFee,
1 gwei
);
assertEq(prevBoughtGas, 0);
assertEq(prevBlockNum, initialBlockNum + 10);
}
...
...
@@ -130,8 +129,7 @@ contract ResourceMetering_Test is Test {
vm.roll(initialBlockNum + 1);
meter.use(0);
(uint128 postBaseFee, , ) = meter.params();
// Base fee increases by 1/8 the difference
assertEq(postBaseFee, 1375000000);
assertEq(postBaseFee, 1500000000);
}
function test_meter_useMoreThanMax_reverts() external {
...
...
@@ -141,36 +139,6 @@ contract ResourceMetering_Test is Test {
meter.use(target * elasticity + 1);
}
/**
* @notice The max resource limit should be able to be used when the L1
* deposit base fee is at its max value. This previously would
* revert because prevBaseFee is a uint128 and checked math when
* multiplying against a uint64 _amount can result in an overflow
* even though its assigning to a uint256. The values MUST be casted
* to uint256 when doing the multiplication to prevent overflows.
* The function is called with the L1 block gas limit to ensure that
* the MAX_RESOURCE_LIMIT can be consumed at the MAXIMUM_BASE_FEE.
*/
function test_meter_useMaxWithMaxBaseFee_succeeds() external {
uint128 _prevBaseFee = uint128(uint256(meter.MAXIMUM_BASE_FEE()));
uint64 _prevBoughtGas = 0;
uint64 _prevBlockNum = uint64(block.number);
meter.set({
_prevBaseFee: _prevBaseFee,
_prevBoughtGas: _prevBoughtGas,
_prevBlockNum: _prevBlockNum
});
(uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();
assertEq(prevBaseFee, _prevBaseFee);
assertEq(prevBoughtGas, _prevBoughtGas);
assertEq(prevBlockNum, _prevBlockNum);
uint64 gasRequested = uint64(uint256(meter.MAX_RESOURCE_LIMIT()));
meter.use{ gas: 30_000_000 }(gasRequested);
}
// Demonstrates that the resource metering arithmetic can tolerate very large gaps between
// deposits.
function testFuzz_meter_largeBlockDiff_succeeds(uint64 _amount, uint256 _blockDiff) external {
...
...
@@ -187,11 +155,11 @@ contract ResourceMetering_Test is Test {
}
/**
* @title
MeterUserCustom
* @title
CustomMeterUser
* @notice A simple wrapper around `ResourceMetering` that allows the initial
* params to be set in the constructor.
*/
contract
MeterUserCustom
is ResourceMetering {
contract
CustomMeterUser
is ResourceMetering {
uint256 public startGas;
uint256 public endGas;
...
...
@@ -215,17 +183,20 @@ contract MeterUserCustom is ResourceMetering {
}
/**
* @title
ResourceMeteringCustom
_Test
* @title
ArtifactResourceMetering
_Test
* @notice A table test that sets the state of the ResourceParams and then requests
* various amounts of gas. This test ensures that a wide range of values
* can safely be used with the `ResourceMetering` contract.
* It also writes a CSV file to disk that includes useful information
* about how much gas is used and how expensive it is in USD terms to
* purchase the deposit gas.
* This contract is designed to have only a single test.
*/
contract ResourceMeteringCustom_Test is Test {
MeterUser internal base;
contract ArtifactResourceMetering_Test is Test {
uint128 internal minimumBaseFee;
uint128 internal maximumBaseFee;
uint64 internal maxResourceLimit;
uint64 internal targetResourceLimit;
string internal outfile;
// keccak256(abi.encodeWithSignature("Error(string)", "ResourceMetering: cannot buy more gas than available gas limit"))
...
...
@@ -234,23 +205,26 @@ contract ResourceMeteringCustom_Test is Test {
// keccak256(abi.encodeWithSignature("Panic(uint256)", 0x11))
bytes32 internal overflowErr =
0x1ca389f2c8264faa4377de9ce8e14d6263ef29c68044a9272d405761bab2db27;
// keccak256(hex"")
bytes32 internal emptyReturnData =
0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
/**
* @notice Sets the initial block number to something sane for the
* deployment of MeterUser. Delete the CSV file if it exists
* then write the first line of the CSV.
* @notice Sets up the tests by getting constants from the ResourceMetering
* contract.
*/
function setUp() public {
vm.roll(1_000_000);
base = new MeterUser();
outfile = string.concat(vm.projectRoot(), "/.resource-metering.csv");
MeterUser base = new MeterUser();
minimumBaseFee = uint128(uint256(base.MINIMUM_BASE_FEE()));
maximumBaseFee = uint128(uint256(base.MAXIMUM_BASE_FEE()));
maxResourceLimit = uint64(uint256(base.MAX_RESOURCE_LIMIT()));
targetResourceLimit = uint64(uint256(base.TARGET_RESOURCE_LIMIT()));
outfile = string.concat(vm.projectRoot(), "/.resource-metering.csv");
try vm.removeFile(outfile) {} catch {}
vm.writeLine(
outfile,
"prevBaseFee,prevBoughtGas,prevBlockNumDiff,l1BaseFee,requestedGas,gasConsumed,ethPrice,usdCost,success"
);
}
/**
...
...
@@ -259,19 +233,22 @@ contract ResourceMeteringCustom_Test is Test {
* gas, it can take very long to execute.
*/
function test_meter_generateArtifact_succeeds() external {
vm.writeLine(
outfile,
"prevBaseFee,prevBoughtGas,prevBlockNumDiff,l1BaseFee,requestedGas,gasConsumed,ethPrice,usdCost,success"
);
// prevBaseFee value in ResourceParams
uint128[] memory prevBaseFees = new uint128[](5);
prevBaseFees[0] =
uint128(uint256(base.MAXIMUM_BASE_FEE()))
;
prevBaseFees[1] =
uint128(uint256(base.MINIMUM_BASE_FEE()))
;
prevBaseFees[2] = uint128(
uint256(base.INITIAL_BASE_FEE())
);
prevBaseFees[3] = uint128(100
_000
);
prevBaseFees[4] = uint128(
500_000
);
prevBaseFees[0] =
minimumBaseFee
;
prevBaseFees[1] =
maximumBaseFee
;
prevBaseFees[2] = uint128(
50 gwei
);
prevBaseFees[3] = uint128(100
gwei
);
prevBaseFees[4] = uint128(
200 gwei
);
// prevBoughtGas value in ResourceParams
uint64[] memory prevBoughtGases = new uint64[](3);
prevBoughtGases[0] = uint64(uint256(base.MAX_RESOURCE_LIMIT()));
prevBoughtGases[1] = uint64(uint256(base.TARGET_RESOURCE_LIMIT()));
prevBoughtGases[2] = uint64(0);
uint64[] memory prevBoughtGases = new uint64[](1);
prevBoughtGases[0] = uint64(0);
// prevBlockNum diff, simulates blocks with no deposits when non zero
uint64[] memory prevBlockNumDiffs = new uint64[](2);
...
...
@@ -280,8 +257,8 @@ contract ResourceMeteringCustom_Test is Test {
// The amount of L2 gas that a user requests
uint64[] memory requestedGases = new uint64[](3);
requestedGases[0] =
uint64(uint256(base.MAX_RESOURCE_LIMIT()))
;
requestedGases[1] =
uint64(uint256(base.TARGET_RESOURCE_LIMIT()))
;
requestedGases[0] =
maxResourceLimit
;
requestedGases[1] =
targetResourceLimit
;
requestedGases[2] = uint64(100_000);
// The L1 base fee
...
...
@@ -315,7 +292,7 @@ contract ResourceMeteringCustom_Test is Test {
vm.fee(l1BaseFee);
MeterUserCustom meter = new MeterUserCustom
({
CustomMeterUser meter = new CustomMeterUser
({
_prevBaseFee: prevBaseFee,
_prevBoughtGas: prevBoughtGas,
_prevBlockNum: uint64(block.number)
...
...
@@ -323,6 +300,8 @@ contract ResourceMeteringCustom_Test is Test {
vm.roll(block.number + prevBlockNumDiff);
// Call the metering code and catch the various
// types of errors.
uint256 gasConsumed = 0;
try meter.use{ gas: 30_000_000 }(requestedGas) returns (
uint256 _gasConsumed
...
...
@@ -334,13 +313,14 @@ contract ResourceMeteringCustom_Test is Test {
result = "ResourceMetering: cannot buy more gas than available gas limit";
} else if (hash == overflowErr) {
result = "arithmetic overflow/underflow";
} else if (hash == emptyReturnData) {
result = "out of gas";
} else {
result = "UNKNOWN ERROR";
}
}
// Compute the USD cost of the gas used, don't
// worry too much about loss of precison under $1
// Compute the USD cost of the gas used
uint256 usdCost = (gasConsumed * l1BaseFee * ethPrice) / 1 ether;
vm.writeLine(
...
...
packages/contracts-bedrock/foundry.toml
View file @
b3bfb3c7
...
...
@@ -20,7 +20,7 @@ fuzz_runs = 16
no_match_contract
=
'EchidnaFuzz'
fs_permissions
=
[
{
'access'='read-write'
,
'path'='./'
}
,
{
'access'='read-write'
,
'path'='./
.resource-metering.csv
'
}
,
]
[profile.ci]
...
...
packages/contracts-bedrock/package.json
View file @
b3bfb3c7
...
...
@@ -28,7 +28,7 @@
"test"
:
"yarn build:differential && yarn build:fuzz && forge test"
,
"coverage"
:
"yarn build:differential && yarn build:fuzz && forge coverage"
,
"coverage:lcov"
:
"yarn build:differential && yarn build:fuzz && forge coverage --report lcov"
,
"gas-snapshot"
:
"yarn build:differential && yarn build:fuzz && forge snapshot --no-match-test 'testDiff|testFuzz|invariant|
ResourceMeteringCustom
'"
,
"gas-snapshot"
:
"yarn build:differential && yarn build:fuzz && forge snapshot --no-match-test 'testDiff|testFuzz|invariant|
generateArtifact
'"
,
"storage-snapshot"
:
"./scripts/storage-snapshot.sh"
,
"validate-spacers"
:
"hardhat compile && hardhat validate-spacers"
,
"slither"
:
"./scripts/slither.sh"
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment