diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..871ccf6c3 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,5 @@ +!Dockerfile +/build/* +*.md +.git/ +.gitignore diff --git a/Dockerfile b/Dockerfile index 999290c95..af268785e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,18 +1,32 @@ -# Multistage docker build, requires docker 17.05 +FROM debian:stable-slim -# builder stage -FROM ubuntu:16.04 as builder +WORKDIR /data -RUN set -ex && \ - apt-get update && \ - apt-get --no-install-recommends --yes install \ +RUN echo "\e[33mThis will take some time. Go and get a cup of coffee. We could be here all night.\e[39m" + +#su-exec +ARG SUEXEC_VERSION=v0.2 +ARG SUEXEC_HASH=f85e5bde1afef399021fbc2a99c837cf851ceafa +#Cmake +ARG CMAKE_VERSION=3.14.0 +ARG CMAKE_VERSION_DOT=v3.14 +ARG CMAKE_HASH=aa76ba67b3c2af1946701f847073f4652af5cbd9f141f221c97af99127e75502 +## Boost +ARG BOOST_VERSION=1_69_0 +ARG BOOST_VERSION_DOT=1.69.0 +ARG BOOST_HASH=8f32d4617390d1c2d16f26a27ab60d97807b35440d45891fa340fc2648b04406 + +ENV CFLAGS '-fPIC -O2 -g' +ENV CXXFLAGS '-fPIC -O2 -g' +ENV LDFLAGS '-static-libstdc++' + +ENV BASE_DIR /usr/local + +RUN apt-get update -qq && apt-get --no-install-recommends -yqq install \ ca-certificates \ - cmake \ g++ \ make \ pkg-config \ - graphviz \ - doxygen \ git \ curl \ libtool-bin \ @@ -21,192 +35,249 @@ RUN set -ex && \ bzip2 \ xsltproc \ gperf \ - unzip - -WORKDIR /usr/local - -ENV CFLAGS='-fPIC' -ENV CXXFLAGS='-fPIC' - -#Cmake -ARG CMAKE_VERSION=3.14.0 -ARG CMAKE_VERSION_DOT=v3.14 -ARG CMAKE_HASH=aa76ba67b3c2af1946701f847073f4652af5cbd9f141f221c97af99127e75502 -RUN set -ex \ - && curl -s -O https://cmake.org/files/${CMAKE_VERSION_DOT}/cmake-${CMAKE_VERSION}.tar.gz \ + unzip > /dev/null \ + g++-aarch64-linux-gnu \ + apt-utils \ + && cd /data || exit 1 \ + && echo "\e[32mbuilding: su-exec\e[39m" \ + && git clone --branch ${SUEXEC_VERSION} --single-branch --depth 1 https://github.com/ncopa/su-exec.git su-exec.git > /dev/null \ + && cd su-exec.git || exit 1 \ + && test `git rev-parse HEAD` = ${SUEXEC_HASH} || exit 1 \ + && make > /dev/null \ + && cp su-exec /data \ + && cd /data || exit 1 \ + && rm -rf /data/su-exec.git \ + && echo "\e[32mbuilding: Cmake\e[39m" \ + && set -ex \ + && curl -s -O https://cmake.org/files/${CMAKE_VERSION_DOT}/cmake-${CMAKE_VERSION}.tar.gz > /dev/null \ && echo "${CMAKE_HASH} cmake-${CMAKE_VERSION}.tar.gz" | sha256sum -c \ - && tar -xzf cmake-${CMAKE_VERSION}.tar.gz \ - && cd cmake-${CMAKE_VERSION} \ - && ./configure \ - && make \ - && make install - -## Boost -ARG BOOST_VERSION=1_69_0 -ARG BOOST_VERSION_DOT=1.69.0 -ARG BOOST_HASH=8f32d4617390d1c2d16f26a27ab60d97807b35440d45891fa340fc2648b04406 -RUN set -ex \ - && curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://dl.bintray.com/boostorg/release/${BOOST_VERSION_DOT}/source/boost_${BOOST_VERSION}.tar.bz2 \ + && tar -xzf cmake-${CMAKE_VERSION}.tar.gz > /dev/null \ + && cd cmake-${CMAKE_VERSION} || exit 1 \ + && ./configure --prefix=$BASE_DIR > /dev/null \ + && make > /dev/null \ + && make install > /dev/null \ + && cd /data || exit 1 \ + && rm -rf /data/cmake-${CMAKE_VERSION} \ + && rm -rf /data/cmake-${CMAKE_VERSION}.tar.gz \ + && echo "\e[32mbuilding: Boost\e[39m" \ + && set -ex \ + && curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://dl.bintray.com/boostorg/release/${BOOST_VERSION_DOT}/source/boost_${BOOST_VERSION}.tar.bz2 > /dev/null \ && echo "${BOOST_HASH} boost_${BOOST_VERSION}.tar.bz2" | sha256sum -c \ - && tar -xvf boost_${BOOST_VERSION}.tar.bz2 \ - && cd boost_${BOOST_VERSION} \ - && ./bootstrap.sh \ - && ./b2 --build-type=minimal link=static runtime-link=static --with-chrono --with-date_time --with-filesystem --with-program_options --with-regex --with-serialization --with-system --with-thread --with-locale threading=multi threadapi=pthread cflags="$CFLAGS" cxxflags="$CXXFLAGS" stage -ENV BOOST_ROOT /usr/local/boost_${BOOST_VERSION} + && tar -xvf boost_${BOOST_VERSION}.tar.bz2 > /dev/null \ + && cd boost_${BOOST_VERSION} || exit 1 \ + && ./bootstrap.sh > /dev/null \ + && ./b2 -a install --prefix=$BASE_DIR --build-type=minimal link=static runtime-link=static --with-chrono --with-date_time --with-filesystem --with-program_options --with-regex --with-serialization --with-system --with-thread --with-locale threading=multi threadapi=pthread cflags="$CFLAGS" cxxflags="$CXXFLAGS" stage > /dev/null \ + && cd /data || exit 1 \ + && rm -rf /data/boost_${BOOST_VERSION} \ + && rm -rf /data/boost_${BOOST_VERSION}.tar.bz2 + +RUN echo "\e[33mDid I ever tell you the story of when my cousin Nicolas boost a lambo in less than 60 seconds?\e[39m" + +WORKDIR /data + +ENV BASE_DIR /usr/local # OpenSSL ARG OPENSSL_VERSION=1.1.1b ARG OPENSSL_HASH=5c557b023230413dfb0756f3137a13e6d726838ccd1430888ad15bfb2b43ea4b -RUN set -ex \ - && curl -s -O https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz \ - && echo "${OPENSSL_HASH} openssl-${OPENSSL_VERSION}.tar.gz" | sha256sum -c \ - && tar -xzf openssl-${OPENSSL_VERSION}.tar.gz \ - && cd openssl-${OPENSSL_VERSION} \ - && ./Configure linux-x86_64 no-shared --static "$CFLAGS" \ - && make build_generated \ - && make libcrypto.a \ - && make install -ENV OPENSSL_ROOT_DIR=/usr/local/openssl-${OPENSSL_VERSION} - # ZMQ ARG ZMQ_VERSION=v4.3.1 ARG ZMQ_HASH=2cb1240db64ce1ea299e00474c646a2453a8435b -RUN set -ex \ - && git clone https://github.com/zeromq/libzmq.git -b ${ZMQ_VERSION} \ - && cd libzmq \ - && test `git rev-parse HEAD` = ${ZMQ_HASH} || exit 1 \ - && ./autogen.sh \ - && ./configure --enable-static --disable-shared \ - && make \ - && make install \ - && ldconfig - # zmq.hpp ARG CPPZMQ_VERSION=v4.3.0 ARG CPPZMQ_HASH=213da0b04ae3b4d846c9abc46bab87f86bfb9cf4 -RUN set -ex \ - && git clone https://github.com/zeromq/cppzmq.git -b ${CPPZMQ_VERSION} \ - && cd cppzmq \ - && test `git rev-parse HEAD` = ${CPPZMQ_HASH} || exit 1 \ - && mv *.hpp /usr/local/include - # Readline ARG READLINE_VERSION=8.0 ARG READLINE_HASH=e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461 -RUN set -ex \ - && curl -s -O https://ftp.gnu.org/gnu/readline/readline-${READLINE_VERSION}.tar.gz \ - && echo "${READLINE_HASH} readline-${READLINE_VERSION}.tar.gz" | sha256sum -c \ - && tar -xzf readline-${READLINE_VERSION}.tar.gz \ - && cd readline-${READLINE_VERSION} \ - && ./configure \ - && make \ - && make install - # Sodium ARG SODIUM_VERSION=1.0.17 ARG SODIUM_HASH=b732443c442239c2e0184820e9b23cca0de0828c -RUN set -ex \ - && git clone https://github.com/jedisct1/libsodium.git -b ${SODIUM_VERSION} \ - && cd libsodium \ + +ENV CFLAGS '-fPIC -O2 -g' +ENV CXXFLAGS '-fPIC -O2 -g' +ENV LDFLAGS '-static-libstdc++' + +RUN echo "\e[32mbuilding: Openssl\e[39m" \ + && set -ex \ + && curl -s -O https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz > /dev/null \ + && echo "${OPENSSL_HASH} openssl-${OPENSSL_VERSION}.tar.gz" | sha256sum -c \ + && tar -xzf openssl-${OPENSSL_VERSION}.tar.gz > /dev/null \ + && cd openssl-${OPENSSL_VERSION} || exit 1 \ + && ./Configure --prefix=$BASE_DIR linux-x86_64 no-shared --static "$CFLAGS" > /dev/null \ + && make build_generated > /dev/null \ + && make libcrypto.a > /dev/null \ + && make install > /dev/null \ + && cd /data || exit 1 \ + && rm -rf /data/openssl-${OPENSSL_VERSION} \ + && rm -rf /data/openssl-${OPENSSL_VERSION}.tar.gz \ + && echo "\e[32mbuilding: ZMQ\e[39m" \ + && set -ex \ + && git clone --branch ${ZMQ_VERSION} --single-branch --depth 1 https://github.com/zeromq/libzmq.git > /dev/null \ + && cd libzmq || exit 1 \ + && test `git rev-parse HEAD` = ${ZMQ_HASH} || exit 1 \ + && ./autogen.sh > /dev/null \ + && ./configure --prefix=$BASE_DIR --enable-libunwind=no --enable-static --disable-shared > /dev/null \ + && make > /dev/null \ + && make install > /dev/null \ + && ldconfig > /dev/null \ + && cd /data || exit 1 \ + && rm -rf /data/libzmq \ + && echo "\e[32mbuilding: zmq.hpp\e[39m" \ + && set -ex \ + && git clone --branch ${CPPZMQ_VERSION} --single-branch --depth 1 https://github.com/zeromq/cppzmq.git > /dev/null \ + && cd cppzmq || exit 1 \ + && test `git rev-parse HEAD` = ${CPPZMQ_HASH} || exit 1 \ + && mv *.hpp $BASE_DIR/include \ + && cd /data || exit 1 \ + && rm -rf /data/cppzmq \ + && echo "\e[32mbuilding: Readline\e[39m" \ + && set -ex \ + && curl -s -O https://ftp.gnu.org/gnu/readline/readline-${READLINE_VERSION}.tar.gz > /dev/null \ + && echo "${READLINE_HASH} readline-${READLINE_VERSION}.tar.gz" | sha256sum -c \ + && tar -xzf readline-${READLINE_VERSION}.tar.gz > /dev/null \ + && cd readline-${READLINE_VERSION} || exit 1 \ + && ./configure --prefix=$BASE_DIR > /dev/null \ + && make > /dev/null \ + && make install > /dev/null \ + && cd /data || exit 1 \ + && rm -rf /data/readline-${READLINE_VERSION} \ + && rm -rf readline-${READLINE_VERSION}.tar.gz \ + && echo "\e[32mbuilding: Sodium\e[39m" \ + && set -ex \ + && git clone --branch ${SODIUM_VERSION} --single-branch --depth 1 https://github.com/jedisct1/libsodium.git > /dev/null \ + && cd libsodium || exit 1 \ && test `git rev-parse HEAD` = ${SODIUM_HASH} || exit 1 \ && ./autogen.sh \ - && ./configure \ - && make \ - && make check \ - && make install + && ./configure --prefix=$BASE_DIR > /dev/null \ + && make > /dev/null \ + && make check > /dev/null \ + && make install > /dev/null \ + && cd /data || exit 1 \ + && rm -rf /data/libsodium + +RUN echo "\e[33mOoh wee, that was close. I thought I broke something.\e[39m" + +WORKDIR /data + +ENV BASE_DIR /usr/local # Udev ARG UDEV_VERSION=v3.2.7 ARG UDEV_HASH=4758e346a14126fc3a964de5831e411c27ebe487 -RUN set -ex \ - && git clone https://github.com/gentoo/eudev -b ${UDEV_VERSION} \ - && cd eudev \ - && test `git rev-parse HEAD` = ${UDEV_HASH} || exit 1 \ - && ./autogen.sh \ - && ./configure --disable-gudev --disable-introspection --disable-hwdb --disable-manpages --disable-shared \ - && make \ - && make install - # Libusb ARG USB_VERSION=v1.0.22 ARG USB_HASH=0034b2afdcdb1614e78edaa2a9e22d5936aeae5d -RUN set -ex \ - && git clone https://github.com/libusb/libusb.git -b ${USB_VERSION} \ - && cd libusb \ - && test `git rev-parse HEAD` = ${USB_HASH} || exit 1 \ - && ./autogen.sh \ - && ./configure --disable-shared \ - && make \ - && make install - # Hidapi ARG HIDAPI_VERSION=hidapi-0.8.0-rc1 ARG HIDAPI_HASH=40cf516139b5b61e30d9403a48db23d8f915f52c -RUN set -ex \ - && git clone https://github.com/signal11/hidapi -b ${HIDAPI_VERSION} \ - && cd hidapi \ - && test `git rev-parse HEAD` = ${HIDAPI_HASH} || exit 1 \ - && ./bootstrap \ - && ./configure --enable-static --disable-shared \ - && make \ - && make install - # Protobuf ARG PROTOBUF_VERSION=v3.7.0 ARG PROTOBUF_HASH=582743bf40c5d3639a70f98f183914a2c0cd0680 -RUN set -ex \ - && git clone https://github.com/protocolbuffers/protobuf -b ${PROTOBUF_VERSION} \ - && cd protobuf \ - && test `git rev-parse HEAD` = ${PROTOBUF_HASH} || exit 1 \ - && git submodule update --init --recursive \ + +ENV CFLAGS '-fPIC -O2 -g' +ENV CXXFLAGS '-fPIC -O2 -g' +ENV LDFLAGS '-static-libstdc++' + +RUN echo "\e[32mbuilding: Udev\e[39m" \ + && set -ex \ + && git clone --branch ${UDEV_VERSION} --single-branch --depth 1 https://github.com/gentoo/eudev > /dev/null \ + && cd eudev || exit 1 \ + && test `git rev-parse HEAD` = ${UDEV_HASH} || exit 1 \ && ./autogen.sh \ - && ./configure --enable-static --disable-shared \ - && make \ - && make install \ - && ldconfig + && ./configure --prefix=$BASE_DIR --disable-gudev --disable-introspection --disable-hwdb --disable-manpages --disable-shared > /dev/null \ + && make > /dev/null \ + && make install > /dev/null \ + && cd /data || exit 1 \ + && rm -rf /data/eudev \ + && echo "\e[32mbuilding: Libusb\e[39m" \ + && set -ex \ + && git clone --branch ${USB_VERSION} --single-branch --depth 1 https://github.com/libusb/libusb.git > /dev/null \ + && cd libusb || exit 1 \ + && test `git rev-parse HEAD` = ${USB_HASH} || exit 1 \ + && ./autogen.sh > /dev/null \ + && ./configure --prefix=$BASE_DIR --disable-shared > /dev/null \ + && make > /dev/null \ + && make install > /dev/null \ + && cd /data || exit 1 \ + && rm -rf /data/libusb \ + && echo "\e[32mbuilding: Hidapi\e[39m" \ + && set -ex \ + && git clone --branch ${HIDAPI_VERSION} --single-branch --depth 1 https://github.com/signal11/hidapi > /dev/null \ + && cd hidapi || exit 1 \ + && test `git rev-parse HEAD` = ${HIDAPI_HASH} || exit 1 \ + && ./bootstrap \ + && ./configure --prefix=$BASE_DIR --enable-static --disable-shared > /dev/null \ + && make > /dev/null \ + && make install > /dev/null \ + && cd /data || exit 1 \ + && rm -rf /data/hidapi \ + && echo "\e[32mbuilding: Protobuf\e[39m" \ + && set -ex \ + && git clone --branch ${PROTOBUF_VERSION} --single-branch --depth 1 https://github.com/protocolbuffers/protobuf > /dev/null \ + && cd protobuf || exit 1 \ + && test `git rev-parse HEAD` = ${PROTOBUF_HASH} || exit 1 \ + && git submodule update --init --recursive > /dev/null \ + && ./autogen.sh > /dev/null \ + && ./configure --prefix=$BASE_DIR --enable-static --disable-shared > /dev/null \ + && make > /dev/null \ + && make install > /dev/null \ + && ldconfig \ + && cd /data || exit 1 \ + && rm -rf /data/protobuf -WORKDIR /src -COPY . . +WORKDIR /data +# BUILD_PATH: +# Using 'USE_SINGLE_BUILDDIR=1 make' creates a unified build dir (/wownero.git/build/release/bin) -ENV USE_SINGLE_BUILDDIR=1 -ARG NPROC -RUN set -ex && \ - git submodule init && git submodule update && \ - rm -rf build && \ - if [ -z "$NPROC" ] ; \ - then make -j$(nproc) release-static ; \ - else make -j$NPROC release-static ; \ - fi +ARG PROJECT_URL=https://github.com/wownero/wownero.git +ARG BRANCH=master +ARG BUILD_PATH=/wownero.git/build/release/bin -# runtime stage -FROM ubuntu:16.04 +ENV CFLAGS '-fPIC -O1' +ENV CXXFLAGS '-fPIC -O1' +ENV LDFLAGS '-static-libstdc++' -RUN set -ex && \ - apt-get update && \ - apt-get --no-install-recommends --yes install ca-certificates && \ - apt-get clean && \ - rm -rf /var/lib/apt -COPY --from=builder /src/build/release/bin /usr/local/bin/ +RUN echo "\e[33mNow we're getting somewhere.\e[39m" -# Create monero user -RUN adduser --system --group --disabled-password monero && \ - mkdir -p /wallet /home/monero/.bitmonero && \ - chown -R monero:monero /home/monero/.bitmonero && \ - chown -R monero:monero /wallet +RUN echo "\e[32mcloning: $PROJECT_URL on branch: $BRANCH\e[39m" \ + && git clone --branch "$BRANCH" --single-branch --recursive $PROJECT_URL wownero.git > /dev/null \ + && cd wownero.git || exit 1 \ + && echo "\e[32mbuilding static binaries\e[39m" \ + && apt-get update -qq && apt-get install -yqq --no-install-recommends \ + libreadline-dev \ + && USE_SINGLE_BUILDDIR=1 make release-static > /dev/null \ + && echo "\e[32mcopy and clean up\e[39m" \ + && mv /data$BUILD_PATH/wownerod /data/ \ + && chmod +x /data/wownerod \ + && mv /data$BUILD_PATH/wownero-wallet-rpc /data/ \ + && chmod +x /data/wownero-wallet-rpc \ + && mv /data$BUILD_PATH/wownero-wallet-cli /data/ \ + && chmod +x /data/wownero-wallet-cli \ + && cp /data/wownerod /usr/local/bin/wownerod \ + && cp /data/wownero-wallet-rpc /usr/local/bin/wownero-wallet-rpc \ + && cp /data/wownero-wallet-cli /usr/local/bin/wownero-wallet-cli \ + && cp /data/su-exec /usr/local/bin/su-exec \ + && rm /data/su-exec \ + && cd /data || exit 1 \ + && apt-get autoremove --purge -yqq > /dev/null \ + && apt-get clean > /dev/null \ + && rm -rf /var/tmp/* /tmp/* /var/lib/apt/* > /dev/null -# Contains the blockchain -VOLUME /home/monero/.bitmonero +VOLUME ["/data"] -# Generate your wallet via accessing the container and run: -# cd /wallet -# monero-wallet-cli -VOLUME /wallet - -EXPOSE 18080 -EXPOSE 18081 - -# switch to user monero -USER monero - -ENTRYPOINT ["monerod", "--p2p-bind-ip=0.0.0.0", "--p2p-bind-port=18080", "--rpc-bind-ip=0.0.0.0", "--rpc-bind-port=18081", "--non-interactive", "--confirm-external-bind"] +ENV USER_ID 1000 +ENV LOG_LEVEL 0 +ENV DAEMON_HOST 127.0.0.1 +ENV DAEMON_PORT 34568 +ENV RPC_USER "" +ENV RPC_PASSWD "" +ENV RPC_LOGIN "" +ENV WALLET_PASSWD "" +ENV WALLET_ACCESS "" +ENV RPC_BIND_IP 0.0.0.0 +ENV RPC_BIND_PORT 34568 +ENV P2P_BIND_IP 0.0.0.0 +ENV P2P_BIND_PORT 34567 +RUN wownerod --version +RUN echo "\e[33mAll done.\e[39m" diff --git a/PKGBUILD b/PKGBUILD index 875ce5da6..11c346284 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -3,13 +3,13 @@ pkgbase=('wownero-git') pkgname=('wownero-git') -pkgver=0.5.0.2 +pkgver=v0.6.1.1.r2.9afbcfb7 pkgrel=1 pkgdesc="a fairly launched privacy-centric meme coin with no premine and a finite supply" license=('custom:Cryptonote') arch=('x86_64') url="http://wownero.org/" -depends=('boost-libs' 'zeromq' 'unbound' 'libusb') +depends=('openssl' 'zeromq' 'libpgm' 'unbound' 'libsodium') makedepends=('git' 'cmake' 'boost') provides=('wownero-git') @@ -18,14 +18,12 @@ source=("${pkgname}"::"git+https://github.com/wownero/wownero") sha256sums=('SKIP') pkgver() { - cd "${srcdir}/${pkgname}" - printf "$(echo ${pkgver} | sed 's/\.r.*//').r%s.g%s" \ - "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)" + cd "$srcdir/$pkgname" + git describe --long --tags | sed 's/\([^-]*-\)g/r\1/;s/-/./g' } build() { cd "${srcdir}/${pkgname}" - git fetch --tags && git checkout tags/v0.5.0.2 -b v0.5.0.2 USE_SINGLE_BUILDDIR=1 make } diff --git a/README.md b/README.md index 9a6db4887..c6007e489 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ Dates are provided in the format YYYY-MM-DD. | 53666 | 2018-10-06 | Cool Cage | v0.3.0.0 | v0.3.1.3 | Cryptonight variant 2, LWMA v2, ringsize = 22, MMS | 63469 | 2018-11-11 | Dank Doge | v0.4.0.0 | v0.4.0.0 | LWMA v4 | 81769 | 2019-02-19 | Erotic EggplantEmoji | v0.5.0.0 | v0.5.0.2 | Cryptonight/wow, LWMA v1 with N=144, Updated Bulletproofs, Fee Per Byte, Auto-churn -| 114969 | 2019-06-14 | F For Fappening | v0.6.1.0 | v0.6.1.1 | RandomWOW, new block weight algorithm, slightly more efficient RingCT format +| 114969 | 2019-06-14 | F For Fappening | v0.6.1.0 | v0.6.1.2 | RandomWOW, new block weight algorithm, slightly more efficient RingCT format X's indicate that these details have not been determined as of commit date. diff --git a/contrib/epee/include/net/abstract_tcp_server2.inl b/contrib/epee/include/net/abstract_tcp_server2.inl index 821594355..fa5858b9f 100644 --- a/contrib/epee/include/net/abstract_tcp_server2.inl +++ b/contrib/epee/include/net/abstract_tcp_server2.inl @@ -54,6 +54,9 @@ #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "net" +#define AGGRESSIVE_TIMEOUT_THRESHOLD 120 // sockets +#define NEW_CONNECTION_TIMEOUT_LOCAL 1200000 // 2 minutes +#define NEW_CONNECTION_TIMEOUT_REMOTE 10000 // 10 seconds #define DEFAULT_TIMEOUT_MS_LOCAL 1800000 // 30 minutes #define DEFAULT_TIMEOUT_MS_REMOTE 300000 // 5 minutes #define TIMEOUT_EXTRA_MS_PER_BYTE 0.2 @@ -189,7 +192,7 @@ PRAGMA_WARNING_DISABLE_VS(4355) m_protocol_handler.after_init_connection(); - reset_timer(get_default_timeout(), false); + reset_timer(boost::posix_time::milliseconds(m_local ? NEW_CONNECTION_TIMEOUT_LOCAL : NEW_CONNECTION_TIMEOUT_REMOTE), false); // first read on the raw socket to detect SSL for the server buffer_ssl_init_fill = 0; @@ -691,7 +694,7 @@ PRAGMA_WARNING_DISABLE_VS(4355) { unsigned count; try { count = host_count(m_host); } catch (...) { count = 0; } - const unsigned shift = std::min(std::max(count, 1u) - 1, 8u); + const unsigned shift = get_state().sock_count > AGGRESSIVE_TIMEOUT_THRESHOLD ? std::min(std::max(count, 1u) - 1, 8u) : 0; boost::posix_time::milliseconds timeout(0); if (m_local) timeout = boost::posix_time::milliseconds(DEFAULT_TIMEOUT_MS_LOCAL >> shift); @@ -730,8 +733,6 @@ PRAGMA_WARNING_DISABLE_VS(4355) template void connection::reset_timer(boost::posix_time::milliseconds ms, bool add) { - if (m_connection_type != e_connection_type_RPC) - return; MTRACE("Setting " << ms << " expiry"); auto self = safe_shared_from_this(); if(!self) diff --git a/contrib/epee/include/net/levin_protocol_handler_async.h b/contrib/epee/include/net/levin_protocol_handler_async.h index 116b3ace1..8d7ffb2c2 100644 --- a/contrib/epee/include/net/levin_protocol_handler_async.h +++ b/contrib/epee/include/net/levin_protocol_handler_async.h @@ -99,6 +99,8 @@ public: template bool for_connection(const boost::uuids::uuid &connection_id, const callback_t &cb); size_t get_connections_count(); + size_t get_out_connections_count(); + size_t get_in_connections_count(); void set_handler(levin_commands_handler* handler, void (*destroy)(levin_commands_handler*) = NULL); async_protocol_handler_config():m_pcommands_handler(NULL), m_pcommands_handler_destroy(NULL), m_max_packet_size(LEVIN_DEFAULT_MAX_PACKET_SIZE), m_invoke_timeout(LEVIN_DEFAULT_TIMEOUT_PRECONFIGURED) @@ -882,6 +884,28 @@ size_t async_protocol_handler_config::get_connections_coun } //------------------------------------------------------------------------------------------ template +size_t async_protocol_handler_config::get_out_connections_count() +{ + CRITICAL_REGION_LOCAL(m_connects_lock); + size_t count = 0; + for (const auto &c: m_connects) + if (!c.second->m_connection_context.m_is_income) + ++count; + return count; +} +//------------------------------------------------------------------------------------------ +template +size_t async_protocol_handler_config::get_in_connections_count() +{ + CRITICAL_REGION_LOCAL(m_connects_lock); + size_t count = 0; + for (const auto &c: m_connects) + if (c.second->m_connection_context.m_is_income) + ++count; + return count; +} +//------------------------------------------------------------------------------------------ +template void async_protocol_handler_config::set_handler(levin_commands_handler* handler, void (*destroy)(levin_commands_handler*)) { if (m_pcommands_handler && m_pcommands_handler_destroy) diff --git a/contrib/epee/include/storages/portable_storage_from_bin.h b/contrib/epee/include/storages/portable_storage_from_bin.h index 2884f8c5e..e0a32b3ca 100644 --- a/contrib/epee/include/storages/portable_storage_from_bin.h +++ b/contrib/epee/include/storages/portable_storage_from_bin.h @@ -136,6 +136,7 @@ namespace epee //for pod types array_entry_t sa; size_t size = read_varint(); + CHECK_AND_ASSERT_THROW_MES(size <= m_count, "Size sanity check failed"); sa.reserve(size); //TODO: add some optimization here later while(size--) diff --git a/contrib/epee/src/buffer.cpp b/contrib/epee/src/buffer.cpp index d637b905e..10ea6de56 100644 --- a/contrib/epee/src/buffer.cpp +++ b/contrib/epee/src/buffer.cpp @@ -64,7 +64,8 @@ void buffer::append(const void *data, size_t sz) size_t reserve = (((size() + sz) * 3 / 2) + 4095) & ~4095; new_storage.reserve(reserve); new_storage.resize(size()); - memcpy(new_storage.data(), storage.data() + offset, storage.size() - offset); + if (size() > 0) + memcpy(new_storage.data(), storage.data() + offset, storage.size() - offset); offset = 0; std::swap(storage, new_storage); } diff --git a/contrib/epee/src/wipeable_string.cpp b/contrib/epee/src/wipeable_string.cpp index 3a6ee5dac..4209b71bf 100644 --- a/contrib/epee/src/wipeable_string.cpp +++ b/contrib/epee/src/wipeable_string.cpp @@ -62,13 +62,15 @@ wipeable_string::wipeable_string(wipeable_string &&other) wipeable_string::wipeable_string(const std::string &other) { grow(other.size()); - memcpy(buffer.data(), other.c_str(), size()); + if (size() > 0) + memcpy(buffer.data(), other.c_str(), size()); } wipeable_string::wipeable_string(std::string &&other) { grow(other.size()); - memcpy(buffer.data(), other.c_str(), size()); + if (size() > 0) + memcpy(buffer.data(), other.c_str(), size()); if (!other.empty()) { memwipe(&other[0], other.size()); // we're kinda left with this again aren't we @@ -79,7 +81,8 @@ wipeable_string::wipeable_string(std::string &&other) wipeable_string::wipeable_string(const char *s) { grow(strlen(s)); - memcpy(buffer.data(), s, size()); + if (size() > 0) + memcpy(buffer.data(), s, size()); } wipeable_string::wipeable_string(const char *s, size_t len) @@ -112,14 +115,18 @@ void wipeable_string::grow(size_t sz, size_t reserved) } size_t old_sz = buffer.size(); std::unique_ptr tmp{new char[old_sz]}; - memcpy(tmp.get(), buffer.data(), old_sz * sizeof(char)); if (old_sz > 0) + { + memcpy(tmp.get(), buffer.data(), old_sz * sizeof(char)); memwipe(buffer.data(), old_sz * sizeof(char)); + } buffer.reserve(reserved); buffer.resize(sz); - memcpy(buffer.data(), tmp.get(), old_sz * sizeof(char)); if (old_sz > 0) + { + memcpy(buffer.data(), tmp.get(), old_sz * sizeof(char)); memwipe(tmp.get(), old_sz * sizeof(char)); + } } void wipeable_string::push_back(char c) diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp index 29b75f0b0..f73d4ba1c 100644 --- a/src/blockchain_db/lmdb/db_lmdb.cpp +++ b/src/blockchain_db/lmdb/db_lmdb.cpp @@ -1081,11 +1081,11 @@ void BlockchainLMDB::add_tx_amount_output_indices(const uint64_t tx_id, int result = 0; - int num_outputs = amount_output_indices.size(); + size_t num_outputs = amount_output_indices.size(); MDB_val_set(k_tx_id, tx_id); MDB_val v; - v.mv_data = (void *)amount_output_indices.data(); + v.mv_data = num_outputs ? (void *)amount_output_indices.data() : (void*)""; v.mv_size = sizeof(uint64_t) * num_outputs; // LOG_PRINT_L1("tx_outputs[tx_hash] size: " << v.mv_size); @@ -1468,7 +1468,7 @@ void BlockchainLMDB::open(const std::string& filename, const int db_flags) mdb_env_close(m_env); m_open = false; MFATAL("Existing lmdb database needs to be converted, which cannot be done on a read-only database."); - MFATAL("Please run monerod once to convert the database."); + MFATAL("Please run wownerod once to convert the database."); return; } // Note that there was a schema change within version 0 as well. @@ -1960,7 +1960,7 @@ bool BlockchainLMDB::prune_worker(int mode, uint32_t pruning_seed) TIME_MEASURE_START(t); - size_t n_total_records = 0, n_prunable_records = 0, n_pruned_records = 0; + size_t n_total_records = 0, n_prunable_records = 0, n_pruned_records = 0, commit_counter = 0; uint64_t n_bytes = 0; mdb_txn_safe txn; @@ -2063,6 +2063,7 @@ bool BlockchainLMDB::prune_worker(int mode, uint32_t pruning_seed) { MDEBUG("Pruning at height " << block_height << "/" << blockchain_height); ++n_pruned_records; + ++commit_counter; n_bytes += k.mv_size + v.mv_size; result = mdb_cursor_del(c_txs_prunable, 0); if (result) @@ -2072,6 +2073,25 @@ bool BlockchainLMDB::prune_worker(int mode, uint32_t pruning_seed) result = mdb_cursor_del(c_txs_prunable_tip, 0); if (result) throw0(DB_ERROR(lmdb_error("Failed to delete transaction tip data: ", result).c_str())); + + if (mode != prune_mode_check && commit_counter >= 4096) + { + MDEBUG("Committing txn at checkpoint..."); + txn.commit(); + result = mdb_txn_begin(m_env, NULL, 0, txn); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", result).c_str())); + result = mdb_cursor_open(txn, m_txs_pruned, &c_txs_pruned); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to open a cursor for txs_pruned: ", result).c_str())); + result = mdb_cursor_open(txn, m_txs_prunable, &c_txs_prunable); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to open a cursor for txs_prunable: ", result).c_str())); + result = mdb_cursor_open(txn, m_txs_prunable_tip, &c_txs_prunable_tip); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to open a cursor for txs_prunable_tip: ", result).c_str())); + commit_counter = 0; + } } } } @@ -2141,6 +2161,7 @@ bool BlockchainLMDB::prune_worker(int mode, uint32_t pruning_seed) result = mdb_cursor_del(c_txs_prunable, 0); if (result) throw0(DB_ERROR(lmdb_error("Failed to delete transaction prunable data: ", result).c_str())); + ++commit_counter; } } } @@ -2157,6 +2178,34 @@ bool BlockchainLMDB::prune_worker(int mode, uint32_t pruning_seed) ", seed " << epee::string_tools::to_string_hex(pruning_seed)); } } + + if (mode != prune_mode_check && commit_counter >= 4096) + { + MDEBUG("Committing txn at checkpoint..."); + txn.commit(); + result = mdb_txn_begin(m_env, NULL, 0, txn); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", result).c_str())); + result = mdb_cursor_open(txn, m_txs_pruned, &c_txs_pruned); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to open a cursor for txs_pruned: ", result).c_str())); + result = mdb_cursor_open(txn, m_txs_prunable, &c_txs_prunable); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to open a cursor for txs_prunable: ", result).c_str())); + result = mdb_cursor_open(txn, m_txs_prunable_tip, &c_txs_prunable_tip); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to open a cursor for txs_prunable_tip: ", result).c_str())); + result = mdb_cursor_open(txn, m_tx_indices, &c_tx_indices); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to open a cursor for tx_indices: ", result).c_str())); + MDB_val val; + val.mv_size = sizeof(ti); + val.mv_data = (void *)&ti; + result = mdb_cursor_get(c_tx_indices, (MDB_val*)&zerokval, &val, MDB_GET_BOTH); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to restore cursor for tx_indices: ", result).c_str())); + commit_counter = 0; + } } mdb_cursor_close(c_tx_indices); } diff --git a/src/blockchain_utilities/blockchain_export.cpp b/src/blockchain_utilities/blockchain_export.cpp index 9b67ddb6b..216f7cfe3 100644 --- a/src/blockchain_utilities/blockchain_export.cpp +++ b/src/blockchain_utilities/blockchain_export.cpp @@ -177,7 +177,7 @@ int main(int argc, char* argv[]) } r = core_storage->init(db, opt_testnet ? cryptonote::TESTNET : opt_stagenet ? cryptonote::STAGENET : cryptonote::MAINNET); - if (core_storage->get_blockchain_pruning_seed()) + if (core_storage->get_blockchain_pruning_seed() && !opt_blocks_dat) { LOG_PRINT_L0("Blockchain is pruned, cannot export"); return 1; diff --git a/src/blocks/checkpoints.dat b/src/blocks/checkpoints.dat index 90c59adb0..e530541d3 100644 Binary files a/src/blocks/checkpoints.dat and b/src/blocks/checkpoints.dat differ diff --git a/src/checkpoints/checkpoints.cpp b/src/checkpoints/checkpoints.cpp index 460bf6241..aea24cb65 100644 --- a/src/checkpoints/checkpoints.cpp +++ b/src/checkpoints/checkpoints.cpp @@ -219,6 +219,8 @@ namespace cryptonote ADD_CHECKPOINT(111450, "d6eadc95607765b36afd8b9148eac20eb101632021348cd34371fc1d8b67f6b6"); ADD_CHECKPOINT(114969, "b48245956b87f243048fd61021f4b3e5443e57eee7ff8ba4762d18926e80b80c"); //Hard fork to v13 ADD_CHECKPOINT(114980, "3a96963b93154889bd7d59c8a60cf8005e864b930627616e51a4ad11cd9a3d50"); + ADD_CHECKPOINT(115257, "338e056551087fe23d6c4b4280244bc5362b004716d85ec799a775f190f9fea9"); //Hard fork to v14 + ADD_CHECKPOINT(118500, "2ef1cd0c68f1b8e1acf384109431b6377dbdbd6705964be17b7358c47ea07447"); return true; } diff --git a/src/crypto/keccak.c b/src/crypto/keccak.c index 170911262..18ed3152f 100644 --- a/src/crypto/keccak.c +++ b/src/crypto/keccak.c @@ -116,7 +116,8 @@ void keccak(const uint8_t *in, size_t inlen, uint8_t *md, int mdlen) local_abort("Bad keccak use"); } - memcpy(temp, in, inlen); + if (inlen > 0) + memcpy(temp, in, inlen); temp[inlen++] = 1; memset(temp + inlen, 0, rsiz - inlen); temp[rsiz - 1] |= 0x80; diff --git a/src/crypto/tree-hash.c b/src/crypto/tree-hash.c index 7802fb67f..0a5860f3b 100644 --- a/src/crypto/tree-hash.c +++ b/src/crypto/tree-hash.c @@ -30,6 +30,7 @@ #include #include +#include #include #include "hash-ops.h" @@ -82,23 +83,24 @@ void tree_hash(const char (*hashes)[HASH_SIZE], size_t count, char *root_hash) { size_t cnt = tree_hash_cnt( count ); - char ints[cnt][HASH_SIZE]; - memset(ints, 0 , sizeof(ints)); // zero out as extra protection for using uninitialized mem + char *ints = calloc(cnt, HASH_SIZE); // zero out as extra protection for using uninitialized mem + assert(ints); memcpy(ints, hashes, (2 * cnt - count) * HASH_SIZE); for (i = 2 * cnt - count, j = 2 * cnt - count; j < cnt; i += 2, ++j) { - cn_fast_hash(hashes[i], 64, ints[j]); + cn_fast_hash(hashes[i], 64, ints + j * HASH_SIZE); } assert(i == count); while (cnt > 2) { cnt >>= 1; for (i = 0, j = 0; j < cnt; i += 2, ++j) { - cn_fast_hash(ints[i], 64, ints[j]); + cn_fast_hash(ints + i * HASH_SIZE, 64, ints + j * HASH_SIZE); } } - cn_fast_hash(ints[0], 64, root_hash); + cn_fast_hash(ints, 64, root_hash); + free(ints); } } diff --git a/src/cryptonote_basic/cryptonote_basic.h b/src/cryptonote_basic/cryptonote_basic.h index 20d92bdf1..055c4a22b 100644 --- a/src/cryptonote_basic/cryptonote_basic.h +++ b/src/cryptonote_basic/cryptonote_basic.h @@ -320,7 +320,7 @@ namespace cryptonote } if (!typename Archive::is_saving()) pruned = true; - return true; + return ar.stream().good(); } private: diff --git a/src/cryptonote_basic/cryptonote_format_utils.cpp b/src/cryptonote_basic/cryptonote_format_utils.cpp index fc33a7fb8..838e34f28 100644 --- a/src/cryptonote_basic/cryptonote_format_utils.cpp +++ b/src/cryptonote_basic/cryptonote_format_utils.cpp @@ -241,8 +241,7 @@ namespace cryptonote tx.invalidate_hashes(); //TODO: validate tx - get_transaction_hash(tx, tx_hash); - return true; + return get_transaction_hash(tx, tx_hash); } //--------------------------------------------------------------- bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx, crypto::hash& tx_hash, crypto::hash& tx_prefix_hash) @@ -997,6 +996,7 @@ namespace cryptonote { crypto::hash h = null_hash; get_transaction_hash(t, h, NULL); + CHECK_AND_ASSERT_THROW_MES(get_transaction_hash(t, h, NULL), "Failed to calculate transaction hash"); return h; } //--------------------------------------------------------------- @@ -1289,7 +1289,7 @@ namespace cryptonote txs_ids.reserve(1 + b.tx_hashes.size()); crypto::hash h = null_hash; size_t bl_sz = 0; - get_transaction_hash(b.miner_tx, h, bl_sz); + CHECK_AND_ASSERT_THROW_MES(get_transaction_hash(b.miner_tx, h, bl_sz), "Failed to calculate transaction hash"); txs_ids.push_back(h); for(auto& th: b.tx_hashes) txs_ids.push_back(th); diff --git a/src/cryptonote_config.h b/src/cryptonote_config.h index 199977a0a..26ca50aed 100644 --- a/src/cryptonote_config.h +++ b/src/cryptonote_config.h @@ -101,8 +101,8 @@ #define BLOCKS_IDS_SYNCHRONIZING_DEFAULT_COUNT 10000 //by default, blocks ids count in synchronizing -#define BLOCKS_SYNCHRONIZING_DEFAULT_COUNT_PRE_V4 100 //by default, blocks count in blocks downloading -#define BLOCKS_SYNCHRONIZING_DEFAULT_COUNT 20 //by default, blocks count in blocks downloading +#define BLOCKS_SYNCHRONIZING_DEFAULT_COUNT_PRE_V4 20 //by default, blocks count in blocks downloading +#define BLOCKS_SYNCHRONIZING_DEFAULT_COUNT 10 //by default, blocks count in blocks downloading #define BLOCKS_SYNCHRONIZING_MAX_COUNT 2048 //must be a power of 2, greater than 128, equal to SEEDHASH_EPOCH_BLOCKS #define CRYPTONOTE_MEMPOOL_TX_LIVETIME (86400*3) //seconds, three days @@ -113,7 +113,7 @@ #define P2P_LOCAL_WHITE_PEERLIST_LIMIT 1000 #define P2P_LOCAL_GRAY_PEERLIST_LIMIT 5000 -#define P2P_DEFAULT_CONNECTIONS_COUNT 8 +#define P2P_DEFAULT_CONNECTIONS_COUNT 12 #define P2P_DEFAULT_HANDSHAKE_INTERVAL 60 //secondes #define P2P_DEFAULT_PACKET_MAX_SIZE 50000000 //50000000 bytes maximum packet size #define P2P_DEFAULT_PEERS_IN_HANDSHAKE 250 diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index c6fb52bed..29d328489 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -1951,10 +1951,14 @@ bool Blockchain::handle_get_objects(NOTIFY_REQUEST_GET_OBJECTS::request& arg, NO if (missed_tx_ids.size() != 0) { - LOG_ERROR("Error retrieving blocks, missed " << missed_tx_ids.size() - << " transactions for block with hash: " << get_block_hash(bl.second) - << std::endl - ); + // do not display an error if the peer asked for an unpruned block which we are not meant to have + if (tools::has_unpruned_block(get_block_height(bl.second), get_current_blockchain_height(), get_blockchain_pruning_seed())) + { + LOG_ERROR("Error retrieving blocks, missed " << missed_tx_ids.size() + << " transactions for block with hash: " << get_block_hash(bl.second) + << std::endl + ); + } // append missed transaction hashes to response missed_ids field, // as done below if any standalone transactions were requested @@ -4960,7 +4964,7 @@ void Blockchain::cancel() } #if defined(PER_BLOCK_CHECKPOINT) -static const char expected_block_hashes_hash[] = "4907556dee9a2b2f124c218f21525c7a19e894583ca4989e84b74c945a6c1998"; +static const char expected_block_hashes_hash[] = "156a2a9adf0478a1a72c5f886940ab5d9462441e592914c4fa9f72ce8e3fd46e"; void Blockchain::load_compiled_in_block_hashes(const GetCheckpointsCallback& get_checkpoints) { if (get_checkpoints == nullptr || !m_fast_sync) diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index 3175ad89c..7f7df27f2 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -686,7 +686,7 @@ namespace cryptonote if (prune_blockchain) { // display a message if the blockchain is not pruned yet - if (m_blockchain_storage.get_current_blockchain_height() > 1 && !m_blockchain_storage.get_blockchain_pruning_seed()) + if (!m_blockchain_storage.get_blockchain_pruning_seed()) { MGINFO("Pruning blockchain..."); CHECK_AND_ASSERT_MES(m_blockchain_storage.prune_blockchain(), false, "Failed to prune blockchain"); @@ -1918,7 +1918,7 @@ namespace cryptonote //----------------------------------------------------------------------------------------------- bool core::check_block_rate() { - if (m_offline || m_nettype == FAKECHAIN || m_target_blockchain_height > get_current_blockchain_height()) + if (m_offline || m_nettype == FAKECHAIN || m_target_blockchain_height > get_current_blockchain_height() || m_target_blockchain_height == 0) { MDEBUG("Not checking block rate, offline or syncing"); return true; diff --git a/src/cryptonote_core/tx_sanity_check.cpp b/src/cryptonote_core/tx_sanity_check.cpp index 10198a3d3..5bb723814 100644 --- a/src/cryptonote_core/tx_sanity_check.cpp +++ b/src/cryptonote_core/tx_sanity_check.cpp @@ -72,7 +72,7 @@ bool tx_sanity_check(Blockchain &blockchain, const cryptonote::blobdata &tx_blob if (n_indices <= 10) { - MERROR("n_indices is only " << n_indices); + MDEBUG("n_indices is only " << n_indices << ", not checking"); return true; } diff --git a/src/cryptonote_protocol/cryptonote_protocol_defs.h b/src/cryptonote_protocol/cryptonote_protocol_defs.h index 3083a5b4c..0c8155593 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_defs.h +++ b/src/cryptonote_protocol/cryptonote_protocol_defs.h @@ -83,6 +83,8 @@ namespace cryptonote uint32_t pruning_seed; + uint8_t address_type; + BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(incoming) KV_SERIALIZE(localhost) @@ -107,6 +109,7 @@ namespace cryptonote KV_SERIALIZE(connection_id) KV_SERIALIZE(height) KV_SERIALIZE(pruning_seed) + KV_SERIALIZE(address_type) END_KV_SERIALIZE_MAP() }; diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.h b/src/cryptonote_protocol/cryptonote_protocol_handler.h index 0927b5d7f..dcc5ec6ed 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.h +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.h @@ -52,6 +52,7 @@ PUSH_WARNINGS DISABLE_VS_WARNINGS(4355) #define LOCALHOST_INT 2130706433 +#define CURRENCY_PROTOCOL_MAX_OBJECT_REQUEST_COUNT 500 namespace cryptonote { diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl index 0ad89f7b2..0a5a1e802 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl @@ -285,6 +285,7 @@ namespace cryptonote cnx.height = cntxt.m_remote_blockchain_height; cnx.pruning_seed = cntxt.m_pruning_seed; + cnx.address_type = (uint8_t)cntxt.m_remote_address.get_type_id(); connections.push_back(cnx); @@ -809,12 +810,27 @@ namespace cryptonote NOTIFY_NEW_FLUFFY_BLOCK::request fluffy_response; fluffy_response.b.block = t_serializable_object_to_blob(b); fluffy_response.current_blockchain_height = arg.current_blockchain_height; + std::vector seen(b.tx_hashes.size(), false); for(auto& tx_idx: arg.missing_tx_indices) { if(tx_idx < b.tx_hashes.size()) { MDEBUG(" tx " << b.tx_hashes[tx_idx]); + if (seen[tx_idx]) + { + LOG_ERROR_CCONTEXT + ( + "Failed to handle request NOTIFY_REQUEST_FLUFFY_MISSING_TX" + << ", request is asking for duplicate tx " + << ", tx index = " << tx_idx << ", block tx count " << b.tx_hashes.size() + << ", block_height = " << arg.current_blockchain_height + << ", dropping connection" + ); + drop_connection(context, true, false); + return 1; + } txids.push_back(b.tx_hashes[tx_idx]); + seen[tx_idx] = true; } else { @@ -914,6 +930,17 @@ namespace cryptonote int t_cryptonote_protocol_handler::handle_request_get_objects(int command, NOTIFY_REQUEST_GET_OBJECTS::request& arg, cryptonote_connection_context& context) { MLOG_P2P_MESSAGE("Received NOTIFY_REQUEST_GET_OBJECTS (" << arg.blocks.size() << " blocks, " << arg.txs.size() << " txes)"); + + if (arg.blocks.size() + arg.txs.size() > CURRENCY_PROTOCOL_MAX_OBJECT_REQUEST_COUNT) + { + LOG_ERROR_CCONTEXT( + "Requested objects count is too big (" + << arg.blocks.size() + arg.txs.size() << ") expected not more then " + << CURRENCY_PROTOCOL_MAX_OBJECT_REQUEST_COUNT); + drop_connection(context, false, false); + return 1; + } + NOTIFY_RESPONSE_GET_OBJECTS::request rsp; if(!m_core.handle_get_objects(arg, rsp, context)) { @@ -2369,7 +2396,7 @@ skip: MINFO("Target height decreasing from " << previous_target << " to " << target); m_core.set_target_blockchain_height(target); if (target == 0 && context.m_state > cryptonote_connection_context::state_before_handshake && !m_stopping) - MCWARNING("global", "monerod is now disconnected from the network"); + MCWARNING("global", "wownerod is now disconnected from the network"); } m_block_queue.flush_spans(context.m_connection_id, false); diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp index ba02a0c38..9dec3a9a2 100644 --- a/src/daemon/rpc_command_executor.cpp +++ b/src/daemon/rpc_command_executor.cpp @@ -46,6 +46,19 @@ namespace daemonize { namespace { + const char *get_address_type_name(epee::net_utils::address_type address_type) + { + switch (address_type) + { + default: + case epee::net_utils::address_type::invalid: return "invalid"; + case epee::net_utils::address_type::ipv4: return "IPv4"; + case epee::net_utils::address_type::ipv6: return "IPv6"; + case epee::net_utils::address_type::i2p: return "I2P"; + case epee::net_utils::address_type::tor: return "Tor"; + } + } + void print_peer(std::string const & prefix, cryptonote::peer const & peer) { time_t now; @@ -559,8 +572,7 @@ bool t_rpc_command_executor::mining_status() { uint64_t daily = 86400ull / mres.block_target * mres.block_reward * ratio; uint64_t monthly = 86400ull / mres.block_target * 30.5 * mres.block_reward * ratio; uint64_t yearly = 86400ull / mres.block_target * 356 * mres.block_reward * ratio; - tools::msg_writer() << "Expected: " << cryptonote::print_money(daily) << " monero daily, " - << cryptonote::print_money(monthly) << " monero monthly, " << cryptonote::print_money(yearly) << " yearly"; + tools::msg_writer() << "Possible reward: " << cryptonote::print_money(monthly) << " WOW monthly, " << cryptonote::print_money(yearly) << " WOW yearly"; } return true; @@ -590,6 +602,7 @@ bool t_rpc_command_executor::print_connections() { } tools::msg_writer() << std::setw(30) << std::left << "Remote Host" + << std::setw(8) << "Type" << std::setw(6) << "SSL" << std::setw(20) << "Peer id" << std::setw(20) << "Support Flags" @@ -610,6 +623,7 @@ bool t_rpc_command_executor::print_connections() { tools::msg_writer() //<< std::setw(30) << std::left << in_out << std::setw(30) << std::left << address + << std::setw(8) << (get_address_type_name((epee::net_utils::address_type)info.address_type)) << std::setw(6) << (info.ssl ? "yes" : "no") << std::setw(20) << epee::string_tools::pad_string(info.peer_id, 16, '0', true) << std::setw(20) << info.support_flags diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl index c666e6ad9..4fdb953bd 100644 --- a/src/p2p/net_node.inl +++ b/src/p2p/net_node.inl @@ -1579,7 +1579,7 @@ namespace nodetool } else { - const el::Level level = el::Level::Warning; + const el::Level level = el::Level::Debug; MCLOG_RED(level, "global", "No incoming connections - check firewalls/routers allow port " << get_this_peer_port()); } } @@ -2207,10 +2207,11 @@ namespace nodetool auto public_zone = m_network_zones.find(epee::net_utils::zone::public_); if (public_zone != m_network_zones.end()) { - const auto current = public_zone->second.m_config.m_net_config.max_out_connection_count; + const auto current = public_zone->second.m_net_server.get_config_object().get_out_connections_count(); public_zone->second.m_config.m_net_config.max_out_connection_count = count; if(current > count) public_zone->second.m_net_server.get_config_object().del_out_connections(current - count); + m_payload_handler.set_max_out_peers(count); } } @@ -2220,7 +2221,7 @@ namespace nodetool auto public_zone = m_network_zones.find(epee::net_utils::zone::public_); if (public_zone != m_network_zones.end()) { - const auto current = public_zone->second.m_config.m_net_config.max_in_connection_count; + const auto current = public_zone->second.m_net_server.get_config_object().get_in_connections_count(); public_zone->second.m_config.m_net_config.max_in_connection_count = count; if(current > count) public_zone->second.m_net_server.get_config_object().del_in_connections(current - count); diff --git a/src/p2p/net_peerlist.h b/src/p2p/net_peerlist.h index f4fa921e2..fdbd3617a 100644 --- a/src/p2p/net_peerlist.h +++ b/src/p2p/net_peerlist.h @@ -379,8 +379,14 @@ namespace nodetool trim_gray_peerlist(); }else { - //update record in white list - m_peers_gray.replace(by_addr_it_gr, ple); + //update record in gray list + peerlist_entry new_ple = ple; + if (by_addr_it_gr->pruning_seed && ple.pruning_seed == 0) // guard against older nodes not passing pruning info around + new_ple.pruning_seed = by_addr_it_gr->pruning_seed; + if (by_addr_it_gr->rpc_port && ple.rpc_port == 0) // guard against older nodes not passing RPC port around + new_ple.rpc_port = by_addr_it_gr->rpc_port; + new_ple.last_seen = by_addr_it_gr->last_seen; // do not overwrite the last seen timestamp, incoming peer list are untrusted + m_peers_gray.replace(by_addr_it_gr, new_ple); } return true; CATCH_ENTRY_L0("peerlist_manager::append_with_peer_gray()", false); diff --git a/src/ringct/rctTypes.h b/src/ringct/rctTypes.h index 97ffe3f96..03a52775f 100644 --- a/src/ringct/rctTypes.h +++ b/src/ringct/rctTypes.h @@ -256,7 +256,7 @@ namespace rct { { FIELD(type) if (type == RCTTypeNull) - return true; + return ar.stream().good(); if (type != RCTTypeFull && type != RCTTypeSimple && type != RCTTypeBulletproof && type != RCTTypeBulletproof2 && type != RCTTypeFullBulletproof && type != RCTTypeSimpleBulletproof) return false; VARINT_FIELD(txnFee) @@ -316,7 +316,7 @@ namespace rct { ar.delimit_array(); } ar.end_array(); - return true; + return ar.stream().good(); } }; struct rctSigPrunable { @@ -329,7 +329,7 @@ namespace rct { bool serialize_rctsig_prunable(Archive &ar, uint8_t type, size_t inputs, size_t outputs, size_t mixin) { if (type == RCTTypeNull) - return true; + return ar.stream().good(); if (type != RCTTypeFull && type != RCTTypeSimple && type != RCTTypeBulletproof && type != RCTTypeBulletproof2 && type != RCTTypeFullBulletproof && type != RCTTypeSimpleBulletproof) return false; if (type == RCTTypeSimpleBulletproof || type == RCTTypeFullBulletproof) @@ -448,7 +448,7 @@ namespace rct { } ar.end_array(); } - return true; + return ar.stream().good(); } }; diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index c44864ced..562ceeac2 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -59,6 +59,8 @@ using namespace epee; #define MAX_RESTRICTED_FAKE_OUTS_COUNT 40 #define MAX_RESTRICTED_GLOBAL_FAKE_OUTS_COUNT 5000 +#define OUTPUT_HISTOGRAM_RECENT_CUTOFF_RESTRICTION (3 * 86400) // 3 days max, the wallet requests 1.8 days + namespace { void add_reason(std::string &reasons, const char *reason) @@ -1895,6 +1897,13 @@ namespace cryptonote if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON_RPC, "get_output_histogram", req, res, r)) return r; + const bool restricted = m_restricted && ctx; + if (restricted && req.recent_cutoff > 0 && req.recent_cutoff < (uint64_t)time(NULL) - OUTPUT_HISTOGRAM_RECENT_CUTOFF_RESTRICTION) + { + res.status = "Recent cutoff is too old"; + return true; + } + std::map> histogram; try { diff --git a/src/rpc/rpc_handler.cpp b/src/rpc/rpc_handler.cpp index af5cb98a3..d528ffef3 100644 --- a/src/rpc/rpc_handler.cpp +++ b/src/rpc/rpc_handler.cpp @@ -63,7 +63,9 @@ namespace rpc d.cached_to -= 10; d.cached_top_hash = hash10; d.cached_m10_hash = crypto::null_hash; - d.cached_distribution.resize(d.cached_distribution.size() - 10); + CHECK_AND_ASSERT_MES(d.cached_distribution.size() >= 10, boost::none, "Cached distribution size does not match cached bounds"); + for (int p = 0; p < 10; ++p) + d.cached_distribution.pop_back(); can_extend = true; } } diff --git a/src/serialization/binary_archive.h b/src/serialization/binary_archive.h index a0e4eff9d..9f60cf311 100644 --- a/src/serialization/binary_archive.h +++ b/src/serialization/binary_archive.h @@ -146,7 +146,8 @@ struct binary_archive : public binary_archive_base void serialize_uvarint(T &v) { typedef std::istreambuf_iterator it; - tools::read_varint(it(stream_), it(), v); // XXX handle failure + if (tools::read_varint(it(stream_), it(), v) < 0) + stream_.setstate(std::ios_base::failbit); } void begin_array(size_t &s) diff --git a/src/serialization/json_object.cpp b/src/serialization/json_object.cpp index 73e17a775..cc52bde58 100644 --- a/src/serialization/json_object.cpp +++ b/src/serialization/json_object.cpp @@ -566,6 +566,7 @@ void toJsonValue(rapidjson::Document& doc, const cryptonote::connection_info& in INSERT_INTO_JSON_OBJECT(val, doc, incoming, info.incoming); INSERT_INTO_JSON_OBJECT(val, doc, localhost, info.localhost); INSERT_INTO_JSON_OBJECT(val, doc, local_ip, info.local_ip); + INSERT_INTO_JSON_OBJECT(val, doc, address_type, info.address_type); INSERT_INTO_JSON_OBJECT(val, doc, ip, info.ip); INSERT_INTO_JSON_OBJECT(val, doc, port, info.port); @@ -601,6 +602,7 @@ void fromJsonValue(const rapidjson::Value& val, cryptonote::connection_info& inf GET_FROM_JSON_OBJECT(val, info.incoming, incoming); GET_FROM_JSON_OBJECT(val, info.localhost, localhost); GET_FROM_JSON_OBJECT(val, info.local_ip, local_ip); + GET_FROM_JSON_OBJECT(val, info.address_type, address_type); GET_FROM_JSON_OBJECT(val, info.ip, ip); GET_FROM_JSON_OBJECT(val, info.port, port); diff --git a/src/serialization/serialization.h b/src/serialization/serialization.h index 007bf265f..553e9951f 100644 --- a/src/serialization/serialization.h +++ b/src/serialization/serialization.h @@ -212,7 +212,7 @@ inline bool do_serialize(Archive &ar, bool &v) * \brief self-explanatory */ #define END_SERIALIZE() \ - return true; \ + return ar.stream().good(); \ } /*! \macro VALUE(f) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 6c1c987b5..8e7be70c8 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -4121,7 +4121,9 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) m_wallet->callback(this); - check_background_mining(password); + bool skip_check_backround_mining = !command_line::get_arg(vm, arg_command).empty(); + if (!skip_check_backround_mining) + check_background_mining(password); if (welcome) message_writer(console_color_yellow, true) << tr("If you are new to Wownero, type \"welcome\" for a brief overview."); @@ -4744,7 +4746,7 @@ void simple_wallet::stop_background_mining() return; } } - message_writer(console_color_red, false) << tr("Background mining not enabled. Run \"set setup-background-mining 1\" to change."); + message_writer() << tr("To enable automatic background mining run \"set setup-background-mining 1\"."); } //---------------------------------------------------------------------------------------------------- void simple_wallet::check_background_mining(const epee::wipeable_string &password) @@ -4752,7 +4754,7 @@ void simple_wallet::check_background_mining(const epee::wipeable_string &passwor tools::wallet2::BackgroundMiningSetupType setup = m_wallet->setup_background_mining(); if (setup == tools::wallet2::BackgroundMiningNo) { - message_writer(console_color_red, false) << tr("Background mining not enabled. Run \"set setup-background-mining 1\" to change."); + message_writer() << tr("To enable automatic background mining run \"set setup-background-mining 1\"."); return; } @@ -4790,7 +4792,7 @@ void simple_wallet::check_background_mining(const epee::wipeable_string &passwor if (std::cin.eof() || !command_line::is_yes(accepted)) { m_wallet->setup_background_mining(tools::wallet2::BackgroundMiningNo); m_wallet->rewrite(m_wallet_file, password); - message_writer(console_color_red, false) << tr("Background mining not enabled. Set setup-background-mining to 1 to change."); + message_writer() << tr("To enable automatic background mining run \"set setup-background-mining 1\"."); return; } m_wallet->setup_background_mining(tools::wallet2::BackgroundMiningYes); diff --git a/src/version.cpp.in b/src/version.cpp.in index 57e851ade..1f4134bda 100644 --- a/src/version.cpp.in +++ b/src/version.cpp.in @@ -1,5 +1,5 @@ #define DEF_MONERO_VERSION_TAG "@VERSIONTAG@" -#define DEF_MONERO_VERSION "0.6.1.1" +#define DEF_MONERO_VERSION "0.6.1.2" #define DEF_MONERO_RELEASE_NAME "F For Fappening" #define DEF_MONERO_VERSION_FULL DEF_MONERO_VERSION "-" DEF_MONERO_VERSION_TAG diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index ee53442de..6c3eaa757 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -1113,7 +1113,7 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds, bool unattended): m_segregation_height(0), m_ignore_fractional_outputs(true), m_track_uses(false), - m_setup_background_mining(BackgroundMiningMaybe), + m_setup_background_mining(BackgroundMiningNo), m_is_initialized(false), m_kdf_rounds(kdf_rounds), is_old_file_format(false), @@ -3789,7 +3789,7 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_ m_segregation_height = 0; m_ignore_fractional_outputs = true; m_track_uses = false; - m_setup_background_mining = BackgroundMiningMaybe; + m_setup_background_mining = BackgroundMiningNo; m_subaddress_lookahead_major = SUBADDRESS_LOOKAHEAD_MAJOR; m_subaddress_lookahead_minor = SUBADDRESS_LOOKAHEAD_MINOR; m_original_keys_available = false; diff --git a/src/wallet/wallet_args.cpp b/src/wallet/wallet_args.cpp index f585da357..02abcdd48 100644 --- a/src/wallet/wallet_args.cpp +++ b/src/wallet/wallet_args.cpp @@ -141,7 +141,7 @@ namespace wallet_args if (command_line::get_arg(vm, command_line::arg_help)) { Print(print) << "Wownero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL; - Print(print) << wallet_args::tr("This is the command line monero wallet. It needs to connect to a monero\n" + Print(print) << wallet_args::tr("This is the command line wownero wallet. It needs to connect to a wownero\n" "daemon to work correctly.") << ENDL; Print(print) << wallet_args::tr("Usage:") << ENDL << " " << usage; Print(print) << desc_all; diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index c5e1dc8a9..8189f432b 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -260,7 +260,7 @@ namespace tools tools::wallet2::BackgroundMiningSetupType setup = m_wallet->setup_background_mining(); if (setup == tools::wallet2::BackgroundMiningNo) { - MLOG_RED(el::Level::Warning, "Background mining not enabled. Run \"set setup-background-mining 1\" in monero-wallet-cli to change."); + MLOG_RED(el::Level::Warning, "Background mining not enabled. Run \"set setup-background-mining 1\" in wownero-wallet-cli to change."); return; } @@ -285,8 +285,8 @@ namespace tools { MINFO("The daemon is not set up to background mine."); MINFO("With background mining enabled, the daemon will mine when idle and not on batttery."); - MINFO("Enabling this supports the network you are using, and makes you eligible for receiving new monero"); - MINFO("Set setup-background-mining to 1 in monero-wallet-cli to change."); + MINFO("Enabling this supports the network you are using, and makes you eligible for receiving new wownero"); + MINFO("Set setup-background-mining to 1 in wownero-wallet-cli to change."); return; }