Align desktop history reads with Merkle schema and fix PM test setup
This commit is contained in:
1 parent
cd0329b301
commit
f1da7d7ee8
3 files changed
+17
-50
No files matched your search
@@ -41,30 +41,6 @@ uint64_t DbManager::computeDatahash(const QByteArray& data) {
|
||||
uint64_t dh; memcpy(&dh, hash, 8); return dh;
|
||||
}
|
||||
|
||||
QByteArray DbManager::computeChainHash(const QByteArray& prevChain,
|
||||
qint64 timestamp, uint64_t datahash) {
|
||||
uint8_t buf[32 + 8 + 8];
|
||||
memcpy(buf, prevChain.constData(), 32);
|
||||
memcpy(buf + 32, ×tamp, 8);
|
||||
memcpy(buf + 40, &datahash, 8);
|
||||
uint8_t hash[32];
|
||||
SHA256(buf, 48, hash);
|
||||
return QByteArray((const char*)hash, 32);
|
||||
}
|
||||
|
||||
QByteArray DbManager::getLastChainHash(const QString& chId) const {
|
||||
QString tbl = msgTableName(chId);
|
||||
QByteArray sql = QStringLiteral(
|
||||
"SELECT chain_hash FROM \"%1\" ORDER BY timestamp, author_signature DESC LIMIT 1")
|
||||
.arg(tbl).toUtf8();
|
||||
sqlite3_stmt* stmt = prepareOrNull(sql.constData());
|
||||
if (!stmt) return QByteArray(32, '\0');
|
||||
QByteArray r = (sqlite3_step(stmt) == SQLITE_ROW) ? colBlob(stmt, 0)
|
||||
: QByteArray(32, '\0');
|
||||
sqlite3_finalize(stmt);
|
||||
return r.size() == 32 ? r : QByteArray(32, '\0');
|
||||
}
|
||||
|
||||
/* ── lifecycle ── */
|
||||
|
||||
DbManager::DbManager(QObject* parent)
|
||||
@@ -247,9 +223,9 @@ static MessageRow readMessage(sqlite3_stmt* stmt, quint64 myId) {
|
||||
GUI_WARN("reply: malformed reference message_row=%lld", (long long)m.id); m.replyTo.clear();
|
||||
}
|
||||
}
|
||||
m.timestamp = sqlite3_column_int64(stmt, 3); m.chainHash = DbManager::colBlob(stmt, 4);
|
||||
m.signature = DbManager::colBlob(stmt, 5); m.localAttrs = DbManager::colBlob(stmt, 6);
|
||||
m.messageId = DbManager::colBlob(stmt, 7); m.isOutgoing = m.authorNodeId == myId; m.isRead = true;
|
||||
m.timestamp = sqlite3_column_int64(stmt, 3); m.signature = DbManager::colBlob(stmt, 4);
|
||||
m.localAttrs = DbManager::colBlob(stmt, 5); m.messageId = DbManager::colBlob(stmt, 6);
|
||||
m.isOutgoing = m.authorNodeId == myId; m.isRead = true;
|
||||
return m;
|
||||
}
|
||||
|
||||
@@ -260,7 +236,7 @@ QList<MessageRow> DbManager::getMessages(const QString& chId, int limit, const Q
|
||||
GUI_ERROR("history: invalid anchor/window bytes=%d limit=%d", int(around.size()), limit); return list;
|
||||
}
|
||||
QString sql = QStringLiteral(
|
||||
"SELECT id, node_id, data, timestamp, chain_hash, author_signature, local_attrs, message_id"
|
||||
"SELECT id, node_id, data, timestamp, author_signature, local_attrs, message_id"
|
||||
" FROM \"%1\" ORDER BY timestamp DESC, author_signature DESC LIMIT ?1").arg(msgTableName(chId));
|
||||
if (!around.isEmpty()) sql += QStringLiteral(
|
||||
" OFFSET min(max(0,(SELECT count(*) FROM \"%1\" n JOIN \"%1\" a ON a.message_id=?2 "
|
||||
@@ -287,7 +263,7 @@ QList<MessageRow> DbManager::getMessages(const QString& chId, int limit, const Q
|
||||
QList<MessageRow> DbManager::getMessagesSince(const QString& chId, qint64 sinceId) const {
|
||||
QList<MessageRow> list;
|
||||
QString sql = QStringLiteral(
|
||||
"SELECT id, node_id, data, timestamp, chain_hash, author_signature, local_attrs, message_id"
|
||||
"SELECT id, node_id, data, timestamp, author_signature, local_attrs, message_id"
|
||||
" FROM \"%1\" WHERE id > ? ORDER BY id ASC").arg(msgTableName(chId));
|
||||
sqlite3_stmt* stmt = prepareOrNull(sql.toUtf8().constData());
|
||||
if (!stmt) return list;
|
||||
@@ -303,7 +279,7 @@ QList<MessageRow> DbManager::getMessagesSince(const QString& chId, qint64 sinceI
|
||||
MessageRow DbManager::getMessageById(const QString& chId, qint64 msgId) const {
|
||||
MessageRow m;
|
||||
QString sql = QStringLiteral(
|
||||
"SELECT id, node_id, data, timestamp, chain_hash, author_signature, local_attrs, message_id"
|
||||
"SELECT id, node_id, data, timestamp, author_signature, local_attrs, message_id"
|
||||
" FROM \"%1\" WHERE id = ?").arg(msgTableName(chId));
|
||||
sqlite3_stmt* stmt = prepareOrNull(sql.toUtf8().constData());
|
||||
if (!stmt) return m;
|
||||
@@ -321,7 +297,7 @@ MessageRow DbManager::getMessageById(const QString& chId, qint64 msgId) const {
|
||||
MessageRow DbManager::getMessageByKey(const QString& chId, const QByteArray& key) const {
|
||||
MessageRow message;
|
||||
if (key.size() != 32) { GUI_ERROR("reply: invalid lookup key bytes=%d", int(key.size())); return message; }
|
||||
const auto sql = QStringLiteral("SELECT id,node_id,data,timestamp,chain_hash,author_signature,local_attrs,message_id "
|
||||
const auto sql = QStringLiteral("SELECT id,node_id,data,timestamp,author_signature,local_attrs,message_id "
|
||||
"FROM \"%1\" WHERE message_id=?").arg(msgTableName(chId)).toUtf8();
|
||||
sqlite3_stmt* stmt = prepareOrNull(sql.constData());
|
||||
if (!stmt) return message;
|
||||
@@ -625,19 +601,6 @@ QByteArray DbManager::syncCount(const QString& chId) const {
|
||||
QByteArray out; out.append((const char*)&cnt, 4); return out;
|
||||
}
|
||||
|
||||
QByteArray DbManager::syncChainHashAt(const QString& chId, uint32_t pos) const {
|
||||
QString sql = QStringLiteral(
|
||||
"SELECT chain_hash FROM \"%1\" ORDER BY timestamp, author_signature ASC LIMIT 1 OFFSET ?")
|
||||
.arg(msgTableName(chId));
|
||||
sqlite3_stmt* stmt = prepareOrNull(sql.toUtf8().constData());
|
||||
if (!stmt) return QByteArray(32, '\0');
|
||||
sqlite3_bind_int64(stmt, 1, pos);
|
||||
QByteArray r;
|
||||
if (sqlite3_step(stmt) == SQLITE_ROW) r = colBlob(stmt, 0);
|
||||
sqlite3_finalize(stmt);
|
||||
return r.size() == 32 ? r : QByteArray(32, '\0');
|
||||
}
|
||||
|
||||
QByteArray DbManager::syncCursorOpen(const QString& chId) {
|
||||
QString sql = QStringLiteral(
|
||||
"SELECT timestamp, node_id, data, author_signature"
|
||||
|
||||
@@ -40,7 +40,6 @@ struct MessageRow {
|
||||
QByteArray data;
|
||||
qint64 timestamp = 0;
|
||||
uint64_t datahash = 0;
|
||||
QByteArray chainHash;
|
||||
QByteArray signature;
|
||||
QByteArray messageId; // общий ID подписанного сообщения, 32 байта
|
||||
QByteArray replyTo; // общий ID оригинала в этом канале, либо пусто
|
||||
@@ -140,7 +139,6 @@ public:
|
||||
/* ── Sync-операции (read-only, для gui_bridge/inline) ── */
|
||||
QByteArray syncListChannels() const;
|
||||
QByteArray syncCount(const QString& chId) const;
|
||||
QByteArray syncChainHashAt(const QString& chId, uint32_t pos) const;
|
||||
QByteArray syncCursorOpen(const QString& chId);
|
||||
QByteArray syncCursorNext(uint32_t cursorId);
|
||||
void syncCursorClose(uint32_t cursorId);
|
||||
@@ -155,9 +153,6 @@ public:
|
||||
QString peersTableName(const QString& chId) const;
|
||||
static QString sanitizeTableName(const QString& chId);
|
||||
static uint64_t computeDatahash(const QByteArray& data);
|
||||
static QByteArray computeChainHash(const QByteArray& prevChain,
|
||||
qint64 timestamp, uint64_t datahash);
|
||||
QByteArray getLastChainHash(const QString& chId) const;
|
||||
|
||||
IntegrityResult integrityCheckQuick() const;
|
||||
IntegrityResult integrityCheckFull() const;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QMenu>
|
||||
#include <QScopeGuard>
|
||||
#include <future>
|
||||
#include <memory>
|
||||
extern "C" {
|
||||
@@ -63,9 +64,17 @@ private slots:
|
||||
|
||||
void deleteThroughWindowAndCore() {
|
||||
QTemporaryDir directory; QVERIFY(directory.isValid());
|
||||
directory.setAutoRemove(false);
|
||||
auto diagnostics = qScopeGuard([&directory] {
|
||||
directory.setAutoRemove(!QTest::currentTestFailed());
|
||||
if (QTest::currentTestFailed()) DEBUG_ERROR(DEBUG_CATEGORY_DEBUG, "DM test diagnostics retained: %s", qPrintable(directory.path()));
|
||||
});
|
||||
const QString configPath = directory.filePath("node.cfg");
|
||||
QFile config(configPath); QVERIFY(config.open(QIODevice::WriteOnly));
|
||||
const QByteArray text = "[global]\ntun_enabled=no\n[server:local]\naddr=127.0.0.1:0\ntype=private\n"
|
||||
const QByteArray text = "[global]\n"
|
||||
"my_private_key=704f2e012c8fa8768130cb0f988a997dccb628372bc5ceccacc78dcbfec5916f\n"
|
||||
"my_public_key=b3193173def895bd0fcea6f86af077c7d77216f10395275f627ac18242ec0f01\n"
|
||||
"tun_enabled=no\n[server:local]\naddr=127.0.0.1:0\ntype=private\n"
|
||||
"[chatserver]\ngroup_autoconnect=0\nstorage_autoload=0\nlocal_invites_enabled=0\nlocal_broadcasts_enabled=0\n"
|
||||
"[ntp]\nenabled=no\n";
|
||||
QCOMPARE(config.write(text), text.size()); config.close();
|
||||
|
||||
Reference in new issue
Block a user