diff --git a/libtorrent/src/kademlia/node.cpp b/libtorrent/src/kademlia/node.cpp index 81ddb686..f1a14a8b 100644 --- a/libtorrent/src/kademlia/node.cpp +++ b/libtorrent/src/kademlia/node.cpp @@ -499,8 +499,16 @@ static void processEntryForHashtags(lazy_entry &p) const lazy_entry *userpost = v->dict_find_dict("userpost"); if( userpost ) { int64_t time = p.dict_find_int_value("time"); - std::string msg = userpost->dict_find_string_value("msg"); - updateSeenHashtags(msg,time); + const lazy_entry *rt = userpost->dict_find_dict("rt"); + std::string msg; + if( rt ) { + msg = rt->dict_find_string_value("msg"); + } else { + msg = userpost->dict_find_string_value("msg"); + } + if( msg.size() ) { + updateSeenHashtags(msg,time); + } } } } diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index c1348414..fe9538ce 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -261,6 +261,7 @@ static const CRPCCommand vRPCCommands[] = { "rescandirectmsgs", &rescandirectmsgs, false, true }, { "recheckusertorrent", &recheckusertorrent, false, true }, { "gettrendinghashtags", &gettrendinghashtags, false, true }, + { "getspamposts", &getspamposts, false, true }, }; CRPCTable::CRPCTable() @@ -1283,6 +1284,9 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector 1) ConvertTo(params[1]); if (strMethod == "listusernamespartial" && n > 2) ConvertTo(params[2]); if (strMethod == "gettrendinghashtags" && n > 0) ConvertTo(params[0]); + if (strMethod == "getspamposts" && n > 0) ConvertTo(params[0]); + if (strMethod == "getspamposts" && n > 1) ConvertTo(params[1]); + if (strMethod == "getspamposts" && n > 2) ConvertTo(params[2]); return params; } diff --git a/src/bitcoinrpc.h b/src/bitcoinrpc.h index 07d3dcb8..c563ffe3 100644 --- a/src/bitcoinrpc.h +++ b/src/bitcoinrpc.h @@ -213,5 +213,6 @@ extern json_spirit::Value listusernamespartial(const json_spirit::Array& params, extern json_spirit::Value rescandirectmsgs(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value recheckusertorrent(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value gettrendinghashtags(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getspamposts(const json_spirit::Array& params, bool fHelp); #endif diff --git a/src/twister.cpp b/src/twister.cpp index 24650183..3f074689 100644 --- a/src/twister.cpp +++ b/src/twister.cpp @@ -1179,6 +1179,9 @@ void receivedSpamMessage(std::string const &message, std::string const &user) void updateSeenHashtags(std::string &message, int64_t msgTime) { + if( message.find('#') == string::npos ) + return; + boost::int64_t curTime = GetAdjustedTime(); if( msgTime > curTime ) msgTime = curTime; @@ -1216,6 +1219,23 @@ void updateSeenHashtags(std::string &message, int64_t msgTime) } } +entry formatSpamPost(const string &msg, const string &username, uint64_t utcTime = 0, int height = 0) +{ + entry v; + entry &userpost = v["userpost"]; + + userpost["n"] = username; + userpost["k"] = height ? height : 1; + userpost["time"] = utcTime ? utcTime : GetAdjustedTime(); + userpost["height"] = height ? height : getBestHeight(); + userpost["msg"] = msg; + + unsigned char vchSig[65]; + RAND_bytes(vchSig,sizeof(vchSig)); + v["sig_userpost"] = HexStr( string((const char *)vchSig, sizeof(vchSig)) ); + return v; +} + Value dhtput(const Array& params, bool fHelp) { if (fHelp || params.size() < 5 || params.size() > 6) @@ -1631,19 +1651,7 @@ Value getposts(const Array& params, bool fHelp) if( m_receivedSpamMsgStr.length() && GetAdjustedTime() > m_lastSpamTime + (8*3600) ) { m_lastSpamTime = GetAdjustedTime(); - entry v; - entry &userpost = v["userpost"]; - - userpost["n"] = m_receivedSpamUserStr; - userpost["k"] = 1; - userpost["time"] = GetAdjustedTime(); - userpost["height"] = getBestHeight(); - - userpost["msg"] = m_receivedSpamMsgStr; - - unsigned char vchSig[65]; - RAND_bytes(vchSig,sizeof(vchSig)); - v["sig_userpost"] = HexStr( string((const char *)vchSig, sizeof(vchSig)) ); + entry v = formatSpamPost(m_receivedSpamMsgStr, m_receivedSpamUserStr); ret.insert(ret.begin(),entryToJson(v)); m_receivedSpamMsgStr = ""; @@ -1970,3 +1978,45 @@ Value gettrendinghashtags(const Array& params, bool fHelp) return ret; } +Value getspamposts(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 3) + throw runtime_error( + "getspamposts [max_id] [since_id]\n" + "get spam posts from blockchain\n" + "max_id and since_id may be omited (or -1)"); + + int count = params[0].get_int(); + int max_id = getBestHeight(); + if (params.size() > 1 && params[1].get_int() != -1) + max_id = std::min(params[1].get_int(), max_id); + int since_id = -1; + if (params.size() > 2) + since_id = std::max(params[2].get_int(), since_id); + + Array ret; + std::string lastMsg; + + for( int height = max_id; height > since_id && (int)ret.size() < count; height-- ) { + CBlockIndex* pblockindex = FindBlockByHeight(height); + CBlock block; + ReadBlockFromDisk(block, pblockindex); + + const CTransaction &tx = block.vtx[0]; + if( tx.IsSpamMessage() ) { + std::string spamMessage = tx.message.ExtractPushDataString(0); + std::string spamUser = tx.userName.ExtractPushDataString(0); + + // remove consecutive duplicates + if( spamMessage == lastMsg) + continue; + lastMsg = spamMessage; + + entry v = formatSpamPost(spamMessage, spamUser, + block.GetBlockTime(), height); + ret.insert(ret.begin(),entryToJson(v)); + } + } + + return ret; +}