| 155 | WasmModuleManager::~WasmModuleManager() = default; |
| 156 | |
| 157 | void WasmModuleManager::saveModule(std::string_view module_name, std::string_view wasm_code, UInt256 expected_hash) |
| 158 | { |
| 159 | if (auto res = checkValidWasmCode(module_name, wasm_code); !res) |
| 160 | throw Exception(std::move(res.error()), ErrorCodes::INCORRECT_DATA); |
| 161 | |
| 162 | UInt256 actual_hash = calculateHash(wasm_code); |
| 163 | if (expected_hash && actual_hash != expected_hash) |
| 164 | throw Exception(ErrorCodes::INCORRECT_DATA, |
| 165 | "Hash mismatch for WebAssembly module '{}', expected {}, got {}", |
| 166 | module_name, hashToHex(expected_hash), hashToHex(actual_hash)); |
| 167 | |
| 168 | UniqueLock lock(modules_mutex); |
| 169 | auto it = modules.find(module_name); |
| 170 | if (it != modules.end()) |
| 171 | { |
| 172 | UInt256 existing_hash = it->second.hash; |
| 173 | if (!existing_hash) |
| 174 | { |
| 175 | existing_hash = calculateHash(loadModuleImpl(module_name)); |
| 176 | it->second.hash = existing_hash; |
| 177 | } |
| 178 | |
| 179 | if (existing_hash == actual_hash) |
| 180 | { |
| 181 | LOG_DEBUG(log, "WebAssembly module '{}' with the same hash already exists, skipping saving", module_name); |
| 182 | return; |
| 183 | } |
| 184 | throw Exception(ErrorCodes::FILE_ALREADY_EXISTS, "WebAssembly module '{}' already exists", module_name); |
| 185 | } |
| 186 | |
| 187 | auto out_buf = user_scripts_disk->writeFile(getFilePath(module_name), DBMS_DEFAULT_BUFFER_SIZE, WriteMode::Rewrite, {}); |
| 188 | out_buf->write(wasm_code.data(), wasm_code.size()); |
| 189 | out_buf->finalize(); |
| 190 | |
| 191 | modules.emplace(String(module_name), ModuleRef{{}, actual_hash}); |
| 192 | } |
| 193 | |
| 194 | |
| 195 | static void linkHostFunctions(WasmModule & module) |
no test coverage detected