@@ -11,16 +11,11 @@ uint160 constant PRECOMPILES_END = 0xffff;
11
11
// Denotes that passGas has been consumed
12
12
uint256 constant INF_PASS_GAS = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ;
13
13
14
- contract EvmGasManager {
15
- // We need strust to use `storage` pointers
16
- struct WarmAccountInfo {
17
- bool isWarm;
18
- }
14
+ uint256 constant IS_ACCOUNT_EVM_PREFIX = 1 << 255 ;
15
+ uint256 constant IS_ACCOUNT_WARM_PREFIX = 1 << 254 ;
16
+ uint256 constant IS_SLOT_WARM_PREFIX = 1 << 253 ;
19
17
20
- struct AccountInfo {
21
- bool isEVM;
22
- }
23
-
18
+ contract EvmGasManager {
24
19
struct SlotInfo {
25
20
bool warm;
26
21
uint256 originalValue;
@@ -34,24 +29,25 @@ contract EvmGasManager {
34
29
35
30
// The following storage variables are not used anywhere explicitly and are just used to obtain the storage pointers
36
31
// to use the transient storage with.
37
- mapping (address => WarmAccountInfo ) private warmAccounts;
32
+ mapping (address => bool ) private warmAccounts;
38
33
mapping (address => mapping (uint256 => SlotInfo)) private warmSlots;
39
34
EVMStackFrameInfo[] private evmStackFrames;
40
- mapping (address => AccountInfo) private isAccountEVM;
41
35
42
36
modifier onlySystemEvm () {
43
37
// cache use is safe since we do not support SELFDESTRUCT
44
- AccountInfo storage ptr = isAccountEVM[msg .sender ];
38
+ uint256 slot = IS_ACCOUNT_EVM_PREFIX;
39
+ address _sender = msg .sender ;
45
40
bool isEVM;
46
41
assembly {
47
- isEVM := tload (ptr.slot)
42
+ slot := add (slot, _sender)
43
+ isEVM := tload (slot)
48
44
}
49
45
50
46
if (! isEVM) {
51
47
isEVM = ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT.isAccountEVM (msg .sender );
52
48
if (isEVM) {
53
49
assembly {
54
- tstore (ptr. slot, isEVM)
50
+ tstore (slot, isEVM)
55
51
}
56
52
}
57
53
}
@@ -66,44 +62,54 @@ contract EvmGasManager {
66
62
function warmAccount (address account ) external payable onlySystemEvm returns (bool wasWarm ) {
67
63
if (uint160 (account) < PRECOMPILES_END) return true ;
68
64
69
- WarmAccountInfo storage ptr = warmAccounts[ account] ;
65
+ uint256 slot = IS_ACCOUNT_WARM_PREFIX | uint256 ( uint160 ( account)) ;
70
66
71
67
assembly {
72
- wasWarm := tload (ptr. slot)
68
+ wasWarm := tload (slot)
73
69
}
74
70
75
71
if (! wasWarm) {
76
72
assembly {
77
- tstore (ptr. slot, 1 )
73
+ tstore (slot, 1 )
78
74
}
79
75
}
80
76
}
81
77
82
78
function isSlotWarm (uint256 _slot ) external view returns (bool isWarm ) {
83
- SlotInfo storage ptr = warmSlots[msg .sender ][_slot];
79
+ uint256 slot = IS_SLOT_WARM_PREFIX | uint256 (uint160 (msg .sender ));
80
+ assembly {
81
+ mstore (0 , slot)
82
+ mstore (0x20 , _slot)
83
+ slot := keccak256 (0 , 64 )
84
+ }
84
85
85
86
assembly {
86
- isWarm := tload (ptr. slot)
87
+ isWarm := tload (slot)
87
88
}
88
89
}
89
90
90
91
function warmSlot (uint256 _slot , uint256 _currentValue ) external payable onlySystemEvm returns (bool isWarm , uint256 originalValue ) {
91
- SlotInfo storage ptr = warmSlots[msg .sender ][_slot];
92
+ uint256 slot = IS_SLOT_WARM_PREFIX | uint256 (uint160 (msg .sender ));
93
+ assembly {
94
+ mstore (0 , slot)
95
+ mstore (0x20 , _slot)
96
+ slot := keccak256 (0 , 64 )
97
+ }
92
98
93
99
assembly {
94
- isWarm := tload (ptr. slot)
100
+ isWarm := tload (slot)
95
101
}
96
102
97
103
if (isWarm) {
98
104
assembly {
99
- originalValue := tload (add (ptr. slot, 1 ))
105
+ originalValue := tload (add (slot, 1 ))
100
106
}
101
107
} else {
102
108
originalValue = _currentValue;
103
109
104
110
assembly {
105
- tstore (ptr. slot, 1 )
106
- tstore (add (ptr. slot, 1 ), originalValue)
111
+ tstore (slot, 1 )
112
+ tstore (add (slot, 1 ), originalValue)
107
113
}
108
114
}
109
115
}
0 commit comments