LCOV - differential code coverage report
Current view: top level - test/state - precompiles_cache.cpp (source / functions) Coverage Total Hit UBC
Current: DIFF_COVERAGE Lines: 0.0 % 50 0 50
Current Date: 2024-03-20 16:29:22 Functions: 0.0 % 4 0 4
Baseline: coverage_BASE.lcov
Baseline Date: 2024-03-20 14:19:08

           TLA  Line data    Source code
       1                 : // evmone: Fast Ethereum Virtual Machine implementation
       2                 : // Copyright 2022 The evmone Authors.
       3                 : // SPDX-License-Identifier: Apache-2.0
       4                 : 
       5                 : #ifdef _MSC_VER
       6                 : // Disable warning C4996: 'getenv': This function or variable may be unsafe.
       7                 : #define _CRT_SECURE_NO_WARNINGS
       8                 : #endif
       9                 : 
      10                 : #include "precompiles_cache.hpp"
      11                 : #include <nlohmann/json.hpp>
      12                 : #include <fstream>
      13                 : #include <iostream>
      14                 : 
      15                 : namespace evmone::state
      16                 : {
      17 UBC           0 : std::optional<evmc::Result> Cache::find(PrecompileId id, bytes_view input, int64_t gas_left) const
      18                 : {
      19               0 :     if (const auto& cache = m_cache.at(stdx::to_underlying(id)); !cache.empty())
      20                 :     {
      21               0 :         const auto input_hash = keccak256(input);
      22               0 :         if (const auto it = cache.find(input_hash); it != cache.end())
      23                 :         {
      24               0 :             if (const auto& o = it->second; !o.has_value())
      25               0 :                 return evmc::Result{EVMC_PRECOMPILE_FAILURE};
      26                 :             else
      27               0 :                 return evmc::Result{EVMC_SUCCESS, gas_left, 0, o->data(), o->size()};
      28                 :         }
      29                 :     }
      30               0 :     return {};
      31                 : }
      32                 : 
      33               0 : void Cache::insert(PrecompileId id, bytes_view input, const evmc::Result& result)
      34                 : {
      35               0 :     if (id == PrecompileId::identity)  // Do not cache "identity".
      36               0 :         return;
      37               0 :     const auto input_hash = keccak256(input);
      38               0 :     std::optional<bytes> cached_output;
      39               0 :     if (result.status_code == EVMC_SUCCESS)
      40               0 :         cached_output = bytes{result.output_data, result.output_size};
      41               0 :     m_cache.at(stdx::to_underlying(id)).insert({input_hash, std::move(cached_output)});
      42               0 : }
      43                 : 
      44               0 : Cache::Cache() noexcept
      45                 : {
      46               0 :     const auto stub_file = std::getenv("EVMONE_PRECOMPILES_STUB");
      47               0 :     if (stub_file == nullptr)
      48               0 :         return;
      49                 : 
      50                 :     try
      51                 :     {
      52               0 :         const auto j = nlohmann::json::parse(std::ifstream{stub_file});
      53               0 :         for (size_t id = 0; id < j.size(); ++id)
      54                 :         {
      55               0 :             auto& cache = m_cache.at(id);
      56               0 :             for (const auto& [h_str, j_input] : j[id].items())
      57                 :             {
      58               0 :                 auto& e = cache[evmc::from_hex<hash256>(h_str).value()];
      59               0 :                 if (!j_input.is_null())
      60               0 :                     e = evmc::from_hex(j_input.get<std::string>());
      61               0 :             }
      62                 :         }
      63               0 :     }
      64               0 :     catch (...)
      65                 :     {
      66               0 :         std::cerr << "evmone: Loading precompiles stub from '" << stub_file << "' has failed!\n";
      67               0 :     }
      68                 : }
      69                 : 
      70               0 : Cache::~Cache() noexcept
      71                 : {
      72               0 :     const auto dump_file = std::getenv("EVMONE_PRECOMPILES_DUMP");
      73               0 :     if (dump_file == nullptr)
      74               0 :         return;
      75                 : 
      76                 :     try
      77                 :     {
      78               0 :         nlohmann::json j;
      79               0 :         for (size_t id = 0; id < std::size(m_cache); ++id)
      80                 :         {
      81               0 :             auto& q = j[id];
      82               0 :             for (const auto& [h, o] : m_cache[id])
      83                 :             {
      84               0 :                 auto& v = q[evmc::hex(h)];
      85               0 :                 if (o)
      86               0 :                     v = evmc::hex(*o);
      87                 :             }
      88                 :         }
      89               0 :         std::ofstream{dump_file} << std::setw(2) << j << '\n';
      90               0 :     }
      91               0 :     catch (...)
      92                 :     {
      93               0 :         std::cerr << "evmone: Dumping precompiles to '" << dump_file << "' has failed!\n";
      94               0 :     }
      95               0 : }
      96                 : }  // namespace evmone::state
        

Generated by: LCOV version 2.0-1