Skip to content

Commit

Permalink
Move EVM hashes to AccountCodeStorage
Browse files Browse the repository at this point in the history
  • Loading branch information
0xVolosnikov committed Dec 12, 2024
1 parent daf7022 commit 0a69eb4
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 25 deletions.
26 changes: 25 additions & 1 deletion system-contracts/contracts/AccountCodeStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ import {Unauthorized, InvalidCodeHash, CodeHashReason} from "./SystemContractErr
contract AccountCodeStorage is IAccountCodeStorage {
bytes32 private constant EMPTY_STRING_KECCAK = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;

/// @dev Prefix for EVM contracts hashes storage slots.
uint256 private constant EVM_HASHES_PREFIX = 1 << 254;

modifier onlyDeployer() {
if (msg.sender != address(DEPLOYER_SYSTEM_CONTRACT)) {
revert Unauthorized(msg.sender);
Expand Down Expand Up @@ -81,6 +84,16 @@ contract AccountCodeStorage is IAccountCodeStorage {
}
}

/// @notice Stores the keccak hash of constructed EVM contract.
/// @param _address The address of the account to set the hash to.
/// @param _hash The new keccak hash of the constructed EVM account.
/// @dev This method can be called only by ContractDeployer.
function storeAccountEvmHash(address _address, bytes32 _hash) external override onlyDeployer {
assembly {
sstore(or(EVM_HASHES_PREFIX, _address), _hash)
}
}

/// @notice Get the codehash stored for an address.
/// @param _address The address of the account of which the codehash to return
/// @return codeHash The codehash stored for this account.
Expand Down Expand Up @@ -116,7 +129,7 @@ contract AccountCodeStorage is IAccountCodeStorage {
else if (Utils.isContractConstructing(codeHash)) {
codeHash = EMPTY_STRING_KECCAK;
} else if (Utils.isCodeHashEVM(codeHash)) {
codeHash = DEPLOYER_SYSTEM_CONTRACT.evmCodeHash(account);
codeHash = _getEvmCodeHash(account);
}

return codeHash;
Expand Down Expand Up @@ -153,4 +166,15 @@ contract AccountCodeStorage is IAccountCodeStorage {
bytes32 bytecodeHash = getRawCodeHash(_addr);
return Utils.isCodeHashEVM(bytecodeHash);
}

/// @notice Returns keccak of EVM bytecode at address if it is an EVM contract. Returns bytes32(0) if it isn't a EVM contract.
function getEvmCodeHash(address _address) external view override returns (bytes32 _hash) {
_hash = _getEvmCodeHash(_address);
}

function _getEvmCodeHash(address _address) internal view returns (bytes32 _hash) {
assembly {
_hash := sload(or(EVM_HASHES_PREFIX, _address))
}
}
}
28 changes: 7 additions & 21 deletions system-contracts/contracts/ContractDeployer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ import {Unauthorized, InvalidAllowedBytecodeTypesMode, InvalidNonceOrderingChang
* do not need to be published anymore.
*/
contract ContractDeployer is IContractDeployer, SystemContractBase {
/// @dev Prefix for EVM contracts hashes storage slots.
uint256 private constant EVM_HASHES_PREFIX = 1 << 254;
/// @dev keccak256("ALLOWED_BYTECODE_TYPES_MODE_SLOT").
bytes32 private constant ALLOWED_BYTECODE_TYPES_MODE_SLOT =
0xd70708d0b933e26eab552567ce3a8ad69e6fbec9a2a68f16d51bd417a47d9d3b;
Expand All @@ -44,11 +42,6 @@ contract ContractDeployer is IContractDeployer, SystemContractBase {
mode = _getAllowedBytecodeTypesMode();
}

/// @notice Returns keccak of EVM bytecode at address if it is an EVM contract. Returns bytes32(0) if it isn't a EVM contract.
function evmCodeHash(address _address) external view returns (bytes32 _hash) {
_hash = _getEvmCodeHash(_address);
}

/// @notice Returns information about a certain account.
function getAccountInfo(address _address) external view returns (AccountInfo memory info) {
return accountInfo[_address];
Expand Down Expand Up @@ -250,7 +243,12 @@ contract ContractDeployer is IContractDeployer, SystemContractBase {
address _newAddress,
bytes calldata _initCode
) external payable onlySystemCallFromEvmEmulator returns (uint256, address) {
uint256 constructorReturnEvmGas = _performDeployOnAddressEVM(msg.sender, _newAddress, AccountAbstractionVersion.None, _initCode);
uint256 constructorReturnEvmGas = _performDeployOnAddressEVM(
msg.sender,
_newAddress,
AccountAbstractionVersion.None,
_initCode
);
return (constructorReturnEvmGas, _newAddress);
}

Expand Down Expand Up @@ -607,23 +605,11 @@ contract ContractDeployer is IContractDeployer, SystemContractBase {
evmBytecodeHash := keccak256(add(paddedBytecode, 0x40), bytecodeLen)
}

_setEvmCodeHash(_newAddress, evmBytecodeHash);
ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT.storeAccountEvmHash(_newAddress, evmBytecodeHash);

emit ContractDeployed(_sender, versionedCodeHash, _newAddress);
}

function _setEvmCodeHash(address _address, bytes32 _hash) internal {
assembly {
sstore(or(EVM_HASHES_PREFIX, _address), _hash)
}
}

function _getEvmCodeHash(address _address) internal view returns (bytes32 _hash) {
assembly {
_hash := sload(or(EVM_HASHES_PREFIX, _address))
}
}

function _getAllowedBytecodeTypesMode() internal view returns (AllowedBytecodeTypes mode) {
assembly {
mode := sload(ALLOWED_BYTECODE_TYPES_MODE_SLOT)
Expand Down
4 changes: 4 additions & 0 deletions system-contracts/contracts/interfaces/IAccountCodeStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,15 @@ interface IAccountCodeStorage {

function markAccountCodeHashAsConstructed(address _address) external;

function storeAccountEvmHash(address _address, bytes32 _hash) external;

function getRawCodeHash(address _address) external view returns (bytes32 codeHash);

function getCodeHash(uint256 _input) external view returns (bytes32 codeHash);

function getCodeSize(uint256 _input) external view returns (uint256 codeSize);

function getEvmCodeHash(address) external view returns (bytes32);

function isAccountEVM(address _addr) external view returns (bool);
}
3 changes: 0 additions & 3 deletions system-contracts/contracts/interfaces/IContractDeployer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,6 @@ interface IContractDeployer {
bytes calldata _initCode
) external payable returns (uint256 evmGasUsed, address newAddress);

/// @notice Returns keccak of EVM bytecode at address if it is an EVM contract. Returns bytes32(0) if it isn't a EVM contract.
function evmCodeHash(address) external view returns (bytes32);

/// @notice Changes what types of bytecodes are allowed to be deployed on the chain. Can be used only during upgrades.
/// @param newAllowedBytecodeTypes The new allowed bytecode types mode.
function setAllowedBytecodeTypesToDeploy(uint256 newAllowedBytecodeTypes) external;
Expand Down

0 comments on commit 0a69eb4

Please sign in to comment.