diff --git a/.gitmodules b/.gitmodules index a6f7081ebe..8f877689b6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,9 +7,6 @@ [submodule "cbor-cpp"] path = third_party/cbor-cpp/cbor-cpp url = https://github.com/torquem-ch/cbor-cpp.git -[submodule "libmdbx"] - path = third_party/libmdbx/libmdbx - url = https://github.com/torquem-ch/libmdbx.git [submodule "interfaces"] path = third_party/erigon-interfaces url = https://github.com/ledgerwatch/interfaces.git @@ -17,6 +14,9 @@ [submodule "stbrumme-crc32"] path = third_party/stbrumme-crc32/stbrumme-crc32 url = https://github.com/battlmonstr/stbrumme-crc32.git +[submodule "erigon-mdbx-go"] + path = third_party/erigon-mdbx-go/mdbx-go + url = https://github.com/erigontech/mdbx-go.git [submodule "erigon-snapshot"] path = third_party/erigon-snapshot url = https://github.com/ledgerwatch/erigon-snapshot diff --git a/cmd/capi/execute.cpp b/cmd/capi/execute.cpp index a5af71913c..e917310824 100644 --- a/cmd/capi/execute.cpp +++ b/cmd/capi/execute.cpp @@ -389,6 +389,9 @@ int main(int argc, char* argv[]) { } strncpy(silkworm_settings.data_dir_path, data_dir_path.c_str(), SILKWORM_PATH_SIZE - 1); + SILK_INFO << "libmdbx version: " << silkworm_libmdbx_version(); + strncpy(silkworm_settings.libmdbx_version, ::mdbx::get_version().git.describe, sizeof(silkworm_settings.libmdbx_version) - 1); + const int init_status_code = silkworm_init(&handle, &silkworm_settings); if (init_status_code != SILKWORM_OK) { SILK_ERROR << "silkworm_init failed [code=" << std::to_string(init_status_code) << "]"; diff --git a/silkworm/capi/silkworm.cpp b/silkworm/capi/silkworm.cpp index a7a59c3216..d41296b51e 100644 --- a/silkworm/capi/silkworm.cpp +++ b/silkworm/capi/silkworm.cpp @@ -19,8 +19,11 @@ #include #include #include +#include +#include #include +#include #include #include @@ -67,6 +70,36 @@ struct ExecutionProgress { float gas_state_perc{0.0}; }; +//! Kind of match to perform between Erigon and Silkworm libmdbx versions +enum class MdbxVersionCheck : uint8_t { + kNone, /// no check at all + kExact, /// git-describe versions must match perfectly + kSemantic, /// compare semantic versions ( == ) +}; + +static bool is_compatible_mdbx_version(std::string_view their_version, std::string_view our_version, MdbxVersionCheck check) { + SILK_TRACE << "is_compatible_mdbx_version their_version: " << their_version << " our_version: " << our_version; + bool compatible{false}; + switch (check) { + case MdbxVersionCheck::kNone: { + compatible = true; + } break; + case MdbxVersionCheck::kExact: { + compatible = their_version == our_version; + } break; + case MdbxVersionCheck::kSemantic: { + const std::vector their_version_parts = absl::StrSplit(std::string(their_version), '.'); + const std::vector our_version_parts = absl::StrSplit(std::string(our_version), '.'); + compatible = (their_version_parts.size() >= 3) && + (our_version_parts.size() >= 3) && + (their_version_parts[0] == our_version_parts[0]) && + (their_version_parts[1] == our_version_parts[1]) && + (their_version_parts[2] == our_version_parts[2]); + } + } + return compatible; +} + //! Generate log arguments for Silkworm library version static log::Args log_args_for_version() { const auto build_info{silkworm_get_buildinfo()}; @@ -158,6 +191,10 @@ SILKWORM_EXPORT int silkworm_init( return SILKWORM_INVALID_SETTINGS; } + if (!is_compatible_mdbx_version(settings->libmdbx_version, silkworm_libmdbx_version(), MdbxVersionCheck::kExact)) { + return SILKWORM_INCOMPATIBLE_LIBMDBX; + } + static bool is_initialized = false; if (is_initialized) { return SILKWORM_TOO_MANY_INSTANCES; @@ -310,6 +347,10 @@ SILKWORM_EXPORT int silkworm_add_snapshot(SilkwormHandle handle, SilkwormChainSn return SILKWORM_OK; } +SILKWORM_EXPORT const char* silkworm_libmdbx_version() SILKWORM_NOEXCEPT { + return ::mdbx::get_version().git.describe; +} + SILKWORM_EXPORT int silkworm_start_rpcdaemon(SilkwormHandle handle, MDBX_env* env) SILKWORM_NOEXCEPT { if (!handle) { return SILKWORM_INVALID_HANDLE; diff --git a/silkworm/capi/silkworm.h b/silkworm/capi/silkworm.h index f6657e5338..4e9c06178b 100644 --- a/silkworm/capi/silkworm.h +++ b/silkworm/capi/silkworm.h @@ -58,6 +58,7 @@ extern "C" { #define SILKWORM_INVALID_SETTINGS 14 #define SILKWORM_TERMINATION_SIGNAL 15 #define SILKWORM_SERVICE_ALREADY_STARTED 16 +#define SILKWORM_INCOMPATIBLE_LIBMDBX 17 typedef struct MDBX_env MDBX_env; typedef struct MDBX_txn MDBX_txn; @@ -98,6 +99,8 @@ struct SilkwormChainSnapshot { struct SilkwormSettings { //! Data directory path in UTF-8. char data_dir_path[SILKWORM_PATH_SIZE]; + //! libmdbx version string in git describe format. + char libmdbx_version[32]; }; /** @@ -129,6 +132,12 @@ SILKWORM_EXPORT int silkworm_build_recsplit_indexes(SilkwormHandle handle, struc */ SILKWORM_EXPORT int silkworm_add_snapshot(SilkwormHandle handle, struct SilkwormChainSnapshot* snapshot) SILKWORM_NOEXCEPT; +/** + * \brief Get libmdbx version for compatibility checks. + * \return A string in git describe format. + */ +SILKWORM_EXPORT const char* silkworm_libmdbx_version() SILKWORM_NOEXCEPT; + /** * \brief Start Silkworm RPC daemon. * \param[in] handle A valid Silkworm instance handle, got with silkworm_init.Must not be zero. diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt index 28db982c21..52708e42db 100644 --- a/third_party/CMakeLists.txt +++ b/third_party/CMakeLists.txt @@ -28,8 +28,8 @@ add_subdirectory(evmone) # depends on ethash, intx if(NOT SILKWORM_CORE_ONLY) add_subdirectory(cbor-cpp) add_subdirectory(cpp-base64) + add_subdirectory(erigon-mdbx-go) add_subdirectory(glaze) - add_subdirectory(libmdbx) add_subdirectory(libtorrent) add_subdirectory(picohttpparser) add_subdirectory(sais-lite) diff --git a/third_party/libmdbx/CMakeLists.txt b/third_party/erigon-mdbx-go/CMakeLists.txt similarity index 89% rename from third_party/libmdbx/CMakeLists.txt rename to third_party/erigon-mdbx-go/CMakeLists.txt index 950c5b3ee1..e9f1fbb34a 100644 --- a/third_party/libmdbx/CMakeLists.txt +++ b/third_party/erigon-mdbx-go/CMakeLists.txt @@ -15,6 +15,5 @@ ]] set(MDBX_ENABLE_TESTS OFF) -add_subdirectory(libmdbx) -target_include_directories(mdbx-static INTERFACE "libmdbx") +add_subdirectory(mdbx-go/mdbxdist) target_compile_definitions(mdbx-static PUBLIC CONSTEXPR_ASSERT=assert) diff --git a/third_party/erigon-mdbx-go/mdbx-go b/third_party/erigon-mdbx-go/mdbx-go new file mode 160000 index 0000000000..839cb7b1a9 --- /dev/null +++ b/third_party/erigon-mdbx-go/mdbx-go @@ -0,0 +1 @@ +Subproject commit 839cb7b1a9a5e6f8cff751ec1b25814d24a7ab38 diff --git a/third_party/libmdbx/libmdbx b/third_party/libmdbx/libmdbx deleted file mode 160000 index 1cac653637..0000000000 --- a/third_party/libmdbx/libmdbx +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 1cac65363763e7523ed3b52eed8f2c617cead973