mirror of
https://github.com/twisterarmy/twister-core.git
synced 2025-01-09 06:18:02 +00:00
implement expiring dht items (but it is not enabled yet)
This commit is contained in:
parent
bdb70b0d14
commit
7e1726ba8c
6
TODO
6
TODO
@ -47,6 +47,10 @@ according to previous bittorrent research, would be enough to keep data availabl
|
|||||||
probability). twister also persists keys to disk. As userbase increases, old post storage and
|
probability). twister also persists keys to disk. As userbase increases, old post storage and
|
||||||
unreliable multivalued keys should better expire. Since those posts include the height and time, a
|
unreliable multivalued keys should better expire. Since those posts include the height and time, a
|
||||||
policy may me defined.
|
policy may me defined.
|
||||||
|
=> Implemented shouldDhtResourceExpire() which is tested on initialization but not really used yet.
|
||||||
|
|
||||||
|
- Check stored dht values if their signature is still valid before trying to refresh another node.
|
||||||
|
Key pair might have changed and currently we receive a lot of errors from other nodes.
|
||||||
|
|
||||||
|
|
||||||
-
|
|
||||||
|
|
||||||
|
@ -180,6 +180,7 @@ public:
|
|||||||
|
|
||||||
void tick();
|
void tick();
|
||||||
bool refresh_storage();
|
bool refresh_storage();
|
||||||
|
bool has_expired(dht_storage_item const& item);
|
||||||
bool save_storage(entry &save) const;
|
bool save_storage(entry &save) const;
|
||||||
void refresh(node_id const& id, find_data::nodes_callback const& f);
|
void refresh(node_id const& id, find_data::nodes_callback const& f);
|
||||||
void bootstrap(std::vector<udp::endpoint> const& nodes
|
void bootstrap(std::vector<udp::endpoint> const& nodes
|
||||||
|
@ -537,6 +537,49 @@ bool node_impl::refresh_storage() {
|
|||||||
return did_something;
|
return did_something;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool node_impl::has_expired(dht_storage_item const& item) {
|
||||||
|
if (!verifySignature(item.p, item.sig_user, item.sig_p)) {
|
||||||
|
// invalid signature counts as expired
|
||||||
|
printf("node_impl::has_expired verifySignature failed\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
lazy_entry arg_ent;
|
||||||
|
int pos;
|
||||||
|
error_code err;
|
||||||
|
// FIXME: optimize to avoid bdecode (store seq separated, etc)
|
||||||
|
int ret = lazy_bdecode(item.p.data(), item.p.data() + item.p.size(), arg_ent, err, &pos, 10, 500);
|
||||||
|
|
||||||
|
const static key_desc_t msg_desc[] = {
|
||||||
|
{"v", lazy_entry::none_t, 0, 0},
|
||||||
|
{"seq", lazy_entry::int_t, 0, key_desc_t::optional},
|
||||||
|
{"time", lazy_entry::int_t, 0, 0},
|
||||||
|
{"height", lazy_entry::int_t, 0, 0},
|
||||||
|
{"target", lazy_entry::dict_t, 0, key_desc_t::parse_children},
|
||||||
|
{"n", lazy_entry::string_t, 0, 0},
|
||||||
|
{"r", lazy_entry::string_t, 0, 0},
|
||||||
|
{"t", lazy_entry::string_t, 0, 0},
|
||||||
|
};
|
||||||
|
enum {mk_v = 0, mk_seq, mk_time, mk_height,
|
||||||
|
mk_target, mk_n, mk_r, mk_t};
|
||||||
|
|
||||||
|
// attempt to parse the message
|
||||||
|
lazy_entry const* msg_keys[8];
|
||||||
|
char error_string[200];
|
||||||
|
if (!verify_message(&arg_ent, msg_desc, msg_keys, 8, error_string, sizeof(error_string)))
|
||||||
|
{
|
||||||
|
printf("node_impl::has_expired verify_message failed\n");
|
||||||
|
// parse error (how come?) counts as expired
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool multi = (msg_keys[mk_t]->string_value() == "m");
|
||||||
|
int height = msg_keys[mk_height]->int_value();
|
||||||
|
std::string resource = msg_keys[mk_r]->string_value();
|
||||||
|
|
||||||
|
return shouldDhtResourceExpire(resource, multi, height);
|
||||||
|
}
|
||||||
|
|
||||||
bool node_impl::save_storage(entry &save) const {
|
bool node_impl::save_storage(entry &save) const {
|
||||||
bool did_something = false;
|
bool did_something = false;
|
||||||
|
|
||||||
@ -593,6 +636,10 @@ void node_impl::load_storage(entry const* e) {
|
|||||||
item.p = j->find_key("p")->string();
|
item.p = j->find_key("p")->string();
|
||||||
item.sig_p = j->find_key("sig_p")->string();
|
item.sig_p = j->find_key("sig_p")->string();
|
||||||
item.sig_user = j->find_key("sig_user")->string();
|
item.sig_user = j->find_key("sig_user")->string();
|
||||||
|
|
||||||
|
// just for printf for now
|
||||||
|
has_expired(item);
|
||||||
|
|
||||||
to_add.push_back(item);
|
to_add.push_back(item);
|
||||||
}
|
}
|
||||||
m_storage_table.insert(std::make_pair(target, to_add));
|
m_storage_table.insert(std::make_pair(target, to_add));
|
||||||
@ -1152,6 +1199,18 @@ void node_impl::incoming_request(msg const& m, entry& e)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* we can't check username, otherwise we break hashtags etc.
|
||||||
|
if (multi && !usernameExists(msg_keys[mk_n]->string_value())) {
|
||||||
|
incoming_error(e, "unknown user for resource");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (msg_keys[mk_r]->string_value().size() > 32) {
|
||||||
|
incoming_error(e, "resource name too big");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!multi && (!msg_keys[mk_seq] || msg_keys[mk_seq]->int_value() < 0)) {
|
if (!multi && (!msg_keys[mk_seq] || msg_keys[mk_seq]->int_value() < 0)) {
|
||||||
incoming_error(e, "seq is required for single");
|
incoming_error(e, "seq is required for single");
|
||||||
return;
|
return;
|
||||||
|
@ -41,6 +41,7 @@ static map<sha1_hash, alert_manager*> m_dhtgetMap;
|
|||||||
|
|
||||||
static CCriticalSection cs_twister;
|
static CCriticalSection cs_twister;
|
||||||
static map<std::string, bool> m_specialResources;
|
static map<std::string, bool> m_specialResources;
|
||||||
|
static map<std::string, bool> m_noExpireResources; // bool is true if expected number after resource string
|
||||||
static map<std::string, torrent_handle> m_userTorrent;
|
static map<std::string, torrent_handle> m_userTorrent;
|
||||||
|
|
||||||
static std::string m_preferredSpamLang = "[en]";
|
static std::string m_preferredSpamLang = "[en]";
|
||||||
@ -389,6 +390,11 @@ void startSessionTorrent(boost::thread_group& threadGroup)
|
|||||||
m_specialResources["tracker"] = true;
|
m_specialResources["tracker"] = true;
|
||||||
m_specialResources["swarm"] = true;
|
m_specialResources["swarm"] = true;
|
||||||
|
|
||||||
|
// these are the resources which shouldn't expire (true when numbering is expected)
|
||||||
|
m_noExpireResources["avatar"] = false;
|
||||||
|
m_noExpireResources["profile"] = false;
|
||||||
|
m_noExpireResources["following"] = true;
|
||||||
|
|
||||||
|
|
||||||
threadGroup.create_thread(boost::bind(&ThreadWaitExtIP));
|
threadGroup.create_thread(boost::bind(&ThreadWaitExtIP));
|
||||||
threadGroup.create_thread(boost::bind(&ThreadMaintainDHTNodes));
|
threadGroup.create_thread(boost::bind(&ThreadMaintainDHTNodes));
|
||||||
@ -713,6 +719,15 @@ bool validatePostNumberForUser(std::string const &username, int k)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool usernameExists(std::string const &username)
|
||||||
|
{
|
||||||
|
CTransaction txOut;
|
||||||
|
uint256 hashBlock;
|
||||||
|
uint256 userhash = SerializeHash(username);
|
||||||
|
return GetTransaction(userhash, txOut, hashBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
"userpost" :
|
"userpost" :
|
||||||
{
|
{
|
||||||
@ -808,6 +823,43 @@ int getBestHeight()
|
|||||||
return nBestHeight;
|
return nBestHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool shouldDhtResourceExpire(std::string resource, bool multi, int height)
|
||||||
|
{
|
||||||
|
if ((height + BLOCK_AGE_TO_EXPIRE_DHT_ENTRY) < getBestHeight() ) {
|
||||||
|
if( multi ) {
|
||||||
|
printf("shouldDhtResourceExpire: expiring resource multi '%s'\n", resource.c_str());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string resourceBasic;
|
||||||
|
for(size_t i = 0; i < resource.size() && isalpha(resource.at(i)); i++) {
|
||||||
|
resourceBasic.push_back(resource.at(i));
|
||||||
|
}
|
||||||
|
int resourceNumber = -1;
|
||||||
|
|
||||||
|
if( resource.length() > resourceBasic.length() ) {
|
||||||
|
resourceNumber = atoi( resource.c_str() + resourceBasic.length() );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !m_noExpireResources.count(resourceBasic) ) {
|
||||||
|
// unknown resource. expire it.
|
||||||
|
printf("shouldDhtResourceExpire: expiring non-special resource '%s'\n", resource.c_str());
|
||||||
|
} else {
|
||||||
|
if( !m_noExpireResources[resourceBasic] && resourceNumber >= 0 ) {
|
||||||
|
// this resource admits no number. expire it!
|
||||||
|
printf("shouldDhtResourceExpire: expiring resource with unexpected numbering '%s'\n", resource.c_str());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if( m_noExpireResources[resourceBasic] && resourceNumber > 200 ) {
|
||||||
|
// try keeping a sane number here, otherwise expire it!
|
||||||
|
printf("shouldDhtResourceExpire: expiring resource with numbering too big '%s'\n", resource.c_str());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void receivedSpamMessage(std::string const &message, std::string const &user)
|
void receivedSpamMessage(std::string const &message, std::string const &user)
|
||||||
{
|
{
|
||||||
LOCK(cs_twister);
|
LOCK(cs_twister);
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#define USERPOST_FLAG_RT 0x01
|
#define USERPOST_FLAG_RT 0x01
|
||||||
#define USERPOST_FLAG_DM 0x02
|
#define USERPOST_FLAG_DM 0x02
|
||||||
|
|
||||||
|
#define BLOCK_AGE_TO_EXPIRE_DHT_ENTRY 2000
|
||||||
|
|
||||||
class twister
|
class twister
|
||||||
{
|
{
|
||||||
@ -26,9 +27,11 @@ bool verifySignature(std::string const &strMessage, std::string const &strUserna
|
|||||||
|
|
||||||
bool acceptSignedPost(char const *data, int data_size, std::string username, int seq, std::string &errmsg, boost::uint32_t *flags);
|
bool acceptSignedPost(char const *data, int data_size, std::string username, int seq, std::string &errmsg, boost::uint32_t *flags);
|
||||||
bool validatePostNumberForUser(std::string const &username, int k);
|
bool validatePostNumberForUser(std::string const &username, int k);
|
||||||
|
bool usernameExists(std::string const &username);
|
||||||
|
|
||||||
void receivedSpamMessage(std::string const &message, std::string const &user);
|
void receivedSpamMessage(std::string const &message, std::string const &user);
|
||||||
|
|
||||||
int getBestHeight();
|
int getBestHeight();
|
||||||
|
bool shouldDhtResourceExpire(std::string resource, bool multi, int height);
|
||||||
|
|
||||||
#endif // TWISTER_H
|
#endif // TWISTER_H
|
||||||
|
Loading…
Reference in New Issue
Block a user