forked from such-gitea/wownero
Compare commits
57 Commits
v0.8.0.1
...
release-v0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
255b6a95f8 | ||
|
|
de53dd8386 | ||
|
|
b78d24db4f | ||
|
|
54a3c19ae2 | ||
|
|
fb5fad0768 | ||
|
|
bd0c321d2c | ||
|
|
2d8b8eb43c | ||
|
|
470045d660 | ||
|
|
3068408d04 | ||
|
|
1ecb5046d2 | ||
|
|
b99731e7b9 | ||
|
|
bc3acd54d5 | ||
|
|
ed3cb7cafb | ||
|
|
0419afa92e | ||
|
|
79bd185ec2 | ||
|
|
7e02dc3dca | ||
|
|
6537668224 | ||
|
|
5267747297 | ||
|
|
0a825e0a3e | ||
|
|
1c05789afc | ||
|
|
eee0e5e92f | ||
|
|
dff7e526a6 | ||
|
|
6fbb9cfa4f | ||
|
|
7681f4c364 | ||
|
|
74e6c5d2fe | ||
|
|
a01ad8b296 | ||
|
|
c236474c4b | ||
|
|
0781357b33 | ||
|
|
bb93513a7c | ||
|
|
88b4cb8f9c | ||
|
|
2de71c3beb | ||
|
|
6fb8129cb9 | ||
|
|
f8acc3a695 | ||
|
|
385c3fd9ab | ||
|
|
e61627d2e2 | ||
|
|
4c6c7ab87b | ||
|
|
de7ef82dc7 | ||
|
|
c73d4d0ce0 | ||
|
|
383c892488 | ||
|
|
0ba90c2b09 | ||
|
|
d55d97ac69 | ||
|
|
f3284eeaf0 | ||
|
|
104563af49 | ||
|
|
d1aa0a0449 | ||
|
|
ba2f6f4fc3 | ||
|
|
a65823a794 | ||
|
|
903a34edde | ||
|
|
8635d5dd3e | ||
|
|
62af9acbbd | ||
|
|
1fa73fa684 | ||
|
|
4265df1460 | ||
|
|
3d513d85a2 | ||
|
|
44a3b3f22c | ||
|
|
e671b5f89b | ||
|
|
ffee430b36 | ||
|
|
47a74343da | ||
|
|
34940d2e14 |
62
.github/workflows/build.yml
vendored
62
.github/workflows/build.yml
vendored
@@ -1,62 +0,0 @@
|
||||
name: continuous-integration/gh-actions/cli
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build-macos:
|
||||
runs-on: macOS-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: update brew and install dependencies
|
||||
run: brew update && brew install boost hidapi zmq libpgm miniupnpc ldns expat libunwind-headers protobuf
|
||||
- name: build
|
||||
run: make -j3
|
||||
|
||||
build-windows:
|
||||
runs-on: windows-latest
|
||||
defaults:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
with:
|
||||
submodules: recursive
|
||||
- uses: eine/setup-msys2@v1
|
||||
with:
|
||||
update: true
|
||||
install: mingw-w64-x86_64-toolchain make mingw-w64-x86_64-cmake mingw-w64-x86_64-boost mingw-w64-x86_64-openssl mingw-w64-x86_64-zeromq mingw-w64-x86_64-libsodium mingw-w64-x86_64-hidapi mingw-w64-x86_64-protobuf-c mingw-w64-x86_64-libusb git
|
||||
- name: build
|
||||
run: make release-static-win64 -j2
|
||||
|
||||
build-ubuntu:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: remove bundled boost
|
||||
run: sudo rm -rf /usr/local/share/boost
|
||||
- name: update apt
|
||||
run: sudo apt update
|
||||
- name: install monero dependencies
|
||||
run: sudo apt -y install build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev libzmq3-dev libsodium-dev libhidapi-dev libnorm-dev libusb-1.0-0-dev libpgm-dev
|
||||
- name: build
|
||||
run: make -j3
|
||||
|
||||
libwallet-ubuntu:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: remove bundled boost
|
||||
run: sudo rm -rf /usr/local/share/boost
|
||||
- name: update apt
|
||||
run: sudo apt update
|
||||
- name: install monero dependencies
|
||||
run: sudo apt -y install build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev libzmq3-dev libsodium-dev libhidapi-dev libnorm-dev libusb-1.0-0-dev libpgm-dev
|
||||
- name: build
|
||||
run: cmake -DBUILD_GUI_DEPS=ON && make -j3
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -107,5 +107,3 @@ nbproject
|
||||
.idea/
|
||||
|
||||
/testnet
|
||||
|
||||
__pycache__/
|
||||
|
||||
2
.gitmodules
vendored
2
.gitmodules
vendored
@@ -15,5 +15,5 @@
|
||||
[submodule "external/RandomWOW"]
|
||||
path = external/RandomWOW
|
||||
url = https://github.com/wownero/RandomWOW
|
||||
branch = 1.1.7-wow
|
||||
branch = 1.1.6-wow
|
||||
|
||||
|
||||
@@ -34,8 +34,6 @@ env:
|
||||
- HOST=x86_64-unknown-linux-gnu PACKAGES="gperf cmake python3-zmq libdbus-1-dev libharfbuzz-dev"
|
||||
# Cross-Mac
|
||||
- HOST=x86_64-apple-darwin11 PACKAGES="cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python-dev python3-setuptools-git" OSX_SDK=10.11
|
||||
# x86_64 Freebsd
|
||||
- HOST=x86_64-unknown-freebsd PACKAGES="clang-8 gperf cmake python3-zmq libdbus-1-dev libharfbuzz-dev"
|
||||
|
||||
before_install:
|
||||
- export PATH=$(echo $PATH | tr ':' "\n" | sed '/\/opt\/python/d' | tr "\n" ":" | sed "s|::|:|g")
|
||||
|
||||
@@ -46,10 +46,8 @@ Connecting to an anonymous address requires the command line option
|
||||
`--tx-proxy` which tells `monerod` the ip/port of a socks proxy provided by a
|
||||
separate process. On most systems the configuration will look like:
|
||||
|
||||
```
|
||||
--tx-proxy tor,127.0.0.1:9050,10
|
||||
--tx-proxy i2p,127.0.0.1:9000
|
||||
```
|
||||
> `--tx-proxy tor,127.0.0.1:9050,10`
|
||||
> `--tx-proxy i2p,127.0.0.1:9000`
|
||||
|
||||
which tells `monerod` that ".onion" p2p addresses can be forwarded to a socks
|
||||
proxy at IP 127.0.0.1 port 9050 with a max of 10 outgoing connections and
|
||||
@@ -57,14 +55,12 @@ proxy at IP 127.0.0.1 port 9050 with a max of 10 outgoing connections and
|
||||
9000 with the default max outgoing connections. Since there are no seed nodes
|
||||
for anonymity connections, peers must be manually specified:
|
||||
|
||||
```
|
||||
--add-exclusive-node rveahdfho7wo4b2m.onion:28083
|
||||
--add-peer rveahdfho7wo4b2m.onion:28083
|
||||
```
|
||||
> `--add-exclusive-node rveahdfho7wo4b2m.onion:28083`
|
||||
> `--add-peer rveahdfho7wo4b2m.onion:28083`
|
||||
|
||||
Either option can be listed multiple times, and can specify any mix of Tor,
|
||||
I2P, and IPv4 addresses. Using `--add-exclusive-node` will prevent the usage of
|
||||
seed nodes on ALL networks, which will typically be undesirable.
|
||||
seed nodes on ALL networks, which will typically be undesireable.
|
||||
|
||||
### Inbound Connections
|
||||
|
||||
@@ -72,10 +68,8 @@ Receiving anonymity connections is done through the option
|
||||
`--anonymous-inbound`. This option tells `monerod` the inbound address, network
|
||||
type, and max connections:
|
||||
|
||||
```
|
||||
--anonymous-inbound rveahdfho7wo4b2m.onion:28083,127.0.0.1:28083,25
|
||||
--anonymous-inbound cmeua5767mz2q5jsaelk2rxhf67agrwuetaso5dzbenyzwlbkg2q.b32.i2p:5000,127.0.0.1:30000
|
||||
```
|
||||
> `--anonymous-inbound rveahdfho7wo4b2m.onion:28083,127.0.0.1:28083,25`
|
||||
> `--anonymous-inbound cmeua5767mz2q5jsaelk2rxhf67agrwuetaso5dzbenyzwlbkg2q.b32.i2p:5000,127.0.0.1:30000`
|
||||
|
||||
which tells `monerod` that a max of 25 inbound Tor connections are being
|
||||
received at address "rveahdfho7wo4b2m.onion:28083" and forwarded to `monerod`
|
||||
@@ -93,16 +87,12 @@ P2P anonymity connections. The anonymity network (Tor/i2p) is
|
||||
[configured in the same manner](#configuration), except the localhost port
|
||||
must be the RPC port (typically 18081 for mainnet) instead of the p2p port:
|
||||
|
||||
```
|
||||
HiddenServiceDir /var/lib/tor/data/monero
|
||||
HiddenServicePort 18081 127.0.0.1:18081
|
||||
```
|
||||
> HiddenServiceDir /var/lib/tor/data/monero
|
||||
> HiddenServicePort 18081 127.0.0.1:18081
|
||||
|
||||
Then the wallet will be configured to use a Tor/i2p address:
|
||||
```
|
||||
--proxy 127.0.0.1:9050
|
||||
--daemon-address rveahdfho7wo4b2m.onion
|
||||
```
|
||||
> `--proxy 127.0.0.1:9050`
|
||||
> `--daemon-address rveahdfho7wo4b2m.onion`
|
||||
|
||||
The proxy must match the address type - a Tor proxy will not work properly with
|
||||
i2p addresses, etc.
|
||||
@@ -135,10 +125,8 @@ can distribute the address to its other peers.
|
||||
Tor must be configured for hidden services. An example configuration ("torrc")
|
||||
might look like:
|
||||
|
||||
```
|
||||
HiddenServiceDir /var/lib/tor/data/monero
|
||||
HiddenServicePort 28083 127.0.0.1:28083
|
||||
```
|
||||
> HiddenServiceDir /var/lib/tor/data/monero
|
||||
> HiddenServicePort 28083 127.0.0.1:28083
|
||||
|
||||
This will store key information in `/var/lib/tor/data/monero` and will forward
|
||||
"Tor port" 28083 to port 28083 of ip 127.0.0.1. The file
|
||||
@@ -182,7 +170,7 @@ be used by an ISP to link a user to a transaction.
|
||||
Run `monerod` as often as possible to conceal when transactions are being sent.
|
||||
Future versions will also have peers that first receive a transaction over an
|
||||
anonymity network delay the broadcast to public peers by a randomized amount.
|
||||
This will not completely mitigate a user who syncs up sends then quits, in
|
||||
This will not completetely mitigate a user who syncs up sends then quits, in
|
||||
part because this rule is not enforceable, so this mitigation strategy is
|
||||
simply a best effort attempt.
|
||||
|
||||
@@ -195,9 +183,9 @@ the connections are not circuit based.
|
||||
|
||||
#### Mitigation
|
||||
|
||||
The best mitigation is to use I2P instead of Tor. However, I2P
|
||||
The best mitigiation is to use I2P instead of Tor. However, I2P
|
||||
has a smaller set of users (less cover traffic) and academic reviews, so there
|
||||
is a trade off in potential issues. Also, anyone attempting this strategy really
|
||||
is a tradeoff in potential isses. Also, anyone attempting this strategy really
|
||||
wants to uncover a user, it seems unlikely that this would be performed against
|
||||
every Tor/I2P user.
|
||||
|
||||
@@ -225,7 +213,7 @@ key identity.
|
||||
@secparam (twitter) recommended changing circuits (Tor) as an additional
|
||||
precaution. This is likely not a good idea - forcibly requesting Tor to change
|
||||
circuits is observable by the ISP. Instead, `monerod` should likely disconnect
|
||||
from peers occasionally. Tor will rotate circuits every ~10 minutes, so
|
||||
from peers ocassionally. Tor will rotate circuits every ~10 minutes, so
|
||||
establishing new connections will use a new public key identity and make it
|
||||
more difficult for the hidden service to link information. This process will
|
||||
have to be done carefully because closing/reconnecting connections can also
|
||||
|
||||
@@ -48,8 +48,6 @@ message(STATUS "CMake version ${CMAKE_VERSION}")
|
||||
|
||||
project(monero)
|
||||
|
||||
include(FindCcache) # Has to be included after the project() macro, to be able to read the CXX variable.
|
||||
|
||||
enable_language(C ASM)
|
||||
|
||||
function (die msg)
|
||||
|
||||
90
Dockerfile
90
Dockerfile
@@ -11,6 +11,8 @@ RUN set -ex && \
|
||||
g++ \
|
||||
make \
|
||||
pkg-config \
|
||||
graphviz \
|
||||
doxygen \
|
||||
git \
|
||||
curl \
|
||||
libtool-bin \
|
||||
@@ -53,8 +55,8 @@ RUN set -ex \
|
||||
ENV BOOST_ROOT /usr/local/boost_${BOOST_VERSION}
|
||||
|
||||
# OpenSSL
|
||||
ARG OPENSSL_VERSION=1.1.1g
|
||||
ARG OPENSSL_HASH=ddb04774f1e32f0c49751e21b67216ac87852ceb056b75209af2443400636d46
|
||||
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 \
|
||||
@@ -66,6 +68,28 @@ RUN set -ex \
|
||||
&& make install
|
||||
ENV OPENSSL_ROOT_DIR=/usr/local/openssl-${OPENSSL_VERSION}
|
||||
|
||||
# ZMQ
|
||||
ARG ZMQ_VERSION=v4.3.2
|
||||
ARG ZMQ_HASH=a84ffa12b2eb3569ced199660bac5ad128bff1f0
|
||||
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.4.1
|
||||
ARG CPPZMQ_HASH=f5b36e563598d48fcc0d82e589d3596afef945ae
|
||||
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
|
||||
@@ -103,6 +127,44 @@ RUN set -ex \
|
||||
&& 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.1
|
||||
ARG PROTOBUF_HASH=6973c3a5041636c1d8dc5f7f6c8c1f3c15bc63d6
|
||||
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 \
|
||||
&& ./autogen.sh \
|
||||
&& ./configure --enable-static --disable-shared \
|
||||
&& make \
|
||||
&& make install \
|
||||
&& ldconfig
|
||||
|
||||
WORKDIR /src
|
||||
COPY . .
|
||||
|
||||
@@ -126,25 +188,25 @@ RUN set -ex && \
|
||||
rm -rf /var/lib/apt
|
||||
COPY --from=builder /src/build/release/bin /usr/local/bin/
|
||||
|
||||
# Create wownero user
|
||||
RUN adduser --system --group --disabled-password wownero && \
|
||||
mkdir -p /wallet /home/wownero/.wownero && \
|
||||
chown -R wownero:wownero /home/wownero/.wownero && \
|
||||
chown -R wownero:wownero /wallet
|
||||
# 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
|
||||
|
||||
# Contains the blockchain
|
||||
VOLUME /home/wownero/.wownero
|
||||
VOLUME /home/monero/.bitmonero
|
||||
|
||||
# Generate your wallet via accessing the container and run:
|
||||
# cd /wallet
|
||||
# wownero-wallet-cli
|
||||
# monero-wallet-cli
|
||||
VOLUME /wallet
|
||||
|
||||
EXPOSE 34567
|
||||
EXPOSE 34568
|
||||
EXPOSE 18080
|
||||
EXPOSE 18081
|
||||
|
||||
# switch to user wownero
|
||||
USER wownero
|
||||
# switch to user monero
|
||||
USER monero
|
||||
|
||||
ENTRYPOINT ["wownerod", "--p2p-bind-ip=0.0.0.0", "--p2p-bind-port=34567", "--rpc-bind-ip=0.0.0.0", "--rpc-bind-port=34568", "--non-interactive", "--confirm-external-bind"]
|
||||
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"]
|
||||
|
||||
|
||||
20
Makefile
20
Makefile
@@ -73,7 +73,7 @@ debug-test-trezor:
|
||||
|
||||
debug-all:
|
||||
mkdir -p $(builddir)/debug
|
||||
cd $(builddir)/debug && cmake -D BUILD_TESTS=OFF -D USE_DEVICE_TREZOR=OFF -D BUILD_SHARED_LIBS=OFF -D CMAKE_BUILD_TYPE=Debug $(topdir) && $(MAKE)
|
||||
cd $(builddir)/debug && cmake -D BUILD_TESTS=OFF -D BUILD_SHARED_LIBS=OFF -D CMAKE_BUILD_TYPE=Debug $(topdir) && $(MAKE)
|
||||
|
||||
debug-static-all:
|
||||
mkdir -p $(builddir)/debug
|
||||
@@ -81,11 +81,11 @@ debug-static-all:
|
||||
|
||||
debug-static-win64:
|
||||
mkdir -p $(builddir)/debug
|
||||
cd $(builddir)/debug && cmake -G "MSYS Makefiles" -D STATIC=ON -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=Debug -D BUILD_TAG="win-x64" -D CMAKE_TOOLCHAIN_FILE=$(topdir)/cmake/64-bit-toolchain.cmake -D MSYS2_FOLDER=$(shell cd ${MINGW_PREFIX}/.. && pwd -W) $(topdir) && $(MAKE)
|
||||
cd $(builddir)/debug && cmake -G "MSYS Makefiles" -D STATIC=ON -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=Debug -D BUILD_TAG="win-x64" -D CMAKE_TOOLCHAIN_FILE=$(topdir)/cmake/64-bit-toolchain.cmake -D MSYS2_FOLDER=c:/msys64 $(topdir) && $(MAKE)
|
||||
|
||||
debug-static-win32:
|
||||
mkdir -p $(builddir)/debug
|
||||
cd $(builddir)/debug && cmake -G "MSYS Makefiles" -D STATIC=ON -D ARCH="i686" -D BUILD_64=OFF -D CMAKE_BUILD_TYPE=Debug -D BUILD_TAG="win-x32" -D CMAKE_TOOLCHAIN_FILE=$(topdir)/cmake/32-bit-toolchain.cmake -D MSYS2_FOLDER=$(shell cd ${MINGW_PREFIX}/.. && pwd -W) $(topdir) && $(MAKE)
|
||||
cd $(builddir)/debug && cmake -G "MSYS Makefiles" -D STATIC=ON -D ARCH="i686" -D BUILD_64=OFF -D CMAKE_BUILD_TYPE=Debug -D BUILD_TAG="win-x32" -D CMAKE_TOOLCHAIN_FILE=$(topdir)/cmake/32-bit-toolchain.cmake -D MSYS2_FOLDER=c:/msys32 $(topdir) && $(MAKE)
|
||||
|
||||
cmake-release:
|
||||
mkdir -p $(builddir)/release
|
||||
@@ -100,11 +100,11 @@ release-test:
|
||||
|
||||
release-all:
|
||||
mkdir -p $(builddir)/release
|
||||
cd $(builddir)/release && cmake -D BUILD_TESTS=OFF -D USE_DEVICE_TREZOR=OFF -D CMAKE_BUILD_TYPE=release $(topdir) && $(MAKE)
|
||||
cd $(builddir)/release && cmake -D BUILD_TESTS=OFF -D CMAKE_BUILD_TYPE=release $(topdir) && $(MAKE)
|
||||
|
||||
release-static:
|
||||
mkdir -p $(builddir)/release
|
||||
cd $(builddir)/release && cmake -D BUILD_TESTS=OFF -D USE_DEVICE_TREZOR=OFF -D STATIC=ON -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=release $(topdir) && $(MAKE)
|
||||
cd $(builddir)/release && cmake -D BUILD_TESTS=OFF -D STATIC=ON -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=release $(topdir) && $(MAKE)
|
||||
|
||||
coverage:
|
||||
mkdir -p $(builddir)/debug
|
||||
@@ -136,15 +136,15 @@ release-static-linux-armv8:
|
||||
|
||||
release-static-linux-x86_64:
|
||||
mkdir -p $(builddir)/release
|
||||
cd $(builddir)/release && cmake -D STATIC=ON -D USE_DEVICE_TREZOR=OFF -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=release -D BUILD_TAG="linux-x64" $(topdir) && $(MAKE)
|
||||
cd $(builddir)/release && cmake -D STATIC=ON -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=release -D BUILD_TAG="linux-x64" $(topdir) && $(MAKE)
|
||||
|
||||
release-static-freebsd-x86_64:
|
||||
mkdir -p $(builddir)/release
|
||||
cd $(builddir)/release && cmake -D STATIC=ON -D USE_DEVICE_TREZOR=OFF -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=release -D BUILD_TAG="freebsd-x64" $(topdir) && $(MAKE)
|
||||
cd $(builddir)/release && cmake -D STATIC=ON -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=release -D BUILD_TAG="freebsd-x64" $(topdir) && $(MAKE)
|
||||
|
||||
release-static-mac-x86_64:
|
||||
mkdir -p $(builddir)/release
|
||||
cd $(builddir)/release && cmake -D STATIC=ON -D USE_DEVICE_TREZOR=OFF -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=release -D BUILD_TAG="mac-x64" $(topdir) && $(MAKE)
|
||||
cd $(builddir)/release && cmake -D STATIC=ON -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=release -D BUILD_TAG="mac-x64" $(topdir) && $(MAKE)
|
||||
|
||||
release-static-linux-i686:
|
||||
mkdir -p $(builddir)/release
|
||||
@@ -152,11 +152,11 @@ release-static-linux-i686:
|
||||
|
||||
release-static-win64:
|
||||
mkdir -p $(builddir)/release
|
||||
cd $(builddir)/release && cmake -G "MSYS Makefiles" -D STATIC=ON -D USE_DEVICE_TREZOR=OFF -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=Release -D BUILD_TAG="win-x64" -D CMAKE_TOOLCHAIN_FILE=$(topdir)/cmake/64-bit-toolchain.cmake -D MSYS2_FOLDER=$(shell cd ${MINGW_PREFIX}/.. && pwd -W) $(topdir) && $(MAKE)
|
||||
cd $(builddir)/release && cmake -G "MSYS Makefiles" -D STATIC=ON -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=Release -D BUILD_TAG="win-x64" -D CMAKE_TOOLCHAIN_FILE=$(topdir)/cmake/64-bit-toolchain.cmake -D MSYS2_FOLDER=c:/msys64 $(topdir) && $(MAKE)
|
||||
|
||||
release-static-win32:
|
||||
mkdir -p $(builddir)/release
|
||||
cd $(builddir)/release && cmake -G "MSYS Makefiles" -D STATIC=ON -D ARCH="i686" -D BUILD_64=OFF -D CMAKE_BUILD_TYPE=Release -D BUILD_TAG="win-x32" -D CMAKE_TOOLCHAIN_FILE=$(topdir)/cmake/32-bit-toolchain.cmake -D MSYS2_FOLDER=$(shell cd ${MINGW_PREFIX}/.. && pwd -W) $(topdir) && $(MAKE)
|
||||
cd $(builddir)/release && cmake -G "MSYS Makefiles" -D STATIC=ON -D ARCH="i686" -D BUILD_64=OFF -D CMAKE_BUILD_TYPE=Release -D BUILD_TAG="win-x32" -D CMAKE_TOOLCHAIN_FILE=$(topdir)/cmake/32-bit-toolchain.cmake -D MSYS2_FOLDER=c:/msys32 $(topdir) && $(MAKE)
|
||||
|
||||
fuzz:
|
||||
mkdir -p $(builddir)/fuzz
|
||||
|
||||
80
PKGBUILD
80
PKGBUILD
@@ -1,65 +1,37 @@
|
||||
# Maintainer: wowario <wowario[at]protonmail[dot]com>
|
||||
# Maintainer: wowario <wowario at protonmail dot com>
|
||||
# Contributor: wowario <wowario at protonmail dot com>
|
||||
|
||||
pkgname=wownero-git
|
||||
pkgver=0.8.0.0
|
||||
pkgbase=('wownero-git')
|
||||
pkgname=('wownero-git')
|
||||
pkgver=v0.6.1.1.r2.9afbcfb7
|
||||
pkgrel=1
|
||||
pkgdesc="Wownero: a fairly launched privacy-centric meme coin with no premine and a finite supply"
|
||||
license=('BSD')
|
||||
pkgdesc="a fairly launched privacy-centric meme coin with no premine and a finite supply"
|
||||
license=('custom:Cryptonote')
|
||||
arch=('x86_64')
|
||||
url="https://wownero.org/"
|
||||
depends=('boost-libs' 'libunwind' 'openssl' 'readline' 'zeromq' 'pcsclite' 'hidapi' 'protobuf')
|
||||
url="http://wownero.org/"
|
||||
depends=('openssl' 'zeromq' 'libpgm' 'unbound' 'libsodium')
|
||||
makedepends=('git' 'cmake' 'boost')
|
||||
source=(
|
||||
"${pkgname}"::"git+https://github.com/wownero/wownero#tag=v${pkgver}"
|
||||
"git+https://github.com/monero-project/unbound.git"
|
||||
"git+https://github.com/monero-project/miniupnp.git"
|
||||
"git+https://github.com/Tencent/rapidjson.git"
|
||||
"git+https://github.com/trezor/trezor-common.git"
|
||||
"git+https://github.com/wownero/RandomWOW.git"
|
||||
"wownero.sysusers"
|
||||
"wownero.tmpfiles")
|
||||
sha512sums=('SKIP'
|
||||
'SKIP'
|
||||
'SKIP'
|
||||
'SKIP'
|
||||
'SKIP'
|
||||
'SKIP'
|
||||
'SKIP'
|
||||
'SKIP')
|
||||
provides=('wownero-git')
|
||||
|
||||
prepare() {
|
||||
cd "${pkgname}"
|
||||
git submodule init
|
||||
git config submodule.external/unbound.url "$srcdir/unbound"
|
||||
git config submodule.external/miniupnp.url "$srcdir/miniupnp"
|
||||
git config submodule.external/rapidjson.url "$srcdir/rapidjson"
|
||||
git config submodule.external/trezor-common.url "$srcdir/trezor-common"
|
||||
git config submodule.external/RandomWOW.url "$srcdir/RandomWOW"
|
||||
git submodule update
|
||||
source=("${pkgname}"::"git+https://github.com/wownero/wownero")
|
||||
|
||||
sha256sums=('SKIP')
|
||||
|
||||
pkgver() {
|
||||
cd "$srcdir/$pkgname"
|
||||
git describe --long --tags | sed 's/\([^-]*-\)g/r\1/;s/-/./g'
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "${pkgname}"
|
||||
mkdir -p build && cd build
|
||||
cmake -D BUILD_TESTS=OFF -D CMAKE_BUILD_TYPE=release -D ARCH=default ../
|
||||
make
|
||||
cd "${srcdir}/${pkgname}"
|
||||
USE_SINGLE_BUILDDIR=1 make
|
||||
}
|
||||
|
||||
package() {
|
||||
backup=('etc/wownerod.conf')
|
||||
|
||||
cd "${pkgname}"
|
||||
install -Dm644 "LICENSE" -t "${pkgdir}/usr/share/licenses/${pkgname}"
|
||||
|
||||
install -Dm644 "utils/conf/wownerod.conf" "${pkgdir}/etc/wownerod.conf"
|
||||
install -Dm644 "utils/systemd/wownerod.service" "${pkgdir}/usr/lib/systemd/system/wownerod.service"
|
||||
install -Dm644 "../wownero.sysusers" "${pkgdir}/usr/lib/sysusers.d/wownero.conf"
|
||||
install -Dm644 "../wownero.tmpfiles" "${pkgdir}/usr/lib/tmpfiles.d/wownero.conf"
|
||||
|
||||
install -Dm755 "build/bin/wownero-wallet-cli" \
|
||||
"build/bin/wownero-wallet-rpc" \
|
||||
"build/bin/wownerod" \
|
||||
-t "${pkgdir}/usr/bin"
|
||||
package_wownero-git() {
|
||||
install -Dm644 "${srcdir}/${pkgname}/LICENSE" "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
|
||||
install -Dm644 "${srcdir}/${pkgname}/utils/conf/wownerod.conf" "${pkgdir}/etc/wownerod.conf"
|
||||
install -Dm644 "${srcdir}/${pkgname}/utils/systemd/wownerod.service" "${pkgdir}/usr/lib/systemd/system/wownerod.service"
|
||||
install -Dm755 "${srcdir}/${pkgname}/build/release/bin/wownerod" "${pkgdir}/usr/bin/wownerod"
|
||||
install -Dm755 "${srcdir}/${pkgname}/build/release/bin/wownero-wallet-cli" "${pkgdir}/usr/bin/wownero-wallet-cli"
|
||||
install -Dm755 "${srcdir}/${pkgname}/build/release/bin/wownero-wallet-rpc" "${pkgdir}/usr/bin/wownero-wallet-rpc"
|
||||
}
|
||||
|
||||
# vim: ts=2 sw=2 et:
|
||||
|
||||
49
README.md
49
README.md
@@ -25,10 +25,11 @@ An Android Wallet for Wownero
|
||||
- Twitter: [@w0wn3r0](https://twitter.com/w0wn3r0)
|
||||
- Reddit: [/r/wownero](https://www.reddit.com/r/wownero)
|
||||
- Mail: [wownero@protonmail.com](mailto:wownero@protonmail.com)
|
||||
- GitHub: [https://git.wownero.com/wownero/wownero](https://git.wownero.com/wownero/wownero)
|
||||
- GitHub: [https://github.com/wownero/wownero](https://github.com/wownero/wownero)
|
||||
- IRC: [#wownero on Freenode](https://kiwiirc.com/client/irc.freenode.net/?nick=suchchatter|?#wownero)
|
||||
- Bitmessage Chan: wownero (`BM-2cSzWtrj2pzLva9GF1Jp2TYsnLjrnJpvba`)
|
||||
- Wownero Funding System: [https://funding.wownero.com](https://funding.wownero.com)
|
||||
- Keybase Chat Group: [https://keybase.io/team/wownero](https://keybase.io/team/wownero)
|
||||
|
||||
Blockchain Explorers
|
||||
- https://explore.wownero.com
|
||||
@@ -37,14 +38,7 @@ Blockchain Explorers
|
||||
|
||||
Free Public Nodes
|
||||
- wow7dhbgiljnkspkzpjyy66auegbrye2ptfv4gucgbhireg5rrjza5ad.onion:34568
|
||||
- so.wow.candy.surf:34568 (US)
|
||||
- such.wow.candy.surf:34568 (CAN)
|
||||
- very.wow.candy.surf:34568 (IN)
|
||||
- much.wow.candy.surf:34568 (UK)
|
||||
|
||||
Tor Peers
|
||||
- wowp2p5gelm6vhl2d5tvfqills63jilgy6hkvlrqljooov5ktaxgqdad.onion
|
||||
- f3moshycuklu3mb3wnlfjwn26nsgzreqtfzfuyjjk46u7jqxlhf7d5id.onion
|
||||
- wow.aluisyo.network:34568
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -58,17 +52,16 @@ Dates are provided in the format YYYY-MM-DD.
|
||||
| Software upgrade block height | Date | Release Name | Minimum Wownero version | Recommended Wownero version | Details |
|
||||
| ------------------------------ | -----------| ----------------- | ---------------------- | -------------------------- | ---------------------------------------------------------------------------------- |
|
||||
| 1 | 2018-04-01 | Awesome Akita | v0.1.0.0 | v0.1.0.0 | Cryptonight variant 1, ringsize >= 8, sorted inputs
|
||||
| 69,69 | 2018-04-24 | Busty Brazzers | v0.2.0.0 | v0.2.0.0 | Bulletproofs, LWMA difficulty algorithm, ringsize >= 10, reduce unlock to 4
|
||||
| 53,666 | 2018-10-06 | Cool Cage | v0.3.0.0 | v0.3.1.3 | Cryptonight variant 2, LWMA v2, ringsize = 22, MMS
|
||||
| 63,469 | 2018-11-11 | Dank Doge | v0.4.0.0 | v0.4.0.0 | LWMA v4
|
||||
| 81,769 | 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
|
||||
| 114,969 | 2019-06-14 | F For Fappening | v0.6.1.0 | v0.6.1.2 | RandomWOW, new block weight algorithm, slightly more efficient RingCT format
|
||||
| 160,777 | 2019-11-20 | Gaping Goatse | v0.7.0.0 | v0.7.1.0 | Only allow >= 2 outputs, change to the block median used to calculate penalty, rct sigs in coinbase forbidden, 4 unlock time as protocol rule
|
||||
| 288,888 | 2021-02-08 | Hallucinogenic Hypnotoad | v0.8.0.0 | v0.8.0.1 | SHA3-256 PoW, Dandelion++ support
|
||||
| 6969 | 2018-04-24 | Busty Brazzers | v0.2.0.0 | v0.2.0.0 | Bulletproofs, LWMA difficulty algorithm, ringsize >= 10, reduce unlock to 4
|
||||
| 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.2 | RandomWOW, new block weight algorithm, slightly more efficient RingCT format
|
||||
| 160777 | 2019-11-20 | Gaping Goatse | v0.7.0.0 | v0.7.1.0 | Only allow >= 2 outputs, change to the block median used to calculate penalty, rct sigs in coinbase forbidden, 4 unlock time as protocol rule
|
||||
| XXXXX | 2020-04-XX | XXXX | v0.8.0.0 | v0.8.0.0 | Dandelion++ support
|
||||
|
||||
X's indicate that these details have not been determined as of commit date.
|
||||
|
||||
\* indicates estimate as of commit date
|
||||
* indicates estimate as of commit date
|
||||
|
||||
## Release staging and Contributing
|
||||
|
||||
@@ -84,21 +77,13 @@ Packages are available for
|
||||
|
||||
yay -S wownero-git
|
||||
|
||||
* Gentoo
|
||||
|
||||
emerge --noreplace eselect-repository
|
||||
eselect repository enable monero
|
||||
emaint sync -r monero
|
||||
echo '*/*::monero ~amd64' >> /etc/portage/package.accept_keywords
|
||||
emerge net-p2p/wownero
|
||||
|
||||
* NixOS
|
||||
|
||||
nix-shell -p wownero
|
||||
|
||||
* Ubuntu 18.04/Ubuntu 16.04/Debian 9/Debian 8 (amd64)
|
||||
|
||||
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 8BC34ABB48E565F0
|
||||
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys B09DF0E4B0C56A94
|
||||
sudo add-apt-repository "deb http://ppa.wownero.com/ bionic main"
|
||||
sudo apt-get update
|
||||
sudo apt-get install wownero
|
||||
@@ -113,17 +98,17 @@ Packaging for your favorite distribution would be a welcome contribution!
|
||||
* Arch Linux/Manjaro
|
||||
|
||||
sudo pacman -Syu && sudo pacman -S base-devel cmake boost openssl zeromq libpgm unbound libsodium git
|
||||
git clone https://git.wownero.com/wownero/wownero
|
||||
git clone https://github.com/wownero/wownero
|
||||
cd wownero
|
||||
make -j2
|
||||
make
|
||||
|
||||
|
||||
* Debian/Ubuntu
|
||||
|
||||
sudo apt update && sudo apt install build-essential cmake pkg-config libboost-all-dev libssl-dev libzmq3-dev libunbound-dev libsodium-dev libpgm-dev git
|
||||
git clone https://git.wownero.com/wownero/wownero
|
||||
git clone https://github.com/wownero/wownero
|
||||
cd wownero
|
||||
make -j2
|
||||
make
|
||||
|
||||
|
||||
## Running Binaries
|
||||
@@ -181,7 +166,7 @@ HiddenServicePort 44568 127.0.0.1:44568
|
||||
./wownero-wallet-cli --proxy 127.0.0.1:9150 --daemon-address wow7dhbgiljnkspkzpjyy66auegbrye2ptfv4gucgbhireg5rrjza5ad.onion:34568
|
||||
```
|
||||
|
||||
Use port `9050` instead of `9150` if you installed Tor as a standalone daemon. For more information, check out [ANONYMITY_NETWORKS](https://git.wownero.com/wownero/wownero/src/branch/master/ANONYMITY_NETWORKS.md).
|
||||
Use port `9050` instead of `9150` if you installed Tor as a standalone daemon. For more information, check out [ANONYMITY_NETWORKS](https://github.com/wownero/wownero/blob/master/ANONYMITY_NETWORKS.md).
|
||||
|
||||
## Donating to Wownero Project
|
||||
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
# Copyright (c) 2014-2020, The Monero Project
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification, are
|
||||
# permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
# conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
# of conditions and the following disclaimer in the documentation and/or other
|
||||
# materials provided with the distribution.
|
||||
#
|
||||
# 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
# used to endorse or promote products derived from this software without specific
|
||||
# prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
# - Try to find readline include dirs and libraries
|
||||
#
|
||||
# Automatically finds ccache build accelerator, if it's found in PATH.
|
||||
#
|
||||
# Usage of this module as follows:
|
||||
#
|
||||
# project(monero)
|
||||
# include(FindCcache) # Include AFTER the project() macro to be able to reach the CMAKE_CXX_COMPILER variable
|
||||
#
|
||||
# Properties modified by this module:
|
||||
#
|
||||
# GLOBAL PROPERTY RULE_LAUNCH_COMPILE set to ccache, when ccache found
|
||||
# GLOBAL PROPERTY RULE_LAUNCH_LINK set to ccache, when ccache found
|
||||
|
||||
find_program(CCACHE_FOUND ccache)
|
||||
if (CCACHE_FOUND)
|
||||
set(TEMP_CPP_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/test-program.cpp")
|
||||
file(WRITE "${TEMP_CPP_FILE}" "int main() { return 0; }")
|
||||
execute_process(COMMAND "${CCACHE_FOUND}" "${CMAKE_CXX_COMPILER}" "${TEMP_CPP_FILE}" RESULT_VARIABLE RET)
|
||||
if (${RET} EQUAL 0)
|
||||
message("found usable ccache: ${CCACHE_FOUND}")
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_FOUND}")
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK "${CCACHE_FOUND}")
|
||||
else()
|
||||
message("found ccache ${CCACHE_FOUND}, but is UNUSABLE! Return code: ${RET}")
|
||||
endif()
|
||||
else()
|
||||
message("ccache NOT found!")
|
||||
endif()
|
||||
|
||||
@@ -135,9 +135,9 @@ $(1)_config_env+=$($(1)_config_env_$(host_arch)_$(host_os)) $($(1)_config_env_$(
|
||||
|
||||
$(1)_config_env+=PKG_CONFIG_LIBDIR=$($($(1)_type)_prefix)/lib/pkgconfig
|
||||
$(1)_config_env+=PKG_CONFIG_PATH=$($($(1)_type)_prefix)/share/pkgconfig
|
||||
$(1)_config_env+=PATH="$(build_prefix)/bin:$(PATH)"
|
||||
$(1)_build_env+=PATH="$(build_prefix)/bin:$(PATH)"
|
||||
$(1)_stage_env+=PATH="$(build_prefix)/bin:$(PATH)"
|
||||
$(1)_config_env+=PATH=$(build_prefix)/bin:$(PATH)
|
||||
$(1)_build_env+=PATH=$(build_prefix)/bin:$(PATH)
|
||||
$(1)_stage_env+=PATH=$(build_prefix)/bin:$(PATH)
|
||||
$(1)_autoconf=./configure --host=$($($(1)_type)_host) --disable-dependency-tracking --prefix=$($($(1)_type)_prefix) $$($(1)_config_opts) CC="$$($(1)_cc)" CXX="$$($(1)_cxx)"
|
||||
|
||||
ifneq ($($(1)_nm),)
|
||||
|
||||
15
contrib/depends/packages/cppzmq.mk
Normal file
15
contrib/depends/packages/cppzmq.mk
Normal file
@@ -0,0 +1,15 @@
|
||||
package=cppzmq
|
||||
$(package)_version=4.4.1
|
||||
$(package)_download_path=https://github.com/zeromq/cppzmq/archive/
|
||||
$(package)_file_name=v$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=117fc1ca24d98dbe1a60c072cde13be863d429134907797f8e03f654ce679385
|
||||
$(package)_dependencies=zeromq
|
||||
|
||||
define $(package)_stage_cmds
|
||||
mkdir $($(package)_staging_prefix_dir)/include &&\
|
||||
cp zmq.hpp $($(package)_staging_prefix_dir)/include
|
||||
endef
|
||||
|
||||
define $(package)_postprocess_cmds
|
||||
rm -rf bin share
|
||||
endef
|
||||
@@ -1,6 +1,6 @@
|
||||
package=openssl
|
||||
$(package)_version=1.0.2r
|
||||
$(package)_download_path=https://ftp.openssl.org/source/old/1.0.2
|
||||
$(package)_download_path=https://www.openssl.org/source
|
||||
$(package)_file_name=$(package)-$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=ae51d08bba8a83958e894946f15303ff894d75c2b8bbd44a852b64e3fe11d0d6
|
||||
$(package)_patches=fix_arflags.patch
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
PACKAGE=qt
|
||||
$(package)_version=5.7.1
|
||||
$(package)_download_path=http://linorg.usp.br/Qt/archive/qt/5.7/5.7.1/submodules
|
||||
$(package)_download_path=https://download.qt.io/archive/qt/5.7/5.7.1/submodules
|
||||
$(package)_suffix=opensource-src-$($(package)_version).tar.gz
|
||||
$(package)_file_name=qtbase-$($(package)_suffix)
|
||||
$(package)_sha256_hash=95f83e532d23b3ddbde7973f380ecae1bac13230340557276f75f2e37984e410
|
||||
|
||||
@@ -3,7 +3,7 @@ $(package)_version=1.0.18
|
||||
$(package)_download_path=https://download.libsodium.org/libsodium/releases/
|
||||
$(package)_file_name=libsodium-$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=6f504490b342a4f8a4c4a02fc9b866cbef8622d5df4e5452b46be121e46636c1
|
||||
$(package)_patches=disable-glibc-getrandom-getentropy.patch fix-whitespace.patch
|
||||
$(package)_patches=fix-whitespace.patch
|
||||
|
||||
define $(package)_set_vars
|
||||
$(package)_config_opts=--enable-static --disable-shared
|
||||
@@ -13,7 +13,6 @@ $(package)_config_opts_darwin=RANLIB="$(host_prefix)/native/bin/x86_64-apple-dar
|
||||
endef
|
||||
|
||||
define $(package)_config_cmds
|
||||
patch -p1 < $($(package)_patch_dir)/disable-glibc-getrandom-getentropy.patch &&\
|
||||
./autogen.sh &&\
|
||||
patch -p1 < $($(package)_patch_dir)/fix-whitespace.patch &&\
|
||||
$($(package)_autoconf) $($(package)_config_opts) AR_FLAGS=$($(package)_arflags)
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 9e2de27c..0fa85c2d 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -807,6 +807,10 @@ AS_IF([test "x$EMSCRIPTEN" = "x"],[
|
||||
# include <sys/random.h>
|
||||
#endif
|
||||
]], [[
|
||||
+#ifdef __linux__
|
||||
+# error getrandom() is currently disabled on Linux to support glibc < 2.25
|
||||
+#endif
|
||||
+
|
||||
unsigned char buf;
|
||||
(void) getrandom((void *) &buf, 1U, 0U);
|
||||
]])],
|
||||
@@ -825,6 +829,9 @@ unsigned char buf;
|
||||
# include <sys/random.h>
|
||||
#endif
|
||||
]], [[
|
||||
+#ifdef __linux__
|
||||
+# error getentropy() is currently disabled on Linux to support glibc < 2.25
|
||||
+#endif
|
||||
#ifdef __APPLE__
|
||||
# error getentropy() is currently disabled on Apple operating systems
|
||||
#endif
|
||||
@@ -218,7 +218,7 @@ namespace demo
|
||||
|
||||
s.m_subobj.m_str = "subszzzzzzzz";
|
||||
s.m_list_of_self.push_back(s);
|
||||
s.m_storage_entry_int = epee::serialization::storage_entry(uint64_t(22222));
|
||||
s.m_storage_entry_int = epee::serialization::storage_entry(uint64_t(22222));;
|
||||
s.m_storage_entry_string = epee::serialization::storage_entry(std::string("sdsvsdvs"));
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2019-2020, The Monero Project
|
||||
// Copyright (c) 2019, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
@@ -39,22 +39,10 @@
|
||||
namespace epee
|
||||
{
|
||||
struct byte_slice_data;
|
||||
class byte_stream;
|
||||
|
||||
struct release_byte_slice
|
||||
{
|
||||
//! For use with `zmq_message_init_data`, use second arg for buffer pointer.
|
||||
static void call(void*, void* ptr) noexcept;
|
||||
void operator()(byte_slice_data* ptr) const noexcept
|
||||
{
|
||||
call(nullptr, ptr);
|
||||
}
|
||||
};
|
||||
|
||||
//! Frees ref count + buffer allocated internally by `byte_buffer`.
|
||||
struct release_byte_buffer
|
||||
{
|
||||
void operator()(std::uint8_t* buf) const noexcept;
|
||||
void operator()(byte_slice_data*) const noexcept;
|
||||
};
|
||||
|
||||
/*! Inspired by slices in golang. Storage is thread-safe reference counted,
|
||||
@@ -111,9 +99,6 @@ namespace epee
|
||||
//! Convert `buffer` into a slice using one allocation for shared count.
|
||||
explicit byte_slice(std::string&& buffer);
|
||||
|
||||
//! Convert `stream` into a slice with zero allocations.
|
||||
explicit byte_slice(byte_stream&& stream) noexcept;
|
||||
|
||||
byte_slice(byte_slice&& source) noexcept;
|
||||
~byte_slice() noexcept = default;
|
||||
|
||||
@@ -155,23 +140,6 @@ namespace epee
|
||||
\throw std::out_of_range If `size() < end`.
|
||||
\return Slice starting at `data() + begin` of size `end - begin`. */
|
||||
byte_slice get_slice(std::size_t begin, std::size_t end) const;
|
||||
|
||||
//! \post `empty()` \return Ownership of ref-counted buffer.
|
||||
std::unique_ptr<byte_slice_data, release_byte_slice> take_buffer() noexcept;
|
||||
};
|
||||
|
||||
//! Alias for a buffer that has space for a `byte_slice` ref count.
|
||||
using byte_buffer = std::unique_ptr<std::uint8_t, release_byte_buffer>;
|
||||
|
||||
/*! \return `buf` with a new size of exactly `length`. New bytes not
|
||||
initialized. A `nullptr` is returned on allocation failure. */
|
||||
byte_buffer byte_buffer_resize(byte_buffer buf, std::size_t length) noexcept;
|
||||
|
||||
/*! Increase `buf` of size `current` by `more` bytes.
|
||||
|
||||
\throw std::range_error if `current + more` exceeds `size_t` bounds.
|
||||
\return Buffer of `current + more` bytes. A `nullptr` is returned on
|
||||
allocation failure. */
|
||||
byte_buffer byte_buffer_increase(byte_buffer buf, std::size_t current, std::size_t more);
|
||||
} // epee
|
||||
|
||||
|
||||
@@ -1,224 +0,0 @@
|
||||
// Copyright (c) 2020, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
#include "byte_slice.h"
|
||||
#include "span.h"
|
||||
|
||||
namespace epee
|
||||
{
|
||||
/*! \brief A partial drop-in replacement for `std::ostream`.
|
||||
|
||||
Only a few base `std::ostream` functions are implemented - enough for
|
||||
rapidjson output currently.
|
||||
|
||||
Advantages over `std::stringstream` or `rapidjson::StringBuffer`:
|
||||
- The internal buffer can be taken without a copy.
|
||||
- The internal buffer can be given to `byte_slice` with zero
|
||||
allocations for reference count.
|
||||
- The internal buffer can be given to `zmq_msg_data_init` without a
|
||||
copy or extra allocation.
|
||||
an additional advantage over `std::stringstream`:
|
||||
- Construction is significantly faster - the global `std::locale`
|
||||
does not have to be acquired (global thread synchronization), and
|
||||
an extra allocation for `std::stringbuf` is not needed (which is an
|
||||
addition to the buffer inside of that object). */
|
||||
class byte_stream
|
||||
{
|
||||
byte_buffer buffer_; //! Beginning of buffer
|
||||
std::uint8_t* next_write_; //! Current write position
|
||||
const std::uint8_t* end_; //! End of buffer
|
||||
std::size_t increase_size_; //! Minimum buffer size increase
|
||||
|
||||
//! \post `requested <= available()`
|
||||
void overflow(const std::size_t requested);
|
||||
|
||||
//! Ensures that at least `requested` bytes are available.
|
||||
void check(const std::size_t requested)
|
||||
{
|
||||
const std::size_t remaining = available();
|
||||
if (remaining < requested)
|
||||
overflow(requested);
|
||||
}
|
||||
|
||||
public:
|
||||
using char_type = std::uint8_t;
|
||||
using Ch = char_type;
|
||||
|
||||
//! \return Default minimum size increase on buffer overflow
|
||||
static constexpr std::size_t default_increase() noexcept { return 4096; }
|
||||
|
||||
//! Increase internal buffer by at least `byte_stream_increase` bytes.
|
||||
byte_stream() noexcept
|
||||
: byte_stream(default_increase())
|
||||
{}
|
||||
|
||||
//! Increase internal buffer by at least `increase` bytes.
|
||||
explicit byte_stream(const std::size_t increase) noexcept
|
||||
: buffer_(nullptr),
|
||||
next_write_(nullptr),
|
||||
end_(nullptr),
|
||||
increase_size_(increase)
|
||||
{}
|
||||
|
||||
byte_stream(byte_stream&& rhs) noexcept;
|
||||
~byte_stream() noexcept = default;
|
||||
byte_stream& operator=(byte_stream&& rhs) noexcept;
|
||||
|
||||
//! \return The minimum increase size on buffer overflow
|
||||
std::size_t increase_size() const noexcept { return increase_size_; }
|
||||
|
||||
const std::uint8_t* data() const noexcept { return buffer_.get(); }
|
||||
std::uint8_t* tellp() const noexcept { return next_write_; }
|
||||
std::size_t available() const noexcept { return end_ - next_write_; }
|
||||
std::size_t size() const noexcept { return next_write_ - buffer_.get(); }
|
||||
std::size_t capacity() const noexcept { return end_ - buffer_.get(); }
|
||||
|
||||
//! Compatibility with rapidjson.
|
||||
void Flush() const noexcept
|
||||
{}
|
||||
|
||||
/*! Reserve at least `more` bytes.
|
||||
\post `size() + more <= available()`.
|
||||
\throw std::range_error if exceeding max `size_t` value.
|
||||
\throw std::bad_alloc if allocation fails. */
|
||||
void reserve(const std::size_t more)
|
||||
{
|
||||
check(more);
|
||||
}
|
||||
|
||||
/*! Copy `length` bytes starting at `ptr` to end of stream.
|
||||
\throw std::range_error If exceeding max size_t value.
|
||||
\throw std::bad_alloc If allocation fails. */
|
||||
void write(const std::uint8_t* ptr, const std::size_t length)
|
||||
{
|
||||
check(length);
|
||||
std::memcpy(tellp(), ptr, length);
|
||||
next_write_ += length;
|
||||
}
|
||||
|
||||
/*! Copy `length` bytes starting at `ptr` to end of stream.
|
||||
\throw std::range_error if exceeding max `size_t` value.
|
||||
\throw std::bad_alloc if allocation fails. */
|
||||
void write(const char* ptr, const std::size_t length)
|
||||
{
|
||||
write(reinterpret_cast<const std::uint8_t*>(ptr), length);
|
||||
}
|
||||
|
||||
/*! Copy `source` to end of stream.
|
||||
\throw std::range_error if exceeding max `size_t` value.
|
||||
\throw std::bad_alloc if allocation fails. */
|
||||
void write(const epee::span<const std::uint8_t> source)
|
||||
{
|
||||
write(source.data(), source.size());
|
||||
}
|
||||
|
||||
/*! Copy `source` to end of stream.
|
||||
\throw std::range_error if exceeding max `size_t` value.
|
||||
\throw std::bad_alloc if allocation fails. */
|
||||
void write(const epee::span<const char> source)
|
||||
{
|
||||
write(source.data(), source.size());
|
||||
}
|
||||
|
||||
/*! Copy `ch` to end of stream.
|
||||
\throw std::range_error if exceeding max `size_t` value.
|
||||
\throw std::bad_alloc if allocation fails. */
|
||||
void put(const std::uint8_t ch)
|
||||
{
|
||||
check(1);
|
||||
put_unsafe(ch);
|
||||
}
|
||||
|
||||
/*! Copy `ch` to end of stream. Provides rapidjson compatability.
|
||||
\throw std::range_error if exceeding max `size_t` value.
|
||||
\throw std::bad_alloc if allocation fails. */
|
||||
void Put(const std::uint8_t ch)
|
||||
{
|
||||
put(ch);
|
||||
}
|
||||
|
||||
/*! Writes `ch` to end of stream without runtime capacity checks. Must use
|
||||
`reserve` before calling this function. Primarily for use with
|
||||
rapidjson, which writes characters at a time but reserves memory in
|
||||
blocks. Most applications want to use `put` or `write`. */
|
||||
void put_unsafe(const std::uint8_t ch) noexcept
|
||||
{
|
||||
assert(1 <= available());
|
||||
*(tellp()) = ch;
|
||||
++next_write_;
|
||||
}
|
||||
|
||||
/*! Write `ch` to end of stream `count` times.
|
||||
\throw std::range_error if exceeding max `size_t` value.
|
||||
\throw std::bad_alloc if allocation fails. */
|
||||
void put_n(const std::uint8_t ch, const std::size_t count)
|
||||
{
|
||||
check(count);
|
||||
std::memset(tellp(), count, ch);
|
||||
next_write_ += count;
|
||||
}
|
||||
|
||||
/*! Copy `ch` to end of stream.
|
||||
\throw std::range_error if exceeding max `size_t` value.
|
||||
\throw std::bad_alloc if allocation fails. */
|
||||
void push_back(const std::uint8_t ch)
|
||||
{
|
||||
put(ch);
|
||||
}
|
||||
|
||||
//! \return The internal buffer. \post `size() == capacity() == 0`.
|
||||
byte_buffer take_buffer() noexcept;
|
||||
};
|
||||
|
||||
//! Compatability/optimization for rapidjson.
|
||||
|
||||
inline void PutReserve(byte_stream& dest, const std::size_t length)
|
||||
{
|
||||
dest.reserve(length);
|
||||
}
|
||||
|
||||
//! Compatability/optimization for rapidjson.
|
||||
|
||||
inline void PutUnsafe(byte_stream& dest, const std::uint8_t ch)
|
||||
{
|
||||
dest.put_unsafe(ch);
|
||||
}
|
||||
|
||||
//! Compability/optimization for rapidjson.
|
||||
inline void PutN(byte_stream& dest, const std::uint8_t ch, const std::size_t count)
|
||||
{
|
||||
dest.put_n(ch, count);
|
||||
}
|
||||
} // epee
|
||||
|
||||
@@ -465,7 +465,7 @@ eof:
|
||||
bool run_default_console_handler_no_srv_param(t_server* ptsrv, t_handler handlr, std::function<std::string(void)> prompt, const std::string& usage = "")
|
||||
{
|
||||
async_console_handler console_handler;
|
||||
return console_handler.run(ptsrv, std::bind<bool>(no_srv_param_adapter<t_server, t_handler>, std::placeholders::_1, std::placeholders::_2, handlr), prompt, usage);
|
||||
return console_handler.run(ptsrv, boost::bind<bool>(no_srv_param_adapter<t_server, t_handler>, _1, _2, handlr), prompt, usage);
|
||||
}
|
||||
|
||||
template<class t_server, class t_handler>
|
||||
@@ -605,21 +605,10 @@ eof:
|
||||
std::unique_ptr<boost::thread> m_console_thread;
|
||||
async_console_handler m_console_handler;
|
||||
public:
|
||||
~console_handlers_binder() {
|
||||
try
|
||||
{
|
||||
stop_handling();
|
||||
if (m_console_thread.get() != nullptr)
|
||||
{
|
||||
m_console_thread->join();
|
||||
}
|
||||
}
|
||||
catch (const std::exception &e) { /* ignore */ }
|
||||
}
|
||||
|
||||
bool start_handling(std::function<std::string(void)> prompt, const std::string& usage_string = "", std::function<void(void)> exit_handler = NULL)
|
||||
{
|
||||
m_console_thread.reset(new boost::thread(boost::bind(&console_handlers_binder::run_handling, this, prompt, usage_string, exit_handler)));
|
||||
m_console_thread->detach();
|
||||
return true;
|
||||
}
|
||||
bool start_handling(const std::string &prompt, const std::string& usage_string = "", std::function<void(void)> exit_handler = NULL)
|
||||
@@ -634,7 +623,7 @@ eof:
|
||||
|
||||
bool run_handling(std::function<std::string(void)> prompt, const std::string& usage_string, std::function<void(void)> exit_handler = NULL)
|
||||
{
|
||||
return m_console_handler.run(std::bind(&console_handlers_binder::process_command_str, this, std::placeholders::_1), prompt, usage_string, exit_handler);
|
||||
return m_console_handler.run(boost::bind(&console_handlers_binder::process_command_str, this, _1), prompt, usage_string, exit_handler);
|
||||
}
|
||||
|
||||
void print_prompt()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2017-2020, The Monero Project
|
||||
// Copyright (c) 2017-2019, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
@@ -51,22 +51,12 @@ namespace epee
|
||||
template<std::size_t N>
|
||||
static std::array<char, N * 2> array(const std::array<std::uint8_t, N>& src) noexcept
|
||||
{
|
||||
std::array<char, N * 2> out;
|
||||
std::array<char, N * 2> out{{}};
|
||||
static_assert(N <= 128, "keep the stack size down");
|
||||
buffer_unchecked(out.data(), {src.data(), src.size()});
|
||||
return out;
|
||||
}
|
||||
|
||||
//! \return An array containing hex of `src`.
|
||||
template<typename T>
|
||||
static std::array<char, sizeof(T) * 2> array(const T& src) noexcept
|
||||
{
|
||||
std::array<char, sizeof(T) * 2> out;
|
||||
static_assert(sizeof(T) <= 128, "keep the stack size down");
|
||||
buffer_unchecked(out.data(), as_byte_span(src));
|
||||
return out;
|
||||
}
|
||||
|
||||
//! Append `src` as hex to `out`.
|
||||
static void buffer(std::ostream& out, const span<const std::uint8_t> src);
|
||||
|
||||
@@ -80,20 +70,9 @@ namespace epee
|
||||
static void buffer_unchecked(char* out, const span<const std::uint8_t> src) noexcept;
|
||||
};
|
||||
|
||||
//! Convert hex in UTF8 encoding to binary
|
||||
struct from_hex
|
||||
{
|
||||
static bool to_string(std::string& out, boost::string_ref src);
|
||||
|
||||
static bool to_buffer(span<std::uint8_t> out, boost::string_ref src) noexcept;
|
||||
|
||||
private:
|
||||
static bool to_buffer_unchecked(std::uint8_t* out, boost::string_ref src) noexcept;
|
||||
};
|
||||
|
||||
//! Convert hex in current C locale encoding to binary
|
||||
struct from_hex_locale
|
||||
{
|
||||
static std::vector<uint8_t> to_vector(boost::string_ref src);
|
||||
//! \return An std::vector of unsigned integers from the `src`
|
||||
static std::vector<uint8_t> vector(boost::string_ref src);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace md5
|
||||
MD5Update( &ctx, input, ilen );
|
||||
MD5Final( output, &ctx);
|
||||
|
||||
memwipe( &ctx, sizeof( MD5_CTX ));
|
||||
memset( &ctx, 0, sizeof( MD5_CTX) );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -277,7 +277,7 @@ namespace md5
|
||||
/* Zeroize sensitive information.
|
||||
|
||||
*/
|
||||
memwipe ((POINTER)context, sizeof (*context));
|
||||
MD5_memset ((POINTER)context, 0, sizeof (*context));
|
||||
}
|
||||
|
||||
/* MD5 basic transformation. Transforms state based on block.
|
||||
@@ -369,7 +369,7 @@ namespace md5
|
||||
|
||||
/* Zeroize sensitive information.
|
||||
*/
|
||||
memwipe ((POINTER)x, sizeof (x));
|
||||
MD5_memset ((POINTER)x, 0, sizeof (x));
|
||||
}
|
||||
|
||||
/* Note: Replace "for loop" with standard memcpy if possible.
|
||||
@@ -431,9 +431,9 @@ namespace md5
|
||||
MD5Update(&hmac->octx, k_opad, 64); /* apply outer pad */
|
||||
|
||||
/* scrub the pads and key context (if used) */
|
||||
memwipe( (POINTER)&k_ipad, sizeof(k_ipad));
|
||||
memwipe( (POINTER)&k_opad, sizeof(k_opad));
|
||||
memwipe( (POINTER)&tk, sizeof(tk));
|
||||
MD5_memset( (POINTER)&k_ipad, 0, sizeof(k_ipad));
|
||||
MD5_memset( (POINTER)&k_opad, 0, sizeof(k_opad));
|
||||
MD5_memset( (POINTER)&tk, 0, sizeof(tk));
|
||||
|
||||
/* and we're done. */
|
||||
}
|
||||
@@ -459,7 +459,7 @@ namespace md5
|
||||
state->istate[lupe] = htonl(hmac.ictx.state[lupe]);
|
||||
state->ostate[lupe] = htonl(hmac.octx.state[lupe]);
|
||||
}
|
||||
memwipe( (POINTER)&hmac, sizeof(hmac));
|
||||
MD5_memset( (POINTER)&hmac, 0, sizeof(hmac));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Andrey N. Sabelnikov nor the
|
||||
// names of its contributors may be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
|
||||
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <boost/optional/optional.hpp>
|
||||
#include "http_auth.h"
|
||||
#include "net/net_ssl.h"
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace net_utils
|
||||
{
|
||||
inline const char* get_hex_vals()
|
||||
{
|
||||
static constexpr const char hexVals[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
|
||||
return hexVals;
|
||||
}
|
||||
|
||||
inline const char* get_unsave_chars()
|
||||
{
|
||||
//static constexpr char unsave_chars[] = "\"<>%\\^[]`+$,@:;/!#?=&";
|
||||
static constexpr const char unsave_chars[] = "\"<>%\\^[]`+$,@:;!#&";
|
||||
return unsave_chars;
|
||||
}
|
||||
|
||||
bool is_unsafe(unsigned char compare_char);
|
||||
std::string dec_to_hex(char num, int radix);
|
||||
int get_index(const char *s, char c);
|
||||
std::string hex_to_dec_2bytes(const char *s);
|
||||
std::string convert(char val);
|
||||
std::string conver_to_url_format(const std::string& uri);
|
||||
std::string convert_from_url_format(const std::string& uri);
|
||||
std::string convert_to_url_format_force_all(const std::string& uri);
|
||||
|
||||
namespace http
|
||||
{
|
||||
class abstract_http_client
|
||||
{
|
||||
public:
|
||||
abstract_http_client() {}
|
||||
virtual ~abstract_http_client() {}
|
||||
bool set_server(const std::string& address, boost::optional<login> user, ssl_options_t ssl_options = ssl_support_t::e_ssl_support_autodetect);
|
||||
virtual void set_server(std::string host, std::string port, boost::optional<login> user, ssl_options_t ssl_options = ssl_support_t::e_ssl_support_autodetect) = 0;
|
||||
virtual void set_auto_connect(bool auto_connect) = 0;
|
||||
virtual bool connect(std::chrono::milliseconds timeout) = 0;
|
||||
virtual bool disconnect() = 0;
|
||||
virtual bool is_connected(bool *ssl = NULL) = 0;
|
||||
virtual bool invoke(const boost::string_ref uri, const boost::string_ref method, const std::string& body, std::chrono::milliseconds timeout, const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list()) = 0;
|
||||
virtual bool invoke_get(const boost::string_ref uri, std::chrono::milliseconds timeout, const std::string& body = std::string(), const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list()) = 0;
|
||||
virtual bool invoke_post(const boost::string_ref uri, const std::string& body, std::chrono::milliseconds timeout, const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list()) = 0;
|
||||
virtual uint64_t get_bytes_sent() const = 0;
|
||||
virtual uint64_t get_bytes_received() const = 0;
|
||||
};
|
||||
|
||||
class http_client_factory
|
||||
{
|
||||
public:
|
||||
virtual ~http_client_factory() {}
|
||||
virtual std::unique_ptr<abstract_http_client> create() = 0;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/uuid/random_generator.hpp>
|
||||
#include <boost/chrono.hpp>
|
||||
@@ -209,15 +210,15 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
socket().async_receive(boost::asio::buffer(buffer_),
|
||||
boost::asio::socket_base::message_peek,
|
||||
strand_.wrap(
|
||||
std::bind(&connection<t_protocol_handler>::handle_receive, self,
|
||||
std::placeholders::_1,
|
||||
std::placeholders::_2)));
|
||||
boost::bind(&connection<t_protocol_handler>::handle_receive, self,
|
||||
boost::asio::placeholders::error,
|
||||
boost::asio::placeholders::bytes_transferred)));
|
||||
else
|
||||
async_read_some(boost::asio::buffer(buffer_),
|
||||
strand_.wrap(
|
||||
std::bind(&connection<t_protocol_handler>::handle_read, self,
|
||||
std::placeholders::_1,
|
||||
std::placeholders::_2)));
|
||||
boost::bind(&connection<t_protocol_handler>::handle_read, self,
|
||||
boost::asio::placeholders::error,
|
||||
boost::asio::placeholders::bytes_transferred)));
|
||||
#if !defined(_WIN32) || !defined(__i686)
|
||||
// not supported before Windows7, too lazy for runtime check
|
||||
// Just exclude for 32bit windows builds
|
||||
@@ -362,8 +363,8 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
}
|
||||
|
||||
delay *= 0.5;
|
||||
long int ms = (long int)(delay * 100);
|
||||
if (ms > 0) {
|
||||
if (delay > 0) {
|
||||
long int ms = (long int)(delay * 100);
|
||||
reset_timer(boost::posix_time::milliseconds(ms + 1), true);
|
||||
boost::this_thread::sleep_for(boost::chrono::milliseconds(ms));
|
||||
}
|
||||
@@ -687,7 +688,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
reset_timer(get_default_timeout(), false);
|
||||
async_write(boost::asio::buffer(m_send_que.front().data(), size_now ) ,
|
||||
strand_.wrap(
|
||||
std::bind(&connection<t_protocol_handler>::handle_write, self, std::placeholders::_1, std::placeholders::_2)
|
||||
boost::bind(&connection<t_protocol_handler>::handle_write, self, _1, _2)
|
||||
)
|
||||
);
|
||||
//_dbg3("(chunk): " << size_now);
|
||||
@@ -720,9 +721,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
boost::posix_time::milliseconds connection<t_protocol_handler>::get_timeout_from_bytes_read(size_t bytes)
|
||||
{
|
||||
boost::posix_time::milliseconds ms = (boost::posix_time::milliseconds)(unsigned)(bytes * TIMEOUT_EXTRA_MS_PER_BYTE);
|
||||
const auto cur = m_timer.expires_from_now().total_milliseconds();
|
||||
if (cur > 0)
|
||||
ms += (boost::posix_time::milliseconds)cur;
|
||||
ms += m_timer.expires_from_now();
|
||||
if (ms > get_default_timeout())
|
||||
ms = get_default_timeout();
|
||||
return ms;
|
||||
@@ -748,12 +747,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
template<class t_protocol_handler>
|
||||
void connection<t_protocol_handler>::reset_timer(boost::posix_time::milliseconds ms, bool add)
|
||||
{
|
||||
if (ms.total_milliseconds() < 0)
|
||||
{
|
||||
MWARNING("Ignoring negative timeout " << ms);
|
||||
return;
|
||||
}
|
||||
MTRACE((add ? "Adding" : "Setting") << " " << ms << " expiry");
|
||||
MTRACE("Setting " << ms << " expiry");
|
||||
auto self = safe_shared_from_this();
|
||||
if(!self)
|
||||
{
|
||||
@@ -766,11 +760,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
return;
|
||||
}
|
||||
if (add)
|
||||
{
|
||||
const auto cur = m_timer.expires_from_now().total_milliseconds();
|
||||
if (cur > 0)
|
||||
ms += (boost::posix_time::milliseconds)cur;
|
||||
}
|
||||
ms += m_timer.expires_from_now();
|
||||
m_timer.expires_from_now(ms);
|
||||
m_timer.async_wait([=](const boost::system::error_code& ec)
|
||||
{
|
||||
@@ -891,7 +881,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
CHECK_AND_ASSERT_MES( size_now == m_send_que.front().size(), void(), "Unexpected queue size");
|
||||
async_write(boost::asio::buffer(m_send_que.front().data(), size_now) ,
|
||||
strand_.wrap(
|
||||
std::bind(&connection<t_protocol_handler>::handle_write, connection<t_protocol_handler>::shared_from_this(), std::placeholders::_1, std::placeholders::_2)
|
||||
boost::bind(&connection<t_protocol_handler>::handle_write, connection<t_protocol_handler>::shared_from_this(), _1, _2)
|
||||
)
|
||||
);
|
||||
//_dbg3("(normal)" << size_now);
|
||||
@@ -1401,7 +1391,7 @@ POP_WARNINGS
|
||||
shared_context->connect_mut.lock(); shared_context->ec = ec_; shared_context->cond.notify_one(); shared_context->connect_mut.unlock();
|
||||
};
|
||||
|
||||
sock_.async_connect(remote_endpoint, std::bind<void>(connect_callback, std::placeholders::_1, local_shared_context));
|
||||
sock_.async_connect(remote_endpoint, boost::bind<void>(connect_callback, _1, local_shared_context));
|
||||
while(local_shared_context->ec == boost::asio::error::would_block)
|
||||
{
|
||||
bool r = local_shared_context->cond.timed_wait(lock, boost::get_system_time() + boost::posix_time::milliseconds(conn_timeout));
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "memwipe.h"
|
||||
#include "string_tools.h"
|
||||
|
||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
@@ -201,11 +200,6 @@ namespace net_utils
|
||||
this->~http_response_info();
|
||||
new(this) http_response_info();
|
||||
}
|
||||
|
||||
void wipe()
|
||||
{
|
||||
memwipe(&m_body[0], m_body.size());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,6 @@
|
||||
|
||||
#include "string_tools.h"
|
||||
#include "reg_exp_definer.h"
|
||||
#include "abstract_http_client.h"
|
||||
#include "http_base.h"
|
||||
#include "http_auth.h"
|
||||
#include "to_nonconst_iterator.h"
|
||||
@@ -106,11 +105,140 @@ namespace net_utils
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
static inline const char* get_hex_vals()
|
||||
{
|
||||
static const char hexVals[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
|
||||
return hexVals;
|
||||
}
|
||||
|
||||
static inline const char* get_unsave_chars()
|
||||
{
|
||||
//static char unsave_chars[] = "\"<>%\\^[]`+$,@:;/!#?=&";
|
||||
static const char unsave_chars[] = "\"<>%\\^[]`+$,@:;!#&";
|
||||
return unsave_chars;
|
||||
}
|
||||
|
||||
static inline bool is_unsafe(unsigned char compare_char)
|
||||
{
|
||||
if(compare_char <= 32 || compare_char >= 123)
|
||||
return true;
|
||||
|
||||
const char* punsave = get_unsave_chars();
|
||||
|
||||
for(int ichar_pos = 0; 0!=punsave[ichar_pos] ;ichar_pos++)
|
||||
if(compare_char == punsave[ichar_pos])
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline
|
||||
std::string dec_to_hex(char num, int radix)
|
||||
{
|
||||
int temp=0;
|
||||
std::string csTmp;
|
||||
int num_char;
|
||||
|
||||
num_char = (int) num;
|
||||
if (num_char < 0)
|
||||
num_char = 256 + num_char;
|
||||
|
||||
while (num_char >= radix)
|
||||
{
|
||||
temp = num_char % radix;
|
||||
num_char = (int)floor((float)num_char / (float)radix);
|
||||
csTmp = get_hex_vals()[temp];
|
||||
}
|
||||
|
||||
csTmp += get_hex_vals()[num_char];
|
||||
|
||||
if(csTmp.size() < 2)
|
||||
{
|
||||
csTmp += '0';
|
||||
}
|
||||
|
||||
std::reverse(csTmp.begin(), csTmp.end());
|
||||
//_mbsrev((unsigned char*)csTmp.data());
|
||||
|
||||
return csTmp;
|
||||
}
|
||||
static inline int get_index(const char *s, char c) { const char *ptr = (const char*)memchr(s, c, 16); return ptr ? ptr-s : -1; }
|
||||
static inline
|
||||
std::string hex_to_dec_2bytes(const char *s)
|
||||
{
|
||||
const char *hex = get_hex_vals();
|
||||
int i0 = get_index(hex, toupper(s[0]));
|
||||
int i1 = get_index(hex, toupper(s[1]));
|
||||
if (i0 < 0 || i1 < 0)
|
||||
return std::string("%") + std::string(1, s[0]) + std::string(1, s[1]);
|
||||
return std::string(1, i0 * 16 | i1);
|
||||
}
|
||||
|
||||
static inline std::string convert(char val)
|
||||
{
|
||||
std::string csRet;
|
||||
csRet += "%";
|
||||
csRet += dec_to_hex(val, 16);
|
||||
return csRet;
|
||||
}
|
||||
static inline std::string conver_to_url_format(const std::string& uri)
|
||||
{
|
||||
|
||||
std::string result;
|
||||
|
||||
for(size_t i = 0; i!= uri.size(); i++)
|
||||
{
|
||||
if(is_unsafe(uri[i]))
|
||||
result += convert(uri[i]);
|
||||
else
|
||||
result += uri[i];
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
static inline std::string convert_from_url_format(const std::string& uri)
|
||||
{
|
||||
|
||||
std::string result;
|
||||
|
||||
for(size_t i = 0; i!= uri.size(); i++)
|
||||
{
|
||||
if(uri[i] == '%' && i + 2 < uri.size())
|
||||
{
|
||||
result += hex_to_dec_2bytes(uri.c_str() + i + 1);
|
||||
i += 2;
|
||||
}
|
||||
else
|
||||
result += uri[i];
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline std::string convert_to_url_format_force_all(const std::string& uri)
|
||||
{
|
||||
|
||||
std::string result;
|
||||
|
||||
for(size_t i = 0; i!= uri.size(); i++)
|
||||
{
|
||||
result += convert(uri[i]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
namespace http
|
||||
{
|
||||
|
||||
template<typename net_client_type>
|
||||
class http_simple_client_template : public i_target_handler, public abstract_http_client
|
||||
class http_simple_client_template: public i_target_handler
|
||||
{
|
||||
private:
|
||||
enum reciev_machine_state
|
||||
@@ -151,7 +279,7 @@ namespace net_utils
|
||||
|
||||
public:
|
||||
explicit http_simple_client_template()
|
||||
: i_target_handler(), abstract_http_client()
|
||||
: i_target_handler()
|
||||
, m_net_client()
|
||||
, m_host_buff()
|
||||
, m_port()
|
||||
@@ -171,19 +299,26 @@ namespace net_utils
|
||||
const std::string &get_host() const { return m_host_buff; };
|
||||
const std::string &get_port() const { return m_port; };
|
||||
|
||||
using abstract_http_client::set_server;
|
||||
bool set_server(const std::string& address, boost::optional<login> user, ssl_options_t ssl_options = ssl_support_t::e_ssl_support_autodetect)
|
||||
{
|
||||
http::url_content parsed{};
|
||||
const bool r = parse_url(address, parsed);
|
||||
CHECK_AND_ASSERT_MES(r, false, "failed to parse url: " << address);
|
||||
set_server(std::move(parsed.host), std::to_string(parsed.port), std::move(user), std::move(ssl_options));
|
||||
return true;
|
||||
}
|
||||
|
||||
void set_server(std::string host, std::string port, boost::optional<login> user, ssl_options_t ssl_options = ssl_support_t::e_ssl_support_autodetect) override
|
||||
void set_server(std::string host, std::string port, boost::optional<login> user, ssl_options_t ssl_options = ssl_support_t::e_ssl_support_autodetect)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_lock);
|
||||
disconnect();
|
||||
m_host_buff = std::move(host);
|
||||
m_port = std::move(port);
|
||||
m_auth = user ? http_client_auth{std::move(*user)} : http_client_auth{};
|
||||
m_auth = user ? http_client_auth{std::move(*user)} : http_client_auth{};
|
||||
m_net_client.set_ssl(std::move(ssl_options));
|
||||
}
|
||||
|
||||
void set_auto_connect(bool auto_connect) override
|
||||
void set_auto_connect(bool auto_connect)
|
||||
{
|
||||
m_auto_connect = auto_connect;
|
||||
}
|
||||
@@ -195,25 +330,25 @@ namespace net_utils
|
||||
m_net_client.set_connector(std::move(connector));
|
||||
}
|
||||
|
||||
bool connect(std::chrono::milliseconds timeout) override
|
||||
bool connect(std::chrono::milliseconds timeout)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_lock);
|
||||
return m_net_client.connect(m_host_buff, m_port, timeout);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool disconnect() override
|
||||
bool disconnect()
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_lock);
|
||||
return m_net_client.disconnect();
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool is_connected(bool *ssl = NULL) override
|
||||
bool is_connected(bool *ssl = NULL)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_lock);
|
||||
return m_net_client.is_connected(ssl);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
virtual bool handle_target_data(std::string& piece_of_transfer) override
|
||||
virtual bool handle_target_data(std::string& piece_of_transfer)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_lock);
|
||||
m_response_info.m_body += piece_of_transfer;
|
||||
@@ -226,14 +361,15 @@ namespace net_utils
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
inline bool invoke_get(const boost::string_ref uri, std::chrono::milliseconds timeout, const std::string& body = std::string(), const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list()) override
|
||||
inline
|
||||
bool invoke_get(const boost::string_ref uri, std::chrono::milliseconds timeout, const std::string& body = std::string(), const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list())
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_lock);
|
||||
return invoke(uri, "GET", body, timeout, ppresponse_info, additional_params);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
inline bool invoke(const boost::string_ref uri, const boost::string_ref method, const std::string& body, std::chrono::milliseconds timeout, const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list()) override
|
||||
inline bool invoke(const boost::string_ref uri, const boost::string_ref method, const std::string& body, std::chrono::milliseconds timeout, const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list())
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_lock);
|
||||
if(!is_connected())
|
||||
@@ -306,7 +442,7 @@ namespace net_utils
|
||||
return false;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
inline bool invoke_post(const boost::string_ref uri, const std::string& body, std::chrono::milliseconds timeout, const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list()) override
|
||||
inline bool invoke_post(const boost::string_ref uri, const std::string& body, std::chrono::milliseconds timeout, const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list())
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_lock);
|
||||
return invoke(uri, "POST", body, timeout, ppresponse_info, additional_params);
|
||||
@@ -320,21 +456,16 @@ namespace net_utils
|
||||
return handle_reciev(timeout);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
uint64_t get_bytes_sent() const override
|
||||
uint64_t get_bytes_sent() const
|
||||
{
|
||||
return m_net_client.get_bytes_sent();
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
uint64_t get_bytes_received() const override
|
||||
uint64_t get_bytes_received() const
|
||||
{
|
||||
return m_net_client.get_bytes_received();
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void wipe_response()
|
||||
{
|
||||
m_response_info.wipe();
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
private:
|
||||
//---------------------------------------------------------------------------
|
||||
inline bool handle_reciev(std::chrono::milliseconds timeout)
|
||||
@@ -885,14 +1016,6 @@ namespace net_utils
|
||||
}
|
||||
};
|
||||
typedef http_simple_client_template<blocked_mode_client> http_simple_client;
|
||||
|
||||
class http_simple_client_factory : public http_client_factory
|
||||
{
|
||||
public:
|
||||
std::unique_ptr<abstract_http_client> create() override {
|
||||
return std::unique_ptr<epee::net_utils::http::abstract_http_client>(new epee::net_utils::http::http_simple_client());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,7 +202,7 @@ namespace net_utils
|
||||
|
||||
virtual bool thread_init()
|
||||
{
|
||||
return m_config.m_phandler->init_server_thread();
|
||||
return m_config.m_phandler->init_server_thread();;
|
||||
}
|
||||
|
||||
virtual bool thread_deinit()
|
||||
|
||||
@@ -120,7 +120,6 @@
|
||||
#define BEGIN_JSON_RPC_MAP(uri) else if(query_info.m_URI == uri) \
|
||||
{ \
|
||||
uint64_t ticks = epee::misc_utils::get_tick_count(); \
|
||||
response_info.m_mime_tipe = "application/json"; \
|
||||
epee::serialization::portable_storage ps; \
|
||||
if(!ps.load_from_json(query_info.m_body)) \
|
||||
{ \
|
||||
@@ -149,7 +148,6 @@
|
||||
|
||||
#define PREPARE_OBJECTS_FROM_JSON(command_type) \
|
||||
handled = true; \
|
||||
response_info.m_mime_tipe = "application/json"; \
|
||||
boost::value_initialized<epee::json_rpc::request<command_type::request> > req_; \
|
||||
epee::json_rpc::request<command_type::request>& req = static_cast<epee::json_rpc::request<command_type::request>&>(req_);\
|
||||
if(!req.load(ps)) \
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/bind/bind.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#include "net/abstract_tcp_server2.h"
|
||||
#include "http_protocol_handler.h"
|
||||
|
||||
@@ -949,12 +949,7 @@ bool async_protocol_handler_config<t_connection_context>::close(boost::uuids::uu
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_connects_lock);
|
||||
async_protocol_handler<t_connection_context>* aph = find_connection(connection_id);
|
||||
if (!aph)
|
||||
return false;
|
||||
if (!aph->close())
|
||||
return false;
|
||||
m_connects.erase(connection_id);
|
||||
return true;
|
||||
return 0 != aph ? aph->close() : false;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------
|
||||
template<class t_connection_context>
|
||||
|
||||
@@ -237,7 +237,7 @@ namespace net_utils
|
||||
return send_hook("Unknown command. Try list, nodes, config, fetch, version or quit\n");
|
||||
}
|
||||
|
||||
return send_hook("Unknown command. Try list, nodes, config, fetch, version or quit\n");
|
||||
return send_hook("Unknown command. Try list, nodes, config, fetch, version or quit\n");;
|
||||
}
|
||||
|
||||
bool handle_list_command()
|
||||
|
||||
@@ -103,8 +103,8 @@ namespace net_utils
|
||||
blocked_mode_client() :
|
||||
m_io_service(),
|
||||
m_ctx(boost::asio::ssl::context::tlsv12),
|
||||
m_ssl_socket(new boost::asio::ssl::stream<boost::asio::ip::tcp::socket>(m_io_service, m_ctx)),
|
||||
m_connector(direct_connect{}),
|
||||
m_ssl_socket(new boost::asio::ssl::stream<boost::asio::ip::tcp::socket>(m_io_service, m_ctx)),
|
||||
m_ssl_options(epee::net_utils::ssl_support_t::e_ssl_support_autodetect),
|
||||
m_initialized(true),
|
||||
m_connected(false),
|
||||
|
||||
@@ -94,13 +94,17 @@ namespace net_utils
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
if (is_store)
|
||||
{
|
||||
KV_SERIALIZE_VAL_POD_AS_BLOB_N(m_ip, "ip")
|
||||
uint32_t ip = SWAP32LE(this_ref.m_ip);
|
||||
epee::serialization::selector<is_store>::serialize(ip, stg, hparent_section, "m_ip");
|
||||
}
|
||||
else
|
||||
{
|
||||
KV_SERIALIZE(m_ip)
|
||||
const_cast<ipv4_network_address&>(this_ref).m_ip = SWAP32LE(this_ref.m_ip);
|
||||
if (!epee::serialization::selector<is_store>::serialize_t_val_as_blob(this_ref.m_ip, stg, hparent_section, "ip"))
|
||||
{
|
||||
KV_SERIALIZE(m_ip)
|
||||
const_cast<ipv4_network_address&>(this_ref).m_ip = SWAP32LE(this_ref.m_ip);
|
||||
}
|
||||
}
|
||||
KV_SERIALIZE(m_port)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
|
||||
@@ -89,8 +89,6 @@ public: \
|
||||
|
||||
#define KV_SERIALIZE_OPT_N(variable, val_name, default_value) \
|
||||
do { \
|
||||
if (is_store && this_ref.variable == default_value) \
|
||||
break; \
|
||||
if (!epee::serialization::selector<is_store>::serialize(this_ref.variable, stg, hparent_section, val_name)) \
|
||||
epee::serialize_default(this_ref.variable, default_value); \
|
||||
} while (0);
|
||||
|
||||
@@ -46,12 +46,24 @@ namespace epee
|
||||
namespace serialization
|
||||
{
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
template<class t_type, class t_storage>
|
||||
static bool serialize_t_val(const t_type& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
|
||||
{
|
||||
return stg.set_value(pname, d, hparent_section);
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
template<class t_type, class t_storage>
|
||||
static bool unserialize_t_val(t_type& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
|
||||
{
|
||||
return stg.get_value(pname, d, hparent_section);
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
template<class t_type, class t_storage>
|
||||
static bool serialize_t_val_as_blob(const t_type& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
|
||||
{
|
||||
std::string blob((const char *)&d, sizeof(d));
|
||||
return stg.set_value(pname, std::move(blob), hparent_section);
|
||||
return stg.set_value(pname, blob, hparent_section);
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
template<class t_type, class t_storage>
|
||||
@@ -102,15 +114,13 @@ namespace epee
|
||||
template<class stl_container, class t_storage>
|
||||
static bool serialize_stl_container_t_val (const stl_container& container, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
|
||||
{
|
||||
using value_type = typename stl_container::value_type;
|
||||
|
||||
if(!container.size()) return true;
|
||||
typename stl_container::const_iterator it = container.begin();
|
||||
typename t_storage::harray hval_array = stg.insert_first_value(pname, value_type(*it), hparent_section);
|
||||
typename t_storage::harray hval_array = stg.insert_first_value(pname, *it, hparent_section);
|
||||
CHECK_AND_ASSERT_MES(hval_array, false, "failed to insert first value to storage");
|
||||
it++;
|
||||
for(;it!= container.end();it++)
|
||||
stg.insert_next_value(hval_array, value_type(*it));
|
||||
stg.insert_next_value(hval_array, *it);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -139,7 +149,7 @@ namespace epee
|
||||
*p_elem = v;
|
||||
p_elem++;
|
||||
}
|
||||
return stg.set_value(pname, std::move(mb), hparent_section);
|
||||
return stg.set_value(pname, mb, hparent_section);
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------------------------
|
||||
template<class stl_container, class t_storage>
|
||||
@@ -211,7 +221,7 @@ namespace epee
|
||||
template<class t_type, class t_storage>
|
||||
static bool kv_serialize(const t_type& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
|
||||
{
|
||||
return stg.set_value(pname, t_type(d), hparent_section);
|
||||
return stg.set_value(pname, d, hparent_section);
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
template<class t_type, class t_storage>
|
||||
|
||||
@@ -110,8 +110,7 @@ namespace epee
|
||||
constexpr std::size_t size() const noexcept { return len; }
|
||||
constexpr std::size_t size_bytes() const noexcept { return size() * sizeof(value_type); }
|
||||
|
||||
T &operator[](size_t idx) noexcept { return ptr[idx]; }
|
||||
const T &operator[](size_t idx) const noexcept { return ptr[idx]; }
|
||||
const T &operator[](size_t idx) const { return ptr[idx]; }
|
||||
|
||||
private:
|
||||
T* ptr;
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace epee
|
||||
namespace net_utils
|
||||
{
|
||||
template<class t_request, class t_response, class t_transport>
|
||||
bool invoke_http_json(const boost::string_ref uri, const t_request& out_struct, t_response& result_struct, t_transport& transport, std::chrono::milliseconds timeout = std::chrono::seconds(15), const boost::string_ref method = "POST")
|
||||
bool invoke_http_json(const boost::string_ref uri, const t_request& out_struct, t_response& result_struct, t_transport& transport, std::chrono::milliseconds timeout = std::chrono::seconds(15), const boost::string_ref method = "GET")
|
||||
{
|
||||
std::string req_param;
|
||||
if(!serialization::store_t_to_json(out_struct, req_param))
|
||||
@@ -72,7 +72,7 @@ namespace epee
|
||||
|
||||
|
||||
template<class t_request, class t_response, class t_transport>
|
||||
bool invoke_http_bin(const boost::string_ref uri, const t_request& out_struct, t_response& result_struct, t_transport& transport, std::chrono::milliseconds timeout = std::chrono::seconds(15), const boost::string_ref method = "POST")
|
||||
bool invoke_http_bin(const boost::string_ref uri, const t_request& out_struct, t_response& result_struct, t_transport& transport, std::chrono::milliseconds timeout = std::chrono::seconds(15), const boost::string_ref method = "GET")
|
||||
{
|
||||
std::string req_param;
|
||||
if(!serialization::store_t_to_binary(out_struct, req_param))
|
||||
@@ -101,7 +101,7 @@ namespace epee
|
||||
}
|
||||
|
||||
template<class t_request, class t_response, class t_transport>
|
||||
bool invoke_http_json_rpc(const boost::string_ref uri, std::string method_name, const t_request& out_struct, t_response& result_struct, epee::json_rpc::error &error_struct, t_transport& transport, std::chrono::milliseconds timeout = std::chrono::seconds(15), const boost::string_ref http_method = "POST", const std::string& req_id = "0")
|
||||
bool invoke_http_json_rpc(const boost::string_ref uri, std::string method_name, const t_request& out_struct, t_response& result_struct, epee::json_rpc::error &error_struct, t_transport& transport, std::chrono::milliseconds timeout = std::chrono::seconds(15), const boost::string_ref http_method = "GET", const std::string& req_id = "0")
|
||||
{
|
||||
epee::json_rpc::request<t_request> req_t = AUTO_VAL_INIT(req_t);
|
||||
req_t.jsonrpc = "2.0";
|
||||
@@ -125,14 +125,14 @@ namespace epee
|
||||
}
|
||||
|
||||
template<class t_request, class t_response, class t_transport>
|
||||
bool invoke_http_json_rpc(const boost::string_ref uri, std::string method_name, const t_request& out_struct, t_response& result_struct, t_transport& transport, std::chrono::milliseconds timeout = std::chrono::seconds(15), const boost::string_ref http_method = "POST", const std::string& req_id = "0")
|
||||
bool invoke_http_json_rpc(const boost::string_ref uri, std::string method_name, const t_request& out_struct, t_response& result_struct, t_transport& transport, std::chrono::milliseconds timeout = std::chrono::seconds(15), const boost::string_ref http_method = "GET", const std::string& req_id = "0")
|
||||
{
|
||||
epee::json_rpc::error error_struct;
|
||||
return invoke_http_json_rpc(uri, method_name, out_struct, result_struct, error_struct, transport, timeout, http_method, req_id);
|
||||
}
|
||||
|
||||
template<class t_command, class t_transport>
|
||||
bool invoke_http_json_rpc(const boost::string_ref uri, typename t_command::request& out_struct, typename t_command::response& result_struct, t_transport& transport, std::chrono::milliseconds timeout = std::chrono::seconds(15), const boost::string_ref http_method = "POST", const std::string& req_id = "0")
|
||||
bool invoke_http_json_rpc(const boost::string_ref uri, typename t_command::request& out_struct, typename t_command::response& result_struct, t_transport& transport, std::chrono::milliseconds timeout = std::chrono::seconds(15), const boost::string_ref http_method = "GET", const std::string& req_id = "0")
|
||||
{
|
||||
return invoke_http_json_rpc(uri, t_command::methodname(), out_struct, result_struct, transport, timeout, http_method, req_id);
|
||||
}
|
||||
|
||||
@@ -28,35 +28,16 @@
|
||||
|
||||
#include "portable_storage_template_helper.h"
|
||||
#include <boost/utility/value_init.hpp>
|
||||
#include <functional>
|
||||
#include "span.h"
|
||||
#include "net/levin_base.h"
|
||||
|
||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
#define MONERO_DEFAULT_LOG_CATEGORY "net"
|
||||
|
||||
namespace
|
||||
{
|
||||
template<typename context_t>
|
||||
void on_levin_traffic(const context_t &context, bool initiator, bool sent, bool error, size_t bytes, const char *category)
|
||||
{
|
||||
MCINFO("net.p2p.traffic", context << bytes << " bytes " << (sent ? "sent" : "received") << (error ? "/corrupt" : "")
|
||||
<< " for category " << category << " initiated by " << (initiator ? "us" : "peer"));
|
||||
}
|
||||
template<typename context_t>
|
||||
void on_levin_traffic(const context_t &context, bool initiator, bool sent, bool error, size_t bytes, int command)
|
||||
{
|
||||
char buf[32];
|
||||
snprintf(buf, sizeof(buf), "command-%u", command);
|
||||
return on_levin_traffic(context, initiator, sent, error, bytes, buf);
|
||||
}
|
||||
}
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace net_utils
|
||||
{
|
||||
#if 0
|
||||
template<class t_arg, class t_result, class t_transport>
|
||||
bool invoke_remote_command2(int command, const t_arg& out_struct, t_result& result_struct, t_transport& transport)
|
||||
{
|
||||
@@ -102,18 +83,16 @@ namespace epee
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
template<class t_arg, class t_result, class t_transport>
|
||||
bool invoke_remote_command2(const epee::net_utils::connection_context_base context, int command, const t_arg& out_struct, t_result& result_struct, t_transport& transport)
|
||||
bool invoke_remote_command2(boost::uuids::uuid conn_id, int command, const t_arg& out_struct, t_result& result_struct, t_transport& transport)
|
||||
{
|
||||
const boost::uuids::uuid &conn_id = context.m_connection_id;
|
||||
|
||||
typename serialization::portable_storage stg;
|
||||
out_struct.store(stg);
|
||||
std::string buff_to_send, buff_to_recv;
|
||||
stg.store_to_binary(buff_to_send);
|
||||
|
||||
on_levin_traffic(context, true, true, false, buff_to_send.size(), command);
|
||||
int res = transport.invoke(command, buff_to_send, buff_to_recv, conn_id);
|
||||
if( res <=0 )
|
||||
{
|
||||
@@ -123,30 +102,24 @@ namespace epee
|
||||
typename serialization::portable_storage stg_ret;
|
||||
if(!stg_ret.load_from_binary(buff_to_recv))
|
||||
{
|
||||
on_levin_traffic(context, true, false, true, buff_to_recv.size(), command);
|
||||
LOG_ERROR("Failed to load_from_binary on command " << command);
|
||||
return false;
|
||||
}
|
||||
on_levin_traffic(context, true, false, false, buff_to_recv.size(), command);
|
||||
return result_struct.load(stg_ret);
|
||||
}
|
||||
|
||||
template<class t_result, class t_arg, class callback_t, class t_transport>
|
||||
bool async_invoke_remote_command2(const epee::net_utils::connection_context_base &context, int command, const t_arg& out_struct, t_transport& transport, const callback_t &cb, size_t inv_timeout = LEVIN_DEFAULT_TIMEOUT_PRECONFIGURED)
|
||||
bool async_invoke_remote_command2(boost::uuids::uuid conn_id, int command, const t_arg& out_struct, t_transport& transport, const callback_t &cb, size_t inv_timeout = LEVIN_DEFAULT_TIMEOUT_PRECONFIGURED)
|
||||
{
|
||||
const boost::uuids::uuid &conn_id = context.m_connection_id;
|
||||
typename serialization::portable_storage stg;
|
||||
const_cast<t_arg&>(out_struct).store(stg);//TODO: add true const support to searilzation
|
||||
std::string buff_to_send;
|
||||
stg.store_to_binary(buff_to_send);
|
||||
on_levin_traffic(context, true, true, false, buff_to_send.size(), command);
|
||||
int res = transport.invoke_async(command, epee::strspan<uint8_t>(buff_to_send), conn_id, [cb, command](int code, const epee::span<const uint8_t> buff, typename t_transport::connection_context& context)->bool
|
||||
{
|
||||
t_result result_struct = AUTO_VAL_INIT(result_struct);
|
||||
if( code <=0 )
|
||||
{
|
||||
if (!buff.empty())
|
||||
on_levin_traffic(context, true, false, true, buff.size(), command);
|
||||
LOG_PRINT_L1("Failed to invoke command " << command << " return code " << code);
|
||||
cb(code, result_struct, context);
|
||||
return false;
|
||||
@@ -154,19 +127,16 @@ namespace epee
|
||||
serialization::portable_storage stg_ret;
|
||||
if(!stg_ret.load_from_binary(buff))
|
||||
{
|
||||
on_levin_traffic(context, true, false, true, buff.size(), command);
|
||||
LOG_ERROR("Failed to load_from_binary on command " << command);
|
||||
cb(LEVIN_ERROR_FORMAT, result_struct, context);
|
||||
return false;
|
||||
}
|
||||
if (!result_struct.load(stg_ret))
|
||||
{
|
||||
on_levin_traffic(context, true, false, true, buff.size(), command);
|
||||
LOG_ERROR("Failed to load result struct on command " << command);
|
||||
cb(LEVIN_ERROR_FORMAT, result_struct, context);
|
||||
return false;
|
||||
}
|
||||
on_levin_traffic(context, true, false, false, buff.size(), command);
|
||||
cb(code, result_struct, context);
|
||||
return true;
|
||||
}, inv_timeout);
|
||||
@@ -179,15 +149,14 @@ namespace epee
|
||||
}
|
||||
|
||||
template<class t_arg, class t_transport>
|
||||
bool notify_remote_command2(const typename t_transport::connection_context &context, int command, const t_arg& out_struct, t_transport& transport)
|
||||
bool notify_remote_command2(boost::uuids::uuid conn_id, int command, const t_arg& out_struct, t_transport& transport)
|
||||
{
|
||||
const boost::uuids::uuid &conn_id = context.m_connection_id;
|
||||
|
||||
serialization::portable_storage stg;
|
||||
out_struct.store(stg);
|
||||
std::string buff_to_send;
|
||||
stg.store_to_binary(buff_to_send);
|
||||
|
||||
on_levin_traffic(context, true, true, false, buff_to_send.size(), command);
|
||||
int res = transport.notify(command, epee::strspan<uint8_t>(buff_to_send), conn_id);
|
||||
if(res <=0 )
|
||||
{
|
||||
@@ -204,7 +173,6 @@ namespace epee
|
||||
serialization::portable_storage strg;
|
||||
if(!strg.load_from_binary(in_buff))
|
||||
{
|
||||
on_levin_traffic(context, false, false, true, in_buff.size(), command);
|
||||
LOG_ERROR("Failed to load_from_binary in command " << command);
|
||||
return -1;
|
||||
}
|
||||
@@ -213,11 +181,9 @@ namespace epee
|
||||
|
||||
if (!static_cast<t_in_type&>(in_struct).load(strg))
|
||||
{
|
||||
on_levin_traffic(context, false, false, true, in_buff.size(), command);
|
||||
LOG_ERROR("Failed to load in_struct in command " << command);
|
||||
return -1;
|
||||
}
|
||||
on_levin_traffic(context, false, false, false, in_buff.size(), command);
|
||||
int res = cb(command, static_cast<t_in_type&>(in_struct), static_cast<t_out_type&>(out_struct), context);
|
||||
serialization::portable_storage strg_out;
|
||||
static_cast<t_out_type&>(out_struct).store(strg_out);
|
||||
@@ -227,7 +193,6 @@ namespace epee
|
||||
LOG_ERROR("Failed to store_to_binary in command" << command);
|
||||
return -1;
|
||||
}
|
||||
on_levin_traffic(context, false, true, false, buff_out.size(), command);
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -238,18 +203,15 @@ namespace epee
|
||||
serialization::portable_storage strg;
|
||||
if(!strg.load_from_binary(in_buff))
|
||||
{
|
||||
on_levin_traffic(context, false, false, true, in_buff.size(), command);
|
||||
LOG_ERROR("Failed to load_from_binary in notify " << command);
|
||||
return -1;
|
||||
}
|
||||
boost::value_initialized<t_in_type> in_struct;
|
||||
if (!static_cast<t_in_type&>(in_struct).load(strg))
|
||||
{
|
||||
on_levin_traffic(context, false, false, true, in_buff.size(), command);
|
||||
LOG_ERROR("Failed to load in_struct in notify " << command);
|
||||
return -1;
|
||||
}
|
||||
on_levin_traffic(context, false, false, false, in_buff.size(), command);
|
||||
return cb(command, in_struct, context);
|
||||
}
|
||||
|
||||
@@ -295,20 +257,20 @@ namespace epee
|
||||
|
||||
#define HANDLE_INVOKE2(command_id, func, type_name_in, typename_out) \
|
||||
if(!is_notify && command_id == command) \
|
||||
{handled=true;return epee::net_utils::buff_to_t_adapter<internal_owner_type_name, type_name_in, typename_out>(this, command, in_buff, buff_out, std::bind(func, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4), context);}
|
||||
{handled=true;return epee::net_utils::buff_to_t_adapter<internal_owner_type_name, type_name_in, typename_out>(this, command, in_buff, buff_out, boost::bind(func, this, _1, _2, _3, _4), context);}
|
||||
|
||||
#define HANDLE_INVOKE_T2(COMMAND, func) \
|
||||
if(!is_notify && COMMAND::ID == command) \
|
||||
{handled=true;return epee::net_utils::buff_to_t_adapter<internal_owner_type_name, typename COMMAND::request, typename COMMAND::response>(command, in_buff, buff_out, std::bind(func, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4), context);}
|
||||
{handled=true;return epee::net_utils::buff_to_t_adapter<internal_owner_type_name, typename COMMAND::request, typename COMMAND::response>(command, in_buff, buff_out, boost::bind(func, this, _1, _2, _3, _4), context);}
|
||||
|
||||
|
||||
#define HANDLE_NOTIFY2(command_id, func, type_name_in) \
|
||||
if(is_notify && command_id == command) \
|
||||
{handled=true;return epee::net_utils::buff_to_t_adapter<internal_owner_type_name, type_name_in>(this, command, in_buff, std::bind(func, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), context);}
|
||||
{handled=true;return epee::net_utils::buff_to_t_adapter<internal_owner_type_name, type_name_in>(this, command, in_buff, boost::bind(func, this, _1, _2, _3), context);}
|
||||
|
||||
#define HANDLE_NOTIFY_T2(NOTIFY, func) \
|
||||
if(is_notify && NOTIFY::ID == command) \
|
||||
{handled=true;return epee::net_utils::buff_to_t_adapter<internal_owner_type_name, typename NOTIFY::request>(this, command, in_buff, std::bind(func, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), context);}
|
||||
{handled=true;return epee::net_utils::buff_to_t_adapter<internal_owner_type_name, typename NOTIFY::request>(this, command, in_buff, boost::bind(func, this, _1, _2, _3), context);}
|
||||
|
||||
|
||||
#define CHAIN_INVOKE_MAP2(func) \
|
||||
@@ -334,7 +296,6 @@ namespace epee
|
||||
|
||||
#define END_INVOKE_MAP2() \
|
||||
LOG_ERROR("Unknown command:" << command); \
|
||||
on_levin_traffic(context, false, false, true, in_buff.size(), "invalid-command"); \
|
||||
return LEVIN_ERROR_CONNECTION_HANDLER_NOT_DEFINED; \
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,8 +31,6 @@
|
||||
#include <algorithm>
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
|
||||
#include "misc_log_ex.h"
|
||||
|
||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
#define MONERO_DEFAULT_LOG_CATEGORY "serialization"
|
||||
|
||||
@@ -159,6 +157,7 @@ namespace misc_utils
|
||||
while (fi != buf_end && ((lut[(uint8_t)*fi] & 32)) == 0)
|
||||
++fi;
|
||||
val.assign(it, fi);
|
||||
val.reserve(std::distance(star_end_string, buf_end));
|
||||
it = fi;
|
||||
for(;it != buf_end;it++)
|
||||
{
|
||||
@@ -196,7 +195,7 @@ namespace misc_utils
|
||||
uint32_t dst = 0;
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
const unsigned char tmp = isx[(unsigned char)*++it];
|
||||
const unsigned char tmp = isx[(int)*++it];
|
||||
CHECK_AND_ASSERT_THROW_MES(tmp != 0xff, "Bad Unicode encoding");
|
||||
dst = dst << 4 | tmp;
|
||||
}
|
||||
|
||||
@@ -28,8 +28,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "misc_language.h"
|
||||
#include "portable_storage_base.h"
|
||||
#include "portable_storage_to_bin.h"
|
||||
@@ -61,7 +59,7 @@ namespace epee
|
||||
bool get_value(const std::string& value_name, t_value& val, hsection hparent_section);
|
||||
bool get_value(const std::string& value_name, storage_entry& val, hsection hparent_section);
|
||||
template<class t_value>
|
||||
bool set_value(const std::string& value_name, t_value&& target, hsection hparent_section);
|
||||
bool set_value(const std::string& value_name, const t_value& target, hsection hparent_section);
|
||||
|
||||
//serial access for arrays of values --------------------------------------
|
||||
//values
|
||||
@@ -70,9 +68,9 @@ namespace epee
|
||||
template<class t_value>
|
||||
bool get_next_value(harray hval_array, t_value& target);
|
||||
template<class t_value>
|
||||
harray insert_first_value(const std::string& value_name, t_value&& target, hsection hparent_section);
|
||||
harray insert_first_value(const std::string& value_name, const t_value& target, hsection hparent_section);
|
||||
template<class t_value>
|
||||
bool insert_next_value(harray hval_array, t_value&& target);
|
||||
bool insert_next_value(harray hval_array, const t_value& target);
|
||||
//sections
|
||||
harray get_first_section(const std::string& pSectionName, hsection& h_child_section, hsection hparent_section);
|
||||
bool get_next_section(harray hSecArray, hsection& h_child_section);
|
||||
@@ -96,7 +94,7 @@ namespace epee
|
||||
hsection get_root_section() {return &m_root;}
|
||||
storage_entry* find_storage_entry(const std::string& pentry_name, hsection psection);
|
||||
template<class entry_type>
|
||||
storage_entry* insert_new_entry_get_storage_entry(const std::string& pentry_name, hsection psection, entry_type&& entry);
|
||||
storage_entry* insert_new_entry_get_storage_entry(const std::string& pentry_name, hsection psection, const entry_type& entry);
|
||||
|
||||
hsection insert_new_section(const std::string& pentry_name, hsection psection);
|
||||
|
||||
@@ -243,22 +241,21 @@ namespace epee
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
template<class t_value>
|
||||
bool portable_storage::set_value(const std::string& value_name, t_value&& v, hsection hparent_section)
|
||||
bool portable_storage::set_value(const std::string& value_name, const t_value& v, hsection hparent_section)
|
||||
{
|
||||
using t_real_value = typename std::decay<t_value>::type;
|
||||
BOOST_MPL_ASSERT(( boost::mpl::contains<boost::mpl::push_front<storage_entry::types, storage_entry>::type, t_real_value> ));
|
||||
BOOST_MPL_ASSERT(( boost::mpl::contains<boost::mpl::push_front<storage_entry::types, storage_entry>::type, t_value> ));
|
||||
TRY_ENTRY();
|
||||
if(!hparent_section)
|
||||
hparent_section = &m_root;
|
||||
storage_entry* pentry = find_storage_entry(value_name, hparent_section);
|
||||
if(!pentry)
|
||||
{
|
||||
pentry = insert_new_entry_get_storage_entry(value_name, hparent_section, std::forward<t_value>(v));
|
||||
pentry = insert_new_entry_get_storage_entry(value_name, hparent_section, v);
|
||||
if(!pentry)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
*pentry = std::forward<t_value>(v);
|
||||
*pentry = storage_entry(v);
|
||||
return true;
|
||||
CATCH_ENTRY("portable_storage::template<>set_value", false);
|
||||
}
|
||||
@@ -277,12 +274,11 @@ namespace epee
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
template<class entry_type>
|
||||
storage_entry* portable_storage::insert_new_entry_get_storage_entry(const std::string& pentry_name, hsection psection, entry_type&& entry)
|
||||
storage_entry* portable_storage::insert_new_entry_get_storage_entry(const std::string& pentry_name, hsection psection, const entry_type& entry)
|
||||
{
|
||||
static_assert(std::is_rvalue_reference<entry_type&&>(), "unexpected copy of value");
|
||||
TRY_ENTRY();
|
||||
CHECK_AND_ASSERT(psection, nullptr);
|
||||
auto ins_res = psection->m_entries.emplace(pentry_name, std::forward<entry_type>(entry));
|
||||
auto ins_res = psection->m_entries.insert(std::pair<std::string, storage_entry>(pentry_name, entry));
|
||||
return &ins_res.first->second;
|
||||
CATCH_ENTRY("portable_storage::insert_new_entry_get_storage_entry", nullptr);
|
||||
}
|
||||
@@ -366,45 +362,41 @@ namespace epee
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
template<class t_value>
|
||||
harray portable_storage::insert_first_value(const std::string& value_name, t_value&& target, hsection hparent_section)
|
||||
harray portable_storage::insert_first_value(const std::string& value_name, const t_value& target, hsection hparent_section)
|
||||
{
|
||||
using t_real_value = typename std::decay<t_value>::type;
|
||||
static_assert(std::is_rvalue_reference<t_value&&>(), "unexpected copy of value");
|
||||
TRY_ENTRY();
|
||||
if(!hparent_section) hparent_section = &m_root;
|
||||
storage_entry* pentry = find_storage_entry(value_name, hparent_section);
|
||||
if(!pentry)
|
||||
{
|
||||
pentry = insert_new_entry_get_storage_entry(value_name, hparent_section, array_entry(array_entry_t<t_real_value>()));
|
||||
pentry = insert_new_entry_get_storage_entry(value_name, hparent_section, array_entry(array_entry_t<t_value>()));
|
||||
if(!pentry)
|
||||
return nullptr;
|
||||
}
|
||||
if(pentry->type() != typeid(array_entry))
|
||||
*pentry = storage_entry(array_entry(array_entry_t<t_real_value>()));
|
||||
*pentry = storage_entry(array_entry(array_entry_t<t_value>()));
|
||||
|
||||
array_entry& arr = boost::get<array_entry>(*pentry);
|
||||
if(arr.type() != typeid(array_entry_t<t_real_value>))
|
||||
arr = array_entry(array_entry_t<t_real_value>());
|
||||
if(arr.type() != typeid(array_entry_t<t_value>))
|
||||
arr = array_entry(array_entry_t<t_value>());
|
||||
|
||||
array_entry_t<t_real_value>& arr_typed = boost::get<array_entry_t<t_real_value> >(arr);
|
||||
arr_typed.insert_first_val(std::forward<t_value>(target));
|
||||
array_entry_t<t_value>& arr_typed = boost::get<array_entry_t<t_value> >(arr);
|
||||
arr_typed.insert_first_val(target);
|
||||
return &arr;
|
||||
CATCH_ENTRY("portable_storage::insert_first_value", nullptr);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
template<class t_value>
|
||||
bool portable_storage::insert_next_value(harray hval_array, t_value&& target)
|
||||
bool portable_storage::insert_next_value(harray hval_array, const t_value& target)
|
||||
{
|
||||
using t_real_value = typename std::decay<t_value>::type;
|
||||
static_assert(std::is_rvalue_reference<t_value&&>(), "unexpected copy of value");
|
||||
TRY_ENTRY();
|
||||
CHECK_AND_ASSERT(hval_array, false);
|
||||
|
||||
CHECK_AND_ASSERT_MES(hval_array->type() == typeid(array_entry_t<t_real_value>),
|
||||
false, "unexpected type in insert_next_value: " << typeid(array_entry_t<t_real_value>).name());
|
||||
CHECK_AND_ASSERT_MES(hval_array->type() == typeid(array_entry_t<t_value>),
|
||||
false, "unexpected type in insert_next_value: " << typeid(array_entry_t<t_value>).name());
|
||||
|
||||
array_entry_t<t_real_value>& arr_typed = boost::get<array_entry_t<t_real_value> >(*hval_array);
|
||||
arr_typed.insert_next_value(std::forward<t_value>(target));
|
||||
array_entry_t<t_value>& arr_typed = boost::get<array_entry_t<t_value> >(*hval_array);
|
||||
arr_typed.insert_next_value(target);
|
||||
return true;
|
||||
CATCH_ENTRY("portable_storage::insert_next_value", false);
|
||||
}
|
||||
|
||||
@@ -84,13 +84,6 @@ namespace epee
|
||||
array_entry_t():m_it(m_array.end()){}
|
||||
array_entry_t(const array_entry_t& other):m_array(other.m_array), m_it(m_array.end()){}
|
||||
|
||||
array_entry_t& operator=(const array_entry_t& other)
|
||||
{
|
||||
m_array = other.m_array;
|
||||
m_it = m_array.end();
|
||||
return *this;
|
||||
}
|
||||
|
||||
const t_entry_type* get_first_val() const
|
||||
{
|
||||
m_it = m_array.begin();
|
||||
@@ -118,16 +111,16 @@ namespace epee
|
||||
return (t_entry_type*)&(*(m_it++));//fuckoff
|
||||
}
|
||||
|
||||
t_entry_type& insert_first_val(t_entry_type&& v)
|
||||
t_entry_type& insert_first_val(const t_entry_type& v)
|
||||
{
|
||||
m_array.clear();
|
||||
m_it = m_array.end();
|
||||
return insert_next_value(std::move(v));
|
||||
return insert_next_value(v);
|
||||
}
|
||||
|
||||
t_entry_type& insert_next_value(t_entry_type&& v)
|
||||
t_entry_type& insert_next_value(const t_entry_type& v)
|
||||
{
|
||||
m_array.push_back(std::move(v));
|
||||
m_array.push_back(v);
|
||||
return m_array.back();
|
||||
}
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@ namespace epee
|
||||
//TODO: add some optimization here later
|
||||
while(size--)
|
||||
sa.m_array.push_back(read<type_name>());
|
||||
return storage_entry(array_entry(std::move(sa)));
|
||||
return storage_entry(array_entry(sa));
|
||||
}
|
||||
|
||||
inline
|
||||
@@ -213,7 +213,7 @@ namespace epee
|
||||
{
|
||||
RECURSION_LIMITATION();
|
||||
section s;//use extra variable due to vs bug, line "storage_entry se(section()); " can't be compiled in visual studio
|
||||
storage_entry se(std::move(s));
|
||||
storage_entry se(s);
|
||||
section& section_entry = boost::get<section>(se);
|
||||
read(section_entry);
|
||||
return se;
|
||||
@@ -268,7 +268,7 @@ namespace epee
|
||||
//read section name string
|
||||
std::string sec_name;
|
||||
read_sec_name(sec_name);
|
||||
sec.m_entries.emplace(std::move(sec_name), load_storage_entry());
|
||||
sec.m_entries.insert(std::make_pair(sec_name, load_storage_entry()));
|
||||
}
|
||||
}
|
||||
inline
|
||||
|
||||
@@ -128,20 +128,20 @@ namespace epee
|
||||
errno = 0;
|
||||
int64_t nval = strtoll(val.data(), NULL, 10);
|
||||
if (errno) throw std::runtime_error("Invalid number: " + std::string(val));
|
||||
stg.set_value(name, int64_t(nval), current_section);
|
||||
stg.set_value(name, nval, current_section);
|
||||
}else
|
||||
{
|
||||
errno = 0;
|
||||
uint64_t nval = strtoull(val.data(), NULL, 10);
|
||||
if (errno) throw std::runtime_error("Invalid number: " + std::string(val));
|
||||
stg.set_value(name, uint64_t(nval), current_section);
|
||||
stg.set_value(name, nval, current_section);
|
||||
}
|
||||
}else
|
||||
{
|
||||
errno = 0;
|
||||
double nval = strtod(val.data(), NULL);
|
||||
if (errno) throw std::runtime_error("Invalid number: " + std::string(val));
|
||||
stg.set_value(name, double(nval), current_section);
|
||||
stg.set_value(name, nval, current_section);
|
||||
}
|
||||
state = match_state_wonder_after_value;
|
||||
}else if(isalpha(*it) )
|
||||
@@ -219,13 +219,13 @@ namespace epee
|
||||
errno = 0;
|
||||
int64_t nval = strtoll(val.data(), NULL, 10);
|
||||
if (errno) throw std::runtime_error("Invalid number: " + std::string(val));
|
||||
h_array = stg.insert_first_value(name, int64_t(nval), current_section);
|
||||
h_array = stg.insert_first_value(name, nval, current_section);
|
||||
}else
|
||||
{
|
||||
errno = 0;
|
||||
uint64_t nval = strtoull(val.data(), NULL, 10);
|
||||
if (errno) throw std::runtime_error("Invalid number: " + std::string(val));
|
||||
h_array = stg.insert_first_value(name, uint64_t(nval), current_section);
|
||||
h_array = stg.insert_first_value(name, nval, current_section);
|
||||
}
|
||||
CHECK_AND_ASSERT_THROW_MES(h_array, " failed to insert values section entry");
|
||||
}else
|
||||
@@ -233,7 +233,7 @@ namespace epee
|
||||
errno = 0;
|
||||
double nval = strtod(val.data(), NULL);
|
||||
if (errno) throw std::runtime_error("Invalid number: " + std::string(val));
|
||||
h_array = stg.insert_first_value(name, double(nval), current_section);
|
||||
h_array = stg.insert_first_value(name, nval, current_section);
|
||||
CHECK_AND_ASSERT_THROW_MES(h_array, " failed to insert values section entry");
|
||||
}
|
||||
|
||||
@@ -310,20 +310,20 @@ namespace epee
|
||||
errno = 0;
|
||||
int64_t nval = strtoll(val.data(), NULL, 10);
|
||||
if (errno) throw std::runtime_error("Invalid number: " + std::string(val));
|
||||
insert_res = stg.insert_next_value(h_array, int64_t(nval));
|
||||
insert_res = stg.insert_next_value(h_array, nval);
|
||||
}else
|
||||
{
|
||||
errno = 0;
|
||||
uint64_t nval = strtoull(val.data(), NULL, 10);
|
||||
if (errno) throw std::runtime_error("Invalid number: " + std::string(val));
|
||||
insert_res = stg.insert_next_value(h_array, uint64_t(nval));
|
||||
insert_res = stg.insert_next_value(h_array, nval);
|
||||
}
|
||||
}else
|
||||
{
|
||||
errno = 0;
|
||||
double nval = strtod(val.data(), NULL);
|
||||
if (errno) throw std::runtime_error("Invalid number: " + std::string(val));
|
||||
insert_res = stg.insert_next_value(h_array, double(nval));
|
||||
insert_res = stg.insert_next_value(h_array, nval);
|
||||
}
|
||||
CHECK_AND_ASSERT_THROW_MES(insert_res, "Failed to insert next value");
|
||||
state = match_state_array_after_value;
|
||||
|
||||
@@ -42,7 +42,6 @@
|
||||
#include <type_traits>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
#include "misc_log_ex.h"
|
||||
#include "storages/parserse_base_utils.h"
|
||||
#include "hex.h"
|
||||
@@ -70,9 +69,34 @@ namespace string_tools
|
||||
return to_hex::string(to_byte_span(to_span(src)));
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
inline bool parse_hexstr_to_binbuff(const boost::string_ref s, std::string& res)
|
||||
inline bool parse_hexstr_to_binbuff(const epee::span<const char> s, epee::span<char>& res)
|
||||
{
|
||||
return from_hex::to_string(res, s);
|
||||
if (s.size() != res.size() * 2)
|
||||
return false;
|
||||
|
||||
unsigned char *dst = (unsigned char *)&res[0];
|
||||
const unsigned char *src = (const unsigned char *)s.data();
|
||||
for(size_t i = 0; i < s.size(); i += 2)
|
||||
{
|
||||
int tmp = *src++;
|
||||
tmp = epee::misc_utils::parse::isx[tmp];
|
||||
if (tmp == 0xff) return false;
|
||||
int t2 = *src++;
|
||||
t2 = epee::misc_utils::parse::isx[t2];
|
||||
if (t2 == 0xff) return false;
|
||||
*dst++ = (tmp << 4) | t2;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
inline bool parse_hexstr_to_binbuff(const std::string& s, std::string& res)
|
||||
{
|
||||
if (s.size() & 1)
|
||||
return false;
|
||||
res.resize(s.size() / 2);
|
||||
epee::span<char> rspan((char*)&res[0], res.size());
|
||||
return parse_hexstr_to_binbuff(epee::to_span(s), rspan);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
PUSH_WARNINGS
|
||||
@@ -164,10 +188,8 @@ POP_WARNINGS
|
||||
return boost::lexical_cast<std::string>(val);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
inline std::string to_string_hex(const T &val)
|
||||
inline std::string to_string_hex(uint32_t val)
|
||||
{
|
||||
static_assert(std::is_arithmetic<T>::value, "only arithmetic types");
|
||||
std::stringstream ss;
|
||||
ss << std::hex << val;
|
||||
std::string s;
|
||||
@@ -279,20 +301,23 @@ POP_WARNINGS
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
template<class t_pod_type>
|
||||
bool hex_to_pod(const boost::string_ref hex_str, t_pod_type& s)
|
||||
bool hex_to_pod(const std::string& hex_str, t_pod_type& s)
|
||||
{
|
||||
static_assert(std::is_standard_layout<t_pod_type>(), "expected standard layout type");
|
||||
return from_hex::to_buffer(as_mut_byte_span(s), hex_str);
|
||||
static_assert(std::is_pod<t_pod_type>::value, "expected pod type");
|
||||
if(sizeof(s)*2 != hex_str.size())
|
||||
return false;
|
||||
epee::span<char> rspan((char*)&s, sizeof(s));
|
||||
return parse_hexstr_to_binbuff(epee::to_span(hex_str), rspan);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
template<class t_pod_type>
|
||||
bool hex_to_pod(const boost::string_ref hex_str, tools::scrubbed<t_pod_type>& s)
|
||||
bool hex_to_pod(const std::string& hex_str, tools::scrubbed<t_pod_type>& s)
|
||||
{
|
||||
return hex_to_pod(hex_str, unwrap(s));
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
template<class t_pod_type>
|
||||
bool hex_to_pod(const boost::string_ref hex_str, epee::mlocked<t_pod_type>& s)
|
||||
bool hex_to_pod(const std::string& hex_str, epee::mlocked<t_pod_type>& s)
|
||||
{
|
||||
return hex_to_pod(hex_str, unwrap(s));
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ namespace epee
|
||||
};
|
||||
|
||||
|
||||
#define CRITICAL_REGION_LOCAL(x) {} epee::critical_region_t<decltype(x)> critical_region_var(x)
|
||||
#define CRITICAL_REGION_LOCAL(x) {boost::this_thread::sleep_for(boost::chrono::milliseconds(epee::debug::g_test_dbg_lock_sleep()));} epee::critical_region_t<decltype(x)> critical_region_var(x)
|
||||
#define CRITICAL_REGION_BEGIN(x) { boost::this_thread::sleep_for(boost::chrono::milliseconds(epee::debug::g_test_dbg_lock_sleep())); epee::critical_region_t<decltype(x)> critical_region_var(x)
|
||||
#define CRITICAL_REGION_LOCAL1(x) {boost::this_thread::sleep_for(boost::chrono::milliseconds(epee::debug::g_test_dbg_lock_sleep()));} epee::critical_region_t<decltype(x)> critical_region_var1(x)
|
||||
#define CRITICAL_REGION_BEGIN1(x) { boost::this_thread::sleep_for(boost::chrono::milliseconds(epee::debug::g_test_dbg_lock_sleep())); epee::critical_region_t<decltype(x)> critical_region_var1(x)
|
||||
|
||||
@@ -26,9 +26,8 @@
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
add_library(epee STATIC byte_slice.cpp byte_stream.cpp hex.cpp abstract_http_client.cpp http_auth.cpp mlog.cpp net_helper.cpp net_utils_base.cpp string_tools.cpp
|
||||
wipeable_string.cpp levin_base.cpp memwipe.c connection_basic.cpp network_throttle.cpp network_throttle-detail.cpp mlocker.cpp buffer.cpp net_ssl.cpp
|
||||
add_library(epee STATIC byte_slice.cpp hex.cpp http_auth.cpp mlog.cpp net_helper.cpp net_utils_base.cpp string_tools.cpp wipeable_string.cpp
|
||||
levin_base.cpp memwipe.c connection_basic.cpp network_throttle.cpp network_throttle-detail.cpp mlocker.cpp buffer.cpp net_ssl.cpp
|
||||
int-util.cpp)
|
||||
|
||||
if (USE_READLINE AND (GNU_READLINE_FOUND OR (DEPENDS AND NOT MINGW)))
|
||||
|
||||
@@ -1,142 +0,0 @@
|
||||
#include "net/abstract_http_client.h"
|
||||
#include "net/http_base.h"
|
||||
#include "net/net_parse_helpers.h"
|
||||
|
||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
#define MONERO_DEFAULT_LOG_CATEGORY "net.http"
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace net_utils
|
||||
{
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool is_unsafe(unsigned char compare_char)
|
||||
{
|
||||
if(compare_char <= 32 || compare_char >= 123)
|
||||
return true;
|
||||
|
||||
const char* punsave = get_unsave_chars();
|
||||
|
||||
for(int ichar_pos = 0; 0!=punsave[ichar_pos] ;ichar_pos++)
|
||||
if(compare_char == punsave[ichar_pos])
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
std::string dec_to_hex(char num, int radix)
|
||||
{
|
||||
int temp=0;
|
||||
std::string csTmp;
|
||||
int num_char;
|
||||
|
||||
num_char = (int) num;
|
||||
if (num_char < 0)
|
||||
num_char = 256 + num_char;
|
||||
|
||||
while (num_char >= radix)
|
||||
{
|
||||
temp = num_char % radix;
|
||||
num_char = (int)floor((float)num_char / (float)radix);
|
||||
csTmp = get_hex_vals()[temp];
|
||||
}
|
||||
|
||||
csTmp += get_hex_vals()[num_char];
|
||||
|
||||
if(csTmp.size() < 2)
|
||||
{
|
||||
csTmp += '0';
|
||||
}
|
||||
|
||||
std::reverse(csTmp.begin(), csTmp.end());
|
||||
//_mbsrev((unsigned char*)csTmp.data());
|
||||
|
||||
return csTmp;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
int get_index(const char *s, char c)
|
||||
{
|
||||
const char *ptr = (const char*)memchr(s, c, 16);
|
||||
return ptr ? ptr-s : -1;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
std::string hex_to_dec_2bytes(const char *s)
|
||||
{
|
||||
const char *hex = get_hex_vals();
|
||||
int i0 = get_index(hex, toupper(s[0]));
|
||||
int i1 = get_index(hex, toupper(s[1]));
|
||||
if (i0 < 0 || i1 < 0)
|
||||
return std::string("%") + std::string(1, s[0]) + std::string(1, s[1]);
|
||||
return std::string(1, i0 * 16 | i1);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
std::string convert(char val)
|
||||
{
|
||||
std::string csRet;
|
||||
csRet += "%";
|
||||
csRet += dec_to_hex(val, 16);
|
||||
return csRet;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
std::string conver_to_url_format(const std::string& uri)
|
||||
{
|
||||
|
||||
std::string result;
|
||||
|
||||
for(size_t i = 0; i!= uri.size(); i++)
|
||||
{
|
||||
if(is_unsafe(uri[i]))
|
||||
result += convert(uri[i]);
|
||||
else
|
||||
result += uri[i];
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
std::string convert_from_url_format(const std::string& uri)
|
||||
{
|
||||
|
||||
std::string result;
|
||||
|
||||
for(size_t i = 0; i!= uri.size(); i++)
|
||||
{
|
||||
if(uri[i] == '%' && i + 2 < uri.size())
|
||||
{
|
||||
result += hex_to_dec_2bytes(uri.c_str() + i + 1);
|
||||
i += 2;
|
||||
}
|
||||
else
|
||||
result += uri[i];
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
std::string convert_to_url_format_force_all(const std::string& uri)
|
||||
{
|
||||
std::string result;
|
||||
|
||||
for(size_t i = 0; i!= uri.size(); i++)
|
||||
{
|
||||
result += convert(uri[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
namespace http
|
||||
{
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool epee::net_utils::http::abstract_http_client::set_server(const std::string& address, boost::optional<login> user, ssl_options_t ssl_options)
|
||||
{
|
||||
http::url_content parsed{};
|
||||
const bool r = parse_url(address, parsed);
|
||||
CHECK_AND_ASSERT_MES(r, false, "failed to parse url: " << address);
|
||||
set_server(std::move(parsed.host), std::to_string(parsed.port), std::move(user), std::move(ssl_options));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2019-2020, The Monero Project
|
||||
// Copyright (c) 2019, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
@@ -34,7 +34,6 @@
|
||||
#include <utility>
|
||||
|
||||
#include "byte_slice.h"
|
||||
#include "byte_stream.h"
|
||||
|
||||
namespace epee
|
||||
{
|
||||
@@ -50,16 +49,12 @@ namespace epee
|
||||
std::atomic<std::size_t> ref_count;
|
||||
};
|
||||
|
||||
void release_byte_slice::call(void*, void* ptr) noexcept
|
||||
void release_byte_slice::operator()(byte_slice_data* ptr) const noexcept
|
||||
{
|
||||
if (ptr)
|
||||
if (ptr && --(ptr->ref_count) == 0)
|
||||
{
|
||||
byte_slice_data* self = static_cast<byte_slice_data*>(ptr);
|
||||
if (--(self->ref_count) == 0)
|
||||
{
|
||||
self->~byte_slice_data();
|
||||
free(self);
|
||||
}
|
||||
ptr->~byte_slice_data();
|
||||
free(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,12 +113,6 @@ namespace epee
|
||||
}
|
||||
} // anonymous
|
||||
|
||||
void release_byte_buffer::operator()(std::uint8_t* buf) const noexcept
|
||||
{
|
||||
if (buf)
|
||||
std::free(buf - sizeof(raw_byte_slice));
|
||||
}
|
||||
|
||||
byte_slice::byte_slice(byte_slice_data* storage, span<const std::uint8_t> portion) noexcept
|
||||
: storage_(storage), portion_(portion)
|
||||
{
|
||||
@@ -133,13 +122,10 @@ namespace epee
|
||||
|
||||
template<typename T>
|
||||
byte_slice::byte_slice(const adapt_buffer, T&& buffer)
|
||||
: storage_(nullptr), portion_(nullptr)
|
||||
: storage_(nullptr), portion_(to_byte_span(to_span(buffer)))
|
||||
{
|
||||
if (!buffer.empty())
|
||||
{
|
||||
storage_ = allocate_slice<adapted_byte_slice<T>>(0, std::move(buffer));
|
||||
portion_ = to_byte_span(to_span(static_cast<adapted_byte_slice<T> *>(storage_.get())->buffer));
|
||||
}
|
||||
}
|
||||
|
||||
byte_slice::byte_slice(std::initializer_list<span<const std::uint8_t>> sources)
|
||||
@@ -173,19 +159,6 @@ namespace epee
|
||||
: byte_slice(adapt_buffer{}, std::move(buffer))
|
||||
{}
|
||||
|
||||
byte_slice::byte_slice(byte_stream&& stream) noexcept
|
||||
: storage_(nullptr), portion_(stream.data(), stream.size())
|
||||
{
|
||||
if (stream.size())
|
||||
{
|
||||
std::uint8_t* const data = stream.take_buffer().release() - sizeof(raw_byte_slice);
|
||||
new (data) raw_byte_slice{};
|
||||
storage_.reset(reinterpret_cast<raw_byte_slice*>(data));
|
||||
}
|
||||
else
|
||||
portion_ = nullptr;
|
||||
}
|
||||
|
||||
byte_slice::byte_slice(byte_slice&& source) noexcept
|
||||
: storage_(std::move(source.storage_)), portion_(source.portion_)
|
||||
{
|
||||
@@ -213,17 +186,14 @@ namespace epee
|
||||
byte_slice byte_slice::take_slice(const std::size_t max_bytes) noexcept
|
||||
{
|
||||
byte_slice out{};
|
||||
std::uint8_t const* const ptr = data();
|
||||
out.portion_ = {ptr, portion_.remove_prefix(max_bytes)};
|
||||
|
||||
if (max_bytes)
|
||||
{
|
||||
std::uint8_t const* const ptr = data();
|
||||
out.portion_ = {ptr, portion_.remove_prefix(max_bytes)};
|
||||
if (portion_.empty())
|
||||
out.storage_ = std::move(storage_); // no atomic inc/dec
|
||||
else
|
||||
out = {storage_.get(), out.portion_};
|
||||
|
||||
if (portion_.empty())
|
||||
out.storage_ = std::move(storage_); // no atomic inc/dec
|
||||
else
|
||||
out = {storage_.get(), out.portion_};
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -236,36 +206,4 @@ namespace epee
|
||||
return {};
|
||||
return {storage_.get(), {portion_.begin() + begin, end - begin}};
|
||||
}
|
||||
|
||||
std::unique_ptr<byte_slice_data, release_byte_slice> byte_slice::take_buffer() noexcept
|
||||
{
|
||||
std::unique_ptr<byte_slice_data, release_byte_slice> out{std::move(storage_)};
|
||||
portion_ = nullptr;
|
||||
return out;
|
||||
}
|
||||
|
||||
byte_buffer byte_buffer_resize(byte_buffer buf, const std::size_t length) noexcept
|
||||
{
|
||||
if (std::numeric_limits<std::size_t>::max() - sizeof(raw_byte_slice) < length)
|
||||
return nullptr;
|
||||
|
||||
std::uint8_t* data = buf.get();
|
||||
if (data != nullptr)
|
||||
data -= sizeof(raw_byte_slice);
|
||||
|
||||
data = static_cast<std::uint8_t*>(std::realloc(data, sizeof(raw_byte_slice) + length));
|
||||
if (data == nullptr)
|
||||
return nullptr;
|
||||
|
||||
buf.release();
|
||||
buf.reset(data + sizeof(raw_byte_slice));
|
||||
return buf;
|
||||
}
|
||||
|
||||
byte_buffer byte_buffer_increase(byte_buffer buf, const std::size_t current, const std::size_t more)
|
||||
{
|
||||
if (std::numeric_limits<std::size_t>::max() - current < more)
|
||||
throw std::range_error{"byte_buffer_increase size_t overflow"};
|
||||
return byte_buffer_resize(std::move(buf), current + more);
|
||||
}
|
||||
} // epee
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
// Copyright (c) 2020, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "byte_stream.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <utility>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace epee
|
||||
{
|
||||
void byte_stream::overflow(const std::size_t requested)
|
||||
{
|
||||
// Recalculating `need` bytes removes at least one instruction from every
|
||||
// inlined `put` call in header
|
||||
|
||||
assert(available() < requested);
|
||||
const std::size_t need = requested - available();
|
||||
|
||||
const std::size_t len = size();
|
||||
const std::size_t cap = capacity();
|
||||
const std::size_t increase = std::max(need, increase_size());
|
||||
|
||||
next_write_ = nullptr;
|
||||
end_ = nullptr;
|
||||
|
||||
buffer_ = byte_buffer_increase(std::move(buffer_), cap, increase);
|
||||
if (!buffer_)
|
||||
throw std::bad_alloc{};
|
||||
|
||||
next_write_ = buffer_.get() + len;
|
||||
end_ = buffer_.get() + cap + increase;
|
||||
}
|
||||
|
||||
byte_stream::byte_stream(byte_stream&& rhs) noexcept
|
||||
: buffer_(std::move(rhs.buffer_)),
|
||||
next_write_(rhs.next_write_),
|
||||
end_(rhs.end_),
|
||||
increase_size_(rhs.increase_size_)
|
||||
{
|
||||
rhs.next_write_ = nullptr;
|
||||
rhs.end_ = nullptr;
|
||||
}
|
||||
|
||||
byte_stream& byte_stream::operator=(byte_stream&& rhs) noexcept
|
||||
{
|
||||
if (this != std::addressof(rhs))
|
||||
{
|
||||
buffer_ = std::move(rhs.buffer_);
|
||||
next_write_ = rhs.next_write_;
|
||||
end_ = rhs.end_;
|
||||
increase_size_ = rhs.increase_size_;
|
||||
rhs.next_write_ = nullptr;
|
||||
rhs.end_ = nullptr;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
byte_buffer byte_stream::take_buffer() noexcept
|
||||
{
|
||||
byte_buffer out{std::move(buffer_)};
|
||||
next_write_ = nullptr;
|
||||
end_ = nullptr;
|
||||
return out;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2017-2020, The Monero Project
|
||||
// Copyright (c) 2017-2019, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
@@ -33,8 +33,6 @@
|
||||
#include <ostream>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "storages/parserse_base_utils.h"
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace
|
||||
@@ -86,42 +84,7 @@ namespace epee
|
||||
return write_hex(out, src);
|
||||
}
|
||||
|
||||
|
||||
bool from_hex::to_string(std::string& out, const boost::string_ref src)
|
||||
{
|
||||
out.resize(src.size() / 2);
|
||||
return to_buffer_unchecked(reinterpret_cast<std::uint8_t*>(&out[0]), src);
|
||||
}
|
||||
|
||||
bool from_hex::to_buffer(span<std::uint8_t> out, const boost::string_ref src) noexcept
|
||||
{
|
||||
if (src.size() / 2 != out.size())
|
||||
return false;
|
||||
return to_buffer_unchecked(out.data(), src);
|
||||
}
|
||||
|
||||
bool from_hex::to_buffer_unchecked(std::uint8_t* dst, const boost::string_ref s) noexcept
|
||||
{
|
||||
if (s.size() % 2 != 0)
|
||||
return false;
|
||||
|
||||
const unsigned char *src = (const unsigned char *)s.data();
|
||||
for(size_t i = 0; i < s.size(); i += 2)
|
||||
{
|
||||
int tmp = *src++;
|
||||
tmp = epee::misc_utils::parse::isx[tmp];
|
||||
if (tmp == 0xff) return false;
|
||||
int t2 = *src++;
|
||||
t2 = epee::misc_utils::parse::isx[t2];
|
||||
if (t2 == 0xff) return false;
|
||||
*dst++ = (tmp << 4) | t2;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
std::vector<uint8_t> from_hex_locale::to_vector(const boost::string_ref src)
|
||||
std::vector<uint8_t> from_hex::vector(const boost::string_ref src)
|
||||
{
|
||||
// should we include a specific character
|
||||
auto include = [](char input) {
|
||||
|
||||
@@ -584,8 +584,8 @@ namespace
|
||||
explicit server_parameters(const auth_message& request, const DigestIter& digest)
|
||||
: nonce(request.nonce)
|
||||
, opaque(request.opaque)
|
||||
, realm(request.realm)
|
||||
, stale(request.stale)
|
||||
, realm(request.realm)
|
||||
, value_generator()
|
||||
, index(boost::fusion::distance(boost::fusion::begin(digest_algorithms), digest))
|
||||
{
|
||||
|
||||
@@ -100,7 +100,7 @@ static const char *get_default_categories(int level)
|
||||
switch (level)
|
||||
{
|
||||
case 0:
|
||||
categories = "*:WARNING,net:FATAL,net.http:FATAL,net.ssl:FATAL,net.p2p:FATAL,net.cn:FATAL,daemon.rpc:FATAL,global:INFO,verify:FATAL,serialization:FATAL,daemon.rpc.payment:ERROR,stacktrace:INFO,logging:INFO,msgwriter:INFO";
|
||||
categories = "*:WARNING,net:FATAL,net.http:FATAL,net.ssl:FATAL,net.p2p:FATAL,net.cn:FATAL,global:INFO,verify:FATAL,serialization:FATAL,daemon.rpc.payment:ERROR,stacktrace:INFO,logging:INFO,msgwriter:INFO";
|
||||
break;
|
||||
case 1:
|
||||
categories = "*:INFO,global:INFO,stacktrace:INFO,logging:INFO,msgwriter:INFO,perf.*:DEBUG";
|
||||
|
||||
@@ -43,10 +43,6 @@
|
||||
// openssl req -new -key /tmp/KEY -out /tmp/REQ
|
||||
// openssl x509 -req -days 999999 -sha256 -in /tmp/REQ -signkey /tmp/KEY -out /tmp/CERT
|
||||
|
||||
#ifdef _WIN32
|
||||
static void add_windows_root_certs(SSL_CTX *ctx) noexcept;
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
struct openssl_bio_free
|
||||
@@ -128,7 +124,7 @@ namespace net_utils
|
||||
// https://stackoverflow.com/questions/256405/programmatically-create-x509-certificate-using-openssl
|
||||
bool create_rsa_ssl_certificate(EVP_PKEY *&pkey, X509 *&cert)
|
||||
{
|
||||
MINFO("Generating SSL certificate");
|
||||
MGINFO("Generating SSL certificate");
|
||||
pkey = EVP_PKEY_new();
|
||||
if (!pkey)
|
||||
{
|
||||
@@ -198,7 +194,7 @@ bool create_rsa_ssl_certificate(EVP_PKEY *&pkey, X509 *&cert)
|
||||
|
||||
bool create_ec_ssl_certificate(EVP_PKEY *&pkey, X509 *&cert, int type)
|
||||
{
|
||||
MINFO("Generating SSL certificate");
|
||||
MGINFO("Generating SSL certificate");
|
||||
pkey = EVP_PKEY_new();
|
||||
if (!pkey)
|
||||
{
|
||||
@@ -289,9 +285,7 @@ ssl_options_t::ssl_options_t(std::vector<std::vector<std::uint8_t>> fingerprints
|
||||
|
||||
boost::asio::ssl::context ssl_options_t::create_context() const
|
||||
{
|
||||
// note: this enables a lot of old and insecure protocols, which we
|
||||
// promptly disable below - if the result is actually used
|
||||
boost::asio::ssl::context ssl_context{boost::asio::ssl::context::sslv23};
|
||||
boost::asio::ssl::context ssl_context{boost::asio::ssl::context::tlsv12};
|
||||
if (!bool(*this))
|
||||
return ssl_context;
|
||||
|
||||
@@ -330,12 +324,7 @@ boost::asio::ssl::context ssl_options_t::create_context() const
|
||||
switch (verification)
|
||||
{
|
||||
case ssl_verification_t::system_ca:
|
||||
#ifdef _WIN32
|
||||
try { add_windows_root_certs(ssl_context.native_handle()); }
|
||||
catch (const std::exception &e) { ssl_context.set_default_verify_paths(); }
|
||||
#else
|
||||
ssl_context.set_default_verify_paths();
|
||||
#endif
|
||||
break;
|
||||
case ssl_verification_t::user_certificates:
|
||||
ssl_context.set_verify_depth(0);
|
||||
@@ -511,7 +500,7 @@ bool ssl_options_t::handshake(
|
||||
// autodetect will reconnect without SSL - warn and keep connection encrypted
|
||||
if (support != ssl_support_t::e_ssl_support_autodetect)
|
||||
{
|
||||
MERROR("SSL certificate is not in the allowed list, connection dropped");
|
||||
MERROR("SSL certificate is not in the allowed list, connection droppped");
|
||||
return false;
|
||||
}
|
||||
MWARNING("SSL peer has not been verified");
|
||||
@@ -569,36 +558,3 @@ bool ssl_support_from_string(ssl_support_t &ssl, boost::string_ref s)
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
// https://stackoverflow.com/questions/40307541
|
||||
// Because Windows always has to do things wonkily
|
||||
#include <wincrypt.h>
|
||||
static void add_windows_root_certs(SSL_CTX *ctx) noexcept
|
||||
{
|
||||
HCERTSTORE hStore = CertOpenSystemStore(0, "ROOT");
|
||||
if (hStore == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
X509_STORE *store = X509_STORE_new();
|
||||
PCCERT_CONTEXT pContext = NULL;
|
||||
while ((pContext = CertEnumCertificatesInStore(hStore, pContext)) != NULL) {
|
||||
// convert from DER to internal format
|
||||
X509 *x509 = d2i_X509(NULL,
|
||||
(const unsigned char **)&pContext->pbCertEncoded,
|
||||
pContext->cbCertEncoded);
|
||||
if(x509 != NULL) {
|
||||
X509_STORE_add_cert(store, x509);
|
||||
X509_free(x509);
|
||||
}
|
||||
}
|
||||
|
||||
CertFreeCertificateContext(pContext);
|
||||
CertCloseStore(hStore, 0);
|
||||
|
||||
// attach X509_STORE to boost ssl context
|
||||
SSL_CTX_set_cert_store(ctx, store);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -188,14 +188,13 @@ void wipeable_string::split(std::vector<wipeable_string> &fields) const
|
||||
while (len--)
|
||||
{
|
||||
const char c = *ptr++;
|
||||
const bool space_prev = space;
|
||||
space = std::isspace(c);
|
||||
if (!space)
|
||||
if (c != ' ')
|
||||
{
|
||||
if (space_prev)
|
||||
if (space)
|
||||
fields.push_back({});
|
||||
fields.back().push_back(c);
|
||||
}
|
||||
space = c == ' ';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ echo "%sudo ALL=NOPASSWD: /usr/bin/lxc-execute" >> /etc/sudoers.d/gitian-lxc
|
||||
# make /etc/rc.local script that sets up bridge between guest and host
|
||||
echo '#!/bin/sh -e' > /etc/rc.local
|
||||
echo 'brctl addbr br0' >> /etc/rc.local
|
||||
echo 'ip addr add 10.0.2.2/24 broadcast 10.0.2.255 dev br0' >> /etc/rc.local
|
||||
echo 'ip addr add 10.0.3.1/24 broadcast 10.0.3.255 dev br0' >> /etc/rc.local
|
||||
echo 'ip link set br0 up' >> /etc/rc.local
|
||||
echo 'firewall-cmd --zone=trusted --add-interface=br0' >> /etc/rc.local
|
||||
echo 'exit 0' >> /etc/rc.local
|
||||
@@ -70,8 +70,8 @@ chmod +x /etc/rc.local
|
||||
# make sure that USE_LXC is always set when logging in as gitianuser,
|
||||
# and configure LXC IP addresses
|
||||
echo 'export USE_LXC=1' >> /home/gitianuser/.profile
|
||||
echo 'export GITIAN_HOST_IP=10.0.2.2' >> /home/gitianuser/.profile
|
||||
echo 'export LXC_GUEST_IP=10.0.2.5' >> /home/gitianuser/.profile
|
||||
echo 'export GITIAN_HOST_IP=10.0.3.1' >> /home/gitianuser/.profile
|
||||
echo 'export LXC_GUEST_IP=10.0.3.5' >> /home/gitianuser/.profile
|
||||
reboot
|
||||
```
|
||||
|
||||
@@ -167,12 +167,13 @@ If all went well, this produces a number of (uncommitted) `.assert` files in the
|
||||
Checking your work
|
||||
------------------
|
||||
|
||||
Take a look in the assert files and note the SHA256 checksums listed there.
|
||||
Take a look in the assert files and note the SHA256 checksums listed there. eg for `v0.15.0.0` you should get this checksum:
|
||||
|
||||
You should verify that the checksum that is listed matches each of the binaries you actually built.
|
||||
This may be done on Linux using the `sha256sum` command or on MacOS using `shasum --algorithm 256` for example.
|
||||
```
|
||||
2b95118f53d98d542a85f8732b84ba13b3cd20517ccb40332b0edd0ddf4f8c62 monero-x86_64-linux-gnu.tar.gz
|
||||
```
|
||||
|
||||
You can also look in the [gitian.sigs](https://github.com/monero-project/gitian.sigs/) repo and / or [getmonero.org release checksums](https://web.getmonero.org/downloads/hashes.txt) to see if others got the same checksum for the same version tag. If there is ever a mismatch -- **STOP! Something is wrong**. Contact others on IRC / github to figure out what is going on.
|
||||
You should verify that this is really the checksum you get on that file you built. You can also look in the gitian.sigs repo and / or [getmonero.org release checksums](https://web.getmonero.org/downloads/hashes.txt) to see if others got the same checksum for the same version tag. If there is ever a mismatch -- **STOP! Something is wrong**. Contact others on IRC / github to figure out what is going on.
|
||||
|
||||
|
||||
Signing assert files
|
||||
@@ -187,8 +188,8 @@ VERSION=v0.15.0.0
|
||||
gpg --detach-sign ${VERSION}-linux/${GH_USER}/monero-linux-*-build.assert
|
||||
gpg --detach-sign ${VERSION}-win/${GH_USER}/monero-win-*-build.assert
|
||||
gpg --detach-sign ${VERSION}-osx/${GH_USER}/monero-osx-*-build.assert
|
||||
gpg --detach-sign ${VERSION}-android/${GH_USER}/monero-android-*-build.assert
|
||||
```
|
||||
<!-- TODO: Replace * above with ${VERSION} once gitian builds correct file name -->
|
||||
|
||||
This will create a `.sig` file for each `.assert` file above (2 files for each platform).
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
name: "wownero-android-0.8"
|
||||
name: "monero-android-0.15"
|
||||
enable_cache: true
|
||||
suites:
|
||||
- "bionic"
|
||||
@@ -32,8 +32,8 @@ packages:
|
||||
- "python3-zmq"
|
||||
- "unzip"
|
||||
remotes:
|
||||
- "url": "https://github.com/wownero/wownero.git"
|
||||
"dir": "wownero"
|
||||
- "url": "https://github.com/monero-project/monero.git"
|
||||
"dir": "monero"
|
||||
files: []
|
||||
script: |
|
||||
|
||||
@@ -75,7 +75,7 @@ script: |
|
||||
then
|
||||
ABI=$i"eabi"
|
||||
fi
|
||||
NDKDIR="${BUILD_DIR}/wownero/contrib/depends/$i/native/bin"
|
||||
NDKDIR="${BUILD_DIR}/monero/contrib/depends/$i/native/bin"
|
||||
for prog in ${FAKETIME_HOST_PROGS}; do
|
||||
WRAPPER=${WRAP_DIR}/${ABI}-${prog}
|
||||
echo '#!/usr/bin/env bash' > ${WRAPPER}
|
||||
@@ -97,7 +97,7 @@ script: |
|
||||
export SOURCE_DATE_EPOCH=`date -d 2000-01-01T12:00:00 +%s`
|
||||
|
||||
git config --global core.abbrev 9
|
||||
cd wownero
|
||||
cd monero
|
||||
# Set the version string that gets added to the tar archive name
|
||||
version="`git describe`"
|
||||
if [[ $version == *"-"*"-"* ]]; then
|
||||
@@ -127,7 +127,7 @@ script: |
|
||||
chmod 755 bin/*
|
||||
cp ../LICENSE bin
|
||||
chmod 644 bin/LICENSE
|
||||
DISTNAME=wownero-${i}-${version}
|
||||
DISTNAME=monero-${i}-${version}
|
||||
mv bin ${DISTNAME}
|
||||
find ${DISTNAME}/ | sort | tar --no-recursion --owner=0 --group=0 -c -T - | bzip2 -9 > ${OUTDIR}/${DISTNAME}.tar.bz2
|
||||
cd ..
|
||||
|
||||
@@ -5,8 +5,8 @@ import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
gsigs = 'https://github.com/wownero/gitian.sigs.git'
|
||||
gbrepo = 'https://github.com/wownero/gitian-builder.git'
|
||||
gsigs = 'https://github.com/monero-project/gitian.sigs.git'
|
||||
gbrepo = 'https://github.com/devrandom/gitian-builder.git'
|
||||
|
||||
platforms = {'l': ['Linux', 'linux', 'tar.bz2'],
|
||||
'a': ['Android', 'android', 'tar.bz2'],
|
||||
@@ -31,16 +31,13 @@ def setup():
|
||||
subprocess.check_call(['git', 'checkout', 'c0f77ca018cb5332bfd595e0aff0468f77542c23'])
|
||||
os.makedirs('inputs', exist_ok=True)
|
||||
os.chdir('inputs')
|
||||
if not os.path.isdir('wownero'):
|
||||
subprocess.check_call(['git', 'clone', args.url, 'wownero'])
|
||||
if not os.path.isdir('monero'):
|
||||
subprocess.check_call(['git', 'clone', args.url, 'monero'])
|
||||
os.chdir('..')
|
||||
make_image_prog = ['bin/make-base-vm', '--suite', 'bionic', '--arch', 'amd64']
|
||||
if args.docker:
|
||||
try:
|
||||
subprocess.check_output(['docker', '--help'])
|
||||
except:
|
||||
print("ERROR: Could not find 'docker' command. Ensure this is in your PATH.")
|
||||
sys.exit(1)
|
||||
if not subprocess.call(['docker', '--help'], shell=False, stdout=subprocess.DEVNULL):
|
||||
print("Please install docker first manually")
|
||||
make_image_prog += ['--docker']
|
||||
elif not args.kvm:
|
||||
make_image_prog += ['--lxc']
|
||||
@@ -67,10 +64,10 @@ def rebuild():
|
||||
suffix = platforms[i][2]
|
||||
|
||||
print('\nCompiling ' + args.version + ' ' + os_name)
|
||||
infile = 'inputs/wownero/contrib/gitian/gitian-' + tag_name + '.yml'
|
||||
subprocess.check_call(['bin/gbuild', '-j', args.jobs, '-m', args.memory, '--commit', 'wownero='+args.commit, '--url', 'wownero='+args.url, infile])
|
||||
subprocess.check_call(['bin/gsign', '-p', args.sign_prog, '--signer', args.signer, '--release', args.version+'-'+tag_name, '--destination', '../sigs/', infile])
|
||||
subprocess.check_call('mv build/out/wownero-*.' + suffix + ' ../out/'+args.version, shell=True)
|
||||
infile = 'inputs/monero/contrib/gitian/gitian-' + tag_name + '.yml'
|
||||
subprocess.check_call(['bin/gbuild', '-j', args.jobs, '-m', args.memory, '--commit', 'monero='+args.commit, '--url', 'monero='+args.url, infile])
|
||||
subprocess.check_call(['bin/gsign', '-p', args.sign_prog, '--signer', args.signer, '--release', args.version+'-linux', '--destination', '../sigs/', infile])
|
||||
subprocess.check_call('mv build/out/monero-*.' + suffix + ' ../out/'+args.version, shell=True)
|
||||
print('Moving var/install.log to var/install-' + tag_name + '.log')
|
||||
subprocess.check_call('mv var/install.log var/install-' + tag_name + '.log', shell=True)
|
||||
print('Moving var/build.log to var/build-' + tag_name + '.log')
|
||||
@@ -98,7 +95,7 @@ def build():
|
||||
subprocess.check_call(['wget', '-N', '-P', 'inputs', 'https://bitcoincore.org/cfields/osslsigncode-Backports-to-1.7.1.patch'])
|
||||
subprocess.check_output(["echo 'a8c4e9cafba922f89de0df1f2152e7be286aba73f78505169bc351a7938dd911 inputs/osslsigncode-Backports-to-1.7.1.patch' | sha256sum -c"], shell=True)
|
||||
subprocess.check_output(["echo 'f9a8cdb38b9c309326764ebc937cba1523a3a751a7ab05df3ecc99d18ae466c9 inputs/osslsigncode-1.7.1.tar.gz' | sha256sum -c"], shell=True)
|
||||
subprocess.check_call(['make', '-C', 'inputs/wownero/contrib/depends', 'download', 'SOURCES_PATH=' + os.getcwd() + '/cache/common'])
|
||||
subprocess.check_call(['make', '-C', 'inputs/monero/contrib/depends', 'download', 'SOURCES_PATH=' + os.getcwd() + '/cache/common'])
|
||||
|
||||
rebuild()
|
||||
|
||||
@@ -109,7 +106,7 @@ def verify():
|
||||
|
||||
for i, v in platforms:
|
||||
print('\nVerifying v'+args.version+' '+v[0]+'\n')
|
||||
subprocess.check_call(['bin/gverify', '-v', '-d', '../sigs/', '-r', args.version+'-'+v[1], 'inputs/wownero/contrib/gitian/gitian-'+v[1]+'.yml'])
|
||||
subprocess.check_call(['bin/gverify', '-v', '-d', '../sigs/', '-r', args.version+'-'+v[1], 'inputs/monero/contrib/gitian/gitian-'+v[1]+'.yml'])
|
||||
os.chdir(workdir)
|
||||
|
||||
def main():
|
||||
@@ -118,7 +115,7 @@ def main():
|
||||
parser = argparse.ArgumentParser(description='Script for running full Gitian builds.', usage='%(prog)s [options] signer version')
|
||||
parser.add_argument('-c', '--commit', action='store_true', dest='commit', help='Indicate that the version argument is for a commit or branch')
|
||||
parser.add_argument('-p', '--pull', action='store_true', dest='pull', help='Indicate that the version argument is the number of a github repository pull request')
|
||||
parser.add_argument('-u', '--url', dest='url', default='https://github.com/wownero/wownero', help='Specify the URL of the repository. Default is %(default)s')
|
||||
parser.add_argument('-u', '--url', dest='url', default='https://github.com/monero-project/monero', help='Specify the URL of the repository. Default is %(default)s')
|
||||
parser.add_argument('-v', '--verify', action='store_true', dest='verify', help='Verify the Gitian build')
|
||||
parser.add_argument('-b', '--build', action='store_true', dest='build', help='Do a Gitian build')
|
||||
parser.add_argument('-B', '--buildsign', action='store_true', dest='buildsign', help='Build both signed and unsigned binaries')
|
||||
@@ -160,9 +157,9 @@ def main():
|
||||
elif not args.kvm:
|
||||
os.environ['USE_LXC'] = '1'
|
||||
if not 'GITIAN_HOST_IP' in os.environ.keys():
|
||||
os.environ['GITIAN_HOST_IP'] = '10.0.2.2'
|
||||
os.environ['GITIAN_HOST_IP'] = '10.0.3.1'
|
||||
if not 'LXC_GUEST_IP' in os.environ.keys():
|
||||
os.environ['LXC_GUEST_IP'] = '10.0.2.5'
|
||||
os.environ['LXC_GUEST_IP'] = '10.0.3.5'
|
||||
|
||||
# Disable MacOS build if no SDK found
|
||||
args.nomac = False
|
||||
@@ -190,8 +187,8 @@ def main():
|
||||
if args.setup:
|
||||
setup()
|
||||
|
||||
os.makedirs('builder/inputs/wownero', exist_ok=True)
|
||||
os.chdir('builder/inputs/wownero')
|
||||
os.makedirs('builder/inputs/monero', exist_ok=True)
|
||||
os.chdir('builder/inputs/monero')
|
||||
if args.pull:
|
||||
subprocess.check_call(['git', 'fetch', args.url, 'refs/pull/'+args.version+'/merge'])
|
||||
args.commit = subprocess.check_output(['git', 'show', '-s', '--format=%H', 'FETCH_HEAD'], universal_newlines=True).strip()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
name: "wownero-freebsd-0.8"
|
||||
name: "monero-freebsd-0.15"
|
||||
enable_cache: true
|
||||
suites:
|
||||
- "bionic"
|
||||
@@ -32,8 +32,8 @@ packages:
|
||||
- "libprotobuf-dev"
|
||||
- "python3-zmq"
|
||||
remotes:
|
||||
- "url": "https://github.com/wownero/wownero.git"
|
||||
"dir": "wownero"
|
||||
- "url": "https://github.com/monero-project/monero.git"
|
||||
"dir": "monero"
|
||||
files: []
|
||||
script: |
|
||||
|
||||
@@ -92,7 +92,7 @@ script: |
|
||||
export SOURCE_DATE_EPOCH=`date -d 2000-01-01T12:00:00 +%s`
|
||||
|
||||
git config --global core.abbrev 9
|
||||
cd wownero
|
||||
cd monero
|
||||
# Set the version string that gets added to the tar archive name
|
||||
version="`git describe`"
|
||||
if [[ $version == *"-"*"-"* ]]; then
|
||||
@@ -124,7 +124,7 @@ script: |
|
||||
chmod 755 bin/*
|
||||
cp ../LICENSE bin
|
||||
chmod 644 bin/LICENSE
|
||||
DISTNAME=wownero-${i}-${version}
|
||||
DISTNAME=monero-${i}-${version}
|
||||
mv bin ${DISTNAME}
|
||||
find ${DISTNAME}/ | sort | tar --no-recursion --owner=0 --group=0 -c -T - | bzip2 -9 > ${OUTDIR}/${DISTNAME}.tar.bz2
|
||||
cd ..
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
name: "wownero-linux-0.8"
|
||||
name: "monero-linux-0.15"
|
||||
enable_cache: true
|
||||
suites:
|
||||
- "bionic"
|
||||
@@ -43,8 +43,8 @@ packages:
|
||||
- "libprotobuf-dev"
|
||||
- "python3-zmq"
|
||||
remotes:
|
||||
- "url": "https://github.com/wownero/wownero.git"
|
||||
"dir": "wownero"
|
||||
- "url": "https://github.com/monero-project/monero.git"
|
||||
"dir": "monero"
|
||||
files: []
|
||||
script: |
|
||||
|
||||
@@ -115,7 +115,7 @@ script: |
|
||||
export SOURCE_DATE_EPOCH=`date -d 2000-01-01T12:00:00 +%s`
|
||||
|
||||
git config --global core.abbrev 9
|
||||
cd wownero
|
||||
cd monero
|
||||
# Set the version string that gets added to the tar archive name
|
||||
version="`git describe`"
|
||||
if [[ $version == *"-"*"-"* ]]; then
|
||||
@@ -164,7 +164,7 @@ script: |
|
||||
chmod 755 bin/*
|
||||
cp ../LICENSE bin
|
||||
chmod 644 bin/LICENSE
|
||||
DISTNAME=wownero-${i}-${version}
|
||||
DISTNAME=monero-${i}-${version}
|
||||
mv bin ${DISTNAME}
|
||||
find ${DISTNAME}/ | sort | tar --no-recursion --owner=0 --group=0 -c -T - | bzip2 -9 > ${OUTDIR}/${DISTNAME}.tar.bz2
|
||||
cd ..
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
name: "wownero-osx-0.8"
|
||||
name: "monero-osx-0.15"
|
||||
enable_cache: true
|
||||
suites:
|
||||
- "bionic"
|
||||
@@ -24,8 +24,8 @@ packages:
|
||||
- "python-dev"
|
||||
- "python-setuptools"
|
||||
remotes:
|
||||
- "url": "https://github.com/wownero/wownero.git"
|
||||
"dir": "wownero"
|
||||
- "url": "https://github.com/monero-project/monero.git"
|
||||
"dir": "monero"
|
||||
files:
|
||||
- "MacOSX10.11.sdk.tar.gz"
|
||||
script: |
|
||||
@@ -77,7 +77,7 @@ script: |
|
||||
export PATH=${WRAP_DIR}:${PATH}
|
||||
|
||||
git config --global core.abbrev 9
|
||||
cd wownero
|
||||
cd monero
|
||||
# Set the version string that gets added to the tar archive name
|
||||
version="`git describe`"
|
||||
if [[ $version == *"-"*"-"* ]]; then
|
||||
@@ -113,7 +113,7 @@ script: |
|
||||
chmod 755 bin/*
|
||||
cp ../LICENSE bin
|
||||
chmod 644 bin/LICENSE
|
||||
DISTNAME=wownero-${i}-${version}
|
||||
DISTNAME=monero-${i}-${version}
|
||||
mv bin ${DISTNAME}
|
||||
find ${DISTNAME}/ | sort | tar --no-recursion --owner=0 --group=0 -c -T - | bzip2 -9 > ${OUTDIR}/${DISTNAME}.tar.bz2
|
||||
cd ..
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
name: "wownero-win-0.8"
|
||||
name: "monero-win-0.15"
|
||||
enable_cache: true
|
||||
suites:
|
||||
- "bionic"
|
||||
@@ -36,8 +36,8 @@ alternatives:
|
||||
package: "x86_64-w64-mingw32-gcc"
|
||||
path: "/usr/bin/x86_64-w64-mingw32-gcc-posix"
|
||||
remotes:
|
||||
- "url": "https://github.com/wownero/wownero.git"
|
||||
"dir": "wownero"
|
||||
- "url": "https://github.com/monero-project/monero.git"
|
||||
"dir": "monero"
|
||||
files: []
|
||||
script: |
|
||||
WRAP_DIR=$HOME/wrapped
|
||||
@@ -91,7 +91,7 @@ script: |
|
||||
export SOURCE_DATE_EPOCH=`date -d 2000-01-01T12:00:00 +%s`
|
||||
|
||||
git config --global core.abbrev 9
|
||||
cd wownero
|
||||
cd monero
|
||||
# Set the version string that gets added to the tar archive name
|
||||
version="`git describe`"
|
||||
if [[ $version == *"-"*"-"* ]]; then
|
||||
@@ -128,7 +128,7 @@ script: |
|
||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=${BASEPREFIX}/${i}/share/toolchain.cmake
|
||||
make ${MAKEOPTS}
|
||||
cp ../LICENSE bin
|
||||
DISTNAME=wownero-${i}-${version}
|
||||
DISTNAME=monero-${i}-${version}
|
||||
mv bin ${DISTNAME}
|
||||
find ${DISTNAME}/ | sort | zip -X@ ${OUTDIR}/${DISTNAME}.zip
|
||||
cd .. && rm -rf build
|
||||
|
||||
2
external/RandomWOW
vendored
2
external/RandomWOW
vendored
Submodule external/RandomWOW updated: 759fc58502...ae1377c0d7
98
external/easylogging++/easylogging++.cc
vendored
98
external/easylogging++/easylogging++.cc
vendored
@@ -1243,7 +1243,7 @@ bool OS::termSupportsColor(void) {
|
||||
std::string term = getEnvironmentVariable("TERM", "");
|
||||
return term == "xterm" || term == "xterm-color" || term == "xterm-256color"
|
||||
|| term == "screen" || term == "linux" || term == "cygwin"
|
||||
|| term == "screen-256color" || term == "screen.xterm-256color";
|
||||
|| term == "screen-256color";
|
||||
}
|
||||
|
||||
// DateTime
|
||||
@@ -2475,100 +2475,6 @@ void DefaultLogDispatchCallback::handle(const LogDispatchData* data) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<typename Transform>
|
||||
static inline std::string utf8canonical(const std::string &s, Transform t = [](wint_t c)->wint_t { return c; })
|
||||
{
|
||||
std::string sc = "";
|
||||
size_t avail = s.size();
|
||||
const char *ptr = s.data();
|
||||
wint_t cp = 0;
|
||||
int bytes = 1;
|
||||
char wbuf[8], *wptr;
|
||||
while (avail--)
|
||||
{
|
||||
if ((*ptr & 0x80) == 0)
|
||||
{
|
||||
cp = *ptr++;
|
||||
bytes = 1;
|
||||
}
|
||||
else if ((*ptr & 0xe0) == 0xc0)
|
||||
{
|
||||
if (avail < 1)
|
||||
throw std::runtime_error("Invalid UTF-8");
|
||||
cp = (*ptr++ & 0x1f) << 6;
|
||||
cp |= *ptr++ & 0x3f;
|
||||
--avail;
|
||||
bytes = 2;
|
||||
}
|
||||
else if ((*ptr & 0xf0) == 0xe0)
|
||||
{
|
||||
if (avail < 2)
|
||||
throw std::runtime_error("Invalid UTF-8");
|
||||
cp = (*ptr++ & 0xf) << 12;
|
||||
cp |= (*ptr++ & 0x3f) << 6;
|
||||
cp |= *ptr++ & 0x3f;
|
||||
avail -= 2;
|
||||
bytes = 3;
|
||||
}
|
||||
else if ((*ptr & 0xf8) == 0xf0)
|
||||
{
|
||||
if (avail < 3)
|
||||
throw std::runtime_error("Invalid UTF-8");
|
||||
cp = (*ptr++ & 0x7) << 18;
|
||||
cp |= (*ptr++ & 0x3f) << 12;
|
||||
cp |= (*ptr++ & 0x3f) << 6;
|
||||
cp |= *ptr++ & 0x3f;
|
||||
avail -= 3;
|
||||
bytes = 4;
|
||||
}
|
||||
else
|
||||
throw std::runtime_error("Invalid UTF-8");
|
||||
|
||||
cp = t(cp);
|
||||
if (cp <= 0x7f)
|
||||
bytes = 1;
|
||||
else if (cp <= 0x7ff)
|
||||
bytes = 2;
|
||||
else if (cp <= 0xffff)
|
||||
bytes = 3;
|
||||
else if (cp <= 0x10ffff)
|
||||
bytes = 4;
|
||||
else
|
||||
throw std::runtime_error("Invalid code point UTF-8 transformation");
|
||||
|
||||
wptr = wbuf;
|
||||
switch (bytes)
|
||||
{
|
||||
case 1: *wptr++ = cp; break;
|
||||
case 2: *wptr++ = 0xc0 | (cp >> 6); *wptr++ = 0x80 | (cp & 0x3f); break;
|
||||
case 3: *wptr++ = 0xe0 | (cp >> 12); *wptr++ = 0x80 | ((cp >> 6) & 0x3f); *wptr++ = 0x80 | (cp & 0x3f); break;
|
||||
case 4: *wptr++ = 0xf0 | (cp >> 18); *wptr++ = 0x80 | ((cp >> 12) & 0x3f); *wptr++ = 0x80 | ((cp >> 6) & 0x3f); *wptr++ = 0x80 | (cp & 0x3f); break;
|
||||
default: throw std::runtime_error("Invalid UTF-8");
|
||||
}
|
||||
*wptr = 0;
|
||||
sc.append(wbuf, bytes);
|
||||
cp = 0;
|
||||
bytes = 1;
|
||||
}
|
||||
return sc;
|
||||
}
|
||||
|
||||
void sanitize(std::string &s)
|
||||
{
|
||||
s = utf8canonical(s, [](wint_t c)->wint_t {
|
||||
if (c == 9 || c == 10 || c == 13)
|
||||
return c;
|
||||
if (c < 0x20)
|
||||
return '?';
|
||||
if (c == 0x7f)
|
||||
return '?';
|
||||
if (c >= 0x80 && c <= 0x9f)
|
||||
return '?';
|
||||
return c;
|
||||
});
|
||||
}
|
||||
|
||||
void DefaultLogDispatchCallback::dispatch(base::type::string_t&& rawLinePrefix, base::type::string_t&& rawLinePayload, base::type::string_t&& logLine) {
|
||||
if (m_data->dispatchAction() == base::DispatchAction::NormalLog || m_data->dispatchAction() == base::DispatchAction::FileOnlyLog) {
|
||||
if (m_data->logMessage()->logger()->m_typedConfigurations->toFile(m_data->logMessage()->level())) {
|
||||
@@ -2600,8 +2506,6 @@ void DefaultLogDispatchCallback::dispatch(base::type::string_t&& rawLinePrefix,
|
||||
m_data->logMessage()->logger()->logBuilder()->setColor(el::base::utils::colorFromLevel(level), false);
|
||||
ELPP_COUT << rawLinePrefix;
|
||||
m_data->logMessage()->logger()->logBuilder()->setColor(color == el::Color::Default ? el::base::utils::colorFromLevel(level): color, color != el::Color::Default);
|
||||
try { sanitize(rawLinePayload); }
|
||||
catch (const std::exception &e) { rawLinePayload = "<Invalid UTF-8 in log>"; }
|
||||
ELPP_COUT << rawLinePayload;
|
||||
m_data->logMessage()->logger()->logBuilder()->setColor(el::Color::Default, false);
|
||||
ELPP_COUT << std::flush;
|
||||
|
||||
9
external/easylogging++/easylogging++.h
vendored
9
external/easylogging++/easylogging++.h
vendored
@@ -125,18 +125,13 @@
|
||||
#else
|
||||
# define ELPP_OS_NETBSD 0
|
||||
#endif
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
# define ELPP_OS_EMSCRIPTEN 1
|
||||
#else
|
||||
# define ELPP_OS_EMSCRIPTEN 0
|
||||
#endif
|
||||
#if (defined(__DragonFly__))
|
||||
# define ELPP_OS_DRAGONFLY 1
|
||||
#else
|
||||
# define ELPP_OS_DRAGONFLY 0
|
||||
#endif
|
||||
// Unix
|
||||
#if ((ELPP_OS_LINUX || ELPP_OS_MAC || ELPP_OS_FREEBSD || ELPP_OS_NETBSD || ELPP_OS_SOLARIS || ELPP_OS_AIX || ELPP_OS_EMSCRIPTEN || ELPP_OS_DRAGONFLY || ELPP_OS_OPENBSD) && (!ELPP_OS_WINDOWS))
|
||||
#if ((ELPP_OS_LINUX || ELPP_OS_MAC || ELPP_OS_FREEBSD || ELPP_OS_NETBSD || ELPP_OS_SOLARIS || ELPP_OS_AIX || ELPP_OS_DRAGONFLY || ELPP_OS_OPENBSD) && (!ELPP_OS_WINDOWS))
|
||||
# define ELPP_OS_UNIX 1
|
||||
#else
|
||||
# define ELPP_OS_UNIX 0
|
||||
@@ -221,7 +216,7 @@ ELPP_INTERNAL_DEBUGGING_OUT_INFO << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStre
|
||||
# define ELPP_INTERNAL_INFO(lvl, msg)
|
||||
#endif // (defined(ELPP_DEBUG_INFO))
|
||||
#if (defined(ELPP_FEATURE_ALL)) || (defined(ELPP_FEATURE_CRASH_LOG))
|
||||
# if (ELPP_COMPILER_GCC && !ELPP_MINGW && !ELPP_OS_OPENBSD && !ELPP_OS_NETBSD && !ELPP_OS_ANDROID && !ELPP_OS_EMSCRIPTEN)
|
||||
# if (ELPP_COMPILER_GCC && !ELPP_MINGW && !ELPP_OS_OPENBSD && !ELPP_OS_NETBSD && !ELPP_OS_ANDROID)
|
||||
# define ELPP_STACKTRACE 1
|
||||
# else
|
||||
# define ELPP_STACKTRACE 0
|
||||
|
||||
2
external/trezor-common
vendored
2
external/trezor-common
vendored
Submodule external/trezor-common updated: bff7fdfe43...31a0073c62
@@ -113,10 +113,12 @@ add_subdirectory(lmdb)
|
||||
add_subdirectory(multisig)
|
||||
add_subdirectory(net)
|
||||
add_subdirectory(hardforks)
|
||||
add_subdirectory(blockchain_db)
|
||||
add_subdirectory(mnemonics)
|
||||
add_subdirectory(rpc)
|
||||
if(NOT IOS)
|
||||
add_subdirectory(blockchain_db)
|
||||
endif()
|
||||
add_subdirectory(mnemonics)
|
||||
if(NOT IOS)
|
||||
add_subdirectory(rpc)
|
||||
add_subdirectory(serialization)
|
||||
endif()
|
||||
add_subdirectory(wallet)
|
||||
|
||||
@@ -44,91 +44,6 @@ using epee::string_tools::pod_to_hex;
|
||||
namespace cryptonote
|
||||
{
|
||||
|
||||
bool matches_category(relay_method method, relay_category category) noexcept
|
||||
{
|
||||
switch (category)
|
||||
{
|
||||
default:
|
||||
return false;
|
||||
case relay_category::all:
|
||||
return true;
|
||||
case relay_category::relayable:
|
||||
return method != relay_method::none;
|
||||
case relay_category::broadcasted:
|
||||
case relay_category::legacy:
|
||||
break;
|
||||
}
|
||||
// check for "broadcasted" or "legacy" methods:
|
||||
switch (method)
|
||||
{
|
||||
default:
|
||||
case relay_method::local:
|
||||
case relay_method::stem:
|
||||
return false;
|
||||
case relay_method::block:
|
||||
case relay_method::fluff:
|
||||
return true;
|
||||
case relay_method::none:
|
||||
break;
|
||||
}
|
||||
return category == relay_category::legacy;
|
||||
}
|
||||
|
||||
void txpool_tx_meta_t::set_relay_method(relay_method method) noexcept
|
||||
{
|
||||
kept_by_block = 0;
|
||||
do_not_relay = 0;
|
||||
is_local = 0;
|
||||
dandelionpp_stem = 0;
|
||||
|
||||
switch (method)
|
||||
{
|
||||
case relay_method::none:
|
||||
do_not_relay = 1;
|
||||
break;
|
||||
case relay_method::local:
|
||||
is_local = 1;
|
||||
break;
|
||||
default:
|
||||
case relay_method::fluff:
|
||||
break;
|
||||
case relay_method::stem:
|
||||
dandelionpp_stem = 1;
|
||||
break;
|
||||
case relay_method::block:
|
||||
kept_by_block = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
relay_method txpool_tx_meta_t::get_relay_method() const noexcept
|
||||
{
|
||||
if (kept_by_block)
|
||||
return relay_method::block;
|
||||
if (do_not_relay)
|
||||
return relay_method::none;
|
||||
if (is_local)
|
||||
return relay_method::local;
|
||||
if (dandelionpp_stem)
|
||||
return relay_method::stem;
|
||||
return relay_method::fluff;
|
||||
}
|
||||
|
||||
bool txpool_tx_meta_t::upgrade_relay_method(relay_method method) noexcept
|
||||
{
|
||||
static_assert(relay_method::none < relay_method::local, "bad relay_method value");
|
||||
static_assert(relay_method::local < relay_method::stem, "bad relay_method value");
|
||||
static_assert(relay_method::stem < relay_method::fluff, "bad relay_method value");
|
||||
static_assert(relay_method::fluff < relay_method::block, "bad relay_method value");
|
||||
|
||||
if (get_relay_method() < method)
|
||||
{
|
||||
set_relay_method(method);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const command_line::arg_descriptor<std::string> arg_db_sync_mode = {
|
||||
"db-sync-mode"
|
||||
, "Specify sync option, using format [safe|fast|fastest]:[sync|async]:[<nblocks_per_sync>[blocks]|<nbytes_per_sync>[bytes]]."
|
||||
@@ -434,23 +349,4 @@ void BlockchainDB::fixup()
|
||||
set_batch_transactions(true);
|
||||
}
|
||||
|
||||
bool BlockchainDB::txpool_tx_matches_category(const crypto::hash& tx_hash, relay_category category)
|
||||
{
|
||||
try
|
||||
{
|
||||
txpool_tx_meta_t meta{};
|
||||
if (!get_txpool_tx_meta(tx_hash, meta))
|
||||
{
|
||||
MERROR("Failed to get tx meta from txpool");
|
||||
return false;
|
||||
}
|
||||
return meta.matches(category);
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
MERROR("Failed to get tx meta from txpool: " << e.what());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace cryptonote
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
#include "cryptonote_basic/cryptonote_basic.h"
|
||||
#include "cryptonote_basic/difficulty.h"
|
||||
#include "cryptonote_basic/hardfork.h"
|
||||
#include "cryptonote_protocol/enums.h"
|
||||
|
||||
/** \file
|
||||
* Cryptonote Blockchain Database Interface
|
||||
@@ -106,16 +105,6 @@ typedef std::pair<crypto::hash, uint64_t> tx_out_index;
|
||||
extern const command_line::arg_descriptor<std::string> arg_db_sync_mode;
|
||||
extern const command_line::arg_descriptor<bool, false> arg_db_salvage;
|
||||
|
||||
enum class relay_category : uint8_t
|
||||
{
|
||||
broadcasted = 0,//!< Public txes received via block/fluff
|
||||
relayable, //!< Every tx not marked `relay_method::none`
|
||||
legacy, //!< `relay_category::broadcasted` + `relay_method::none` for rpc relay requests or historical reasons
|
||||
all //!< Everything in the db
|
||||
};
|
||||
|
||||
bool matches_category(relay_method method, relay_category category) noexcept;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
/**
|
||||
@@ -160,33 +149,18 @@ struct txpool_tx_meta_t
|
||||
uint64_t max_used_block_height;
|
||||
uint64_t last_failed_height;
|
||||
uint64_t receive_time;
|
||||
uint64_t last_relayed_time; //!< If Dandelion++ stem, randomized embargo timestamp. Otherwise, last relayed timestmap.
|
||||
uint64_t last_relayed_time;
|
||||
// 112 bytes
|
||||
uint8_t kept_by_block;
|
||||
uint8_t relayed;
|
||||
uint8_t do_not_relay;
|
||||
uint8_t double_spend_seen: 1;
|
||||
uint8_t pruned: 1;
|
||||
uint8_t is_local: 1;
|
||||
uint8_t dandelionpp_stem : 1;
|
||||
uint8_t bf_padding: 4;
|
||||
uint8_t bf_padding: 6;
|
||||
|
||||
uint8_t padding[76]; // till 192 bytes
|
||||
|
||||
void set_relay_method(relay_method method) noexcept;
|
||||
relay_method get_relay_method() const noexcept;
|
||||
|
||||
//! \return True if `get_relay_method()` now returns `method`.
|
||||
bool upgrade_relay_method(relay_method method) noexcept;
|
||||
|
||||
//! See `relay_category` description
|
||||
bool matches(const relay_category category) const noexcept
|
||||
{
|
||||
return matches_category(get_relay_method(), category);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#define DBF_SAFE 1
|
||||
#define DBF_FAST 2
|
||||
#define DBF_FASTEST 4
|
||||
@@ -1278,41 +1252,6 @@ public:
|
||||
*/
|
||||
virtual bool get_pruned_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const = 0;
|
||||
|
||||
/**
|
||||
* @brief fetches a number of pruned transaction blob from the given hash, in canonical blockchain order
|
||||
*
|
||||
* The subclass should return the pruned transactions stored from the one with the given
|
||||
* hash.
|
||||
*
|
||||
* If the first transaction does not exist, the subclass should return false.
|
||||
* If the first transaction exists, but there are fewer transactions starting with it
|
||||
* than requested, the subclass should return false.
|
||||
*
|
||||
* @param h the hash to look for
|
||||
*
|
||||
* @return true iff the transactions were found
|
||||
*/
|
||||
virtual bool get_pruned_tx_blobs_from(const crypto::hash& h, size_t count, std::vector<cryptonote::blobdata> &bd) const = 0;
|
||||
|
||||
/**
|
||||
* @brief fetches a variable number of blocks and transactions from the given height, in canonical blockchain order
|
||||
*
|
||||
* The subclass should return the blocks and transactions stored from the one with the given
|
||||
* height. The number of blocks returned is variable, based on the max_size passed.
|
||||
*
|
||||
* @param start_height the height of the first block
|
||||
* @param min_count the minimum number of blocks to return, if they exist
|
||||
* @param max_count the maximum number of blocks to return
|
||||
* @param max_size the maximum size of block/transaction data to return (will be exceeded by one blocks's worth at most, if min_count is met)
|
||||
* @param blocks the returned block/transaction data
|
||||
* @param pruned whether to return full or pruned tx data
|
||||
* @param skip_coinbase whether to return or skip coinbase transactions (they're in blocks regardless)
|
||||
* @param get_miner_tx_hash whether to calculate and return the miner (coinbase) tx hash
|
||||
*
|
||||
* @return true iff the blocks and transactions were found
|
||||
*/
|
||||
virtual bool get_blocks_from(uint64_t start_height, size_t min_count, size_t max_count, size_t max_size, std::vector<std::pair<std::pair<cryptonote::blobdata, crypto::hash>, std::vector<std::pair<crypto::hash, cryptonote::blobdata>>>>& blocks, bool pruned, bool skip_coinbase, bool get_miner_tx_hash) const = 0;
|
||||
|
||||
/**
|
||||
* @brief fetches the prunable transaction blob with the given hash
|
||||
*
|
||||
@@ -1526,12 +1465,12 @@ public:
|
||||
/**
|
||||
* @brief get the number of transactions in the txpool
|
||||
*/
|
||||
virtual uint64_t get_txpool_tx_count(relay_category tx_category = relay_category::broadcasted) const = 0;
|
||||
virtual uint64_t get_txpool_tx_count(bool include_unrelayed_txes = true) const = 0;
|
||||
|
||||
/**
|
||||
* @brief check whether a txid is in the txpool and meets tx_category requirements
|
||||
* @brief check whether a txid is in the txpool
|
||||
*/
|
||||
virtual bool txpool_has_tx(const crypto::hash &txid, relay_category tx_category) const = 0;
|
||||
virtual bool txpool_has_tx(const crypto::hash &txid) const = 0;
|
||||
|
||||
/**
|
||||
* @brief remove a txpool transaction
|
||||
@@ -1555,11 +1494,10 @@ public:
|
||||
*
|
||||
* @param txid the transaction id of the transation to lookup
|
||||
* @param bd the blob to return
|
||||
* @param tx_category for filtering out hidden/private txes
|
||||
*
|
||||
* @return True iff `txid` is in the pool and meets `tx_category` requirements
|
||||
* @return true if the txid was in the txpool, false otherwise
|
||||
*/
|
||||
virtual bool get_txpool_tx_blob(const crypto::hash& txid, cryptonote::blobdata &bd, relay_category tx_category) const = 0;
|
||||
virtual bool get_txpool_tx_blob(const crypto::hash& txid, cryptonote::blobdata &bd) const = 0;
|
||||
|
||||
/**
|
||||
* @brief get a txpool transaction's blob
|
||||
@@ -1568,17 +1506,7 @@ public:
|
||||
*
|
||||
* @return the blob for that transaction
|
||||
*/
|
||||
virtual cryptonote::blobdata get_txpool_tx_blob(const crypto::hash& txid, relay_category tx_category) const = 0;
|
||||
|
||||
/**
|
||||
* @brief Check if `tx_hash` relay status is in `category`.
|
||||
*
|
||||
* @param tx_hash hash of the transaction to lookup
|
||||
* @param category relay status category to test against
|
||||
*
|
||||
* @return True if `tx_hash` latest relay status is in `category`.
|
||||
*/
|
||||
bool txpool_tx_matches_category(const crypto::hash& tx_hash, relay_category category);
|
||||
virtual cryptonote::blobdata get_txpool_tx_blob(const crypto::hash& txid) const = 0;
|
||||
|
||||
/**
|
||||
* @brief prune output data for the given amount
|
||||
@@ -1676,7 +1604,7 @@ public:
|
||||
*
|
||||
* @return false if the function returns false for any transaction, otherwise true
|
||||
*/
|
||||
virtual bool for_all_txpool_txes(std::function<bool(const crypto::hash&, const txpool_tx_meta_t&, const cryptonote::blobdata*)>, bool include_blob = false, relay_category category = relay_category::broadcasted) const = 0;
|
||||
virtual bool for_all_txpool_txes(std::function<bool(const crypto::hash&, const txpool_tx_meta_t&, const cryptonote::blobdata*)>, bool include_blob = false, bool include_unrelayed_txes = true) const = 0;
|
||||
|
||||
/**
|
||||
* @brief runs a function over all key images stored
|
||||
|
||||
@@ -163,15 +163,7 @@ int BlockchainLMDB::compare_string(const MDB_val *a, const MDB_val *b)
|
||||
{
|
||||
const char *va = (const char*) a->mv_data;
|
||||
const char *vb = (const char*) b->mv_data;
|
||||
const size_t sz = std::min(a->mv_size, b->mv_size);
|
||||
int ret = strncmp(va, vb, sz);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (a->mv_size < b->mv_size)
|
||||
return -1;
|
||||
if (a->mv_size > b->mv_size)
|
||||
return 1;
|
||||
return 0;
|
||||
return strcmp(va, vb);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1779,7 +1771,7 @@ void BlockchainLMDB::update_txpool_tx(const crypto::hash &txid, const txpool_tx_
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t BlockchainLMDB::get_txpool_tx_count(relay_category category) const
|
||||
uint64_t BlockchainLMDB::get_txpool_tx_count(bool include_unrelayed_txes) const
|
||||
{
|
||||
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||
check_open();
|
||||
@@ -1789,7 +1781,7 @@ uint64_t BlockchainLMDB::get_txpool_tx_count(relay_category category) const
|
||||
|
||||
TXN_PREFIX_RDONLY();
|
||||
|
||||
if (category == relay_category::all)
|
||||
if (include_unrelayed_txes)
|
||||
{
|
||||
// No filtering, we can get the number of tx the "fast" way
|
||||
MDB_stat db_stats;
|
||||
@@ -1815,7 +1807,7 @@ uint64_t BlockchainLMDB::get_txpool_tx_count(relay_category category) const
|
||||
if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Failed to enumerate txpool tx metadata: ", result).c_str()));
|
||||
const txpool_tx_meta_t &meta = *(const txpool_tx_meta_t*)v.mv_data;
|
||||
if (meta.matches(category))
|
||||
if (!meta.do_not_relay)
|
||||
++num_entries;
|
||||
}
|
||||
}
|
||||
@@ -1824,7 +1816,7 @@ uint64_t BlockchainLMDB::get_txpool_tx_count(relay_category category) const
|
||||
return num_entries;
|
||||
}
|
||||
|
||||
bool BlockchainLMDB::txpool_has_tx(const crypto::hash& txid, relay_category tx_category) const
|
||||
bool BlockchainLMDB::txpool_has_tx(const crypto::hash& txid) const
|
||||
{
|
||||
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||
check_open();
|
||||
@@ -1833,21 +1825,11 @@ bool BlockchainLMDB::txpool_has_tx(const crypto::hash& txid, relay_category tx_c
|
||||
RCURSOR(txpool_meta)
|
||||
|
||||
MDB_val k = {sizeof(txid), (void *)&txid};
|
||||
MDB_val v;
|
||||
auto result = mdb_cursor_get(m_cur_txpool_meta, &k, &v, MDB_SET);
|
||||
auto result = mdb_cursor_get(m_cur_txpool_meta, &k, NULL, MDB_SET);
|
||||
if (result != 0 && result != MDB_NOTFOUND)
|
||||
throw1(DB_ERROR(lmdb_error("Error finding txpool tx meta: ", result).c_str()));
|
||||
if (result == MDB_NOTFOUND)
|
||||
return false;
|
||||
|
||||
bool found = true;
|
||||
if (tx_category != relay_category::all)
|
||||
{
|
||||
const txpool_tx_meta_t &meta = *(const txpool_tx_meta_t*)v.mv_data;
|
||||
found = meta.matches(tx_category);
|
||||
}
|
||||
TXN_POSTFIX_RDONLY();
|
||||
return found;
|
||||
return result != MDB_NOTFOUND;
|
||||
}
|
||||
|
||||
void BlockchainLMDB::remove_txpool_tx(const crypto::hash& txid)
|
||||
@@ -1901,7 +1883,7 @@ bool BlockchainLMDB::get_txpool_tx_meta(const crypto::hash& txid, txpool_tx_meta
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BlockchainLMDB::get_txpool_tx_blob(const crypto::hash& txid, cryptonote::blobdata &bd, relay_category tx_category) const
|
||||
bool BlockchainLMDB::get_txpool_tx_blob(const crypto::hash& txid, cryptonote::blobdata &bd) const
|
||||
{
|
||||
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||
check_open();
|
||||
@@ -1911,22 +1893,6 @@ bool BlockchainLMDB::get_txpool_tx_blob(const crypto::hash& txid, cryptonote::bl
|
||||
|
||||
MDB_val k = {sizeof(txid), (void *)&txid};
|
||||
MDB_val v;
|
||||
|
||||
// if filtering, make sure those requirements are met before copying blob
|
||||
if (tx_category != relay_category::all)
|
||||
{
|
||||
RCURSOR(txpool_meta)
|
||||
auto result = mdb_cursor_get(m_cur_txpool_meta, &k, &v, MDB_SET);
|
||||
if (result == MDB_NOTFOUND)
|
||||
return false;
|
||||
if (result != 0)
|
||||
throw1(DB_ERROR(lmdb_error("Error finding txpool tx meta: ", result).c_str()));
|
||||
|
||||
const txpool_tx_meta_t& meta = *(const txpool_tx_meta_t*)v.mv_data;
|
||||
if (!meta.matches(tx_category))
|
||||
return false;
|
||||
}
|
||||
|
||||
auto result = mdb_cursor_get(m_cur_txpool_blob, &k, &v, MDB_SET);
|
||||
if (result == MDB_NOTFOUND)
|
||||
return false;
|
||||
@@ -1938,10 +1904,10 @@ bool BlockchainLMDB::get_txpool_tx_blob(const crypto::hash& txid, cryptonote::bl
|
||||
return true;
|
||||
}
|
||||
|
||||
cryptonote::blobdata BlockchainLMDB::get_txpool_tx_blob(const crypto::hash& txid, relay_category tx_category) const
|
||||
cryptonote::blobdata BlockchainLMDB::get_txpool_tx_blob(const crypto::hash& txid) const
|
||||
{
|
||||
cryptonote::blobdata bd;
|
||||
if (!get_txpool_tx_blob(txid, bd, tx_category))
|
||||
if (!get_txpool_tx_blob(txid, bd))
|
||||
throw1(DB_ERROR("Tx not found in txpool: "));
|
||||
return bd;
|
||||
}
|
||||
@@ -1987,7 +1953,7 @@ bool BlockchainLMDB::prune_worker(int mode, uint32_t pruning_seed)
|
||||
const uint32_t log_stripes = tools::get_pruning_log_stripes(pruning_seed);
|
||||
if (log_stripes && log_stripes != CRYPTONOTE_PRUNING_LOG_STRIPES)
|
||||
throw0(DB_ERROR("Pruning seed not in range"));
|
||||
pruning_seed = tools::get_pruning_stripe(pruning_seed);
|
||||
pruning_seed = tools::get_pruning_stripe(pruning_seed);;
|
||||
if (pruning_seed > (1ul << CRYPTONOTE_PRUNING_LOG_STRIPES))
|
||||
throw0(DB_ERROR("Pruning seed not in range"));
|
||||
check_open();
|
||||
@@ -2279,7 +2245,7 @@ bool BlockchainLMDB::check_pruning()
|
||||
return prune_worker(prune_mode_check, 0);
|
||||
}
|
||||
|
||||
bool BlockchainLMDB::for_all_txpool_txes(std::function<bool(const crypto::hash&, const txpool_tx_meta_t&, const cryptonote::blobdata*)> f, bool include_blob, relay_category category) const
|
||||
bool BlockchainLMDB::for_all_txpool_txes(std::function<bool(const crypto::hash&, const txpool_tx_meta_t&, const cryptonote::blobdata*)> f, bool include_blob, bool include_unrelayed_txes) const
|
||||
{
|
||||
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||
check_open();
|
||||
@@ -2303,7 +2269,8 @@ bool BlockchainLMDB::for_all_txpool_txes(std::function<bool(const crypto::hash&,
|
||||
throw0(DB_ERROR(lmdb_error("Failed to enumerate txpool tx metadata: ", result).c_str()));
|
||||
const crypto::hash txid = *(const crypto::hash*)k.mv_data;
|
||||
const txpool_tx_meta_t &meta = *(const txpool_tx_meta_t*)v.mv_data;
|
||||
if (!meta.matches(category))
|
||||
if (!include_unrelayed_txes && meta.do_not_relay)
|
||||
// Skipping that tx
|
||||
continue;
|
||||
const cryptonote::blobdata *passed_bd = NULL;
|
||||
cryptonote::blobdata bd;
|
||||
@@ -3066,146 +3033,6 @@ bool BlockchainLMDB::get_pruned_tx_blob(const crypto::hash& h, cryptonote::blobd
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BlockchainLMDB::get_pruned_tx_blobs_from(const crypto::hash& h, size_t count, std::vector<cryptonote::blobdata> &bd) const
|
||||
{
|
||||
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||
check_open();
|
||||
|
||||
if (!count)
|
||||
return true;
|
||||
|
||||
TXN_PREFIX_RDONLY();
|
||||
RCURSOR(tx_indices);
|
||||
RCURSOR(txs_pruned);
|
||||
|
||||
bd.reserve(bd.size() + count);
|
||||
|
||||
MDB_val_set(v, h);
|
||||
MDB_val result;
|
||||
int res = mdb_cursor_get(m_cur_tx_indices, (MDB_val *)&zerokval, &v, MDB_GET_BOTH);
|
||||
if (res == MDB_NOTFOUND)
|
||||
return false;
|
||||
if (res)
|
||||
throw0(DB_ERROR(lmdb_error("DB error attempting to fetch tx from hash", res).c_str()));
|
||||
|
||||
const txindex *tip = (const txindex *)v.mv_data;
|
||||
const uint64_t id = tip->data.tx_id;
|
||||
MDB_val_set(val_tx_id, id);
|
||||
MDB_cursor_op op = MDB_SET;
|
||||
while (count--)
|
||||
{
|
||||
res = mdb_cursor_get(m_cur_txs_pruned, &val_tx_id, &result, op);
|
||||
op = MDB_NEXT;
|
||||
if (res == MDB_NOTFOUND)
|
||||
return false;
|
||||
if (res)
|
||||
throw0(DB_ERROR(lmdb_error("DB error attempting to fetch tx blob", res).c_str()));
|
||||
bd.emplace_back(reinterpret_cast<char*>(result.mv_data), result.mv_size);
|
||||
}
|
||||
|
||||
TXN_POSTFIX_RDONLY();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BlockchainLMDB::get_blocks_from(uint64_t start_height, size_t min_count, size_t max_count, size_t max_size, std::vector<std::pair<std::pair<cryptonote::blobdata, crypto::hash>, std::vector<std::pair<crypto::hash, cryptonote::blobdata>>>>& blocks, bool pruned, bool skip_coinbase, bool get_miner_tx_hash) const
|
||||
{
|
||||
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||
check_open();
|
||||
|
||||
TXN_PREFIX_RDONLY();
|
||||
RCURSOR(blocks);
|
||||
RCURSOR(tx_indices);
|
||||
RCURSOR(txs_pruned);
|
||||
if (!pruned)
|
||||
{
|
||||
RCURSOR(txs_prunable);
|
||||
}
|
||||
|
||||
blocks.reserve(std::min<size_t>(max_count, 10000)); // guard against very large max count if only checking bytes
|
||||
const uint64_t blockchain_height = height();
|
||||
uint64_t size = 0;
|
||||
MDB_val_copy<uint64_t> key(start_height);
|
||||
MDB_val k, v, val_tx_id;
|
||||
uint64_t tx_id = ~0;
|
||||
MDB_cursor_op op = MDB_SET;
|
||||
for (uint64_t h = start_height; h < blockchain_height && blocks.size() < max_count && (size < max_size || blocks.size() < min_count); ++h)
|
||||
{
|
||||
MDB_cursor_op op = h == start_height ? MDB_SET : MDB_NEXT;
|
||||
int result = mdb_cursor_get(m_cur_blocks, &key, &v, op);
|
||||
if (result == MDB_NOTFOUND)
|
||||
throw0(BLOCK_DNE(std::string("Attempt to get block from height ").append(boost::lexical_cast<std::string>(h)).append(" failed -- block not in db").c_str()));
|
||||
else if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Error attempting to retrieve a block from the db", result).c_str()));
|
||||
|
||||
blocks.resize(blocks.size() + 1);
|
||||
auto ¤t_block = blocks.back();
|
||||
|
||||
current_block.first.first.assign(reinterpret_cast<char*>(v.mv_data), v.mv_size);
|
||||
size += v.mv_size;
|
||||
|
||||
cryptonote::block b;
|
||||
if (!parse_and_validate_block_from_blob(current_block.first.first, b))
|
||||
throw0(DB_ERROR("Invalid block"));
|
||||
current_block.first.second = get_miner_tx_hash ? cryptonote::get_transaction_hash(b.miner_tx) : crypto::null_hash;
|
||||
|
||||
// get the tx_id for the first tx (the first block's coinbase tx)
|
||||
if (h == start_height)
|
||||
{
|
||||
crypto::hash hash = cryptonote::get_transaction_hash(b.miner_tx);
|
||||
MDB_val_set(v, hash);
|
||||
result = mdb_cursor_get(m_cur_tx_indices, (MDB_val *)&zerokval, &v, MDB_GET_BOTH);
|
||||
if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Error attempting to retrieve block coinbase transaction from the db: ", result).c_str()));
|
||||
|
||||
const txindex *tip = (const txindex *)v.mv_data;
|
||||
tx_id = tip->data.tx_id;
|
||||
val_tx_id.mv_data = &tx_id;
|
||||
val_tx_id.mv_size = sizeof(tx_id);
|
||||
}
|
||||
|
||||
if (skip_coinbase)
|
||||
{
|
||||
result = mdb_cursor_get(m_cur_txs_pruned, &val_tx_id, &v, op);
|
||||
if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Error attempting to retrieve transaction data from the db: ", result).c_str()));
|
||||
if (!pruned)
|
||||
{
|
||||
result = mdb_cursor_get(m_cur_txs_prunable, &val_tx_id, &v, op);
|
||||
if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Error attempting to retrieve transaction data from the db: ", result).c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
op = MDB_NEXT;
|
||||
|
||||
current_block.second.reserve(b.tx_hashes.size());
|
||||
for (const auto &tx_hash: b.tx_hashes)
|
||||
{
|
||||
// get pruned data
|
||||
cryptonote::blobdata tx_blob;
|
||||
result = mdb_cursor_get(m_cur_txs_pruned, &val_tx_id, &v, op);
|
||||
if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Error attempting to retrieve transaction data from the db: ", result).c_str()));
|
||||
tx_blob.assign((const char*)v.mv_data, v.mv_size);
|
||||
|
||||
if (!pruned)
|
||||
{
|
||||
result = mdb_cursor_get(m_cur_txs_prunable, &val_tx_id, &v, op);
|
||||
if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Error attempting to retrieve transaction data from the db: ", result).c_str()));
|
||||
tx_blob.append(reinterpret_cast<const char*>(v.mv_data), v.mv_size);
|
||||
}
|
||||
current_block.second.push_back(std::make_pair(tx_hash, std::move(tx_blob)));
|
||||
size += current_block.second.back().second.size();
|
||||
}
|
||||
}
|
||||
|
||||
TXN_POSTFIX_RDONLY();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BlockchainLMDB::get_prunable_tx_blob(const crypto::hash& h, cryptonote::blobdata &bd) const
|
||||
{
|
||||
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||
@@ -3370,7 +3197,7 @@ output_data_t BlockchainLMDB::get_output_key(const uint64_t& amount, const uint6
|
||||
else
|
||||
{
|
||||
const pre_rct_outkey *okp = (const pre_rct_outkey *)v.mv_data;
|
||||
memcpy(&ret, &okp->data, sizeof(pre_rct_output_data_t));
|
||||
memcpy(&ret, &okp->data, sizeof(pre_rct_output_data_t));;
|
||||
if (include_commitmemt)
|
||||
ret.commitment = rct::zeroCommit(amount);
|
||||
}
|
||||
@@ -4048,7 +3875,7 @@ void BlockchainLMDB::get_output_tx_and_index_from_global(const std::vector<uint6
|
||||
void BlockchainLMDB::get_output_key(const epee::span<const uint64_t> &amounts, const std::vector<uint64_t> &offsets, std::vector<output_data_t> &outputs, bool allow_partial) const
|
||||
{
|
||||
if (amounts.size() != 1 && amounts.size() != offsets.size())
|
||||
throw0(DB_ERROR("Invalid sizes of amounts and offsets"));
|
||||
throw0(DB_ERROR("Invalid sizes of amounts and offets"));
|
||||
|
||||
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||
TIME_MEASURE_START(db3);
|
||||
|
||||
@@ -254,8 +254,6 @@ public:
|
||||
|
||||
virtual bool get_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const;
|
||||
virtual bool get_pruned_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const;
|
||||
virtual bool get_pruned_tx_blobs_from(const crypto::hash& h, size_t count, std::vector<cryptonote::blobdata> &bd) const;
|
||||
virtual bool get_blocks_from(uint64_t start_height, size_t min_count, size_t max_count, size_t max_size, std::vector<std::pair<std::pair<cryptonote::blobdata, crypto::hash>, std::vector<std::pair<crypto::hash, cryptonote::blobdata>>>>& blocks, bool pruned, bool skip_coinbase, bool get_miner_tx_hash) const;
|
||||
virtual bool get_prunable_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const;
|
||||
virtual bool get_prunable_tx_hash(const crypto::hash& tx_hash, crypto::hash &prunable_hash) const;
|
||||
|
||||
@@ -283,12 +281,12 @@ public:
|
||||
|
||||
virtual void add_txpool_tx(const crypto::hash &txid, const cryptonote::blobdata &blob, const txpool_tx_meta_t& meta);
|
||||
virtual void update_txpool_tx(const crypto::hash &txid, const txpool_tx_meta_t& meta);
|
||||
virtual uint64_t get_txpool_tx_count(relay_category category = relay_category::broadcasted) const;
|
||||
virtual bool txpool_has_tx(const crypto::hash &txid, relay_category tx_category) const;
|
||||
virtual uint64_t get_txpool_tx_count(bool include_unrelayed_txes = true) const;
|
||||
virtual bool txpool_has_tx(const crypto::hash &txid) const;
|
||||
virtual void remove_txpool_tx(const crypto::hash& txid);
|
||||
virtual bool get_txpool_tx_meta(const crypto::hash& txid, txpool_tx_meta_t &meta) const;
|
||||
virtual bool get_txpool_tx_blob(const crypto::hash& txid, cryptonote::blobdata& bd, relay_category tx_category) const;
|
||||
virtual cryptonote::blobdata get_txpool_tx_blob(const crypto::hash& txid, relay_category tx_category) const;
|
||||
virtual bool get_txpool_tx_blob(const crypto::hash& txid, cryptonote::blobdata &bd) const;
|
||||
virtual cryptonote::blobdata get_txpool_tx_blob(const crypto::hash& txid) const;
|
||||
virtual uint32_t get_blockchain_pruning_seed() const;
|
||||
virtual bool prune_blockchain(uint32_t pruning_seed = 0);
|
||||
virtual bool update_pruning();
|
||||
@@ -300,7 +298,7 @@ public:
|
||||
virtual uint64_t get_alt_block_count();
|
||||
virtual void drop_alt_blocks();
|
||||
|
||||
virtual bool for_all_txpool_txes(std::function<bool(const crypto::hash&, const txpool_tx_meta_t&, const cryptonote::blobdata*)> f, bool include_blob = false, relay_category category = relay_category::broadcasted) const;
|
||||
virtual bool for_all_txpool_txes(std::function<bool(const crypto::hash&, const txpool_tx_meta_t&, const cryptonote::blobdata*)> f, bool include_blob = false, bool include_unrelayed_txes = true) const;
|
||||
|
||||
virtual bool for_all_key_images(std::function<bool(const crypto::key_image&)>) const;
|
||||
virtual bool for_blocks_range(const uint64_t& h1, const uint64_t& h2, std::function<bool(uint64_t, const crypto::hash&, const cryptonote::block&)>) const;
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
// Copyright (c) 2014-2019, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace cryptonote
|
||||
{
|
||||
// This class is meant to create a batch when none currently exists.
|
||||
// If a batch exists, it can't be from another thread, since we can
|
||||
// only be called with the txpool lock taken, and it is held during
|
||||
// the whole prepare/handle/cleanup incoming block sequence.
|
||||
class LockedTXN {
|
||||
public:
|
||||
LockedTXN(BlockchainDB &db): m_db(db), m_batch(false), m_active(false) {
|
||||
m_batch = m_db.batch_start();
|
||||
m_active = true;
|
||||
}
|
||||
void commit() { try { if (m_batch && m_active) { m_db.batch_stop(); m_active = false; } } catch (const std::exception &e) { MWARNING("LockedTXN::commit filtering exception: " << e.what()); } }
|
||||
void abort() { try { if (m_batch && m_active) { m_db.batch_abort(); m_active = false; } } catch (const std::exception &e) { MWARNING("LockedTXN::abort filtering exception: " << e.what()); } }
|
||||
~LockedTXN() { abort(); }
|
||||
private:
|
||||
BlockchainDB &m_db;
|
||||
bool m_batch;
|
||||
bool m_active;
|
||||
};
|
||||
}
|
||||
@@ -69,8 +69,6 @@ public:
|
||||
virtual cryptonote::blobdata get_block_blob(const crypto::hash& h) const override { return cryptonote::blobdata(); }
|
||||
virtual bool get_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const override { return false; }
|
||||
virtual bool get_pruned_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const override { return false; }
|
||||
virtual bool get_pruned_tx_blobs_from(const crypto::hash& h, size_t count, std::vector<cryptonote::blobdata> &bd) const { return false; }
|
||||
virtual bool get_blocks_from(uint64_t start_height, size_t min_count, size_t max_count, size_t max_size, std::vector<std::pair<std::pair<cryptonote::blobdata, crypto::hash>, std::vector<std::pair<crypto::hash, cryptonote::blobdata>>>>& blocks, bool pruned, bool skip_coinbase, bool get_miner_tx_hash) const { return false; }
|
||||
virtual bool get_prunable_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const override { return false; }
|
||||
virtual bool get_prunable_tx_hash(const crypto::hash& tx_hash, crypto::hash &prunable_hash) const override { return false; }
|
||||
virtual uint64_t get_block_height(const crypto::hash& h) const override { return 0; }
|
||||
@@ -128,14 +126,14 @@ public:
|
||||
|
||||
virtual void add_txpool_tx(const crypto::hash &txid, const cryptonote::blobdata &blob, const cryptonote::txpool_tx_meta_t& details) override {}
|
||||
virtual void update_txpool_tx(const crypto::hash &txid, const cryptonote::txpool_tx_meta_t& details) override {}
|
||||
virtual uint64_t get_txpool_tx_count(relay_category tx_relay = relay_category::broadcasted) const override { return 0; }
|
||||
virtual bool txpool_has_tx(const crypto::hash &txid, relay_category tx_category) const override { return false; }
|
||||
virtual uint64_t get_txpool_tx_count(bool include_unrelayed_txes = true) const override { return 0; }
|
||||
virtual bool txpool_has_tx(const crypto::hash &txid) const override { return false; }
|
||||
virtual void remove_txpool_tx(const crypto::hash& txid) override {}
|
||||
virtual bool get_txpool_tx_meta(const crypto::hash& txid, cryptonote::txpool_tx_meta_t &meta) const override { return false; }
|
||||
virtual bool get_txpool_tx_blob(const crypto::hash& txid, cryptonote::blobdata &bd, relay_category tx_category) const override { return false; }
|
||||
virtual bool get_txpool_tx_blob(const crypto::hash& txid, cryptonote::blobdata &bd) const override { return false; }
|
||||
virtual uint64_t get_database_size() const override { return 0; }
|
||||
virtual cryptonote::blobdata get_txpool_tx_blob(const crypto::hash& txid, relay_category tx_category) const override { return ""; }
|
||||
virtual bool for_all_txpool_txes(std::function<bool(const crypto::hash&, const cryptonote::txpool_tx_meta_t&, const cryptonote::blobdata*)>, bool include_blob = false, relay_category category = relay_category::broadcasted) const override { return false; }
|
||||
virtual cryptonote::blobdata get_txpool_tx_blob(const crypto::hash& txid) const override { return ""; }
|
||||
virtual bool for_all_txpool_txes(std::function<bool(const crypto::hash&, const cryptonote::txpool_tx_meta_t&, const cryptonote::blobdata*)>, bool include_blob = false, bool include_unrelayed_txes = false) const override { return false; }
|
||||
|
||||
virtual void add_block( const cryptonote::block& blk
|
||||
, size_t block_weight
|
||||
|
||||
@@ -174,7 +174,7 @@ int check_flush(cryptonote::core &core, std::vector<block_complete_entry> &block
|
||||
for(auto& tx_blob: block_entry.txs)
|
||||
{
|
||||
tx_verification_context tvc = AUTO_VAL_INIT(tvc);
|
||||
core.handle_incoming_tx(tx_blob, tvc, relay_method::block, true);
|
||||
core.handle_incoming_tx(tx_blob, tvc, true, true, false);
|
||||
if(tvc.m_verifivation_failed)
|
||||
{
|
||||
MERROR("transaction verification failed, tx_id = "
|
||||
|
||||
@@ -264,12 +264,12 @@ skip:
|
||||
{
|
||||
throw std::runtime_error("Aborting: tx == null_hash");
|
||||
}
|
||||
if (!db->get_pruned_tx_blob(tx_id, bd))
|
||||
if (!db->get_tx_blob(tx_id, bd))
|
||||
{
|
||||
throw std::runtime_error("Aborting: tx not found");
|
||||
}
|
||||
transaction tx;
|
||||
if (!parse_and_validate_tx_base_from_blob(bd, tx))
|
||||
if (!parse_and_validate_tx_from_blob(bd, tx))
|
||||
{
|
||||
LOG_PRINT_L0("Bad txn from db");
|
||||
return 1;
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <fstream>
|
||||
#include <boost/iostreams/copy.hpp>
|
||||
#include <atomic>
|
||||
|
||||
#include "common/command_line.h"
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <fstream>
|
||||
#include <boost/iostreams/copy.hpp>
|
||||
#include <atomic>
|
||||
|
||||
#include "common/command_line.h"
|
||||
|
||||
Binary file not shown.
@@ -34,7 +34,6 @@
|
||||
#include "string_tools.h"
|
||||
#include "storages/portable_storage_template_helper.h" // epee json include
|
||||
#include "serialization/keyvalue_serialization.h"
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
using namespace epee;
|
||||
@@ -134,9 +133,11 @@ namespace cryptonote
|
||||
//---------------------------------------------------------------------------
|
||||
uint64_t checkpoints::get_max_height() const
|
||||
{
|
||||
if (m_points.empty())
|
||||
return 0;
|
||||
return m_points.rbegin()->first;
|
||||
std::map< uint64_t, crypto::hash >::const_iterator highest =
|
||||
std::max_element( m_points.begin(), m_points.end(),
|
||||
( boost::bind(&std::map< uint64_t, crypto::hash >::value_type::first, _1) <
|
||||
boost::bind(&std::map< uint64_t, crypto::hash >::value_type::first, _2 ) ) );
|
||||
return highest->first;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
const std::map<uint64_t, crypto::hash>& checkpoints::get_points() const
|
||||
@@ -223,9 +224,6 @@ namespace cryptonote
|
||||
ADD_CHECKPOINT(157400, "44445d1fcc845b4d6f8e7730c50af64c09031003d584cdeaa04d6523e0acc049");
|
||||
ADD_CHECKPOINT(160777, "9496690579af21f38f00e67e11c2e85a15912fe4f412aad33d1162be1579e755"); //Hard fork to v15
|
||||
ADD_CHECKPOINT(194444, "0aa7ea6ade2ee8f5a525a079c53888fac415826ee8d1e8c92caa52629773db35");
|
||||
ADD_CHECKPOINT(200500, "1e5c7af11e19a94f334576d79fe0179ff493ce378701f3f810b674db2760c228");
|
||||
ADD_CHECKPOINT(211300, "f712b6dc0dfe896d18c5ca9097144d05ef8810b11277663638c0963d96ea172c");
|
||||
ADD_CHECKPOINT(223800, "878d805ce24368a48c4bd36283f3c53510e86b09511ec6770fbaca8f1fd3c55b");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -86,8 +86,7 @@ set(common_private_headers
|
||||
updates.h
|
||||
aligned.h
|
||||
timings.h
|
||||
combinator.h
|
||||
utf8.h)
|
||||
combinator.h)
|
||||
|
||||
monero_private_headers(common
|
||||
${common_private_headers})
|
||||
|
||||
@@ -107,17 +107,13 @@ namespace tools
|
||||
MINFO("Content-Length: " << length);
|
||||
content_length = length;
|
||||
boost::filesystem::path path(control->path);
|
||||
try
|
||||
boost::filesystem::space_info si = boost::filesystem::space(path);
|
||||
if (si.available < (size_t)content_length)
|
||||
{
|
||||
boost::filesystem::space_info si = boost::filesystem::space(path);
|
||||
if (si.available < (size_t)content_length)
|
||||
{
|
||||
const uint64_t avail = (si.available + 1023) / 1024, needed = (content_length + 1023) / 1024;
|
||||
MERROR("Not enough space to download " << needed << " kB to " << path << " (" << avail << " kB available)");
|
||||
return false;
|
||||
}
|
||||
const uint64_t avail = (si.available + 1023) / 1024, needed = (content_length + 1023) / 1024;
|
||||
MERROR("Not enough space to download " << needed << " kB to " << path << " (" << avail << " kB available)");
|
||||
return false;
|
||||
}
|
||||
catch (const std::exception &e) { MWARNING("Failed to check for free space: " << e.what()); }
|
||||
}
|
||||
if (offset > 0)
|
||||
{
|
||||
|
||||
@@ -84,7 +84,7 @@ void set_performance_timer_log_level(el::Level level);
|
||||
#define PERF_TIMER_START_UNIT(name, unit) std::unique_ptr<tools::LoggingPerformanceTimer> PERF_TIMER_NAME(name)(new tools::LoggingPerformanceTimer(#name, "perf." MONERO_DEFAULT_LOG_CATEGORY, unit, el::Level::Info))
|
||||
#define PERF_TIMER_START(name) PERF_TIMER_START_UNIT(name, 1000000)
|
||||
#define PERF_TIMER_STOP(name) do { PERF_TIMER_NAME(name).reset(NULL); } while(0)
|
||||
#define PERF_TIMER_PAUSE(name) PERF_TIMER_NAME(name).pause()
|
||||
#define PERF_TIMER_RESUME(name) PERF_TIMER_NAME(name).resume()
|
||||
#define PERF_TIMER_PAUSE(name) PERF_TIMER_NAME(name)->pause()
|
||||
#define PERF_TIMER_RESUME(name) PERF_TIMER_NAME(name)->resume()
|
||||
|
||||
}
|
||||
|
||||
@@ -37,14 +37,16 @@ static __thread bool is_leaf = false;
|
||||
namespace tools
|
||||
{
|
||||
threadpool::threadpool(unsigned int max_threads) : running(true), active(0) {
|
||||
create(max_threads);
|
||||
boost::thread::attributes attrs;
|
||||
attrs.set_stack_size(THREAD_STACK_SIZE);
|
||||
max = max_threads ? max_threads : tools::get_max_concurrency();
|
||||
size_t i = max ? max - 1 : 0;
|
||||
while(i--) {
|
||||
threads.push_back(boost::thread(attrs, boost::bind(&threadpool::run, this, false)));
|
||||
}
|
||||
}
|
||||
|
||||
threadpool::~threadpool() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
void threadpool::destroy() {
|
||||
try
|
||||
{
|
||||
const boost::unique_lock<boost::mutex> lock(mutex);
|
||||
@@ -62,24 +64,6 @@ void threadpool::destroy() {
|
||||
try { threads[i].join(); }
|
||||
catch (...) { /* ignore */ }
|
||||
}
|
||||
threads.clear();
|
||||
}
|
||||
|
||||
void threadpool::recycle() {
|
||||
destroy();
|
||||
create(max);
|
||||
}
|
||||
|
||||
void threadpool::create(unsigned int max_threads) {
|
||||
const boost::unique_lock<boost::mutex> lock(mutex);
|
||||
boost::thread::attributes attrs;
|
||||
attrs.set_stack_size(THREAD_STACK_SIZE);
|
||||
max = max_threads ? max_threads : tools::get_max_concurrency();
|
||||
size_t i = max ? max - 1 : 0;
|
||||
running = true;
|
||||
while(i--) {
|
||||
threads.push_back(boost::thread(attrs, boost::bind(&threadpool::run, this, false)));
|
||||
}
|
||||
}
|
||||
|
||||
void threadpool::submit(waiter *obj, std::function<void()> f, bool leaf) {
|
||||
@@ -161,7 +145,7 @@ void threadpool::run(bool flush) {
|
||||
if (!running) break;
|
||||
|
||||
active++;
|
||||
e = std::move(queue.front());
|
||||
e = queue.front();
|
||||
queue.pop_front();
|
||||
lock.unlock();
|
||||
++depth;
|
||||
|
||||
@@ -69,17 +69,12 @@ public:
|
||||
// task to finish.
|
||||
void submit(waiter *waiter, std::function<void()> f, bool leaf = false);
|
||||
|
||||
// destroy and recreate threads
|
||||
void recycle();
|
||||
|
||||
unsigned int get_max_concurrency() const;
|
||||
|
||||
~threadpool();
|
||||
|
||||
private:
|
||||
threadpool(unsigned int max_threads = 0);
|
||||
void destroy();
|
||||
void create(unsigned int max_threads);
|
||||
typedef struct entry {
|
||||
waiter *wo;
|
||||
std::function<void()> f;
|
||||
|
||||
@@ -97,7 +97,7 @@ namespace tools
|
||||
{
|
||||
const char *base = user ? "" : "";
|
||||
#ifdef _WIN32
|
||||
static const char *extension = strncmp(buildtag.c_str(), "source", 6) ? (strncmp(buildtag.c_str(), "install-", 8) ? ".zip" : ".exe") : ".tar.bz2";
|
||||
static const char *extension = strncmp(buildtag.c_str(), "install-", 8) ? ".zip" : ".exe";
|
||||
#else
|
||||
static const char extension[] = ".tar.bz2";
|
||||
#endif
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
// Copyright (c) 2019, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cctype>
|
||||
#include <cwchar>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace tools
|
||||
{
|
||||
template<typename T, typename Transform>
|
||||
inline T utf8canonical(const T &s, Transform t = [](wint_t c)->wint_t { return c; })
|
||||
{
|
||||
T sc = "";
|
||||
size_t avail = s.size();
|
||||
const char *ptr = s.data();
|
||||
wint_t cp = 0;
|
||||
int bytes = 1;
|
||||
char wbuf[8], *wptr;
|
||||
while (avail--)
|
||||
{
|
||||
if ((*ptr & 0x80) == 0)
|
||||
{
|
||||
cp = *ptr++;
|
||||
bytes = 1;
|
||||
}
|
||||
else if ((*ptr & 0xe0) == 0xc0)
|
||||
{
|
||||
if (avail < 1)
|
||||
throw std::runtime_error("Invalid UTF-8");
|
||||
cp = (*ptr++ & 0x1f) << 6;
|
||||
cp |= *ptr++ & 0x3f;
|
||||
--avail;
|
||||
bytes = 2;
|
||||
}
|
||||
else if ((*ptr & 0xf0) == 0xe0)
|
||||
{
|
||||
if (avail < 2)
|
||||
throw std::runtime_error("Invalid UTF-8");
|
||||
cp = (*ptr++ & 0xf) << 12;
|
||||
cp |= (*ptr++ & 0x3f) << 6;
|
||||
cp |= *ptr++ & 0x3f;
|
||||
avail -= 2;
|
||||
bytes = 3;
|
||||
}
|
||||
else if ((*ptr & 0xf8) == 0xf0)
|
||||
{
|
||||
if (avail < 3)
|
||||
throw std::runtime_error("Invalid UTF-8");
|
||||
cp = (*ptr++ & 0x7) << 18;
|
||||
cp |= (*ptr++ & 0x3f) << 12;
|
||||
cp |= (*ptr++ & 0x3f) << 6;
|
||||
cp |= *ptr++ & 0x3f;
|
||||
avail -= 3;
|
||||
bytes = 4;
|
||||
}
|
||||
else
|
||||
throw std::runtime_error("Invalid UTF-8");
|
||||
|
||||
cp = t(cp);
|
||||
if (cp <= 0x7f)
|
||||
bytes = 1;
|
||||
else if (cp <= 0x7ff)
|
||||
bytes = 2;
|
||||
else if (cp <= 0xffff)
|
||||
bytes = 3;
|
||||
else if (cp <= 0x10ffff)
|
||||
bytes = 4;
|
||||
else
|
||||
throw std::runtime_error("Invalid code point UTF-8 transformation");
|
||||
|
||||
wptr = wbuf;
|
||||
switch (bytes)
|
||||
{
|
||||
case 1: *wptr++ = cp; break;
|
||||
case 2: *wptr++ = 0xc0 | (cp >> 6); *wptr++ = 0x80 | (cp & 0x3f); break;
|
||||
case 3: *wptr++ = 0xe0 | (cp >> 12); *wptr++ = 0x80 | ((cp >> 6) & 0x3f); *wptr++ = 0x80 | (cp & 0x3f); break;
|
||||
case 4: *wptr++ = 0xf0 | (cp >> 18); *wptr++ = 0x80 | ((cp >> 12) & 0x3f); *wptr++ = 0x80 | ((cp >> 6) & 0x3f); *wptr++ = 0x80 | (cp & 0x3f); break;
|
||||
default: throw std::runtime_error("Invalid UTF-8");
|
||||
}
|
||||
*wptr = 0;
|
||||
sc.append(wbuf, bytes);
|
||||
cp = 0;
|
||||
bytes = 1;
|
||||
}
|
||||
return sc;
|
||||
}
|
||||
}
|
||||
@@ -66,6 +66,7 @@ using namespace epee;
|
||||
#include "util.h"
|
||||
#include "stack_trace.h"
|
||||
#include "memwipe.h"
|
||||
#include "cryptonote_config.h"
|
||||
#include "net/http_client.h" // epee::net_utils::...
|
||||
#include "readline_buffer.h"
|
||||
|
||||
@@ -1073,33 +1074,16 @@ std::string get_nix_version_display_string()
|
||||
{
|
||||
if (seconds < 60)
|
||||
return std::to_string(seconds) + " seconds";
|
||||
std::stringstream ss;
|
||||
ss << std::fixed << std::setprecision(1);
|
||||
if (seconds < 3600)
|
||||
{
|
||||
ss << seconds / 60.f;
|
||||
return ss.str() + " minutes";
|
||||
}
|
||||
return std::to_string((uint64_t)(seconds / 60)) + " minutes";
|
||||
if (seconds < 3600 * 24)
|
||||
{
|
||||
ss << seconds / 3600.f;
|
||||
return ss.str() + " hours";
|
||||
}
|
||||
if (seconds < 3600 * 24 * 30.5f)
|
||||
{
|
||||
ss << seconds / (3600 * 24.f);
|
||||
return ss.str() + " days";
|
||||
}
|
||||
if (seconds < 3600 * 24 * 365.25f)
|
||||
{
|
||||
ss << seconds / (3600 * 24 * 30.5f);
|
||||
return ss.str() + " months";
|
||||
}
|
||||
if (seconds < 3600 * 24 * 365.25f * 100)
|
||||
{
|
||||
ss << seconds / (3600 * 24 * 365.25f);
|
||||
return ss.str() + " years";
|
||||
}
|
||||
return std::to_string((uint64_t)(seconds / 3600)) + " hours";
|
||||
if (seconds < 3600 * 24 * 30.5)
|
||||
return std::to_string((uint64_t)(seconds / (3600 * 24))) + " days";
|
||||
if (seconds < 3600 * 24 * 365.25)
|
||||
return std::to_string((uint64_t)(seconds / (3600 * 24 * 30.5))) + " months";
|
||||
if (seconds < 3600 * 24 * 365.25 * 100)
|
||||
return std::to_string((uint64_t)(seconds / (3600 * 24 * 30.5 * 365.25))) + " years";
|
||||
return "a long time";
|
||||
}
|
||||
|
||||
@@ -1255,7 +1239,7 @@ std::string get_nix_version_display_string()
|
||||
return get_string_prefix_by_width(s, 999999999).second;
|
||||
};
|
||||
|
||||
std::vector<std::pair<std::string, size_t>> split_line_by_width(const std::string &s, size_t columns)
|
||||
std::vector<std::pair<std::string, size_t>> split_string_by_width(const std::string &s, size_t columns)
|
||||
{
|
||||
std::vector<std::string> words;
|
||||
std::vector<std::pair<std::string, size_t>> lines;
|
||||
@@ -1295,97 +1279,4 @@ std::string get_nix_version_display_string()
|
||||
return lines;
|
||||
}
|
||||
|
||||
// Calculate a "sync weight" over ranges of blocks in the blockchain, suitable for
|
||||
// calculating sync time estimates
|
||||
uint64_t cumulative_block_sync_weight(cryptonote::network_type nettype, uint64_t start_block, uint64_t num_blocks)
|
||||
{
|
||||
if (nettype != cryptonote::MAINNET)
|
||||
{
|
||||
// No detailed data available except for Mainnet: Give back the number of blocks
|
||||
// as a very simple and non-varying block sync weight for ranges of Testnet and
|
||||
// Stagenet blocks
|
||||
return num_blocks;
|
||||
}
|
||||
|
||||
// The following is a table of average blocks sizes in bytes over the Monero mainnet
|
||||
// blockchain, where the block size is averaged over ranges of 10,000 blocks
|
||||
// (about 2 weeks worth of blocks each).
|
||||
// The first array entry of 442 thus means "The average byte size of the blocks
|
||||
// 0 .. 9,999 is 442". The info "block_size" from the "get_block_header_by_height"
|
||||
// RPC call was used for calculating this. This table (and the whole mechanism
|
||||
// of calculating a "sync weight") is most important when estimating times for
|
||||
// syncing from scratch. Without it the fast progress through the (in comparison)
|
||||
// rather small blocks in the early blockchain) would lead to vastly underestimated
|
||||
// total sync times.
|
||||
// It's no big problem for estimates that this table will, over time, and if not
|
||||
// updated, miss larger and larger parts at the top of the blockchain, as long
|
||||
// as block size averages there do not differ wildly.
|
||||
// Without time-consuming tests it's hard to say how much the estimates would
|
||||
// improve if one would not only take block sizes into account, but also varying
|
||||
// verification times i.e. the different CPU effort needed for the different
|
||||
// transaction types (pre / post RingCT, pre / post Bulletproofs).
|
||||
// Testnet and Stagenet are neglected here because of their much smaller
|
||||
// importance.
|
||||
static const uint32_t average_block_sizes[] =
|
||||
{
|
||||
442, 1211, 1445, 1763, 2272, 8217, 5603, 9999, 16358, 10805, 5290, 4362,
|
||||
4325, 5584, 4515, 5008, 4789, 5196, 7660, 3829, 6034, 2925, 3762, 2545,
|
||||
2437, 2553, 2167, 2761, 2015, 1969, 2350, 1731, 2367, 2078, 2026, 3518,
|
||||
2214, 1908, 1780, 1640, 1976, 1647, 1921, 1716, 1895, 2150, 2419, 2451,
|
||||
2147, 2327, 2251, 1644, 1750, 1481, 1570, 1524, 1562, 1668, 1386, 1494,
|
||||
1637, 1880, 1431, 1472, 1637, 1363, 1762, 1597, 1999, 1564, 1341, 1388,
|
||||
1530, 1476, 1617, 1488, 1368, 1906, 1403, 1695, 1535, 1598, 1318, 1234,
|
||||
1358, 1406, 1698, 1554, 1591, 1758, 1426, 2389, 1946, 1533, 1308, 2701,
|
||||
1525, 1653, 3580, 1889, 2913, 8164, 5154, 3762, 3356, 4360, 3589, 4844,
|
||||
4232, 3781, 3882, 5924, 10790, 7185, 7442, 8214, 8509, 7484, 6939, 7391,
|
||||
8210, 15572, 39680, 44810, 53873, 54639, 68227, 63428, 62386, 68504,
|
||||
83073, 103858, 117573, 98089, 96793, 102337, 94714, 129568, 251584,
|
||||
132026, 94579, 94516, 95722, 106495, 121824, 153983, 162338, 136608,
|
||||
137104, 109872, 91114, 84757, 96339, 74251, 94314, 143216, 155837,
|
||||
129968, 120201, 109913, 101588, 97332, 104611, 95310, 93419, 113345,
|
||||
100743, 92152, 57565, 22533, 37564, 21823, 19980, 18277, 18402, 14344,
|
||||
12142, 15842, 13677, 17631, 18294, 22270, 41422, 39296, 36688, 33512,
|
||||
33831, 27582, 22276, 27516, 27317, 25505, 24426, 20566, 23045, 26766,
|
||||
28185, 26169, 27011,
|
||||
28642 // Blocks 1,990,000 to 1,999,999 in December 2019
|
||||
};
|
||||
const uint64_t block_range_size = 10000;
|
||||
|
||||
uint64_t num_block_sizes = sizeof(average_block_sizes) / sizeof(average_block_sizes[0]);
|
||||
uint64_t weight = 0;
|
||||
uint64_t table_index = start_block / block_range_size;
|
||||
for (;;) {
|
||||
if (num_blocks == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (table_index >= num_block_sizes)
|
||||
{
|
||||
// Take all blocks beyond our table as having the size of the blocks
|
||||
// in the last table entry i.e. in the most recent known block range
|
||||
weight += num_blocks * average_block_sizes[num_block_sizes - 1];
|
||||
break;
|
||||
}
|
||||
uint64_t portion_size = std::min(num_blocks, block_range_size - start_block % block_range_size);
|
||||
weight += portion_size * average_block_sizes[table_index];
|
||||
table_index++;
|
||||
num_blocks -= portion_size;
|
||||
start_block += portion_size;
|
||||
}
|
||||
return weight;
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::string, size_t>> split_string_by_width(const std::string &s, size_t columns)
|
||||
{
|
||||
std::vector<std::string> lines;
|
||||
std::vector<std::pair<std::string, size_t>> all_lines;
|
||||
boost::split(lines, s, boost::is_any_of("\n"), boost::token_compress_on);
|
||||
for (const auto &e: lines)
|
||||
{
|
||||
std::vector<std::pair<std::string, size_t>> new_lines = split_line_by_width(e, columns);
|
||||
for (auto &l: new_lines)
|
||||
all_lines.push_back(std::move(l));
|
||||
}
|
||||
return all_lines;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,6 @@
|
||||
#endif
|
||||
|
||||
#include "crypto/hash.h"
|
||||
#include "cryptonote_config.h"
|
||||
|
||||
/*! \brief Various Tools
|
||||
*
|
||||
@@ -253,6 +252,4 @@ namespace tools
|
||||
void clear_screen();
|
||||
|
||||
std::vector<std::pair<std::string, size_t>> split_string_by_width(const std::string &s, size_t columns);
|
||||
|
||||
uint64_t cumulative_block_sync_weight(cryptonote::network_type nettype, uint64_t start_block, uint64_t num_blocks);
|
||||
}
|
||||
|
||||
@@ -42,7 +42,6 @@ set(crypto_sources
|
||||
hmac-keccak.c
|
||||
jh.c
|
||||
keccak.c
|
||||
sha3.c
|
||||
oaes_lib.c
|
||||
random.c
|
||||
skein.c
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <memwipe.h>
|
||||
#include "blake256.h"
|
||||
|
||||
#define U8TO32(p) \
|
||||
@@ -278,7 +277,7 @@ void hmac_blake256_init(hmac_state *S, const uint8_t *_key, uint64_t keylen) {
|
||||
}
|
||||
blake256_update(&S->outer, pad, 512);
|
||||
|
||||
memwipe(keyhash, sizeof(keyhash));
|
||||
memset(keyhash, 0, 32);
|
||||
}
|
||||
|
||||
// keylen = number of bytes
|
||||
@@ -308,7 +307,7 @@ void hmac_blake224_init(hmac_state *S, const uint8_t *_key, uint64_t keylen) {
|
||||
}
|
||||
blake224_update(&S->outer, pad, 512);
|
||||
|
||||
memwipe(keyhash, sizeof(keyhash));
|
||||
memset(keyhash, 0, 32);
|
||||
}
|
||||
|
||||
// datalen = number of bits
|
||||
@@ -328,7 +327,7 @@ void hmac_blake256_final(hmac_state *S, uint8_t *digest) {
|
||||
blake256_final(&S->inner, ihash);
|
||||
blake256_update(&S->outer, ihash, 256);
|
||||
blake256_final(&S->outer, digest);
|
||||
memwipe(ihash, sizeof(ihash));
|
||||
memset(ihash, 0, 32);
|
||||
}
|
||||
|
||||
void hmac_blake224_final(hmac_state *S, uint8_t *digest) {
|
||||
@@ -336,7 +335,7 @@ void hmac_blake224_final(hmac_state *S, uint8_t *digest) {
|
||||
blake224_final(&S->inner, ihash);
|
||||
blake224_update(&S->outer, ihash, 224);
|
||||
blake224_final(&S->outer, digest);
|
||||
memwipe(ihash, sizeof(ihash));
|
||||
memset(ihash, 0, 32);
|
||||
}
|
||||
|
||||
// keylen = number of bytes; inlen = number of bytes
|
||||
|
||||
@@ -294,7 +294,6 @@ namespace crypto {
|
||||
sc_mulsub(&sig.r, &sig.c, &unwrap(sec), &k);
|
||||
if (!sc_isnonzero((const unsigned char*)sig.r.data))
|
||||
goto try_again;
|
||||
memwipe(&k, sizeof(k));
|
||||
}
|
||||
|
||||
bool crypto_ops::check_signature(const hash &prefix_hash, const public_key &pub, const signature &sig) {
|
||||
@@ -391,8 +390,6 @@ namespace crypto {
|
||||
|
||||
// sig.r = k - sig.c*r
|
||||
sc_mulsub(&sig.r, &sig.c, &unwrap(r), &k);
|
||||
|
||||
memwipe(&k, sizeof(k));
|
||||
}
|
||||
|
||||
bool crypto_ops::check_tx_proof(const hash &prefix_hash, const public_key &R, const public_key &A, const boost::optional<public_key> &B, const public_key &D, const signature &sig) {
|
||||
@@ -563,7 +560,6 @@ POP_WARNINGS
|
||||
random_scalar(sig[i].c);
|
||||
random_scalar(sig[i].r);
|
||||
if (ge_frombytes_vartime(&tmp3, &*pubs[i]) != 0) {
|
||||
memwipe(&k, sizeof(k));
|
||||
local_abort("invalid pubkey");
|
||||
}
|
||||
ge_double_scalarmult_base_vartime(&tmp2, &sig[i].c, &tmp3, &sig[i].r);
|
||||
@@ -577,8 +573,6 @@ POP_WARNINGS
|
||||
hash_to_scalar(buf.get(), rs_comm_size(pubs_count), h);
|
||||
sc_sub(&sig[sec_index].c, &h, &sum);
|
||||
sc_mulsub(&sig[sec_index].r, &sig[sec_index].c, &unwrap(sec), &k);
|
||||
|
||||
memwipe(&k, sizeof(k));
|
||||
}
|
||||
|
||||
bool crypto_ops::check_ring_signature(const hash &prefix_hash, const key_image &image,
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
// Copyright (c) 2020, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include "crypto/crypto.h"
|
||||
|
||||
namespace crypto
|
||||
{
|
||||
//! Generate poisson distributed values in discrete `D` time units.
|
||||
template<typename D>
|
||||
struct random_poisson_duration
|
||||
{
|
||||
using result_type = D; //!< std::chrono::duration time unit precision
|
||||
using rep = typename result_type::rep; //!< Type used to represent duration value
|
||||
|
||||
//! \param average for generated durations
|
||||
explicit random_poisson_duration(result_type average)
|
||||
: dist(average.count() < 0 ? 0 : average.count())
|
||||
{}
|
||||
|
||||
//! Generate a crypto-secure random duration
|
||||
result_type operator()()
|
||||
{
|
||||
crypto::random_device rand{};
|
||||
return result_type{dist(rand)};
|
||||
}
|
||||
|
||||
private:
|
||||
std::poisson_distribution<rep> dist;
|
||||
};
|
||||
|
||||
/* A custom duration is used for subsecond precision because of the
|
||||
variance. If 5000 milliseconds is given, 95% of the values fall between
|
||||
4859ms-5141ms in 1ms increments (not enough time variance). Providing 1/4
|
||||
seconds would yield 95% of the values between 3s-7.25s in 1/4s
|
||||
increments. */
|
||||
|
||||
//! Generate random durations with 1 second precision
|
||||
using random_poisson_seconds = random_poisson_duration<std::chrono::seconds>;
|
||||
//! Generate random duration with 1/4 second precision
|
||||
using random_poisson_subseconds =
|
||||
random_poisson_duration<std::chrono::duration<std::chrono::milliseconds::rep, std::ratio<1, 4>>>;
|
||||
}
|
||||
@@ -85,7 +85,6 @@ void hash_extra_blake(const void *data, size_t length, char *hash);
|
||||
void hash_extra_groestl(const void *data, size_t length, char *hash);
|
||||
void hash_extra_jh(const void *data, size_t length, char *hash);
|
||||
void hash_extra_skein(const void *data, size_t length, char *hash);
|
||||
void sha3(const void *data, size_t length, char *hash);
|
||||
|
||||
void tree_hash(const char (*hashes)[HASH_SIZE], size_t count, char *root_hash);
|
||||
|
||||
|
||||
@@ -73,10 +73,6 @@ namespace crypto {
|
||||
inline void cn_slow_hash(const void *data, std::size_t length, hash &hash, int variant = 0, uint64_t height = 0) {
|
||||
cn_slow_hash(data, length, reinterpret_cast<char *>(&hash), variant, 0/*prehashed*/, height);
|
||||
}
|
||||
|
||||
inline void sha3(const void *data, std::size_t length, hash &hash) {
|
||||
sha3(data, length, reinterpret_cast<char *>(&hash));
|
||||
}
|
||||
|
||||
inline void cn_slow_hash_prehashed(const void *data, std::size_t length, hash &hash, int variant = 0, uint64_t height = 0) {
|
||||
cn_slow_hash(data, length, reinterpret_cast<char *>(&hash), variant, 1/*prehashed*/, height);
|
||||
|
||||
@@ -62,7 +62,6 @@ static CTHR_MUTEX_TYPE rx_dataset_mutex = CTHR_MUTEX_INIT;
|
||||
static rx_state rx_s[2] = {{CTHR_MUTEX_INIT,{0},0,0},{CTHR_MUTEX_INIT,{0},0,0}};
|
||||
|
||||
static randomx_dataset *rx_dataset;
|
||||
static int rx_dataset_nomem;
|
||||
static uint64_t rx_dataset_height;
|
||||
static THREADV randomx_vm *rx_vm = NULL;
|
||||
|
||||
@@ -247,25 +246,20 @@ void rx_slow_hash(const uint64_t mainheight, const uint64_t seedheight, const ch
|
||||
}
|
||||
if (miners) {
|
||||
CTHR_MUTEX_LOCK(rx_dataset_mutex);
|
||||
if (!rx_dataset_nomem) {
|
||||
if (rx_dataset == NULL) {
|
||||
rx_dataset = randomx_alloc_dataset(RANDOMX_FLAG_LARGE_PAGES);
|
||||
if (rx_dataset == NULL) {
|
||||
rx_dataset = randomx_alloc_dataset(RANDOMX_FLAG_LARGE_PAGES);
|
||||
if (rx_dataset == NULL) {
|
||||
mdebug(RX_LOGCAT, "Couldn't use largePages for RandomWOW dataset");
|
||||
rx_dataset = randomx_alloc_dataset(RANDOMX_FLAG_DEFAULT);
|
||||
}
|
||||
if (rx_dataset != NULL)
|
||||
rx_initdata(rx_sp->rs_cache, miners, seedheight);
|
||||
mdebug(RX_LOGCAT, "Couldn't use largePages for RandomWOW dataset");
|
||||
rx_dataset = randomx_alloc_dataset(RANDOMX_FLAG_DEFAULT);
|
||||
}
|
||||
if (rx_dataset != NULL)
|
||||
rx_initdata(rx_sp->rs_cache, miners, seedheight);
|
||||
}
|
||||
if (rx_dataset != NULL)
|
||||
flags |= RANDOMX_FLAG_FULL_MEM;
|
||||
else {
|
||||
miners = 0;
|
||||
if (!rx_dataset_nomem) {
|
||||
rx_dataset_nomem = 1;
|
||||
mwarning(RX_LOGCAT, "Couldn't allocate RandomWOW dataset for miner");
|
||||
}
|
||||
mwarning(RX_LOGCAT, "Couldn't allocate RandomWOW dataset for miner");
|
||||
}
|
||||
CTHR_MUTEX_UNLOCK(rx_dataset_mutex);
|
||||
}
|
||||
@@ -284,10 +278,6 @@ void rx_slow_hash(const uint64_t mainheight, const uint64_t seedheight, const ch
|
||||
CTHR_MUTEX_LOCK(rx_dataset_mutex);
|
||||
if (rx_dataset != NULL && rx_dataset_height != seedheight)
|
||||
rx_initdata(cache, miners, seedheight);
|
||||
else if (rx_dataset == NULL) {
|
||||
/* this is a no-op if the cache hasn't changed */
|
||||
randomx_vm_set_cache(rx_vm, rx_sp->rs_cache);
|
||||
}
|
||||
CTHR_MUTEX_UNLOCK(rx_dataset_mutex);
|
||||
} else {
|
||||
/* this is a no-op if the cache hasn't changed */
|
||||
@@ -319,6 +309,5 @@ void rx_stop_mining(void) {
|
||||
rx_dataset = NULL;
|
||||
randomx_release_dataset(rd);
|
||||
}
|
||||
rx_dataset_nomem = 0;
|
||||
CTHR_MUTEX_UNLOCK(rx_dataset_mutex);
|
||||
}
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
#include <stddef.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
void handleErrors(void) {
|
||||
printf("sha3 error, wow is ded\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void sha3(const void *data, size_t length, char *hash)
|
||||
{
|
||||
EVP_MD_CTX *mdctx;
|
||||
|
||||
if((mdctx = EVP_MD_CTX_new()) == NULL) {
|
||||
handleErrors();
|
||||
}
|
||||
|
||||
if(1 != EVP_DigestInit_ex(mdctx, EVP_sha3_256(), NULL)) {
|
||||
handleErrors();
|
||||
}
|
||||
|
||||
if(1 != EVP_DigestUpdate(mdctx, data, length)) {
|
||||
handleErrors();
|
||||
}
|
||||
|
||||
/* the digest context ctx is automatically cleaned up. */
|
||||
if(1 != EVP_DigestFinal(mdctx, (unsigned char*)hash, NULL)) {
|
||||
handleErrors();
|
||||
}
|
||||
}
|
||||
@@ -54,6 +54,7 @@ set(cryptonote_basic_private_headers
|
||||
cryptonote_basic_impl.h
|
||||
cryptonote_boost_serialization.h
|
||||
cryptonote_format_utils.h
|
||||
cryptonote_stat_info.h
|
||||
difficulty.h
|
||||
hardfork.h
|
||||
miner.h
|
||||
|
||||
@@ -40,11 +40,13 @@ extern "C"
|
||||
}
|
||||
#include "cryptonote_basic_impl.h"
|
||||
#include "cryptonote_format_utils.h"
|
||||
#include "cryptonote_config.h"
|
||||
|
||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
#define MONERO_DEFAULT_LOG_CATEGORY "account"
|
||||
|
||||
#define KEYS_ENCRYPTION_SALT 'k'
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
DISABLE_VS_WARNINGS(4244 4345)
|
||||
@@ -67,7 +69,7 @@ DISABLE_VS_WARNINGS(4244 4345)
|
||||
static_assert(sizeof(base_key) == sizeof(crypto::hash), "chacha key and hash should be the same size");
|
||||
epee::mlocked<tools::scrubbed_arr<char, sizeof(base_key)+1>> data;
|
||||
memcpy(data.data(), &base_key, sizeof(base_key));
|
||||
data[sizeof(base_key)] = config::HASH_KEY_MEMORY;
|
||||
data[sizeof(base_key)] = KEYS_ENCRYPTION_SALT;
|
||||
crypto::generate_chacha_key(data.data(), sizeof(data), key, 1);
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
@@ -449,26 +449,14 @@ namespace cryptonote
|
||||
uint8_t minor_version; // now used as a voting mechanism, rather than how this particular block is built
|
||||
uint64_t timestamp;
|
||||
crypto::hash prev_id;
|
||||
uint64_t nonce;
|
||||
uint32_t nonce;
|
||||
|
||||
BEGIN_SERIALIZE()
|
||||
VARINT_FIELD(major_version)
|
||||
VARINT_FIELD(minor_version)
|
||||
VARINT_FIELD(timestamp)
|
||||
FIELD(prev_id)
|
||||
if (major_version >= HF_VERSION_SHA3_POW)
|
||||
{
|
||||
FIELD(nonce)
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t nonce32;
|
||||
if (typename Archive<W>::is_saving())
|
||||
nonce32 = (uint32_t)nonce;
|
||||
FIELD_N("nonce", nonce32);
|
||||
if (!typename Archive<W>::is_saving())
|
||||
nonce = nonce32;
|
||||
}
|
||||
FIELD(nonce)
|
||||
END_SERIALIZE()
|
||||
};
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user