You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

70 lines
2.4 KiB

#pragma once
#include <QObject>
#include <QByteArray>
#include <QHash>
#include <QList>
#include <QTimer>
#include <cstdint>
class UtunNode;
class DbManager;
struct MessageRow;
class ChatPropagator : public QObject {
Q_OBJECT
public:
ChatPropagator(UtunNode* node, DbManager* db, QObject* parent = nullptr);
void setKeys(const QByteArray& edPriv, const QByteArray& edPub, quint64 nodeId);
void start();
void propagateNewMessage(const QString& channelId, const QByteArray& content,
qint64 timestamp, const QByteArray& signature);
signals:
void messageReceived(const QString& channelId, quint64 authorNodeId,
const QByteArray& content, qint64 timestamp);
private:
UtunNode* m_node;
DbManager* m_db;
QTimer* m_ackTimer;
QByteArray m_edPriv;
QByteArray m_edPub;
quint64 m_myNodeId = 0;
struct GossipEntry {
QString channelId;
QByteArray packet; /* full NEW_MSG packet */
QByteArray sig; /* message signature (key) */
QList<quint64> peers; /* target peers */
QList<quint64> acked; /* peers that acknowledged */
qint64 sentAt; /* when sent (ms) */
int retries = 0;
};
QHash<QByteArray, GossipEntry> m_pending; /* sig → entry */
QByteArray m_mySig; /* sig we're waiting for ACK on */
void onReceived(quint64 peerId, const QByteArray& data);
void handleNewMsg(quint64 fromPeer, const QByteArray& payload);
void handleNewAck(const QByteArray& payload);
void onAckTimeout();
void startCatchUp();
void handleBucketsRsp(const QByteArray& payload);
void handleHashesRsp(const QByteArray& payload);
void handleMsgsRsp(const QByteArray& payload);
void fanoutGossip(const QString& channelId, const QByteArray& packet,
const QByteArray& sig, int fanout, const QList<quint64>& exclude);
void sendGossip(quint64 peer, const QByteArray& packet);
QList<quint64> pickRandomPeers(int count, const QList<quint64>& exclude);
QByteArray buildNewMsgPacket(const QString& channelId, const QByteArray& content,
qint64 timestamp, const QByteArray& signature);
QByteArray buildAckPacket(const QByteArray& sig);
bool parseNewMsg(const QByteArray& payload, QString& channelId, QByteArray& content,
qint64& timestamp, QByteArray& sig);
};