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

Cache Manager Tweaks #41

Merged
merged 2 commits into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"@openzeppelin/contracts": "4.5.0",
"@openzeppelin/contracts-upgradeable": "4.5.2",
"patch-package": "^6.4.7",
"solady": "^0.0.182"
"solady": "=0.0.182"
rachel-bousfield marked this conversation as resolved.
Show resolved Hide resolved
},
"private": false,
"devDependencies": {
Expand Down
47 changes: 28 additions & 19 deletions src/chain/CacheManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,14 @@ contract CacheManager {
error NotChainOwner(address sender);
error AsmTooLarge(uint256 asm, uint256 queueSize, uint256 cacheSize);
error AlreadyCached(bytes32 codehash);
error BidTooSmall(uint256 bid, uint256 min);
error BidTooSmall(uint192 bid, uint192 min);
error BidsArePaused();
error MakeSpaceTooLarge(uint64 size, uint64 limit);

event InsertBid(uint256 bid, bytes32 indexed codehash, uint64 size);
event DeleteBid(uint256 bid, bytes32 indexed codehash, uint64 size);
event InsertBid(bytes32 indexed codehash, uint192 bid, uint64 size);
event DeleteBid(bytes32 indexed codehash, uint192 bid, uint64 size);
event SetCacheSize(uint64 size);
event SetDecayRate(uint64 decay);
event Pause();
event Unpause();

Expand All @@ -55,11 +58,13 @@ contract CacheManager {
/// Sets the intended cache size. Note that the queue may temporarily be larger.
function setCacheSize(uint64 newSize) external onlyOwner {
cacheSize = newSize;
emit SetCacheSize(newSize);
}

/// Sets the intended decay factor. Does not modify existing bids.
function setDecayRate(uint64 newDecay) external onlyOwner {
decay = newDecay;
emit SetDecayRate(newDecay);
}

/// Disable new bids.
Expand All @@ -83,7 +88,7 @@ contract CacheManager {
/// Evicts up to `count` programs from the cache.
function evictPrograms(uint256 count) public onlyOwner {
while (bids.length() != 0 && count > 0) {
(uint256 bid, uint64 index) = _getBid(bids.pop());
(uint192 bid, uint64 index) = _getBid(bids.pop());
_deleteEntry(bid, index);
count -= 1;
}
Expand Down Expand Up @@ -111,30 +116,34 @@ contract CacheManager {
}

uint64 asm = _asmSize(codehash);
(uint256 bid, uint64 index) = _makeSpace(asm);
(uint192 bid, uint64 index) = _makeSpace(asm);
return _addBid(bid, codehash, asm, index);
}

/// Evicts entries until enough space exists in the cache, reverting if payment is insufficient.
/// Returns the new amount of space available on success.
/// Note: will only make up to 5Mb of space. Call repeatedly for more.
/// Note: will revert for requests larger than 5Mb. Call repeatedly for more.
function makeSpace(uint64 size) external payable returns (uint64 space) {
if (isPaused) {
revert BidsArePaused();
}
if (size > MAX_MAKE_SPACE) {
size = MAX_MAKE_SPACE;
revert MakeSpaceTooLarge(size, MAX_MAKE_SPACE);
}
_makeSpace(size);
return cacheSize - queueSize;
}

/// Evicts entries until enough space exists in the cache, reverting if payment is insufficient.
/// Returns the bid and the index to use for insertion.
function _makeSpace(uint64 size) internal returns (uint256 bid, uint64 index) {
function _makeSpace(uint64 size) internal returns (uint192 bid, uint64 index) {
// discount historical bids by the number of seconds
bid = msg.value + block.timestamp * uint256(decay);
bid = uint192(msg.value + block.timestamp * uint256(decay));
index = uint64(entries.length);

uint256 min;
while (queueSize + size > cacheSize) {
uint192 min;
uint64 limit = cacheSize;
while (queueSize + size > limit) {
(min, index) = _getBid(bids.pop());
_deleteEntry(min, index);
}
Expand All @@ -145,7 +154,7 @@ contract CacheManager {

/// Adds a bid
function _addBid(
uint256 bid,
uint192 bid,
bytes32 code,
uint64 size,
uint64 index
Expand All @@ -163,27 +172,27 @@ contract CacheManager {
} else {
entries[index] = entry;
}
emit InsertBid(bid, code, size);
emit InsertBid(code, bid, size);
}

/// Clears the entry at the given index
function _deleteEntry(uint256 bid, uint64 index) internal {
function _deleteEntry(uint192 bid, uint64 index) internal {
Entry memory entry = entries[index];
ARB_WASM_CACHE.evictCodehash(entry.code);
queueSize -= entry.size;
emit DeleteBid(bid, entry.code, entry.size);
emit DeleteBid(entry.code, bid, entry.size);
delete entries[index];
}

/// Gets the bid and index from a packed bid item
function _getBid(uint256 info) internal pure returns (uint256 bid, uint64 index) {
bid = info >> 64;
function _getBid(uint256 info) internal pure returns (uint192 bid, uint64 index) {
bid = uint192(info >> 64);
index = uint64(info);
}

/// Creates a packed bid item
function _packBid(uint256 bid, uint64 index) internal pure returns (uint256) {
return (bid << 64) | uint256(index);
function _packBid(uint192 bid, uint64 index) internal pure returns (uint256) {
return (uint256(bid) << 64) | uint256(index);
}

/// Gets the size of the given program in bytes
Expand Down
2 changes: 1 addition & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6931,7 +6931,7 @@ slice-ansi@^4.0.0:
astral-regex "^2.0.0"
is-fullwidth-code-point "^3.0.0"

solady@^0.0.182:
solady@=0.0.182:
version "0.0.182"
resolved "https://registry.yarnpkg.com/solady/-/solady-0.0.182.tgz#bd8c47f128a3a752358ad052782773966d74c400"
integrity sha512-FW6xo1akJoYpkXMzu58/56FcNU3HYYNamEbnFO3iSibXk0nSHo0DV2Gu/zI3FPg3So5CCX6IYli1TT1IWATnvg==
Expand Down
Loading