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
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); |
|
};
|
|
|