/src/solidity/test/EVMHost.cpp
Line | Count | Source |
1 | | /* |
2 | | This file is part of solidity. |
3 | | |
4 | | solidity is free software: you can redistribute it and/or modify |
5 | | it under the terms of the GNU General Public License as published by |
6 | | the Free Software Foundation, either version 3 of the License, or |
7 | | (at your option) any later version. |
8 | | |
9 | | solidity is distributed in the hope that it will be useful, |
10 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | | GNU General Public License for more details. |
13 | | |
14 | | You should have received a copy of the GNU General Public License |
15 | | along with solidity. If not, see <http://www.gnu.org/licenses/>. |
16 | | */ |
17 | | // SPDX-License-Identifier: GPL-3.0 |
18 | | /** |
19 | | * EVM execution host, i.e. component that implements a simulated Ethereum blockchain |
20 | | * for testing purposes. |
21 | | */ |
22 | | |
23 | | // Weird issue when compiling with O3 on gcc 12 and later due to usage of vector<uint8_t> (aka bytes) as std::map key |
24 | | // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98465 |
25 | | // also clang doesn't know stringop-overread |
26 | | #if defined(__GNUC__) && !defined(__clang__) // GCC-specific pragma |
27 | | #pragma GCC diagnostic push |
28 | | #pragma GCC diagnostic ignored "-Wstringop-overread" |
29 | | #endif |
30 | | |
31 | | #include <test/EVMHost.h> |
32 | | #include <test/libsolidity/util/SoltestErrors.h> |
33 | | |
34 | | #if defined(__GNUC__) && !defined(__clang__) // GCC-specific pragma |
35 | | #pragma GCC diagnostic pop |
36 | | #endif |
37 | | |
38 | | #include <test/evmc/loader.h> |
39 | | |
40 | | #include <libevmasm/GasMeter.h> |
41 | | |
42 | | #include <libsolutil/Exceptions.h> |
43 | | #include <libsolutil/Assertions.h> |
44 | | #include <libsolutil/Keccak256.h> |
45 | | #include <libsolutil/picosha2.h> |
46 | | |
47 | | using namespace solidity; |
48 | | using namespace solidity::util; |
49 | | using namespace solidity::test; |
50 | | using namespace evmc::literals; |
51 | | |
52 | | evmc::VM& EVMHost::getVM(std::string const& _path) |
53 | 0 | { |
54 | 0 | static evmc::VM NullVM{nullptr}; |
55 | 0 | static std::map<std::string, std::unique_ptr<evmc::VM>> vms; |
56 | 0 | if (vms.count(_path) == 0) |
57 | 0 | { |
58 | 0 | evmc_loader_error_code errorCode = {}; |
59 | 0 | auto vm = evmc::VM{evmc_load_and_configure(_path.c_str(), &errorCode)}; |
60 | 0 | if (vm && errorCode == EVMC_LOADER_SUCCESS) |
61 | 0 | { |
62 | 0 | if (vm.get_capabilities() & (EVMC_CAPABILITY_EVM1)) |
63 | 0 | vms[_path] = std::make_unique<evmc::VM>(evmc::VM(std::move(vm))); |
64 | 0 | else |
65 | 0 | std::cerr << "VM loaded does not support EVM1" << std::endl; |
66 | 0 | } |
67 | 0 | else |
68 | 0 | { |
69 | 0 | std::cerr << "Error loading VM from " << _path; |
70 | 0 | if (char const* errorMsg = evmc_last_error_msg()) |
71 | 0 | std::cerr << ":" << std::endl << errorMsg; |
72 | 0 | std::cerr << std::endl; |
73 | 0 | } |
74 | 0 | } |
75 | |
|
76 | 0 | if (vms.count(_path) > 0) |
77 | 0 | return *vms[_path]; |
78 | | |
79 | 0 | return NullVM; |
80 | 0 | } |
81 | | |
82 | | bool EVMHost::checkVmPaths(std::vector<boost::filesystem::path> const& _vmPaths) |
83 | 0 | { |
84 | 0 | bool evmVmFound = false; |
85 | 0 | for (auto const& path: _vmPaths) |
86 | 0 | { |
87 | 0 | evmc::VM& vm = EVMHost::getVM(path.string()); |
88 | 0 | if (!vm) |
89 | 0 | continue; |
90 | | |
91 | 0 | if (vm.has_capability(EVMC_CAPABILITY_EVM1)) |
92 | 0 | { |
93 | 0 | if (evmVmFound) |
94 | 0 | BOOST_THROW_EXCEPTION(std::runtime_error("Multiple evm1 evmc vms defined. Please only define one evm1 evmc vm.")); |
95 | 0 | evmVmFound = true; |
96 | 0 | } |
97 | 0 | } |
98 | 0 | return evmVmFound; |
99 | 0 | } |
100 | | |
101 | | EVMHost::EVMHost(langutil::EVMVersion _evmVersion, evmc::VM& _vm): |
102 | 12.2k | m_vm(_vm), |
103 | 12.2k | m_evmVersion(_evmVersion) |
104 | 12.2k | { |
105 | 12.2k | if (!m_vm) |
106 | 0 | { |
107 | 0 | std::cerr << "Unable to find evmone library" << std::endl; |
108 | 0 | solRequire(false, Exception, ""); |
109 | 0 | } |
110 | | |
111 | 12.2k | if (_evmVersion == langutil::EVMVersion::homestead()) |
112 | 0 | m_evmRevision = EVMC_HOMESTEAD; |
113 | 12.2k | else if (_evmVersion == langutil::EVMVersion::tangerineWhistle()) |
114 | 0 | m_evmRevision = EVMC_TANGERINE_WHISTLE; |
115 | 12.2k | else if (_evmVersion == langutil::EVMVersion::spuriousDragon()) |
116 | 0 | m_evmRevision = EVMC_SPURIOUS_DRAGON; |
117 | 12.2k | else if (_evmVersion == langutil::EVMVersion::byzantium()) |
118 | 0 | m_evmRevision = EVMC_BYZANTIUM; |
119 | 12.2k | else if (_evmVersion == langutil::EVMVersion::constantinople()) |
120 | 0 | m_evmRevision = EVMC_CONSTANTINOPLE; |
121 | 12.2k | else if (_evmVersion == langutil::EVMVersion::petersburg()) |
122 | 0 | m_evmRevision = EVMC_PETERSBURG; |
123 | 12.2k | else if (_evmVersion == langutil::EVMVersion::istanbul()) |
124 | 0 | m_evmRevision = EVMC_ISTANBUL; |
125 | 12.2k | else if (_evmVersion == langutil::EVMVersion::berlin()) |
126 | 0 | m_evmRevision = EVMC_BERLIN; |
127 | 12.2k | else if (_evmVersion == langutil::EVMVersion::london()) |
128 | 0 | m_evmRevision = EVMC_LONDON; |
129 | 12.2k | else if (_evmVersion == langutil::EVMVersion::paris()) |
130 | 0 | m_evmRevision = EVMC_PARIS; |
131 | 12.2k | else if (_evmVersion == langutil::EVMVersion::shanghai()) |
132 | 0 | m_evmRevision = EVMC_SHANGHAI; |
133 | 12.2k | else if (_evmVersion == langutil::EVMVersion::cancun()) |
134 | 0 | m_evmRevision = EVMC_CANCUN; |
135 | 12.2k | else if (_evmVersion == langutil::EVMVersion::prague()) |
136 | 0 | m_evmRevision = EVMC_PRAGUE; |
137 | 12.2k | else if (_evmVersion == langutil::EVMVersion::osaka()) |
138 | 12.2k | m_evmRevision = EVMC_OSAKA; |
139 | 0 | else if (_evmVersion == langutil::EVMVersion::amsterdam()) |
140 | 0 | m_evmRevision = EVMC_AMSTERDAM; |
141 | 0 | else if (_evmVersion == langutil::EVMVersion::future()) |
142 | 0 | m_evmRevision = EVMC_MAX_REVISION; |
143 | 0 | else |
144 | 0 | solRequire(false, Exception, "Unsupported EVM version"); |
145 | | |
146 | 12.2k | if (m_evmRevision >= EVMC_PARIS) |
147 | | // This is the value from the merge block. |
148 | 12.2k | tx_context.block_prev_randao = 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777_bytes32; |
149 | 0 | else |
150 | 0 | tx_context.block_prev_randao = evmc::uint256be{200000000}; |
151 | 12.2k | tx_context.block_gas_limit = 20000000; |
152 | 12.2k | tx_context.block_coinbase = 0x7878787878787878787878787878787878787878_address; |
153 | 12.2k | tx_context.tx_gas_price = evmc::uint256be{3000000000}; |
154 | 12.2k | tx_context.tx_origin = 0x9292929292929292929292929292929292929292_address; |
155 | | // Mainnet according to EIP-155 |
156 | 12.2k | tx_context.chain_id = evmc::uint256be{1}; |
157 | | // The minimum value of basefee |
158 | 12.2k | tx_context.block_base_fee = evmc::bytes32{7}; |
159 | | // The minimum value of blobbasefee |
160 | 12.2k | tx_context.blob_base_fee = evmc::bytes32{1}; |
161 | | |
162 | 12.2k | static evmc_bytes32 const blob_hashes_array[] = { |
163 | 12.2k | 0x0100000000000000000000000000000000000000000000000000000000000001_bytes32, |
164 | 12.2k | 0x0100000000000000000000000000000000000000000000000000000000000002_bytes32 |
165 | 12.2k | }; |
166 | 12.2k | tx_context.blob_hashes = blob_hashes_array; |
167 | 12.2k | tx_context.blob_hashes_count = sizeof(blob_hashes_array) / sizeof(blob_hashes_array[0]); |
168 | | |
169 | | // Reserve space for recording calls. |
170 | 12.2k | if (!recorded_calls.capacity()) |
171 | 12.2k | recorded_calls.reserve(max_recorded_calls); |
172 | | |
173 | 12.2k | reset(); |
174 | 12.2k | } |
175 | | |
176 | | void EVMHost::reset() |
177 | 34.8k | { |
178 | 34.8k | accounts.clear(); |
179 | | // Clear self destruct records |
180 | 34.8k | recorded_selfdestructs.clear(); |
181 | | // Clear call records |
182 | 34.8k | recorded_calls.clear(); |
183 | | // Clear EIP-2929 account access indicator |
184 | 34.8k | recorded_account_accesses.clear(); |
185 | 34.8k | m_newlyCreatedAccounts.clear(); |
186 | 34.8k | m_totalCodeDepositGas = 0; |
187 | | |
188 | | // Mark all precompiled contracts as existing. Existing here means to have a balance (as per EIP-161). |
189 | | // NOTE: keep this in sync with `EVMHost::call` below. |
190 | | // |
191 | | // A lot of precompile addresses had a balance before they became valid addresses for precompiles. |
192 | | // For example all the precompile addresses allocated in Byzantium had a 1 wei balance sent to them |
193 | | // roughly 22 days before the update went live. |
194 | 313k | for (unsigned precompiledAddress = 1; precompiledAddress <= 8; precompiledAddress++) |
195 | 278k | { |
196 | 278k | evmc::address address{precompiledAddress}; |
197 | | // 1wei |
198 | 278k | accounts[address].balance = evmc::uint256be{1}; |
199 | | // Set according to EIP-1052. |
200 | 278k | if (precompiledAddress < 5 || m_evmVersion >= langutil::EVMVersion::byzantium()) |
201 | 278k | accounts[address].codehash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470_bytes32; |
202 | 278k | } |
203 | 34.8k | } |
204 | | |
205 | | void EVMHost::newTransactionFrame() |
206 | 0 | { |
207 | | // Clear EIP-2929 account access indicator |
208 | 0 | recorded_account_accesses.clear(); |
209 | |
|
210 | 0 | for (auto& [address, account]: accounts) |
211 | 0 | { |
212 | 0 | for (auto& [slot, value]: account.storage) |
213 | 0 | { |
214 | 0 | value.access_status = EVMC_ACCESS_COLD; // Clear EIP-2929 storage access indicator |
215 | 0 | value.original = value.current; // Clear EIP-2200 dirty slot |
216 | 0 | } |
217 | | |
218 | | // Clear transient storage according to EIP 1153 |
219 | 0 | account.transient_storage.clear(); |
220 | 0 | } |
221 | | // Process selfdestruct list |
222 | 0 | for (auto& [address, _]: recorded_selfdestructs) |
223 | 0 | if (m_evmVersion < langutil::EVMVersion::cancun() || m_newlyCreatedAccounts.count(address)) |
224 | | // EIP-6780: If SELFDESTRUCT is executed in a transaction different from the one |
225 | | // in which it was created, we do NOT record it or clear any data. |
226 | | // Otherwise, the previous behavior (pre-Cancun) is maintained. |
227 | 0 | accounts.erase(address); |
228 | 0 | m_newlyCreatedAccounts.clear(); |
229 | 0 | m_totalCodeDepositGas = 0; |
230 | 0 | recorded_selfdestructs.clear(); |
231 | 0 | } |
232 | | |
233 | | void EVMHost::transfer(evmc::MockedAccount& _sender, evmc::MockedAccount& _recipient, u256 const& _value) noexcept |
234 | 518 | { |
235 | 518 | solRequire(u256(convertFromEVMC(_sender.balance)) >= _value, Exception, "Insufficient balance for transfer"); |
236 | 518 | _sender.balance = convertToEVMC(u256(convertFromEVMC(_sender.balance)) - _value); |
237 | 518 | _recipient.balance = convertToEVMC(u256(convertFromEVMC(_recipient.balance)) + _value); |
238 | 518 | } |
239 | | |
240 | | bool EVMHost::selfdestruct(const evmc::address& _addr, const evmc::address& _beneficiary) noexcept |
241 | 518 | { |
242 | | // TODO actual selfdestruct is even more complicated. |
243 | | |
244 | | // NOTE: EIP-6780: The transfer of the entire account balance to the beneficiary should still happen |
245 | | // after cancun. |
246 | 518 | transfer(accounts[_addr], accounts[_beneficiary], convertFromEVMC(accounts[_addr].balance)); |
247 | | |
248 | | // Record self destructs. Clearing will be done in newTransactionFrame(). |
249 | 518 | return MockedHost::selfdestruct(_addr, _beneficiary); |
250 | 518 | } |
251 | | |
252 | | void EVMHost::recordCalls(evmc_message const& _message) noexcept |
253 | 99.3k | { |
254 | 99.3k | if (recorded_calls.size() < max_recorded_calls) |
255 | 78.8k | recorded_calls.emplace_back(_message); |
256 | 99.3k | } |
257 | | |
258 | | // NOTE: this is used for both internal and external calls. |
259 | | // External calls are triggered from ExecutionFramework and contain only EVMC_CREATE or EVMC_CALL. |
260 | | evmc::Result EVMHost::call(evmc_message const& _message) noexcept |
261 | 99.3k | { |
262 | 99.3k | recordCalls(_message); |
263 | 99.3k | if (_message.recipient == 0x0000000000000000000000000000000000000001_address) |
264 | 0 | return precompileECRecover(_message); |
265 | 99.3k | else if (_message.recipient == 0x0000000000000000000000000000000000000002_address) |
266 | 837 | return precompileSha256(_message); |
267 | 98.4k | else if (_message.recipient == 0x0000000000000000000000000000000000000003_address) |
268 | 1.04k | return precompileRipeMD160(_message); |
269 | 97.4k | else if (_message.recipient == 0x0000000000000000000000000000000000000004_address) |
270 | 935 | return precompileIdentity(_message); |
271 | 96.4k | else if (_message.recipient == 0x0000000000000000000000000000000000000005_address && m_evmVersion >= langutil::EVMVersion::byzantium()) |
272 | 263 | return precompileModExp(_message); |
273 | 96.2k | else if (_message.recipient == 0x0000000000000000000000000000000000000006_address && m_evmVersion >= langutil::EVMVersion::byzantium()) |
274 | 0 | { |
275 | 0 | if (m_evmVersion <= langutil::EVMVersion::istanbul()) |
276 | 0 | return precompileALTBN128G1Add<EVMC_ISTANBUL>(_message); |
277 | 0 | else |
278 | 0 | return precompileALTBN128G1Add<EVMC_LONDON>(_message); |
279 | 0 | } |
280 | 96.2k | else if (_message.recipient == 0x0000000000000000000000000000000000000007_address && m_evmVersion >= langutil::EVMVersion::byzantium()) |
281 | 0 | { |
282 | 0 | if (m_evmVersion <= langutil::EVMVersion::istanbul()) |
283 | 0 | return precompileALTBN128G1Mul<EVMC_ISTANBUL>(_message); |
284 | 0 | else |
285 | 0 | return precompileALTBN128G1Mul<EVMC_LONDON>(_message); |
286 | 0 | } |
287 | 96.2k | else if (_message.recipient == 0x0000000000000000000000000000000000000008_address && m_evmVersion >= langutil::EVMVersion::byzantium()) |
288 | 0 | { |
289 | 0 | if (m_evmVersion <= langutil::EVMVersion::istanbul()) |
290 | 0 | return precompileALTBN128PairingProduct<EVMC_ISTANBUL>(_message); |
291 | 0 | else |
292 | 0 | return precompileALTBN128PairingProduct<EVMC_LONDON>(_message); |
293 | 0 | } |
294 | 96.2k | else if (_message.recipient == 0x0000000000000000000000000000000000000009_address && m_evmVersion >= langutil::EVMVersion::istanbul()) |
295 | 20 | return precompileBlake2f(_message); |
296 | | |
297 | 96.2k | auto const stateBackup = accounts; |
298 | | |
299 | 96.2k | u256 value{convertFromEVMC(_message.value)}; |
300 | 96.2k | auto& sender = accounts[_message.sender]; |
301 | | |
302 | 96.2k | evmc::bytes code; |
303 | | |
304 | 96.2k | evmc_message message = _message; |
305 | 96.2k | if (message.depth == 0) |
306 | 46.1k | { |
307 | 46.1k | message.gas -= message.kind == EVMC_CREATE ? evmasm::GasCosts::txCreateGas : evmasm::GasCosts::txGas; |
308 | 18.7M | for (size_t i = 0; i < message.input_size; ++i) |
309 | 18.6M | message.gas -= message.input_data[i] == 0 ? evmasm::GasCosts::txDataZeroGas : evmasm::GasCosts::txDataNonZeroGas(m_evmVersion); |
310 | 46.1k | if (message.gas < 0) |
311 | 0 | { |
312 | 0 | evmc::Result result; |
313 | 0 | result.status_code = EVMC_OUT_OF_GAS; |
314 | 0 | accounts = stateBackup; |
315 | 0 | return result; |
316 | 0 | } |
317 | 46.1k | } |
318 | | |
319 | 96.2k | if (message.kind == EVMC_CREATE) |
320 | 23.0k | { |
321 | | // TODO is the nonce incremented on failure, too? |
322 | | // NOTE: nonce for creation from contracts starts at 1 |
323 | | // TODO: check if sender is an EOA and do not pre-increment |
324 | 23.0k | sender.nonce++; |
325 | | |
326 | 23.0k | auto encodeRlpInteger = [](int value) -> bytes { |
327 | 23.0k | if (value == 0) { |
328 | 0 | return bytes{128}; |
329 | 23.0k | } else if (value <= 127) { |
330 | 23.0k | return bytes{static_cast<uint8_t>(value)}; |
331 | 23.0k | } else if (value <= 0xff) { |
332 | 0 | return bytes{128 + 1, static_cast<uint8_t>(value)}; |
333 | 0 | } else if (value <= 0xffff) { |
334 | 0 | return bytes{128 + 55 + 2, static_cast<uint8_t>(value >> 8), static_cast<uint8_t>(value)}; |
335 | 0 | } else { |
336 | 0 | solUnimplemented("Can only encode RLP numbers <= 0xffff"); |
337 | 0 | } |
338 | 23.0k | }; |
339 | | |
340 | 23.0k | bytes encodedNonce = encodeRlpInteger(sender.nonce); |
341 | | |
342 | 23.0k | h160 createAddress(keccak256( |
343 | 23.0k | bytes{static_cast<uint8_t>(0xc0 + 21 + encodedNonce.size())} + |
344 | 23.0k | bytes{0x94} + |
345 | 23.0k | bytes(std::begin(message.sender.bytes), std::end(message.sender.bytes)) + |
346 | 23.0k | encodedNonce |
347 | 23.0k | ), h160::AlignRight); |
348 | | |
349 | 23.0k | message.recipient = convertToEVMC(createAddress); |
350 | 23.0k | soltestAssert(accounts.count(message.recipient) == 0, "Account cannot exist"); |
351 | | |
352 | 23.0k | code = evmc::bytes(message.input_data, message.input_data + message.input_size); |
353 | 23.0k | } |
354 | 73.1k | else if (message.kind == EVMC_CREATE2) |
355 | 0 | { |
356 | 0 | h160 createAddress(keccak256( |
357 | 0 | bytes{0xff} + |
358 | 0 | bytes(std::begin(message.sender.bytes), std::end(message.sender.bytes)) + |
359 | 0 | bytes(std::begin(message.create2_salt.bytes), std::end(message.create2_salt.bytes)) + |
360 | 0 | keccak256(bytes(message.input_data, message.input_data + message.input_size)).asBytes() |
361 | 0 | ), h160::AlignRight); |
362 | |
|
363 | 0 | message.recipient = convertToEVMC(createAddress); |
364 | 0 | if (accounts.count(message.recipient) && ( |
365 | 0 | accounts[message.recipient].nonce > 0 || |
366 | 0 | !accounts[message.recipient].code.empty() |
367 | 0 | )) |
368 | 0 | { |
369 | 0 | evmc::Result result; |
370 | 0 | result.status_code = EVMC_OUT_OF_GAS; |
371 | 0 | accounts = stateBackup; |
372 | 0 | return result; |
373 | 0 | } |
374 | | |
375 | | |
376 | 0 | code = evmc::bytes(message.input_data, message.input_data + message.input_size); |
377 | 0 | } |
378 | 73.1k | else |
379 | 73.1k | code = accounts[message.code_address].code; |
380 | | |
381 | 96.2k | auto& destination = accounts[message.recipient]; |
382 | 96.2k | if (message.kind == EVMC_CREATE || message.kind == EVMC_CREATE2) |
383 | | // Mark account as created if it is a CREATE or CREATE2 call |
384 | | // TODO: Should we roll changes back on failure like we do for `accounts`? |
385 | 23.0k | m_newlyCreatedAccounts.emplace(message.recipient); |
386 | | |
387 | 96.2k | if (value != 0 && message.kind != EVMC_DELEGATECALL && message.kind != EVMC_CALLCODE) |
388 | 0 | { |
389 | 0 | if (value > convertFromEVMC(sender.balance)) |
390 | 0 | { |
391 | 0 | evmc::Result result; |
392 | 0 | result.status_code = EVMC_INSUFFICIENT_BALANCE; |
393 | 0 | accounts = stateBackup; |
394 | 0 | return result; |
395 | 0 | } |
396 | 0 | transfer(sender, destination, value); |
397 | 0 | } |
398 | | |
399 | | // Populate the access list (enabled since Berlin). |
400 | | // Note, this will also properly touch the created address. |
401 | | // TODO: support a user supplied access list too |
402 | 96.2k | if (m_evmRevision >= EVMC_BERLIN) |
403 | 96.2k | { |
404 | 96.2k | access_account(message.sender); |
405 | 96.2k | access_account(message.recipient); |
406 | | |
407 | | // EIP-3651 rule |
408 | 96.2k | if (m_evmRevision >= EVMC_SHANGHAI) |
409 | 96.2k | access_account(tx_context.block_coinbase); |
410 | 96.2k | } |
411 | | |
412 | 96.2k | if (message.kind == EVMC_CREATE || message.kind == EVMC_CREATE2) |
413 | 23.0k | { |
414 | 23.0k | message.input_data = nullptr; |
415 | 23.0k | message.input_size = 0; |
416 | 23.0k | } |
417 | 96.2k | evmc::Result result = m_vm.execute(*this, m_evmRevision, message, code.data(), code.size()); |
418 | | |
419 | 96.2k | if (message.kind == EVMC_CREATE || message.kind == EVMC_CREATE2) |
420 | 23.0k | { |
421 | 23.0k | int64_t codeDepositGas = static_cast<int64_t>(evmasm::GasCosts::createDataGas * result.output_size); |
422 | 23.0k | result.gas_left -= codeDepositGas; |
423 | 23.0k | if (result.gas_left < 0) |
424 | 0 | { |
425 | 0 | m_totalCodeDepositGas += -result.gas_left; |
426 | 0 | result.gas_left = 0; |
427 | 0 | result.status_code = EVMC_OUT_OF_GAS; |
428 | | // TODO clear some fields? |
429 | 0 | } |
430 | 23.0k | else |
431 | 23.0k | { |
432 | 23.0k | m_totalCodeDepositGas += codeDepositGas; |
433 | 23.0k | result.create_address = message.recipient; |
434 | 23.0k | destination.code = evmc::bytes(result.output_data, result.output_data + result.output_size); |
435 | 23.0k | destination.codehash = convertToEVMC(keccak256({result.output_data, result.output_size})); |
436 | 23.0k | } |
437 | 23.0k | } |
438 | | |
439 | 96.2k | if (result.status_code != EVMC_SUCCESS) |
440 | 1.34k | accounts = stateBackup; |
441 | | |
442 | 96.2k | return result; |
443 | 96.2k | } |
444 | | |
445 | | evmc::bytes32 EVMHost::get_block_hash(int64_t _number) const noexcept |
446 | 0 | { |
447 | 0 | return convertToEVMC(u256("0x3737373737373737373737373737373737373737373737373737373737373737") + _number); |
448 | 0 | } |
449 | | |
450 | | h160 EVMHost::convertFromEVMC(evmc::address const& _addr) |
451 | 0 | { |
452 | 0 | return h160(bytes(std::begin(_addr.bytes), std::end(_addr.bytes))); |
453 | 0 | } |
454 | | |
455 | | evmc::address EVMHost::convertToEVMC(h160 const& _addr) |
456 | 23.0k | { |
457 | 23.0k | evmc::address a; |
458 | 484k | for (unsigned i = 0; i < 20; ++i) |
459 | 461k | a.bytes[i] = _addr[i]; |
460 | 23.0k | return a; |
461 | 23.0k | } |
462 | | |
463 | | h256 EVMHost::convertFromEVMC(evmc::bytes32 const& _data) |
464 | 281k | { |
465 | 281k | return h256(bytes(std::begin(_data.bytes), std::end(_data.bytes))); |
466 | 281k | } |
467 | | |
468 | | evmc::bytes32 EVMHost::convertToEVMC(h256 const& _data) |
469 | 24.1k | { |
470 | 24.1k | evmc::bytes32 d; |
471 | 795k | for (unsigned i = 0; i < 32; ++i) |
472 | 771k | d.bytes[i] = _data[i]; |
473 | 24.1k | return d; |
474 | 24.1k | } |
475 | | |
476 | | evmc::Result EVMHost::precompileECRecover(evmc_message const& _message) noexcept |
477 | 0 | { |
478 | | // NOTE this is a partial implementation for some inputs. |
479 | | |
480 | | // Fixed cost of 3000 gas. |
481 | 0 | constexpr int64_t gas_cost = 3000; |
482 | |
|
483 | 0 | static std::map<bytes, EVMPrecompileOutput> const inputOutput{ |
484 | 0 | { |
485 | 0 | fromHex( |
486 | 0 | "18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c" |
487 | 0 | "000000000000000000000000000000000000000000000000000000000000001c" |
488 | 0 | "73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f" |
489 | 0 | "eeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549" |
490 | 0 | ), |
491 | 0 | { |
492 | 0 | fromHex("000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b"), |
493 | 0 | gas_cost |
494 | 0 | } |
495 | 0 | }, |
496 | 0 | { |
497 | 0 | fromHex( |
498 | 0 | "47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad" |
499 | 0 | "000000000000000000000000000000000000000000000000000000000000001c" |
500 | 0 | "debaaa0cddb321b2dcaaf846d39605de7b97e77ba6106587855b9106cb104215" |
501 | 0 | "61a22d94fa8b8a687ff9c911c844d1c016d1a685a9166858f9c7c1bc85128aca" |
502 | 0 | ), |
503 | 0 | { |
504 | 0 | fromHex("0000000000000000000000008743523d96a1b2cbe0c6909653a56da18ed484af"), |
505 | 0 | gas_cost |
506 | 0 | } |
507 | 0 | }, |
508 | 0 | { |
509 | 0 | fromHex( |
510 | 0 | "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" |
511 | 0 | "0000000000000000000000000000000000000000000000000000000000000001" |
512 | 0 | "0000000000000000000000000000000000000000000000000000000000000002" |
513 | 0 | "0000000000000000000000000000000000000000000000000000000000000003" |
514 | 0 | ), |
515 | 0 | { |
516 | 0 | fromHex(""), |
517 | 0 | gas_cost |
518 | 0 | } |
519 | 0 | }, |
520 | 0 | { |
521 | 0 | fromHex( |
522 | 0 | "77e5189111eb6557e8a637b27ef8fbb15bc61d61c2f00cc48878f3a296e5e0ca" |
523 | 0 | "0000000000000000000000000000000000000000000000000000000000000000" |
524 | 0 | "6944c77849b18048f6abe0db8084b0d0d0689cdddb53d2671c36967b58691ad4" |
525 | 0 | "ef4f06ba4f78319baafd0424365777241af4dfd3da840471b4b4b087b7750d0d" |
526 | 0 | ), |
527 | 0 | { |
528 | 0 | fromHex(""), |
529 | 0 | gas_cost |
530 | 0 | } |
531 | 0 | } |
532 | 0 | }; |
533 | 0 | evmc::Result result = precompileGeneric(_message, inputOutput, true /* _ignoresTrailingInput */); |
534 | | // ECRecover will return success with empty response in case of failure |
535 | 0 | if (result.status_code != EVMC_SUCCESS && result.status_code != EVMC_OUT_OF_GAS) |
536 | 0 | return resultWithGas(_message.gas, gas_cost, {}); |
537 | 0 | return result; |
538 | 0 | } |
539 | | |
540 | | evmc::Result EVMHost::precompileSha256(evmc_message const& _message) noexcept |
541 | 837 | { |
542 | | // static data so that we do not need a release routine... |
543 | 837 | bytes static hash; |
544 | 837 | hash = picosha2::hash256(bytes( |
545 | 837 | _message.input_data, |
546 | 837 | _message.input_data + _message.input_size |
547 | 837 | )); |
548 | | |
549 | | // Base 60 gas + 12 gas / word. |
550 | 837 | int64_t gas_cost = 60 + 12 * ((static_cast<int64_t>(_message.input_size) + 31) / 32); |
551 | | |
552 | 837 | return resultWithGas(_message.gas, gas_cost, hash); |
553 | 837 | } |
554 | | |
555 | | evmc::Result EVMHost::precompileRipeMD160(evmc_message const& _message) noexcept |
556 | 1.04k | { |
557 | | // NOTE this is a partial implementation for some inputs. |
558 | | |
559 | | // Base 600 gas + 120 gas / word. |
560 | 1.04k | constexpr auto calc_cost = [](int64_t size) -> int64_t { |
561 | 10 | return 600 + 120 * ((size + 31) / 32); |
562 | 10 | }; |
563 | | |
564 | 1.04k | static std::map<bytes, EVMPrecompileOutput> const inputOutput{ |
565 | 1.04k | { |
566 | 1.04k | bytes{}, |
567 | 1.04k | { |
568 | 1.04k | fromHex("0000000000000000000000009c1185a5c5e9fc54612808977ee8f548b2258d31"), |
569 | 1.04k | calc_cost(0) |
570 | 1.04k | } |
571 | 1.04k | }, |
572 | 1.04k | { |
573 | 1.04k | fromHex("0000000000000000000000000000000000000000000000000000000000000004"), |
574 | 1.04k | { |
575 | 1.04k | fromHex("0000000000000000000000001b0f3c404d12075c68c938f9f60ebea4f74941a0"), |
576 | 1.04k | calc_cost(32) |
577 | 1.04k | } |
578 | 1.04k | }, |
579 | 1.04k | { |
580 | 1.04k | fromHex("0000000000000000000000000000000000000000000000000000000000000005"), |
581 | 1.04k | { |
582 | 1.04k | fromHex("000000000000000000000000ee54aa84fc32d8fed5a5fe160442ae84626829d9"), |
583 | 1.04k | calc_cost(32) |
584 | 1.04k | } |
585 | 1.04k | }, |
586 | 1.04k | { |
587 | 1.04k | fromHex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), |
588 | 1.04k | { |
589 | 1.04k | fromHex("0000000000000000000000001cf4e77f5966e13e109703cd8a0df7ceda7f3dc3"), |
590 | 1.04k | calc_cost(32) |
591 | 1.04k | } |
592 | 1.04k | }, |
593 | 1.04k | { |
594 | 1.04k | fromHex("0000000000000000000000000000000000000000000000000000000000000000"), |
595 | 1.04k | { |
596 | 1.04k | fromHex("000000000000000000000000f93175303eba2a7b372174fc9330237f5ad202fc"), |
597 | 1.04k | calc_cost(32) |
598 | 1.04k | } |
599 | 1.04k | }, |
600 | 1.04k | { |
601 | 1.04k | fromHex( |
602 | 1.04k | "0800000000000000000000000000000000000000000000000000000000000000" |
603 | 1.04k | "0401000000000000000000000000000000000000000000000000000000000000" |
604 | 1.04k | "0000000400000000000000000000000000000000000000000000000000000000" |
605 | 1.04k | "00000100" |
606 | 1.04k | ), |
607 | 1.04k | { |
608 | 1.04k | fromHex("000000000000000000000000f93175303eba2a7b372174fc9330237f5ad202fc"), |
609 | 1.04k | calc_cost(100) |
610 | 1.04k | } |
611 | 1.04k | }, |
612 | 1.04k | { |
613 | 1.04k | fromHex( |
614 | 1.04k | "0800000000000000000000000000000000000000000000000000000000000000" |
615 | 1.04k | "0501000000000000000000000000000000000000000000000000000000000000" |
616 | 1.04k | "0000000500000000000000000000000000000000000000000000000000000000" |
617 | 1.04k | "00000100" |
618 | 1.04k | ), |
619 | 1.04k | { |
620 | 1.04k | fromHex("0000000000000000000000004f4fc112e2bfbe0d38f896a46629e08e2fcfad5"), |
621 | 1.04k | calc_cost(100) |
622 | 1.04k | } |
623 | 1.04k | }, |
624 | 1.04k | { |
625 | 1.04k | fromHex( |
626 | 1.04k | "08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" |
627 | 1.04k | "ff010000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff" |
628 | 1.04k | "ffffffff00000000000000000000000000000000000000000000000000000000" |
629 | 1.04k | "00000100" |
630 | 1.04k | ), |
631 | 1.04k | { |
632 | 1.04k | fromHex("000000000000000000000000c0a2e4b1f3ff766a9a0089e7a410391730872495"), |
633 | 1.04k | calc_cost(100) |
634 | 1.04k | } |
635 | 1.04k | }, |
636 | 1.04k | { |
637 | 1.04k | fromHex( |
638 | 1.04k | "6162636465666768696a6b6c6d6e6f707172737475767778797a414243444546" |
639 | 1.04k | "4748494a4b4c4d4e4f505152535455565758595a303132333435363738393f21" |
640 | 1.04k | ), |
641 | 1.04k | { |
642 | 1.04k | fromHex("00000000000000000000000036c6b90a49e17d4c1e1b0e634ec74124d9b207da"), |
643 | 1.04k | calc_cost(64) |
644 | 1.04k | } |
645 | 1.04k | }, |
646 | 1.04k | { |
647 | 1.04k | fromHex("6162636465666768696a6b6c6d6e6f707172737475767778797a414243444546"), |
648 | 1.04k | { |
649 | 1.04k | fromHex("000000000000000000000000ac5ab22e07b0fb80c69b6207902f725e2507e546"), |
650 | 1.04k | calc_cost(32) |
651 | 1.04k | } |
652 | 1.04k | } |
653 | 1.04k | }; |
654 | 1.04k | return precompileGeneric(_message, inputOutput); |
655 | 1.04k | } |
656 | | |
657 | | evmc::Result EVMHost::precompileIdentity(evmc_message const& _message) noexcept |
658 | 935 | { |
659 | | // static data so that we do not need a release routine... |
660 | 935 | bytes static data; |
661 | 935 | data = bytes(_message.input_data, _message.input_data + _message.input_size); |
662 | | |
663 | | // Base 15 gas + 3 gas / word. |
664 | 935 | int64_t gas_cost = 15 + 3 * ((static_cast<int64_t>(_message.input_size) + 31) / 32); |
665 | | |
666 | 935 | return resultWithGas(_message.gas, gas_cost, data); |
667 | 935 | } |
668 | | |
669 | | evmc::Result EVMHost::precompileModExp(evmc_message const&) noexcept |
670 | 263 | { |
671 | | // TODO implement |
672 | 263 | return resultWithFailure(); |
673 | 263 | } |
674 | | |
675 | | template <evmc_revision Revision> |
676 | | evmc::Result EVMHost::precompileALTBN128G1Add(evmc_message const& _message) noexcept |
677 | 0 | { |
678 | | // NOTE this is a partial implementation for some inputs. |
679 | | |
680 | | // Fixed 500 or 150 gas. |
681 | 0 | int64_t gas_cost = (Revision < EVMC_ISTANBUL) ? 500 : 150; |
682 | |
|
683 | 0 | static std::map<bytes, EVMPrecompileOutput> const inputOutput{ |
684 | 0 | { |
685 | 0 | fromHex( |
686 | 0 | "0000000000000000000000000000000000000000000000000000000000000000" |
687 | 0 | "0000000000000000000000000000000000000000000000000000000000000000" |
688 | 0 | "1385281136ff5b2c326807ff0a824b6ca4f21fcc7c8764e9801bc4ad497d5012" |
689 | 0 | "02254594be8473dcf018a2aa66ea301e38fc865823acf75a9901721d1fc6bf4c" |
690 | 0 | ), |
691 | 0 | { |
692 | 0 | fromHex( |
693 | 0 | "1385281136ff5b2c326807ff0a824b6ca4f21fcc7c8764e9801bc4ad497d5012" |
694 | 0 | "02254594be8473dcf018a2aa66ea301e38fc865823acf75a9901721d1fc6bf4c" |
695 | 0 | ), |
696 | 0 | gas_cost |
697 | 0 | } |
698 | 0 | }, |
699 | 0 | { |
700 | 0 | fromHex( |
701 | 0 | "0000000000000000000000000000000000000000000000000000000000000001" |
702 | 0 | "0000000000000000000000000000000000000000000000000000000000000002" |
703 | 0 | "0000000000000000000000000000000000000000000000000000000000000001" |
704 | 0 | "0000000000000000000000000000000000000000000000000000000000000002" |
705 | 0 | ), |
706 | 0 | { |
707 | 0 | fromHex( |
708 | 0 | "030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd3" |
709 | 0 | "15ed738c0e0a7c92e7845f96b2ae9c0a68a6a449e3538fc7ff3ebf7a5a18a2c4" |
710 | 0 | ), |
711 | 0 | gas_cost |
712 | 0 | } |
713 | 0 | }, |
714 | 0 | { |
715 | 0 | fromHex( |
716 | 0 | "0000000000000000000000000000000000000000000000000000000000000001" |
717 | 0 | "0000000000000000000000000000000000000000000000000000000000000002" |
718 | 0 | "0000000000000000000000000000000000000000000000000000000000000001" |
719 | 0 | "30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45" |
720 | 0 | ), |
721 | 0 | { |
722 | 0 | fromHex( |
723 | 0 | "0000000000000000000000000000000000000000000000000000000000000000" |
724 | 0 | "0000000000000000000000000000000000000000000000000000000000000000" |
725 | 0 | ), |
726 | 0 | gas_cost |
727 | 0 | } |
728 | 0 | }, |
729 | 0 | { |
730 | 0 | fromHex( |
731 | 0 | "10b4876441e14a6be92a7fe66550848c01c676a12ac31d7cc13b21f49c4307c8" |
732 | 0 | "09f5528bdb0ef9354837a0f4b4c9da973bd5b805d359976f719ab0b74e0a7368" |
733 | 0 | "28d3c57516712e7843a5b3cfa7d7274a037943f5bd57c227620ad207728e4283" |
734 | 0 | "2795fa9df21d4b8b329a45bae120f1fd9df9049ecacaa9dd1eca18bc6a55cd2f" |
735 | 0 | ), |
736 | 0 | { |
737 | 0 | fromHex( |
738 | 0 | "16aed5ed486df6b2fb38015ded41400009ed4f34bef65b87b1f90f47052f8d94" |
739 | 0 | "16dabf21b3f25b9665269d98dc17b1da6118251dc0b403ae50e96dfe91239375" |
740 | 0 | ), |
741 | 0 | gas_cost |
742 | 0 | } |
743 | 0 | }, |
744 | 0 | { |
745 | 0 | fromHex( |
746 | 0 | "1385281136ff5b2c326807ff0a824b6ca4f21fcc7c8764e9801bc4ad497d5012" |
747 | 0 | "02254594be8473dcf018a2aa66ea301e38fc865823acf75a9901721d1fc6bf4c" |
748 | 0 | "1644e84fef7b7fdc98254f0654580173307a3bc44db990581e7ab55a22446dcf" |
749 | 0 | "28c2916b7e875692b195831945805438fcd30d2693d8a80cf8c88ec6ef4c315d" |
750 | 0 | ), |
751 | 0 | { |
752 | 0 | fromHex( |
753 | 0 | "1e018816fc9bbd91313301ae9c254bb7d64d6cd54f3b49b92925e43e256b5faa" |
754 | 0 | "1d1f2259c715327bedb42c095af6c0267e4e1be836b4e04b3f0502552f93cca9" |
755 | 0 | ), |
756 | 0 | gas_cost |
757 | 0 | } |
758 | 0 | }, |
759 | 0 | { |
760 | 0 | fromHex( |
761 | 0 | "16aed5ed486df6b2fb38015ded41400009ed4f34bef65b87b1f90f47052f8d94" |
762 | 0 | "16dabf21b3f25b9665269d98dc17b1da6118251dc0b403ae50e96dfe91239375" |
763 | 0 | "25ff95a3abccf32adc6a4c3c8caddca67723d8ada802e9b9f612e3ddb40b2005" |
764 | 0 | "0d82b09bb4ec927bbf182bdc402790429322b7e2f285f2aad8ea135cbf7143d8" |
765 | 0 | ), |
766 | 0 | { |
767 | 0 | fromHex( |
768 | 0 | "29d160febeef9770d47a32ee3b763850eb0594844fa57dd31b8ed02c78fdb797" |
769 | 0 | "2c7cdf62c2498486fd52646e577a06723ce97737b3c958262d78c4a413661e8a" |
770 | 0 | ), |
771 | 0 | gas_cost |
772 | 0 | } |
773 | 0 | }, |
774 | 0 | { |
775 | 0 | fromHex( |
776 | 0 | "18014701594179c6b9ccae848e3d15c1f76f8a68b8092578296520e46c9bae0c" |
777 | 0 | "1b5ed0e9e8f3ff35589ea81a45cf63887d4a92c099a3be1d97b26f0db96323dd" |
778 | 0 | "16a1d378d1a98cf5383cdc512011234287ca43b6a078d1842d5c58c5b1f475cc" |
779 | 0 | "1309377a7026d08ca1529eab74381a7e0d3a4b79d80bacec207cd52fc8e3769c" |
780 | 0 | ), |
781 | 0 | { |
782 | 0 | fromHex( |
783 | 0 | "2583ed10e418133e44619c336f1be5ddae9e20d634a7683d9661401c750d7df4" |
784 | 0 | "0185fbba22de9e698262925665735dbc4d6e8288bc3fc39fae10ca58e16e77f7" |
785 | 0 | ), |
786 | 0 | gas_cost |
787 | 0 | } |
788 | 0 | }, |
789 | 0 | { |
790 | 0 | fromHex( |
791 | 0 | "1c76476f4def4bb94541d57ebba1193381ffa7aa76ada664dd31c16024c43f59" |
792 | 0 | "3034dd2920f673e204fee2811c678745fc819b55d3e9d294e45c9b03a76aef41" |
793 | 0 | "0f25929bcb43d5a57391564615c9e70a992b10eafa4db109709649cf48c50dd2" |
794 | 0 | "16da2f5cb6be7a0aa72c440c53c9bbdfec6c36c7d515536431b3a865468acbba" |
795 | 0 | ), |
796 | 0 | { |
797 | 0 | fromHex( |
798 | 0 | "1496064626ba8bffeb7805f0d16143a65649bb0850333ea512c03fcdaf31e254" |
799 | 0 | "07b4f210ab542533f1ee5633ae4406cd16c63494b537ce3f1cf4afff6f76a48f" |
800 | 0 | ), |
801 | 0 | gas_cost |
802 | 0 | } |
803 | 0 | }, |
804 | 0 | { |
805 | 0 | fromHex( |
806 | 0 | "1e018816fc9bbd91313301ae9c254bb7d64d6cd54f3b49b92925e43e256b5faa" |
807 | 0 | "1d1f2259c715327bedb42c095af6c0267e4e1be836b4e04b3f0502552f93cca9" |
808 | 0 | "2364294faf6b89fedeede9986aa777c4f6c2f5c4a4559ee93dfec9b7b94ef80b" |
809 | 0 | "05aeae62655ea23865ae6661ae371a55c12098703d0f2301f4223e708c92efc6" |
810 | 0 | ), |
811 | 0 | { |
812 | 0 | fromHex( |
813 | 0 | "2801b21090cbc48409e352647f3857134d373f81741f9d5e3d432f336d76f517" |
814 | 0 | "13cf106acf943c2a331de21c7d5e3351354e7412f2dba2918483a6593a6828d4" |
815 | 0 | ), |
816 | 0 | gas_cost |
817 | 0 | } |
818 | 0 | }, |
819 | 0 | { |
820 | 0 | fromHex( |
821 | 0 | "2583ed10e418133e44619c336f1be5ddae9e20d634a7683d9661401c750d7df4" |
822 | 0 | "0185fbba22de9e698262925665735dbc4d6e8288bc3fc39fae10ca58e16e77f7" |
823 | 0 | "258f1faa356e470cca19c928afa5ceed6215c756912af5725b8db5777cc8f3b6" |
824 | 0 | "175ced8a58d0c132c2b95ba14c16dde93e7f7789214116ff69da6f44daa966e6" |
825 | 0 | ), |
826 | 0 | { |
827 | 0 | fromHex( |
828 | 0 | "10b4876441e14a6be92a7fe66550848c01c676a12ac31d7cc13b21f49c4307c8" |
829 | 0 | "09f5528bdb0ef9354837a0f4b4c9da973bd5b805d359976f719ab0b74e0a7368" |
830 | 0 | ), |
831 | 0 | gas_cost |
832 | 0 | } |
833 | 0 | }, |
834 | 0 | { |
835 | 0 | fromHex( |
836 | 0 | "26dcfbc2e0bc9d82efb4acd73cb3e99730e27e10177fcfb78b6399a4bfcdf391" |
837 | 0 | "27c440dbd5053253a3a692f9bf89b9b6e9612127cf97db1e11ffa9679acc933b" |
838 | 0 | "1496064626ba8bffeb7805f0d16143a65649bb0850333ea512c03fcdaf31e254" |
839 | 0 | "07b4f210ab542533f1ee5633ae4406cd16c63494b537ce3f1cf4afff6f76a48f" |
840 | 0 | ), |
841 | 0 | { |
842 | 0 | fromHex( |
843 | 0 | "186bac5188a98c45e6016873d107f5cd131f3a3e339d0375e58bd6219347b008" |
844 | 0 | "1e396bc242de0214898b0f68035f53ad5a6f96c6c8390ac56ed6ec9561d23159" |
845 | 0 | ), |
846 | 0 | gas_cost |
847 | 0 | } |
848 | 0 | }, |
849 | 0 | { |
850 | 0 | fromHex( |
851 | 0 | "26dcfbc2e0bc9d82efb4acd73cb3e99730e27e10177fcfb78b6399a4bfcdf391" |
852 | 0 | "27c440dbd5053253a3a692f9bf89b9b6e9612127cf97db1e11ffa9679acc933b" |
853 | 0 | "1c76476f4def4bb94541d57ebba1193381ffa7aa76ada664dd31c16024c43f59" |
854 | 0 | "3034dd2920f673e204fee2811c678745fc819b55d3e9d294e45c9b03a76aef41" |
855 | 0 | ), |
856 | 0 | { |
857 | 0 | fromHex( |
858 | 0 | "20a754d2071d4d53903e3b31a7e98ad6882d58aec240ef981fdf0a9d22c5926a" |
859 | 0 | "29c853fcea789887315916bbeb89ca37edb355b4f980c9a12a94f30deeed3021" |
860 | 0 | ), |
861 | 0 | gas_cost |
862 | 0 | } |
863 | 0 | }, |
864 | 0 | { |
865 | 0 | fromHex( |
866 | 0 | "27231d5cdd0011259ff75678cf5a8f7840c22cb71d52b25e21e071205e8d9bc4" |
867 | 0 | "26dd3d225c9a71476db0cf834232eba84020f3073c6d20c519963e0b98f235e1" |
868 | 0 | "2174f0221490cd9c15b0387f3251ec3d49517a51c37a8076eac12afb4a95a707" |
869 | 0 | "1d1c3fcd3161e2a417b4df0955f02db1fffa9005210fb30c5aa3755307e9d1f5" |
870 | 0 | ), |
871 | 0 | { |
872 | 0 | fromHex( |
873 | 0 | "18014701594179c6b9ccae848e3d15c1f76f8a68b8092578296520e46c9bae0c" |
874 | 0 | "1b5ed0e9e8f3ff35589ea81a45cf63887d4a92c099a3be1d97b26f0db96323dd" |
875 | 0 | ), |
876 | 0 | gas_cost |
877 | 0 | } |
878 | 0 | }, |
879 | 0 | { |
880 | 0 | fromHex( |
881 | 0 | "2801b21090cbc48409e352647f3857134d373f81741f9d5e3d432f336d76f517" |
882 | 0 | "13cf106acf943c2a331de21c7d5e3351354e7412f2dba2918483a6593a6828d4" |
883 | 0 | "2a49621e12910cd90f3e731083d454255bf1c533d6e15b8699156778d0f27f5d" |
884 | 0 | "2590ee31824548d159aa2d22296bf149d564c0872f41b89b7dc5c6e6e3cd1c4d" |
885 | 0 | ), |
886 | 0 | { |
887 | 0 | fromHex( |
888 | 0 | "27231d5cdd0011259ff75678cf5a8f7840c22cb71d52b25e21e071205e8d9bc4" |
889 | 0 | "26dd3d225c9a71476db0cf834232eba84020f3073c6d20c519963e0b98f235e1" |
890 | 0 | ), |
891 | 0 | gas_cost |
892 | 0 | } |
893 | 0 | }, |
894 | 0 | { |
895 | 0 | fromHex( |
896 | 0 | "29d160febeef9770d47a32ee3b763850eb0594844fa57dd31b8ed02c78fdb797" |
897 | 0 | "2c7cdf62c2498486fd52646e577a06723ce97737b3c958262d78c4a413661e8a" |
898 | 0 | "0aee46a7ea6e80a3675026dfa84019deee2a2dedb1bbe11d7fe124cb3efb4b5a" |
899 | 0 | "044747b6e9176e13ede3a4dfd0d33ccca6321b9acd23bf3683a60adc0366ebaf" |
900 | 0 | ), |
901 | 0 | { |
902 | 0 | fromHex( |
903 | 0 | "26dcfbc2e0bc9d82efb4acd73cb3e99730e27e10177fcfb78b6399a4bfcdf391" |
904 | 0 | "27c440dbd5053253a3a692f9bf89b9b6e9612127cf97db1e11ffa9679acc933b" |
905 | 0 | ), |
906 | 0 | gas_cost |
907 | 0 | } |
908 | 0 | } |
909 | 0 | }; |
910 | 0 | return precompileGeneric(_message, inputOutput, true /* _ignoresTrailingInput */); |
911 | 0 | } Unexecuted instantiation: evmc::Result solidity::test::EVMHost::precompileALTBN128G1Add<(evmc_revision)7>(evmc_message const&) Unexecuted instantiation: evmc::Result solidity::test::EVMHost::precompileALTBN128G1Add<(evmc_revision)9>(evmc_message const&) |
912 | | |
913 | | template <evmc_revision Revision> |
914 | | evmc::Result EVMHost::precompileALTBN128G1Mul(evmc_message const& _message) noexcept |
915 | 0 | { |
916 | | // NOTE this is a partial implementation for some inputs. |
917 | | |
918 | | // Fixed 40000 or 6000 gas. |
919 | 0 | int64_t gas_cost = (Revision < EVMC_ISTANBUL) ? 40000 : 6000; |
920 | |
|
921 | 0 | static std::map<bytes, EVMPrecompileOutput> const inputOutput{ |
922 | 0 | { |
923 | 0 | fromHex( |
924 | 0 | "0000000000000000000000000000000000000000000000000000000000000001" |
925 | 0 | "0000000000000000000000000000000000000000000000000000000000000002" |
926 | 0 | "0000000000000000000000000000000000000000000000000000000000000002" |
927 | 0 | ), |
928 | 0 | { |
929 | 0 | fromHex( |
930 | 0 | "030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd3" |
931 | 0 | "15ed738c0e0a7c92e7845f96b2ae9c0a68a6a449e3538fc7ff3ebf7a5a18a2c4" |
932 | 0 | ), |
933 | 0 | gas_cost |
934 | 0 | } |
935 | 0 | }, |
936 | 0 | { |
937 | 0 | fromHex( |
938 | 0 | "0000000000000000000000000000000000000000000000000000000000000001" |
939 | 0 | "0000000000000000000000000000000000000000000000000000000000000002" |
940 | 0 | "0000000000000000000000000000000000000000000000000000000000000005" |
941 | 0 | ), |
942 | 0 | { |
943 | 0 | fromHex( |
944 | 0 | "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa9" |
945 | 0 | "01e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c" |
946 | 0 | ), |
947 | 0 | gas_cost |
948 | 0 | } |
949 | 0 | }, |
950 | 0 | { |
951 | 0 | fromHex( |
952 | 0 | "09b54f111d3b2d1b2fe1ae9669b3db3d7bf93b70f00647e65c849275de6dc7fe" |
953 | 0 | "18b2e77c63a3e400d6d1f1fbc6e1a1167bbca603d34d03edea231eb0ab7b14b4" |
954 | 0 | "030f7b0c405c888aff922307ea2cd1c70f64664bab76899500341f4260a20929" |
955 | 0 | ), |
956 | 0 | { |
957 | 0 | fromHex( |
958 | 0 | "16a1d378d1a98cf5383cdc512011234287ca43b6a078d1842d5c58c5b1f475cc" |
959 | 0 | "1309377a7026d08ca1529eab74381a7e0d3a4b79d80bacec207cd52fc8e3769c" |
960 | 0 | ), |
961 | 0 | gas_cost |
962 | 0 | } |
963 | 0 | }, |
964 | 0 | { |
965 | 0 | fromHex( |
966 | 0 | "0a6de0e2240aa253f46ce0da883b61976e3588146e01c9d8976548c145fe6e4a" |
967 | 0 | "04fbaa3a4aed4bb77f30ebb07a3ec1c7d77a7f2edd75636babfeff97b1ea686e" |
968 | 0 | "1551dcd4965285ef049512d2d30cbfc1a91acd5baad4a6e19e22e93176197f17" |
969 | 0 | ), |
970 | 0 | { |
971 | 0 | fromHex( |
972 | 0 | "28d3c57516712e7843a5b3cfa7d7274a037943f5bd57c227620ad207728e4283" |
973 | 0 | "2795fa9df21d4b8b329a45bae120f1fd9df9049ecacaa9dd1eca18bc6a55cd2f" |
974 | 0 | ), |
975 | 0 | gas_cost |
976 | 0 | } |
977 | 0 | }, |
978 | 0 | { |
979 | 0 | fromHex( |
980 | 0 | "0c54b42137b67cc268cbb53ac62b00ecead23984092b494a88befe58445a244a" |
981 | 0 | "18e3723d37fae9262d58b548a0575f59d9c3266db7afb4d5739555837f6b8b3e" |
982 | 0 | "0c692b41f1acc961f6ea83bae2c3a1a55c54f766c63ba76989f52c149c17b5e7" |
983 | 0 | ), |
984 | 0 | { |
985 | 0 | fromHex( |
986 | 0 | "258f1faa356e470cca19c928afa5ceed6215c756912af5725b8db5777cc8f3b6" |
987 | 0 | "175ced8a58d0c132c2b95ba14c16dde93e7f7789214116ff69da6f44daa966e6" |
988 | 0 | ), |
989 | 0 | gas_cost |
990 | 0 | } |
991 | 0 | }, |
992 | 0 | { |
993 | 0 | fromHex( |
994 | 0 | "0f103f14a584d4203c27c26155b2c955f8dfa816980b24ba824e1972d6486a5d" |
995 | 0 | "0c4165133b9f5be17c804203af781bcf168da7386620479f9b885ecbcd27b17b" |
996 | 0 | "0ea71d0abb524cac7cfff5323e1d0b14ab705842426c978f96753ccce258ed93" |
997 | 0 | ), |
998 | 0 | { |
999 | 0 | fromHex( |
1000 | 0 | "2a49621e12910cd90f3e731083d454255bf1c533d6e15b8699156778d0f27f5d" |
1001 | 0 | "2590ee31824548d159aa2d22296bf149d564c0872f41b89b7dc5c6e6e3cd1c4d" |
1002 | 0 | ), |
1003 | 0 | gas_cost |
1004 | 0 | } |
1005 | 0 | }, |
1006 | 0 | { |
1007 | 0 | fromHex( |
1008 | 0 | "111e2e2a5f8828f80ddad08f9f74db56dac1cc16c1cb278036f79a84cf7a116f" |
1009 | 0 | "1d7d62e192b219b9808faa906c5ced871788f6339e8d91b83ac1343e20a16b30" |
1010 | 0 | "00000000000000000000000000000000000000e40800000000000000008cdcbc" |
1011 | 0 | ), |
1012 | 0 | { |
1013 | 0 | fromHex( |
1014 | 0 | "25ff95a3abccf32adc6a4c3c8caddca67723d8ada802e9b9f612e3ddb40b2005" |
1015 | 0 | "0d82b09bb4ec927bbf182bdc402790429322b7e2f285f2aad8ea135cbf7143d8" |
1016 | 0 | ), |
1017 | 0 | gas_cost |
1018 | 0 | } |
1019 | 0 | }, |
1020 | 0 | { |
1021 | 0 | fromHex( |
1022 | 0 | "17d5d09b4146424bff7e6fb01487c477bbfcd0cdbbc92d5d6457aae0b6717cc5" |
1023 | 0 | "02b5636903efbf46db9235bbe74045d21c138897fda32e079040db1a16c1a7a1" |
1024 | 0 | "1887420878c0c8e37605291c626585eabbec8d8b97a848fe8d58a37b00458351" |
1025 | 0 | ), |
1026 | 0 | { |
1027 | 0 | fromHex( |
1028 | 0 | "2364294faf6b89fedeede9986aa777c4f6c2f5c4a4559ee93dfec9b7b94ef80b" |
1029 | 0 | "05aeae62655ea23865ae6661ae371a55c12098703d0f2301f4223e708c92efc6" |
1030 | 0 | ), |
1031 | 0 | gas_cost |
1032 | 0 | } |
1033 | 0 | }, |
1034 | 0 | { |
1035 | 0 | fromHex( |
1036 | 0 | "1c36e713d4d54e3a9644dffca1fc524be4868f66572516025a61ca542539d43f" |
1037 | 0 | "042dcc4525b82dfb242b09cb21909d5c22643dcdbe98c4d082cc2877e96b24db" |
1038 | 0 | "016086cc934d5cab679c6991a4efcedbab26d7e4fb23b6a1ad4e6b5c2fb59ce5" |
1039 | 0 | ), |
1040 | 0 | { |
1041 | 0 | fromHex( |
1042 | 0 | "1644e84fef7b7fdc98254f0654580173307a3bc44db990581e7ab55a22446dcf" |
1043 | 0 | "28c2916b7e875692b195831945805438fcd30d2693d8a80cf8c88ec6ef4c315d" |
1044 | 0 | ), |
1045 | 0 | gas_cost |
1046 | 0 | } |
1047 | 0 | }, |
1048 | 0 | { |
1049 | 0 | fromHex( |
1050 | 0 | "1e39e9f0f91fa7ff8047ffd90de08785777fe61c0e3434e728fce4cf35047ddc" |
1051 | 0 | "2e0b64d75ebfa86d7f8f8e08abbe2e7ae6e0a1c0b34d028f19fa56e9450527cb" |
1052 | 0 | "1eec35a0e955cad4bee5846ae0f1d0b742d8636b278450c534e38e06a60509f9" |
1053 | 0 | ), |
1054 | 0 | { |
1055 | 0 | fromHex( |
1056 | 0 | "1385281136ff5b2c326807ff0a824b6ca4f21fcc7c8764e9801bc4ad497d5012" |
1057 | 0 | "02254594be8473dcf018a2aa66ea301e38fc865823acf75a9901721d1fc6bf4c" |
1058 | 0 | ), |
1059 | 0 | gas_cost |
1060 | 0 | } |
1061 | 0 | }, |
1062 | 0 | { |
1063 | 0 | fromHex( |
1064 | 0 | "232063b584fb76c8d07995bee3a38fa7565405f3549c6a918ddaa90ab971e7f8" |
1065 | 0 | "2ac9b135a81d96425c92d02296322ad56ffb16299633233e4880f95aafa7fda7" |
1066 | 0 | "0689c3dc4311426ee11707866b2cbdf9751dacd07245bf99d2113d3f5a8cac47" |
1067 | 0 | ), |
1068 | 0 | { |
1069 | 0 | fromHex( |
1070 | 0 | "2174f0221490cd9c15b0387f3251ec3d49517a51c37a8076eac12afb4a95a707" |
1071 | 0 | "1d1c3fcd3161e2a417b4df0955f02db1fffa9005210fb30c5aa3755307e9d1f5" |
1072 | 0 | ), |
1073 | 0 | gas_cost |
1074 | 0 | } |
1075 | 0 | } |
1076 | 0 | }; |
1077 | 0 | return precompileGeneric(_message, inputOutput, true /* _ignoresTrailingInput */); |
1078 | 0 | } Unexecuted instantiation: evmc::Result solidity::test::EVMHost::precompileALTBN128G1Mul<(evmc_revision)7>(evmc_message const&) Unexecuted instantiation: evmc::Result solidity::test::EVMHost::precompileALTBN128G1Mul<(evmc_revision)9>(evmc_message const&) |
1079 | | |
1080 | | template <evmc_revision Revision> |
1081 | | evmc::Result EVMHost::precompileALTBN128PairingProduct(evmc_message const& _message) noexcept |
1082 | 0 | { |
1083 | | // Base + per pairing gas. |
1084 | 0 | constexpr auto calc_cost = [](unsigned points) -> int64_t { |
1085 | | // Number of 192-byte points. |
1086 | 0 | return (Revision < EVMC_ISTANBUL) ? |
1087 | 0 | (100000 + 80000 * points): |
1088 | 0 | (45000 + 34000 * points); |
1089 | 0 | }; Unexecuted instantiation: solidity::test::EVMHost::precompileALTBN128PairingProduct<(evmc_revision)7>(evmc_message const&)::{lambda(unsigned int)#1}::operator()(unsigned int) constUnexecuted instantiation: solidity::test::EVMHost::precompileALTBN128PairingProduct<(evmc_revision)9>(evmc_message const&)::{lambda(unsigned int)#1}::operator()(unsigned int) const |
1090 | | |
1091 | | // NOTE this is a partial implementation for some inputs. |
1092 | 0 | static std::map<bytes, EVMPrecompileOutput> const inputOutput{ |
1093 | 0 | { |
1094 | 0 | fromHex( |
1095 | 0 | "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa9" |
1096 | 0 | "01e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c" |
1097 | 0 | "198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2" |
1098 | 0 | "1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed" |
1099 | 0 | "090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b" |
1100 | 0 | "12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa" |
1101 | 0 | "0000000000000000000000000000000000000000000000000000000000000001" |
1102 | 0 | "30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45" |
1103 | 0 | "0a09ccf561b55fd99d1c1208dee1162457b57ac5af3759d50671e510e428b2a1" |
1104 | 0 | "2e539c423b302d13f4e5773c603948eaf5db5df8ae8a9a9113708390a06410d8" |
1105 | 0 | "19b763513924a736e4eebd0d78c91c1bc1d657fee4214057d21414011cfcc763" |
1106 | 0 | "2f8d9f9ab83727c77a2fec063cb7b6e5eb23044ccf535ad49d46d394fb6f6bf6" |
1107 | 0 | ), |
1108 | 0 | { |
1109 | 0 | fromHex("0000000000000000000000000000000000000000000000000000000000000001"), |
1110 | 0 | calc_cost(2) |
1111 | 0 | } |
1112 | 0 | }, |
1113 | 0 | { |
1114 | 0 | fromHex( |
1115 | 0 | "0000000000000000000000000000000000000000000000000000000000000001" |
1116 | 0 | "0000000000000000000000000000000000000000000000000000000000000002" |
1117 | 0 | "198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2" |
1118 | 0 | "1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed" |
1119 | 0 | "090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b" |
1120 | 0 | "12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa" |
1121 | 0 | "0000000000000000000000000000000000000000000000000000000000000001" |
1122 | 0 | "30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45" |
1123 | 0 | "198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2" |
1124 | 0 | "1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed" |
1125 | 0 | "090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b" |
1126 | 0 | "12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa" |
1127 | 0 | ), |
1128 | 0 | { |
1129 | 0 | fromHex("0000000000000000000000000000000000000000000000000000000000000001"), |
1130 | 0 | calc_cost(2) |
1131 | 0 | } |
1132 | 0 | }, |
1133 | 0 | { |
1134 | 0 | fromHex( |
1135 | 0 | "1c76476f4def4bb94541d57ebba1193381ffa7aa76ada664dd31c16024c43f59" |
1136 | 0 | "3034dd2920f673e204fee2811c678745fc819b55d3e9d294e45c9b03a76aef41" |
1137 | 0 | "209dd15ebff5d46c4bd888e51a93cf99a7329636c63514396b4a452003a35bf7" |
1138 | 0 | "04bf11ca01483bfa8b34b43561848d28905960114c8ac04049af4b6315a41678" |
1139 | 0 | "2bb8324af6cfc93537a2ad1a445cfd0ca2a71acd7ac41fadbf933c2a51be344d" |
1140 | 0 | "120a2a4cf30c1bf9845f20c6fe39e07ea2cce61f0c9bb048165fe5e4de877550" |
1141 | 0 | "111e129f1cf1097710d41c4ac70fcdfa5ba2023c6ff1cbeac322de49d1b6df7c" |
1142 | 0 | "2032c61a830e3c17286de9462bf242fca2883585b93870a73853face6a6bf411" |
1143 | 0 | "198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2" |
1144 | 0 | "1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed" |
1145 | 0 | "090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b" |
1146 | 0 | "12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa" |
1147 | 0 | ), |
1148 | 0 | { |
1149 | 0 | fromHex("0000000000000000000000000000000000000000000000000000000000000001"), |
1150 | 0 | calc_cost(2) |
1151 | 0 | } |
1152 | 0 | }, |
1153 | 0 | { |
1154 | 0 | fromHex( |
1155 | 0 | "2eca0c7238bf16e83e7a1e6c5d49540685ff51380f309842a98561558019fc02" |
1156 | 0 | "03d3260361bb8451de5ff5ecd17f010ff22f5c31cdf184e9020b06fa5997db84" |
1157 | 0 | "1213d2149b006137fcfb23036606f848d638d576a120ca981b5b1a5f9300b3ee" |
1158 | 0 | "2276cf730cf493cd95d64677bbb75fc42db72513a4c1e387b476d056f80aa75f" |
1159 | 0 | "21ee6226d31426322afcda621464d0611d226783262e21bb3bc86b537e986237" |
1160 | 0 | "096df1f82dff337dd5972e32a8ad43e28a78a96a823ef1cd4debe12b6552ea5f" |
1161 | 0 | "06967a1237ebfeca9aaae0d6d0bab8e28c198c5a339ef8a2407e31cdac516db9" |
1162 | 0 | "22160fa257a5fd5b280642ff47b65eca77e626cb685c84fa6d3b6882a283ddd1" |
1163 | 0 | "198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2" |
1164 | 0 | "1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed" |
1165 | 0 | "090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b" |
1166 | 0 | "12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa" |
1167 | 0 | ), |
1168 | 0 | { |
1169 | 0 | fromHex("0000000000000000000000000000000000000000000000000000000000000001"), |
1170 | 0 | calc_cost(2) |
1171 | 0 | } |
1172 | 0 | }, |
1173 | 0 | { |
1174 | 0 | fromHex( |
1175 | 0 | "0f25929bcb43d5a57391564615c9e70a992b10eafa4db109709649cf48c50dd2" |
1176 | 0 | "16da2f5cb6be7a0aa72c440c53c9bbdfec6c36c7d515536431b3a865468acbba" |
1177 | 0 | "2e89718ad33c8bed92e210e81d1853435399a271913a6520736a4729cf0d51eb" |
1178 | 0 | "01a9e2ffa2e92599b68e44de5bcf354fa2642bd4f26b259daa6f7ce3ed57aeb3" |
1179 | 0 | "14a9a87b789a58af499b314e13c3d65bede56c07ea2d418d6874857b70763713" |
1180 | 0 | "178fb49a2d6cd347dc58973ff49613a20757d0fcc22079f9abd10c3baee24590" |
1181 | 0 | "1b9e027bd5cfc2cb5db82d4dc9677ac795ec500ecd47deee3b5da006d6d049b8" |
1182 | 0 | "11d7511c78158de484232fc68daf8a45cf217d1c2fae693ff5871e8752d73b21" |
1183 | 0 | "198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2" |
1184 | 0 | "1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed" |
1185 | 0 | "090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b" |
1186 | 0 | "12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa" |
1187 | 0 | ), |
1188 | 0 | { |
1189 | 0 | fromHex("0000000000000000000000000000000000000000000000000000000000000001"), |
1190 | 0 | calc_cost(2) |
1191 | 0 | } |
1192 | 0 | }, |
1193 | 0 | { |
1194 | 0 | fromHex( |
1195 | 0 | "2f2ea0b3da1e8ef11914acf8b2e1b32d99df51f5f4f206fc6b947eae860eddb6" |
1196 | 0 | "068134ddb33dc888ef446b648d72338684d678d2eb2371c61a50734d78da4b72" |
1197 | 0 | "25f83c8b6ab9de74e7da488ef02645c5a16a6652c3c71a15dc37fe3a5dcb7cb1" |
1198 | 0 | "22acdedd6308e3bb230d226d16a105295f523a8a02bfc5e8bd2da135ac4c245d" |
1199 | 0 | "065bbad92e7c4e31bf3757f1fe7362a63fbfee50e7dc68da116e67d600d9bf68" |
1200 | 0 | "06d302580dc0661002994e7cd3a7f224e7ddc27802777486bf80f40e4ca3cfdb" |
1201 | 0 | "186bac5188a98c45e6016873d107f5cd131f3a3e339d0375e58bd6219347b008" |
1202 | 0 | "122ae2b09e539e152ec5364e7e2204b03d11d3caa038bfc7cd499f8176aacbee" |
1203 | 0 | "1f39e4e4afc4bc74790a4a028aff2c3d2538731fb755edefd8cb48d6ea589b5e" |
1204 | 0 | "283f150794b6736f670d6a1033f9b46c6f5204f50813eb85c8dc4b59db1c5d39" |
1205 | 0 | "140d97ee4d2b36d99bc49974d18ecca3e7ad51011956051b464d9e27d46cc25e" |
1206 | 0 | "0764bb98575bd466d32db7b15f582b2d5c452b36aa394b789366e5e3ca5aabd4" |
1207 | 0 | "15794ab061441e51d01e94640b7e3084a07e02c78cf3103c542bc5b298669f21" |
1208 | 0 | "1b88da1679b0b64a63b7e0e7bfe52aae524f73a55be7fe70c7e9bfc94b4cf0da" |
1209 | 0 | "1213d2149b006137fcfb23036606f848d638d576a120ca981b5b1a5f9300b3ee" |
1210 | 0 | "2276cf730cf493cd95d64677bbb75fc42db72513a4c1e387b476d056f80aa75f" |
1211 | 0 | "21ee6226d31426322afcda621464d0611d226783262e21bb3bc86b537e986237" |
1212 | 0 | "096df1f82dff337dd5972e32a8ad43e28a78a96a823ef1cd4debe12b6552ea5f" |
1213 | 0 | ), |
1214 | 0 | { |
1215 | 0 | fromHex("0000000000000000000000000000000000000000000000000000000000000001"), |
1216 | 0 | calc_cost(3) |
1217 | 0 | } |
1218 | 0 | }, |
1219 | 0 | { |
1220 | 0 | fromHex( |
1221 | 0 | "20a754d2071d4d53903e3b31a7e98ad6882d58aec240ef981fdf0a9d22c5926a" |
1222 | 0 | "29c853fcea789887315916bbeb89ca37edb355b4f980c9a12a94f30deeed3021" |
1223 | 0 | "1213d2149b006137fcfb23036606f848d638d576a120ca981b5b1a5f9300b3ee" |
1224 | 0 | "2276cf730cf493cd95d64677bbb75fc42db72513a4c1e387b476d056f80aa75f" |
1225 | 0 | "21ee6226d31426322afcda621464d0611d226783262e21bb3bc86b537e986237" |
1226 | 0 | "096df1f82dff337dd5972e32a8ad43e28a78a96a823ef1cd4debe12b6552ea5f" |
1227 | 0 | "1abb4a25eb9379ae96c84fff9f0540abcfc0a0d11aeda02d4f37e4baf74cb0c1" |
1228 | 0 | "1073b3ff2cdbb38755f8691ea59e9606696b3ff278acfc098fa8226470d03869" |
1229 | 0 | "217cee0a9ad79a4493b5253e2e4e3a39fc2df38419f230d341f60cb064a0ac29" |
1230 | 0 | "0a3d76f140db8418ba512272381446eb73958670f00cf46f1d9e64cba057b53c" |
1231 | 0 | "26f64a8ec70387a13e41430ed3ee4a7db2059cc5fc13c067194bcc0cb49a9855" |
1232 | 0 | "2fd72bd9edb657346127da132e5b82ab908f5816c826acb499e22f2412d1a2d7" |
1233 | 0 | "0f25929bcb43d5a57391564615c9e70a992b10eafa4db109709649cf48c50dd2" |
1234 | 0 | "198a1f162a73261f112401aa2db79c7dab1533c9935c77290a6ce3b191f2318d" |
1235 | 0 | "198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2" |
1236 | 0 | "1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed" |
1237 | 0 | "090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b" |
1238 | 0 | "12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa" |
1239 | 0 | ), |
1240 | 0 | { |
1241 | 0 | fromHex("0000000000000000000000000000000000000000000000000000000000000001"), |
1242 | 0 | calc_cost(3) |
1243 | 0 | } |
1244 | 0 | } |
1245 | 0 | }; |
1246 | |
|
1247 | 0 | return precompileGeneric(_message, inputOutput); |
1248 | 0 | } Unexecuted instantiation: evmc::Result solidity::test::EVMHost::precompileALTBN128PairingProduct<(evmc_revision)7>(evmc_message const&) Unexecuted instantiation: evmc::Result solidity::test::EVMHost::precompileALTBN128PairingProduct<(evmc_revision)9>(evmc_message const&) |
1249 | | |
1250 | | evmc::Result EVMHost::precompileBlake2f(evmc_message const&) noexcept |
1251 | 20 | { |
1252 | | // TODO implement |
1253 | 20 | return resultWithFailure(); |
1254 | 20 | } |
1255 | | |
1256 | | evmc::Result EVMHost::precompileGeneric( |
1257 | | evmc_message const& _message, |
1258 | | std::map<bytes, EVMPrecompileOutput> const& _inOut, |
1259 | | bool _ignoresTrailingInput |
1260 | | ) noexcept |
1261 | 1.04k | { |
1262 | 1.04k | size_t meaningfulInputSize = _message.input_size; |
1263 | 1.04k | if (_ignoresTrailingInput && !_inOut.empty()) |
1264 | 0 | { |
1265 | | // _ignoresTrailingInput only implemented for the case where all inputs have same size. |
1266 | | // Simpler to implement and it's all we need for now. |
1267 | 0 | for (auto const& [input, output]: _inOut) |
1268 | 0 | solAssert(input.size() == _inOut.begin()->first.size()); |
1269 | | |
1270 | | // If there is more input that expected, precompiles tend to simply ignore it. |
1271 | 0 | meaningfulInputSize = std::min(_message.input_size, _inOut.begin()->first.size()); |
1272 | 0 | } |
1273 | | |
1274 | 1.04k | bytes input(_message.input_data, _message.input_data + meaningfulInputSize); |
1275 | 1.04k | if (_inOut.count(input)) |
1276 | 1.04k | { |
1277 | 1.04k | auto const& ret = _inOut.at(input); |
1278 | 1.04k | return resultWithGas(_message.gas, ret.gas_used, ret.output); |
1279 | 1.04k | } |
1280 | 0 | else |
1281 | | // FIXME: We're in a noexcept function; this will result in terminate() and then abort(). |
1282 | | // Still better than nothing - can't be mistaken for revert and Boost will report test name. |
1283 | 0 | solThrow( |
1284 | 1.04k | Exception, |
1285 | 1.04k | "Test output for a precompile not defined for input: " + toHex(input, HexPrefix::Add) |
1286 | 1.04k | ); |
1287 | 1.04k | } |
1288 | | |
1289 | | evmc::Result EVMHost::resultWithFailure() noexcept |
1290 | 283 | { |
1291 | 283 | evmc::Result result; |
1292 | 283 | result.status_code = EVMC_FAILURE; |
1293 | 283 | return result; |
1294 | 283 | } |
1295 | | |
1296 | | evmc::Result EVMHost::resultWithGas( |
1297 | | int64_t gas_limit, |
1298 | | int64_t gas_required, |
1299 | | bytes const& _data |
1300 | | ) noexcept |
1301 | 2.81k | { |
1302 | 2.81k | evmc::Result result; |
1303 | 2.81k | if (gas_limit < gas_required) |
1304 | 1.11k | { |
1305 | 1.11k | result.status_code = EVMC_OUT_OF_GAS; |
1306 | 1.11k | result.gas_left = 0; |
1307 | 1.11k | } |
1308 | 1.70k | else |
1309 | 1.70k | { |
1310 | 1.70k | result.status_code = EVMC_SUCCESS; |
1311 | 1.70k | result.gas_left = gas_limit - gas_required; |
1312 | 1.70k | } |
1313 | 2.81k | result.output_data = _data.empty() ? nullptr : _data.data(); |
1314 | 2.81k | result.output_size = _data.size(); |
1315 | 2.81k | return result; |
1316 | 2.81k | } |
1317 | | |
1318 | | StorageMap const& EVMHost::get_address_storage(evmc::address const& _addr) |
1319 | 22.0k | { |
1320 | 22.0k | soltestAssert(account_exists(_addr), "Account does not exist."); |
1321 | 22.0k | return accounts[_addr].storage; |
1322 | 22.0k | } |
1323 | | |
1324 | | std::string EVMHostPrinter::state() |
1325 | 22.0k | { |
1326 | | // Print state and execution trace. |
1327 | 22.0k | if (m_host.account_exists(m_account)) |
1328 | 22.0k | { |
1329 | 22.0k | storage(); |
1330 | 22.0k | balance(); |
1331 | 22.0k | } |
1332 | 0 | else |
1333 | 0 | selfdestructRecords(); |
1334 | | |
1335 | 22.0k | callRecords(); |
1336 | 22.0k | return m_stateStream.str(); |
1337 | 22.0k | } |
1338 | | |
1339 | | void EVMHostPrinter::storage() |
1340 | 22.0k | { |
1341 | 22.0k | for (auto const& [slot, value]: m_host.get_address_storage(m_account)) |
1342 | 97.7k | if (m_host.get_storage(m_account, slot)) |
1343 | 44.9k | m_stateStream << " " |
1344 | 44.9k | << m_host.convertFromEVMC(slot) |
1345 | 44.9k | << ": " |
1346 | 44.9k | << m_host.convertFromEVMC(value.current) |
1347 | 44.9k | << std::endl; |
1348 | 22.0k | } |
1349 | | |
1350 | | void EVMHostPrinter::balance() |
1351 | 22.0k | { |
1352 | 22.0k | m_stateStream << "BALANCE " |
1353 | 22.0k | << m_host.convertFromEVMC(m_host.get_balance(m_account)) |
1354 | 22.0k | << std::endl; |
1355 | 22.0k | } |
1356 | | |
1357 | | void EVMHostPrinter::selfdestructRecords() |
1358 | 0 | { |
1359 | 0 | for (auto const& record: m_host.recorded_selfdestructs) |
1360 | 0 | for (auto const& beneficiary: record.second) |
1361 | 0 | m_stateStream << "SELFDESTRUCT" |
1362 | 0 | << " BENEFICIARY " |
1363 | 0 | << m_host.convertFromEVMC(beneficiary) |
1364 | 0 | << std::endl; |
1365 | 0 | } |
1366 | | |
1367 | | void EVMHostPrinter::callRecords() |
1368 | 22.0k | { |
1369 | 22.0k | static auto constexpr callKind = [](evmc_call_kind _kind) -> std::string |
1370 | 71.1k | { |
1371 | 71.1k | switch (_kind) |
1372 | 71.1k | { |
1373 | 26.2k | case evmc_call_kind::EVMC_CALL: |
1374 | 26.2k | return "CALL"; |
1375 | 22.7k | case evmc_call_kind::EVMC_DELEGATECALL: |
1376 | 22.7k | return "DELEGATECALL"; |
1377 | 188 | case evmc_call_kind::EVMC_CALLCODE: |
1378 | 188 | return "CALLCODE"; |
1379 | 22.0k | case evmc_call_kind::EVMC_CREATE: |
1380 | 22.0k | return "CREATE"; |
1381 | 0 | case evmc_call_kind::EVMC_CREATE2: |
1382 | 0 | return "CREATE2"; |
1383 | 71.1k | } |
1384 | 0 | unreachable(); |
1385 | 0 | }; |
1386 | | |
1387 | 22.0k | for (auto const& record: m_host.recorded_calls) |
1388 | 71.1k | m_stateStream << callKind(record.kind) |
1389 | 71.1k | << " VALUE " |
1390 | 71.1k | << m_host.convertFromEVMC(record.value) |
1391 | 71.1k | << std::endl; |
1392 | 22.0k | } |