Update dependent feedback atomically with membership and filter poll results
This commit is contained in:
1 parent
8925503d59
commit
490b30b956
2 files changed
+17
-1
No files matched your search
@@ -1,5 +1,6 @@
|
||||
#include "chat_poll.h"
|
||||
#include "chat_feedback.h"
|
||||
#include "member_sync.h"
|
||||
#include "chat_core_priv.h"
|
||||
#include "chat_event.h"
|
||||
#include "../utun_instance.h"
|
||||
@@ -120,6 +121,10 @@ int chat_feedback_snapshot(struct UTUN_INSTANCE* inst, const char* channel, cons
|
||||
sqlite3_bind_blob(st, 1, message_id, 32, SQLITE_STATIC);
|
||||
while ((step = sqlite3_step(st)) == SQLITE_ROW) {
|
||||
uint64_t author = (uint64_t)sqlite3_column_int64(st, 0), ver = (uint64_t)sqlite3_column_int64(st, 2);
|
||||
uint8_t author_key[32];
|
||||
enum ms_author_status status = member_sync_author_key(inst, channel, author, author_key);
|
||||
if (status == MS_AUTHOR_ERROR) goto done;
|
||||
if (status != MS_AUTHOR_ACTIVE) continue;
|
||||
const uint8_t* data = sqlite3_column_blob(st, 3); size_t len = sqlite3_column_bytes(st, 3);
|
||||
int kind = sqlite3_column_int(st, 1);
|
||||
if (kind == CHAT_FEEDBACK_REACTION) {
|
||||
@@ -191,6 +196,11 @@ void chat_feedback_check_message(struct UTUN_INSTANCE* inst, const char* channel
|
||||
if (sqlite3_prepare_v2(inst->topo_sqlite_db, sql, -1, &st, NULL) != SQLITE_OK) { poll_db_error(inst, "evaluate query"); return; }
|
||||
sqlite3_bind_blob(st, 1, message_id, 32, SQLITE_STATIC); int step; unsigned accepted = 0, rejected = 0;
|
||||
while ((step = sqlite3_step(st)) == SQLITE_ROW) {
|
||||
uint8_t author_key[32];
|
||||
enum ms_author_status status = member_sync_author_key(inst, channel,
|
||||
(uint64_t)sqlite3_column_int64(st, 0), author_key);
|
||||
if (status == MS_AUTHOR_ERROR) { sqlite3_finalize(st); return; }
|
||||
if (status != MS_AUTHOR_ACTIVE) continue;
|
||||
struct chat_poll_answer answer;
|
||||
if (chat_answer_decode(sqlite3_column_blob(st, 2), sqlite3_column_bytes(st, 2), &answer) < 0
|
||||
|| !is_poll || !poll_answer_allowed(&poll, &answer)) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "../routing_layer/topo_group_connect.h"
|
||||
#include "member_sync.h"
|
||||
#include "chat_feedback.h"
|
||||
|
||||
#include "../routing_layer/topo_node_sqlite.h"
|
||||
#include "../routing_layer/topo_group.h"
|
||||
@@ -740,6 +741,8 @@ static int member_apply_record(struct UTUN_INSTANCE* inst, const char* ch_id,
|
||||
|
||||
/* ── recompute и подтвердить реальное изменение по хешу ── */
|
||||
if (changed) {
|
||||
/* Общий ключ может разрешить удостоверения приглашённых в других каналах. */
|
||||
if (chat_feedback_member_update(inst, m->node_id) < 0) return MT_ERR_IO;
|
||||
int rc = merkle_sync_recompute_path(inst, MT_DATA_MEMBERS, ch_id, m->node_id);
|
||||
if (rc < 0) return -1;
|
||||
if (rc == 0) changed = 0; /* запись была no-op (данные идентичны) */
|
||||
@@ -752,6 +755,7 @@ static int member_apply_record(struct UTUN_INSTANCE* inst, const char* ch_id,
|
||||
|
||||
void member_sync_record_committed(struct UTUN_INSTANCE* inst, const char* ns, uint64_t node_id) {
|
||||
merkle_sync_changed(inst, MT_DATA_MEMBERS, ns);
|
||||
chat_feedback_member_committed(inst, node_id);
|
||||
struct TOPO_GROUP* g = inst->topo_groups ? topo_groups_find(inst->topo_groups, strtoull(ns, NULL, 10)) : NULL;
|
||||
struct ETCP_CONN* conn = instance_find_conn(inst, node_id);
|
||||
if (g && g->group_type == TOPO_GROUP_TYPE_CHAT) {
|
||||
@@ -946,7 +950,8 @@ int member_sync_verify_and_purge(struct UTUN_INSTANCE* inst, const char* ch_id)
|
||||
for (int i = 0; i < count; i++) if (topo_node_sqlite_member_del(db, ns, removed[i]) < 0) goto fail;
|
||||
stage = "index";
|
||||
for (int i = 0; i < count; i++)
|
||||
if (merkle_sync_recompute_path(inst, MT_DATA_MEMBERS, ns, removed[i]) < 0) goto fail;
|
||||
if (merkle_sync_recompute_path(inst, MT_DATA_MEMBERS, ns, removed[i]) < 0
|
||||
|| chat_feedback_member_update(inst, removed[i]) < 0) goto fail;
|
||||
stage = "commit";
|
||||
rc = sqlite3_exec(db, "COMMIT", NULL, NULL, NULL);
|
||||
if (rc != SQLITE_OK) goto fail;
|
||||
@@ -956,6 +961,7 @@ int member_sync_verify_and_purge(struct UTUN_INSTANCE* inst, const char* ch_id)
|
||||
}
|
||||
for (int i = 0; i < count; i++) {
|
||||
uint64_t nid = removed[i];
|
||||
chat_feedback_member_committed(inst, nid);
|
||||
radio_forget_member_mute(inst, group_id, nid);
|
||||
struct TOPO_GROUP* g = inst->topo_groups ? topo_groups_find(inst->topo_groups, group_id) : NULL;
|
||||
struct ETCP_CONN* conn = instance_find_conn(inst, nid);
|
||||
|
||||
Reference in new issue
Block a user