From db24ccc635eadf19ad4599ef761ac5c5249cb81c Mon Sep 17 00:00:00 2001 From: Shift Date: Sat, 15 Mar 2014 15:22:57 +0400 Subject: [PATCH 01/12] add md --- TODO => TODO.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename TODO => TODO.md (100%) diff --git a/TODO b/TODO.md similarity index 100% rename from TODO rename to TODO.md From be33ed3c272040e769d7e4b6c48b5ccdd0f45ece Mon Sep 17 00:00:00 2001 From: iShift Date: Sat, 15 Mar 2014 14:38:26 +0300 Subject: [PATCH 02/12] Update TODO.md --- TODO.md | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/TODO.md b/TODO.md index 637dada8..775e4cf1 100644 --- a/TODO.md +++ b/TODO.md @@ -1,28 +1,38 @@ +Security +================ + - Encrypt user_data (which contains all DMs) - Test wallet encrypt to see if it still works from original bitcoin implementation and what are the implications to our code. -- Rescan directmessages after importing a privatekey (importprivkey) +- Move all crypto to javascript, store only encrypted version of the privatekey (which would be +decrypted only in browser memory). getposts may obtain all DMs encrypted to browser, another +newpostmsg needs to be provided to receive posts with signature field added. -- Check libtorrent's limitation on the number of pieces (max_pieces in piece_picker.hpp = 1<<19) -Since post number is constrained by max of 288 posts per day in average, that means we have 5 years -to think about it (for the really heavy users). +Features +================ - Besides increasing the maximum number of pieces, a more pressing issue to save bandwidth and torrent download time would be to define the first piece to download/store locally. People don't need to maintain the entire post history for everybody they follow, they could just keep the last ones. This has to be implemented. -- Move all crypto to javascript, store only encrypted version of the privatekey (which would be -decrypted only in browser memory). getposts may obtain all DMs encrypted to browser, another -newpostmsg needs to be provided to receive posts with signature field added. - - Store a dht resource "publickey" containing not only the public key itself but also information needed to validate it by a lightweight client. That includes: block hash, block height and partial merkle tree inside that block. This resource propagation cannot be sent right after user registration for obvious reasons (no block yet, other nodes wouldn't accept the signed dht put). +- Share images + +Kill bugs +================ +- Rescan directmessages after importing a privatekey (importprivkey) + +- Check libtorrent's limitation on the number of pieces (max_pieces in piece_picker.hpp = 1<<19) +Since post number is constrained by max of 288 posts per day in average, that means we have 5 years +to think about it (for the really heavy users). + - Implement the mention forwarding mechanism discussed in the paper so user don't need to do polling and can also be sure to receive all mentions. @@ -39,8 +49,6 @@ of his own torrent) - Estimate number of online followers by quering the "tracker" resource (implement a value within this resource to report the number of torrent peers) -- Define and enforce html directory to serve from. Do installation scripts. - - Don't accept dht "post"+k if k violates the validatePostNumberForUser() rule. - Implement -secdatadir= parameter to store sensitive data (wallet, dm) in a separated dir. From 7b2b70dcdf961652c91e82f4f4008205f8f198fb Mon Sep 17 00:00:00 2001 From: "Kirill A. Korinskiy" Date: Sat, 22 Mar 2014 14:36:30 +0200 Subject: [PATCH 03/12] Make build on osx easier --- Makefile.am | 5 ++--- configure.ac | 23 +++++++++++++--------- doc/build-osx.md | 33 +++----------------------------- m4/ax_berkeley_db_cxx.m4 | 41 ++++++++++++++++++++++++++++++++++++++-- 4 files changed, 58 insertions(+), 44 deletions(-) diff --git a/Makefile.am b/Makefile.am index 7c5c9d19..0a12adf4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -166,7 +166,7 @@ endif twisterd_SOURCES = $(LIBTORRENT_SOURCES) $(BITCOIN_TWISTER_SOURCES) -twisterd_LDFLAGS = +twisterd_LDFLAGS = @OPENSSL_LDFLAGS@ @DB_CXX_LDFLAGS@ twisterd_DEPENDENCIES = $(LEVELDB_LIB) @@ -178,7 +178,6 @@ AM_CPPFLAGS = -ftemplate-depth-100 -DBOOST_SPIRIT_THREADSAFE -D_FILE_OFFSET_BITS -I$(top_srcdir)/libtorrent/include \ -I$(top_srcdir)/src \ -I$(top_srcdir)/src/leveldb/include -I$(top_srcdir)/src/leveldb/helpers \ - @DEBUGFLAGS@ @OPENSSL_INCLUDES@ + @DEBUGFLAGS@ @OPENSSL_INCLUDES@ @DB_CXX_CPPFLAGS@ AM_LDFLAGS = @OPENSSL_LDFLAGS@ - diff --git a/configure.ac b/configure.ac index 59d956b4..9319a5e4 100644 --- a/configure.ac +++ b/configure.ac @@ -83,26 +83,22 @@ AC_CACHE_CHECK([for __attribute__((visibility("hidden")))], AS_ECHO AS_ECHO "Checking for boost libraries:" -AX_BOOST_BASE([1.44]) +AX_BOOST_BASE([1.44], [], + [AC_MSG_ERROR(Boost library not found. Try using --with-boost=)]) AX_BOOST_SYSTEM() -AS_IF([test -z "$BOOST_SYSTEM_LIB"], - [AC_MSG_ERROR(Boost.System library not found. Try using --with-boost-libdir=)]) AX_BOOST_FILESYSTEM() AX_BOOST_PROGRAM_OPTIONS() AX_BOOST_THREAD() AX_BOOST_CHRONO() -CPPFLAGS="$BOOST_CPPFLAGS $CPPFLAGS" -LDFLAGS="$BOOST_LDFLAGS $LDFLAGS $BOOST_CHRONO_LIB" - - ############################################################################### # Checking for Berkeley DB C++ ############################################################################### AC_LANG([C++]) -AX_BERKELEY_DB_CXX(4.8) +AX_BERKELEY_DB_CXX(4.8, [], + [AC_MSG_ERROR(Berkeley DB C++ library not found. Try using --with-libdb=)]) ############################################################################### # Checking for functions and other stuffs @@ -772,6 +768,15 @@ Boost libraries: CPPFlags: ${BOOST_CPPFLAGS} LDFlags: ${BOOST_LDFLAGS} boost.system: ${BOOST_SYSTEM_LIB} + boost.filesystem: ${BOOST_FILESYSTEM_LIB} + boost.program_opts: ${BOOST_PROGRAM_OPTIONS_LIB} + boost.thread: ${BOOST_THREAD_LIB} + +Berkeley DB C++ library: + header: ${DB_CXX_HEADER} + libraries: ${DB_CXX_LIBS} + LDFlags: ${DB_CXX_LDFLAGS} + CPPFlags: ${DB_CXX_CPPFLAGS} END AS_IF([test "x$ARG_ENABLE_PYTHON_BINDING" = "xyes"], [ @@ -830,7 +835,7 @@ OpenSSL library: OpenSSL Libs: ${OPENSSL_LIBS} OpenSSL LDFlags: ${OPENSSL_LDFLAGS} OpenSSL Includes: ${OPENSSL_INCLUDES} -END +END ]) cat config.report diff --git a/doc/build-osx.md b/doc/build-osx.md index 8add73bb..e59b5d75 100644 --- a/doc/build-osx.md +++ b/doc/build-osx.md @@ -43,18 +43,6 @@ Instructions: HomeBrew brew install boost miniupnpc openssl berkeley-db4 autoconf automake libtool -Note: After you have installed the dependencies, you should check that the Brew-installed -version of OpenSSL is the one available for compilation. You can check this by typing - - openssl version - -into Terminal. You should see OpenSSL 1.0.1e 11 Feb 2013. - -If that's not the case, you *could* `brew link --force openssl` but it's a bad idea. -Instead, it's enough to make sure the right openssl binary is on your $PATH: - - export PATH=/usr/local/opt/openssl/bin:$PATH - ### Building `twisterd` 1. Clone the github tree to get the source code and go into the directory. @@ -63,29 +51,14 @@ Instead, it's enough to make sure the right openssl binary is on your $PATH: git clone https://github.com/miguelfreitas/twister-core.git cd twister-core -2. Set system variables to match your environment. THIS IS IMPORTANT! - - - export OPENSSL_INCLUDE_PATH=/usr/local/opt/openssl/include - export OPENSSL_LIB_PATH=/usr/local/opt/openssl/lib - export BDB_INCLUDE_PATH=/usr/local/opt/berkeley-db4/include - export BDB_LIB_PATH=/usr/local/opt/berkeley-db4/lib - export BOOST_INCLUDE_PATH=/usr/local/opt/boost/include - export BOOST_LIB_PATH=/usr/local/opt/boost/lib - export BOOST_LIB_SUFFIX=-mt - export LDFLAGS="-L$OPENSSL_LIB_PATH -L$BDB_LIB_PATH -L$BOOST_LIB_PATH" - export CPPFLAGS="-I$OPENSSL_INCLUDE_PATH -I$BDB_INCLUDE_PATH -I$BOOST_INCLUDE_PATH" - export PATH=${BDB_INCLUDE_PATH}:${PATH} - -3. Build twister using autotool - +2. Build twister using autotool ./autotool.sh - ./configure --enable-logging + ./configure --enable-logging --with-openssl=/usr/local/opt/openssl --with-libdb=/usr/local/opt/berkeley-db4 make (If you have multi core CPU, use "make -j N" where N = number of your cores) -4. If things go south, before trying again, make sure you clean it up: +3. If things go south, before trying again, make sure you clean it up: make clean diff --git a/m4/ax_berkeley_db_cxx.m4 b/m4/ax_berkeley_db_cxx.m4 index f35e5e89..42b47223 100644 --- a/m4/ax_berkeley_db_cxx.m4 +++ b/m4/ax_berkeley_db_cxx.m4 @@ -21,28 +21,52 @@ # in your C/C++ code. DB_CXX_LIBS is set to linker flags needed to link # against the library (e.g. -ldb3.1_cxx) and AC_SUBST is called on it. # +# when specified user-selected spot (via --with-libdb) also sets +# +# DB_CXX_CPPFLAGS to the include directives required +# DB_CXX_LDFLAGS to the -L flags required +# # LICENSE # # Copyright (c) 2008 Vaclav Slavik # Copyright (c) 2011 Stephan Suerken +# Copyright (c) 2014 Kirill A. Korinskiy # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 3 +#serial 4 AC_DEFUN([AX_BERKELEY_DB_CXX], [ AC_LANG_ASSERT(C++) old_LIBS="$LIBS" + old_LDFLAGS="$LDFLAGS" + old_CPPFLAGS="$CPPFLAGS" + + libdbdir="" + AC_ARG_WITH(libdb, + AS_HELP_STRING([--with-libdb=DIR], + [root of the Berkeley DB directory]), + [ + case "$withval" in + "" | y | ye | yes | n | no) + AC_MSG_ERROR([Invalid --with-libdb value]) + ;; + *) libdbdir="$withval" + ;; + esac + ], []) minversion=ifelse([$1], ,,$1) DB_CXX_HEADER="" DB_CXX_LIBS="" + DB_CXX_LDFLAGS="" + DB_CXX_CPPFLAGS="" if test -z $minversion ; then minvermajor=0 @@ -59,13 +83,20 @@ AC_DEFUN([AX_BERKELEY_DB_CXX], AC_MSG_CHECKING([for Berkeley DB (C++) >= $minversion]) fi + if test x$libdbdir != x""; then + DB_CXX_CPPFLAGS="-I${libdbdir}/include" + DB_CXX_LDFLAGS="-L${libdbdir}/lib" + LDFLAGS="$DB_CXX_LDFLAGS $old_LDFLAGS" + CPPFLAGS="$DB_CXX_CPPFLAGS $old_CPPFLAGS" + fi + for version in "" 5.0 4.9 4.8 4.7 4.6 4.5 4.4 4.3 4.2 4.1 4.0 3.6 3.5 3.4 3.3 3.2 3.1 ; do if test -z $version ; then db_cxx_lib="-ldb_cxx -ldb" try_headers="db_cxx.h" else - db_cxx_lib="-ldb_cxx-$version -ldb-$version" + db_cxx_lib="$libdbdir -ldb_cxx-$version -ldb-$version" try_headers="db$version/db_cxx.h db`echo $version | sed -e 's,\..*,,g'`/db_cxx.h" fi @@ -102,13 +133,19 @@ AC_DEFUN([AX_BERKELEY_DB_CXX], done LIBS="$old_LIBS" + LDFLAGS="$old_LDFLAGS" + CPPFLAGS="$old_CPPFLAGS" if test -z $DB_CXX_HEADER ; then AC_MSG_RESULT([not found]) + DB_CXX_LDFLAGS="" + DB_CXX_CPPFLAGS="" ifelse([$3], , :, [$3]) else AC_DEFINE_UNQUOTED(DB_CXX_HEADER, ["$DB_CXX_HEADER"], ["Berkeley DB C++ Header File"]) AC_SUBST(DB_CXX_LIBS) + AC_SUBST(DB_CXX_LDFLAGS) + AC_SUBST(DB_CXX_CPPFLAGS) ifelse([$2], , :, [$2]) fi ]) From a1d228f9148cc60d334e43ee99e969a9e1ae5489 Mon Sep 17 00:00:00 2001 From: Michael Ford Date: Sun, 23 Mar 2014 10:44:17 +0800 Subject: [PATCH 04/12] Fix typo in readme.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 66341d18..83a45072 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ not interoperate with existing networks (on purpose). Compiling ---------------- -You can build you own twister with this docs: +You can build twister using these docs: [Ubuntu/Debian](https://github.com/miguelfreitas/twister-core/blob/master/doc/building-on-ubuntu-debian.md) From 4509ff7e3fec6bc0b5811ca3e30c0192f7338817 Mon Sep 17 00:00:00 2001 From: Miguel Freitas Date: Tue, 1 Apr 2014 22:23:24 -0300 Subject: [PATCH 05/12] fix crash reported by ankostis --- src/twister.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/twister.cpp b/src/twister.cpp index 7fd95099..d8b7a252 100644 --- a/src/twister.cpp +++ b/src/twister.cpp @@ -1690,7 +1690,7 @@ Value getposts(const Array& params, bool fHelp) Value getdirectmsgs(const Array& params, bool fHelp) { - if (fHelp || params.size() < 2 || params.size() > 3) + if (fHelp || params.size() != 3) throw runtime_error( "getdirectmsgs '[{\"username\":username,\"max_id\":max_id,\"since_id\":since_id},...]'\n" "get (locally stored) decrypted direct messages sent/received by user \n" From b6e20fcea20350d0e0f751713933d97b71f6818f Mon Sep 17 00:00:00 2001 From: Kamil Domanski Date: Sun, 6 Apr 2014 00:22:54 +0200 Subject: [PATCH 06/12] fixed linking against boost chrono --- Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 0a12adf4..17dd8235 100644 --- a/Makefile.am +++ b/Makefile.am @@ -171,7 +171,7 @@ twisterd_LDFLAGS = @OPENSSL_LDFLAGS@ @DB_CXX_LDFLAGS@ twisterd_DEPENDENCIES = $(LEVELDB_LIB) twisterd_LDADD = $(LEVELDB_LIB) $(UPNP_LIB) \ - @BOOST_SYSTEM_LIB@ @BOOST_FILESYSTEM_LIB@ @BOOST_PROGRAM_OPTIONS_LIB@ @BOOST_THREAD_LIB@ \ + @BOOST_SYSTEM_LIB@ @BOOST_FILESYSTEM_LIB@ @BOOST_PROGRAM_OPTIONS_LIB@ @BOOST_THREAD_LIB@ @BOOST_CHRONO_LIB@ \ @DB_CXX_LIBS@ @OPENSSL_LIBS@ AM_CPPFLAGS = -ftemplate-depth-100 -DBOOST_SPIRIT_THREADSAFE -D_FILE_OFFSET_BITS=64 \ From ad83ba061c0b459e386b007633c12e757ed3c1bf Mon Sep 17 00:00:00 2001 From: Miguel Freitas Date: Sat, 5 Apr 2014 23:59:44 -0300 Subject: [PATCH 07/12] store dhtput data locally so it will be refreshed like the other dht entries we maintain. should help with missing DHT entries (issue #165), although i think #165 would benefit of a more agressive (faster) retrying of remote stores. --- .../include/libtorrent/kademlia/node.hpp | 6 +- libtorrent/src/kademlia/node.cpp | 146 ++++++++++-------- src/clientversion.h | 2 +- 3 files changed, 87 insertions(+), 67 deletions(-) diff --git a/libtorrent/include/libtorrent/kademlia/node.hpp b/libtorrent/include/libtorrent/kademlia/node.hpp index 6ca43c7d..a229190b 100644 --- a/libtorrent/include/libtorrent/kademlia/node.hpp +++ b/libtorrent/include/libtorrent/kademlia/node.hpp @@ -119,8 +119,10 @@ struct dht_storage_item { // FIXME: optimize so bdecode is not needed all the time dht_storage_item() : p(), sig_p(), sig_user() {} - dht_storage_item(std::string &_p, lazy_entry const *_sig_p, lazy_entry const *_sig_user) + dht_storage_item(std::string const &_p, lazy_entry const *_sig_p, lazy_entry const *_sig_user) : p(_p), sig_p(_sig_p->string_value()), sig_user(_sig_user->string_value()) {} + dht_storage_item(std::string const &_p, std::string const &_sig_p, std::string const &_sig_user) + : p(_p), sig_p(_sig_p), sig_user(_sig_user) {} std::string p; std::string sig_p; std::string sig_user; @@ -282,6 +284,8 @@ private: std::set m_running_requests; void incoming_request(msg const& h, entry& e); + void store_dht_item(dht_storage_item &item, big_number const &target, + bool multi, int seq, int height, std::pair &bufv); node_id m_id; diff --git a/libtorrent/src/kademlia/node.cpp b/libtorrent/src/kademlia/node.cpp index 9511fb65..9f5ff009 100644 --- a/libtorrent/src/kademlia/node.cpp +++ b/libtorrent/src/kademlia/node.cpp @@ -444,11 +444,13 @@ void node_impl::putData(std::string const &username, std::string const &resource if (seq >= 0 && !multi) p["seq"] = seq; p["v"] = value; p["time"] = timeutc; - p["height"] = getBestHeight()-1; // be conservative + int height = getBestHeight()-1; // be conservative + p["height"] = height; std::vector pbuf; bencode(std::back_inserter(pbuf), p); - std::string sig_p = createSignature(std::string(pbuf.data(),pbuf.size()), sig_user); + std::string str_p = std::string(pbuf.data(),pbuf.size()); + std::string sig_p = createSignature(str_p, sig_user); if( !sig_p.size() ) { printf("putData: createSignature error (this should have been caught earlier)\n"); return; @@ -459,7 +461,16 @@ void node_impl::putData(std::string const &username, std::string const &resource boost::intrusive_ptr ta(new dht_get(*this, username, resource, multi, boost::bind(&nop), boost::bind(&putData_fun, _1, boost::ref(*this), p, sig_p, sig_user), true)); - ta->start(); + + // store it locally so it will be automatically refreshed with the rest + dht_storage_item item(str_p, sig_p, sig_user); + std::vector vbuf; + bencode(std::back_inserter(vbuf), value); + std::pair bufv = std::make_pair(vbuf.data(), vbuf.size()); + store_dht_item(item, ta->target(), multi, seq, height, bufv); + + // now send it to the network (start transversal algorithm) + ta->start(); } void node_impl::getData(std::string const &username, std::string const &resource, bool multi, @@ -1327,71 +1338,13 @@ void node_impl::incoming_request(msg const& m, entry& e) // attack this resource by storing value into non-final nodes. if( !possiblyNeighbor ) { printf("putData with possiblyNeighbor=false, ignoring request.\n"); + return; } dht_storage_item item(str_p, msg_keys[mk_sig_p], msg_keys[mk_sig_user]); - dht_storage_table_t::iterator i = m_storage_table.find(target); - if (i == m_storage_table.end()) { - // make sure we don't add too many items - if (int(m_storage_table.size()) >= m_settings.max_dht_items) - { - // FIXME: erase one? preferably a multi - } - - dht_storage_list_t to_add; - to_add.push_back(item); - - boost::tie(i, boost::tuples::ignore) = m_storage_table.insert( - std::make_pair(target, to_add)); - } else { - dht_storage_list_t & lsto = i->second; - - dht_storage_list_t::reverse_iterator j, rend(lsto.rend()); - dht_storage_list_t::iterator insert_pos = lsto.end(); - for( j = lsto.rbegin(); j != rend; ++j) { - dht_storage_item &olditem = *j; - - lazy_entry p; - int pos; - error_code err; - // FIXME: optimize to avoid bdecode (store seq separated, etc) - int ret = lazy_bdecode(olditem.p.data(), olditem.p.data() + olditem.p.size(), p, err, &pos, 10, 500); - - if( !multi ) { - if( msg_keys[mk_seq]->int_value() > p.dict_find_int("seq")->int_value() ) { - olditem = item; - } else { - // don't report this error (because of refresh storage) - //incoming_error(e, "old sequence number"); - return; - } - } else { - std::pair bufv = msg_keys[mk_v]->data_section(); - - // compare contents before adding to the list - std::pair bufoldv = p.dict_find("v")->data_section(); - if( bufv.second == bufoldv.second && !memcmp(bufv.first, bufoldv.first,bufv.second) ) { - // break so it wont be inserted - break; - } - - // if new entry is newer than existing one, it will be inserted before - if( msg_keys[mk_height]->int_value() >= p.dict_find_int_value("height") ) { - insert_pos = j.base(); - insert_pos--; - } - } - } - if(multi && j == rend) { - // new entry - lsto.insert(insert_pos, item); - } - - if(lsto.size() > m_settings.max_entries_per_multi) { - lsto.resize(m_settings.max_entries_per_multi); - } - - } + std::pair bufv = msg_keys[mk_v]->data_section(); + store_dht_item(item, target, multi, !multi ? msg_keys[mk_seq]->int_value() : 0, + msg_keys[mk_height]->int_value(), bufv); } else if (strcmp(query, "getData") == 0) { @@ -1517,6 +1470,69 @@ void node_impl::incoming_request(msg const& m, entry& e) } } +void node_impl::store_dht_item(dht_storage_item &item, const big_number &target, + bool multi, int seq, int height, std::pair &bufv) +{ + dht_storage_table_t::iterator i = m_storage_table.find(target); + if (i == m_storage_table.end()) { + // make sure we don't add too many items + if (int(m_storage_table.size()) >= m_settings.max_dht_items) + { + // FIXME: erase one? preferably a multi + } + + dht_storage_list_t to_add; + to_add.push_back(item); + + boost::tie(i, boost::tuples::ignore) = m_storage_table.insert( + std::make_pair(target, to_add)); + } else { + dht_storage_list_t & lsto = i->second; + + dht_storage_list_t::reverse_iterator j, rend(lsto.rend()); + dht_storage_list_t::iterator insert_pos = lsto.end(); + for( j = lsto.rbegin(); j != rend; ++j) { + dht_storage_item &olditem = *j; + + lazy_entry p; + int pos; + error_code err; + // FIXME: optimize to avoid bdecode (store seq separated, etc) + int ret = lazy_bdecode(olditem.p.data(), olditem.p.data() + olditem.p.size(), p, err, &pos, 10, 500); + + if( !multi ) { + if( seq > p.dict_find_int("seq")->int_value() ) { + olditem = item; + } else { + // don't report this error (because of refresh storage) + //incoming_error(e, "old sequence number"); + return; + } + } else { + // compare contents before adding to the list + std::pair bufoldv = p.dict_find("v")->data_section(); + if( bufv.second == bufoldv.second && !memcmp(bufv.first, bufoldv.first,bufv.second) ) { + // break so it wont be inserted + break; + } + + // if new entry is newer than existing one, it will be inserted before + if( height >= p.dict_find_int_value("height") ) { + insert_pos = j.base(); + insert_pos--; + } + } + } + if(multi && j == rend) { + // new entry + lsto.insert(insert_pos, item); + } + + if(lsto.size() > m_settings.max_entries_per_multi) { + lsto.resize(m_settings.max_entries_per_multi); + } + } +} } } // namespace libtorrent::dht diff --git a/src/clientversion.h b/src/clientversion.h index 33f62e91..d2292c0d 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -8,7 +8,7 @@ // These need to be macros, as version.cpp's and bitcoin-qt.rc's voodoo requires it #define CLIENT_VERSION_MAJOR 0 #define CLIENT_VERSION_MINOR 9 -#define CLIENT_VERSION_REVISION 19 +#define CLIENT_VERSION_REVISION 20 #define CLIENT_VERSION_BUILD 0 // Set to true for release, false for prerelease or test build From 03d037c1974d8798e6844bfba48b34443e7edc4e Mon Sep 17 00:00:00 2001 From: Miguel Freitas Date: Sun, 6 Apr 2014 17:00:42 -0300 Subject: [PATCH 08/12] truncate file when saving settings --- src/twister_utils.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/twister_utils.cpp b/src/twister_utils.cpp index 5abe5fc0..5260510b 100644 --- a/src/twister_utils.cpp +++ b/src/twister_utils.cpp @@ -71,6 +71,7 @@ int save_file(std::string const& filename, std::vector& v) libtorrent::error_code ec; if (!f.open(filename, file::write_only, ec)) return -1; if (ec) return -1; + f.set_size(0, ec); file::iovec_t b = {&v[0], v.size()}; size_type written = f.writev(0, &b, 1, ec); if (written != int(v.size())) return -3; From 2be53fe95a4ba6cbbaf3c5b44ff8597c956faa63 Mon Sep 17 00:00:00 2001 From: Miguel Freitas Date: Sun, 6 Apr 2014 17:01:39 -0300 Subject: [PATCH 09/12] keep track of dht_storage_item which have been locally added. for now this is used to make sure all kinds of resources (including rts and replies) will have a forced refresh for at least two days. --- libtorrent/include/libtorrent/kademlia/node.hpp | 8 +++++--- libtorrent/src/kademlia/node.cpp | 9 ++++++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/libtorrent/include/libtorrent/kademlia/node.hpp b/libtorrent/include/libtorrent/kademlia/node.hpp index a229190b..5906b1ca 100644 --- a/libtorrent/include/libtorrent/kademlia/node.hpp +++ b/libtorrent/include/libtorrent/kademlia/node.hpp @@ -118,14 +118,16 @@ struct torrent_entry struct dht_storage_item { // FIXME: optimize so bdecode is not needed all the time - dht_storage_item() : p(), sig_p(), sig_user() {} + dht_storage_item() : p(), sig_p(), sig_user(), local_add_time(0) {} dht_storage_item(std::string const &_p, lazy_entry const *_sig_p, lazy_entry const *_sig_user) - : p(_p), sig_p(_sig_p->string_value()), sig_user(_sig_user->string_value()) {} + : p(_p), sig_p(_sig_p->string_value()), sig_user(_sig_user->string_value()), + local_add_time(0) {} dht_storage_item(std::string const &_p, std::string const &_sig_p, std::string const &_sig_user) - : p(_p), sig_p(_sig_p), sig_user(_sig_user) {} + : p(_p), sig_p(_sig_p), sig_user(_sig_user), local_add_time(0) {} std::string p; std::string sig_p; std::string sig_user; + boost::int64_t local_add_time; // the last time we heard about this //ptime last_seen; }; diff --git a/libtorrent/src/kademlia/node.cpp b/libtorrent/src/kademlia/node.cpp index 9f5ff009..1f92bb8c 100644 --- a/libtorrent/src/kademlia/node.cpp +++ b/libtorrent/src/kademlia/node.cpp @@ -464,6 +464,7 @@ void node_impl::putData(std::string const &username, std::string const &resource // store it locally so it will be automatically refreshed with the rest dht_storage_item item(str_p, sig_p, sig_user); + item.local_add_time = time(NULL); std::vector vbuf; bencode(std::back_inserter(vbuf), value); std::pair bufv = std::make_pair(vbuf.data(), vbuf.size()); @@ -566,7 +567,8 @@ bool node_impl::refresh_storage() { bool multi = (target->dict_find_string_value("t") == "m"); // refresh only signed single posts and mentions - if( !multi || (multi && resource == "mention") ) { + if( !multi || (multi && resource == "mention") || + (multi && item.local_add_time && item.local_add_time + 60*60*24*2 > time(NULL)) ) { num_refreshable++; if( refresh_next_item ) { @@ -689,6 +691,8 @@ bool node_impl::save_storage(entry &save) const { entry_item["p"] = item.p; entry_item["sig_p"] = item.sig_p; entry_item["sig_user"] = item.sig_user; + if( item.local_add_time ) + entry_item["local_add_time"] = item.local_add_time; save_list.list().push_back(entry_item); } } @@ -720,6 +724,9 @@ void node_impl::load_storage(entry const* e) { item.p = j->find_key("p")->string(); item.sig_p = j->find_key("sig_p")->string(); item.sig_user = j->find_key("sig_user")->string(); + entry const *local_add_time( j->find_key("local_add_time") ); + if(local_add_time) + item.local_add_time = local_add_time->integer(); // just for printf for now bool expired = has_expired(item); From 03b13711908524f121047f0aef10c8685e4f9e1b Mon Sep 17 00:00:00 2001 From: Miguel Freitas Date: Sun, 6 Apr 2014 20:25:49 -0300 Subject: [PATCH 10/12] use DB_CXX_HEADER. fix #114 --- src/db.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/db.h b/src/db.h index b3f269f3..d550c80d 100644 --- a/src/db.h +++ b/src/db.h @@ -13,7 +13,11 @@ #include #include -#include +#ifdef DB_CXX_HEADER + #include DB_CXX_HEADER +#else + #include +#endif class CAddrMan; class CBlockLocator; From b1ace5cc691dba47f195a012c3d3eaa823682ba4 Mon Sep 17 00:00:00 2001 From: digital dreamer Date: Mon, 7 Apr 2014 12:45:51 +0200 Subject: [PATCH 11/12] add public server mode --- src/bitcoinrpc.cpp | 140 +++++++++++++++++++++++---------------------- src/bitcoinrpc.h | 2 + src/rpcwallet.cpp | 6 ++ 3 files changed, 81 insertions(+), 67 deletions(-) diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index e709321c..66c103b0 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -195,74 +195,74 @@ Value stop(const Array& params, bool fHelp) static const CRPCCommand vRPCCommands[] = -{ // name actor (function) okSafeMode threadSafe - // ------------------------ ----------------------- ---------- ---------- - { "help", &help, true, true }, - { "stop", &stop, true, true }, - { "getblockcount", &getblockcount, true, false }, - { "getbestblockhash", &getbestblockhash, true, false }, - { "getconnectioncount", &getconnectioncount, true, false }, - { "getpeerinfo", &getpeerinfo, true, false }, - { "addnode", &addnode, true, true }, - { "adddnsseed", &adddnsseed, true, true }, - { "getaddednodeinfo", &getaddednodeinfo, true, true }, - { "getdifficulty", &getdifficulty, true, false }, - { "getgenerate", &getgenerate, true, false }, - { "setgenerate", &setgenerate, true, false }, - { "gethashespersec", &gethashespersec, true, false }, - { "getinfo", &getinfo, true, true }, - { "getmininginfo", &getmininginfo, true, false }, - { "createwalletuser", &createwalletuser, true, false }, - { "listwalletusers", &listwalletusers, true, false }, - { "backupwallet", &backupwallet, true, false }, - { "walletpassphrase", &walletpassphrase, true, false }, - { "walletpassphrasechange", &walletpassphrasechange, false, false }, - { "walletlock", &walletlock, true, false }, - { "encryptwallet", &encryptwallet, false, false }, - { "getrawmempool", &getrawmempool, true, false }, - { "getblock", &getblock, false, false }, - { "getblockhash", &getblockhash, false, false }, - { "gettransaction", &gettransaction, false, false }, - { "listtransactions", &listtransactions, false, false }, - { "signmessage", &signmessage, false, false }, - { "verifymessage", &verifymessage, false, false }, - { "getwork", &getwork, true, false }, - { "getblocktemplate", &getblocktemplate, true, false }, - { "submitblock", &submitblock, false, false }, - { "listsinceblock", &listsinceblock, false, false }, - { "dumpprivkey", &dumpprivkey, true, false }, - { "dumppubkey", &dumppubkey, false, false }, - { "dumpwallet", &dumpwallet, true, false }, - { "importprivkey", &importprivkey, false, false }, - { "importwallet", &importwallet, false, false }, - { "getrawtransaction", &getrawtransaction, false, false }, - { "createrawtransaction", &createrawtransaction, false, false }, - { "decoderawtransaction", &decoderawtransaction, false, false }, - { "sendrawtransaction", &sendrawtransaction, false, false }, - { "sendnewusertransaction", &sendnewusertransaction, false, false }, - { "verifychain", &verifychain, true, false }, - { "getlastsoftcheckpoint", &getlastsoftcheckpoint, true, false }, +{ // name actor (function) okSafeMode threadSafe allowOnPublicServer + // ------------------------ ----------------------- ---------- ---------- ------------------- + { "help", &help, true, true, true }, + { "stop", &stop, true, true, false }, + { "getblockcount", &getblockcount, true, false, false }, + { "getbestblockhash", &getbestblockhash, true, false, true }, + { "getconnectioncount", &getconnectioncount, true, false, false }, + { "getpeerinfo", &getpeerinfo, true, false, false }, + { "addnode", &addnode, true, true, false }, + { "adddnsseed", &adddnsseed, true, true, false }, + { "getaddednodeinfo", &getaddednodeinfo, true, true, false }, + { "getdifficulty", &getdifficulty, true, false, false }, + { "getgenerate", &getgenerate, true, false, false }, + { "setgenerate", &setgenerate, true, false, false }, + { "gethashespersec", &gethashespersec, true, false, false }, + { "getinfo", &getinfo, true, true, true }, + { "getmininginfo", &getmininginfo, true, false, false }, + { "createwalletuser", &createwalletuser, true, false, false }, + { "listwalletusers", &listwalletusers, true, false, true }, + { "backupwallet", &backupwallet, true, false, false }, + { "walletpassphrase", &walletpassphrase, true, false, false }, + { "walletpassphrasechange", &walletpassphrasechange, false, false, false }, + { "walletlock", &walletlock, true, false, false }, + { "encryptwallet", &encryptwallet, false, false, false }, + { "getrawmempool", &getrawmempool, true, false, false }, + { "getblock", &getblock, false, false, true }, + { "getblockhash", &getblockhash, false, false, false }, + { "gettransaction", &gettransaction, false, false, false }, + { "listtransactions", &listtransactions, false, false, false }, + { "signmessage", &signmessage, false, false, false }, + { "verifymessage", &verifymessage, false, false, false }, + { "getwork", &getwork, true, false, false }, + { "getblocktemplate", &getblocktemplate, true, false, false }, + { "submitblock", &submitblock, false, false, false }, + { "listsinceblock", &listsinceblock, false, false, false }, + { "dumpprivkey", &dumpprivkey, true, false, false }, + { "dumppubkey", &dumppubkey, false, false, false }, + { "dumpwallet", &dumpwallet, true, false, false }, + { "importprivkey", &importprivkey, false, false, false }, + { "importwallet", &importwallet, false, false, false }, + { "getrawtransaction", &getrawtransaction, false, false, false }, + { "createrawtransaction", &createrawtransaction, false, false, false }, + { "decoderawtransaction", &decoderawtransaction, false, false, false }, + { "sendrawtransaction", &sendrawtransaction, false, false, false }, + { "sendnewusertransaction", &sendnewusertransaction, false, false, false }, + { "verifychain", &verifychain, true, false, false }, + { "getlastsoftcheckpoint", &getlastsoftcheckpoint, true, false, false }, // twister dht network - { "dhtput", &dhtput, false, true }, - { "dhtget", &dhtget, false, true }, - { "newpostmsg", &newpostmsg, false, true }, - { "newdirectmsg", &newdirectmsg, false, true }, - { "newrtmsg", &newrtmsg, false, true }, - { "getposts", &getposts, false, true }, - { "getdirectmsgs", &getdirectmsgs, false, true }, - { "setspammsg", &setspammsg, false, false }, - { "getspammsg", &getspammsg, false, false }, - { "follow", &follow, false, true }, - { "unfollow", &unfollow, false, true }, - { "getfollowing", &getfollowing, false, true }, - { "getlasthave", &getlasthave, false, true }, - { "getnumpieces", &getnumpieces, false, true }, - { "listusernamespartial", &listusernamespartial, false, true }, - { "rescandirectmsgs", &rescandirectmsgs, false, true }, - { "recheckusertorrent", &recheckusertorrent, false, true }, - { "gettrendinghashtags", &gettrendinghashtags, false, true }, - { "getspamposts", &getspamposts, false, true }, - { "torrentstatus", &torrentstatus, false, true }, + { "dhtput", &dhtput, false, true, false }, + { "dhtget", &dhtget, false, true, true }, + { "newpostmsg", &newpostmsg, false, true, false }, + { "newdirectmsg", &newdirectmsg, false, true, false }, + { "newrtmsg", &newrtmsg, false, true, false }, + { "getposts", &getposts, false, true, false }, + { "getdirectmsgs", &getdirectmsgs, false, true, false }, + { "setspammsg", &setspammsg, false, false, false }, + { "getspammsg", &getspammsg, false, false, false }, + { "follow", &follow, false, true, false }, + { "unfollow", &unfollow, false, true, false }, + { "getfollowing", &getfollowing, false, true, false }, + { "getlasthave", &getlasthave, false, true, false }, + { "getnumpieces", &getnumpieces, false, true, false }, + { "listusernamespartial", &listusernamespartial, false, true, true }, + { "rescandirectmsgs", &rescandirectmsgs, false, true, false }, + { "recheckusertorrent", &recheckusertorrent, false, true, false }, + { "gettrendinghashtags", &gettrendinghashtags, false, true, true }, + { "getspamposts", &getspamposts, false, true, false }, + { "torrentstatus", &torrentstatus, false, true, false }, }; CRPCTable::CRPCTable() @@ -989,6 +989,9 @@ void ServiceConnection(AcceptedConnection *conn) // Read HTTP message headers and body ReadHTTPMessage(conn->stream(), mapHeaders, strRequest, nProto); + if(strMethod == "GET" && strURI == "/") + strURI="/home.html"; + if (strURI != "/" && strURI.find("..") == std::string::npos ) { filesystem::path pathFile = filesystem::path(GetHTMLDir()) / strURI; std::string fname = pathFile.string(); @@ -1093,6 +1096,9 @@ json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_s const CRPCCommand *pcmd = tableRPC[strMethod]; if (!pcmd) throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found"); + + if(!pcmd->allowOnPublicServer && GetBoolArg("-public_server_mode",false)) + throw JSONRPCError(RPC_FORBIDDEN_ON_PUBLIC_SERVER, "Forbidden: accessing this method is not allowed on a public server"); // Observe safe mode string strWarning = GetWarnings("rpc"); diff --git a/src/bitcoinrpc.h b/src/bitcoinrpc.h index 7d25e219..b0822e06 100644 --- a/src/bitcoinrpc.h +++ b/src/bitcoinrpc.h @@ -48,6 +48,7 @@ enum RPCErrorCode RPC_INVALID_PARAMETER = -8, // Invalid, missing or duplicate parameter RPC_DATABASE_ERROR = -20, // Database error RPC_DESERIALIZATION_ERROR = -22, // Error parsing or validating structure in raw format + RPC_FORBIDDEN_ON_PUBLIC_SERVER = -23, // public server mode is activated, this method is not allowed // P2P client errors RPC_CLIENT_NOT_CONNECTED = -9, // Bitcoin is not connected @@ -103,6 +104,7 @@ public: rpcfn_type actor; bool okSafeMode; bool threadSafe; + bool allowOnPublicServer; }; /** diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index 12de4bd9..31311139 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -96,6 +96,7 @@ Value getinfo(const Array& params, bool fHelp) if (pwalletMain->IsCrypted()) obj.push_back(Pair("unlocked_until", (boost::int64_t)nWalletUnlockTime)); } + obj.push_back(Pair("public_server_mode", GetBoolArg("-public_server_mode",false))); obj.push_back(Pair("errors", GetWarnings("statusbar"))); } return obj; @@ -155,6 +156,11 @@ Value listwalletusers(const Array& params, bool fHelp) // Find all addresses that have the given account Array ret; + + // Always return an empty array on a public server + if(GetBoolArg("-public_server_mode",false)) + return ret; + LOCK(pwalletMain->cs_wallet); BOOST_FOREACH(const PAIRTYPE(CKeyID, CKeyMetadata)& item, pwalletMain->mapKeyMetadata) { From ca32b8cac1a29b7b46e4023e234a6564218e519f Mon Sep 17 00:00:00 2001 From: iShift Date: Wed, 9 Apr 2014 23:57:53 +0400 Subject: [PATCH 12/12] Update README.md #136 add link to calm theme --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 83a45072..eabba547 100644 --- a/README.md +++ b/README.md @@ -175,3 +175,12 @@ them: Visit [http://localhost:28332/index.html](http://localhost:28332/index.html) in your web browser and you should see a page asking you to choose between the Desktop and Mobile interfaces. + +Different themes +------------------------- + +If you prefer new modern look of twister with new untested things, you can try twister-calm theme +But be careful, it is in beta stage. + + cd ~/.twister/ + git clone https://github.com/iHedgehog/twister-calm.git ./html