diff --git a/@l10n/ru/docs/protocol/key-history.md b/@l10n/ru/docs/protocol/key-history.md index d43f8142d7..eef7ef21ae 100644 --- a/@l10n/ru/docs/protocol/key-history.md +++ b/@l10n/ru/docs/protocol/key-history.md @@ -17,6 +17,8 @@ DLT-нода стартует со снапшота и не хранит про | `valid_until_block` | Последний блок, в котором ключ ещё действовал (включительно); смена — в следующем блоке | | `valid_until_time` | Время этого блока | +Если старая authority роли была пустой (ни ключей, ни аккаунтов), нода всё равно пишет для этой роли одну строку-маркер: `key` — нулевой ключ, `auth_account` пустой, `weight` = `0`. Она нужна, чтобы кулдаун ротации работал и при переходе «пусто → заполнено»; такие строки видны и в `get_key_history_by_key` по нулевому ключу. + Строка значит: у аккаунта A был ключ B в роли R с весом D из требуемых E до блока F во время G. «С какого момента» — блок, следующий за `valid_until_block` предыдущей строки той же роли (или неизвестно для ключей, которые стояли на момент активации HF15: более ранней истории взять неоткуда). Текущие ключи — в самом аккаунте. Строки пишут все пути смены ключей: `account_update`, восстановление аккаунта, прямая продажа и закрытие аукциона. Роль, authority которой не изменился, ничего не пишет — повторная отправка того же authority сменой не считается. Строки не удаляются никогда. Это отдельная вещь от истории master для [восстановления](operations/recovery.md), которая хранится только 30 дней. diff --git a/docs/protocol/key-history.md b/docs/protocol/key-history.md index d509462624..ebd3d4faa0 100644 --- a/docs/protocol/key-history.md +++ b/docs/protocol/key-history.md @@ -17,6 +17,8 @@ When an account's keys change, the node writes one row per member of the **old** | `valid_until_block` | Last block in which the key still held (inclusive); the change is in the next block | | `valid_until_time` | Time of that block | +If the old authority of a role was empty (no keys and no accounts), the node still writes one marker row for that role: `key` is the null key, `auth_account` is empty, `weight` is `0`. It keeps the rotation cooldown working for an empty→populated change; such rows also show up in `get_key_history_by_key` for the null key. + The row says: account A held key B in role R with weight D out of threshold E until block F at time G. "Since when" is the block after the `valid_until_block` of the previous row of the same role (or unknown, for keys that were already in place when HF15 activated — there is no earlier history to take it from). The current keys are in the account itself. Rows are written by every path that changes keys: `account_update`, account recovery, direct sale and auction close. A role whose authority did not change writes nothing — re-sending the same authority is not a change. Rows are never removed. This is separate from the master authority history used by [recovery](operations/recovery.md), which is kept for 30 days only. diff --git a/libraries/protocol/include/graphene/protocol/config.hpp b/libraries/protocol/include/graphene/protocol/config.hpp index 0d99a087af..e2144425e8 100644 --- a/libraries/protocol/include/graphene/protocol/config.hpp +++ b/libraries/protocol/include/graphene/protocol/config.hpp @@ -7,7 +7,7 @@ // current_hardfork_version < CHAIN_HARDFORK_VERSION. A new fork therefore has to move THAT field, // not the revision; 4.1.0 here must stay byte-equal to CHAIN_HARDFORK_15_VERSION in hardfork.d/15.hf, // which database_hardfork.cpp asserts. See docs/prediction-markets/pm-audit-fix-upgrade.md. -#define CHAIN_VERSION (version(4, 1, 0)) +#define CHAIN_VERSION (version(4, 1, 1)) #define CHAIN_HARDFORK_VERSION (hardfork_version(CHAIN_VERSION)) #define CHAIN_NAME "VIZ" diff --git a/plugins/chain/plugin.cpp b/plugins/chain/plugin.cpp index 25ea17889c..ddd75a6239 100644 --- a/plugins/chain/plugin.cpp +++ b/plugins/chain/plugin.cpp @@ -188,7 +188,7 @@ namespace chain { const auto fail = [](const char* action) { throw std::system_error(errno, std::generic_category(), action); }; - int fd = ::open(temp.string().c_str(), O_WRONLY | O_CREAT | O_EXCL, 0644); + int fd = ::open(temp.string().c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0644); if (fd < 0) fail("open schema version temporary file"); try { const std::string value = std::to_string(CHAIN_SCHEMA_VERSION); diff --git a/plugins/snapshot/plugin.cpp b/plugins/snapshot/plugin.cpp index 4529a48e21..c736774f28 100644 --- a/plugins/snapshot/plugin.cpp +++ b/plugins/snapshot/plugin.cpp @@ -1526,6 +1526,9 @@ void snapshot_plugin::plugin_impl::create_snapshot(const fc::path& output_path, fc::variant block_var; fc::to_variant(*head_block, block_var); state["fork_db_head_block"] = std::move(block_var); + } else { + wlog("Snapshot: head block ${n} is not in block_log; the snapshot has no fork_db_head_block and a post-HF15 node will refuse to load it", + ("n", snapshot_head_block_num)); } }