Compare commits

..

80 Commits

Author SHA1 Message Date
Synku
c3c67c7f79 Update 'src/cryptonote_config.h'
Cleanin' it up Gettin' mah mop Washin' teh floor
2020-11-23 19:39:33 +00:00
Synku
3bb5271363 Update 'src/cryptonote_config.h'
c/cryptonote_basic_impl.cpp:84:45: error: static assertion failed: difficulty targets must be a multiple of 60
2020-11-23 00:05:01 +00:00
Synku
52e106ea3c Update 'src/cryptonote_config.h' 2020-11-22 23:50:27 +00:00
Synku
d064957dc7 Update 'contrib/gitian/gitian-win.yml' 2020-11-08 10:23:25 +00:00
Synku
293c8555d0 Update 'contrib/gitian/gitian-osx.yml' 2020-11-08 10:22:38 +00:00
Synku
4b7cf378e6 Update 'contrib/gitian/gitian-linux.yml' 2020-11-08 10:21:43 +00:00
Synku
86a5f86daa Update 'contrib/gitian/gitian-freebsd.yml' 2020-11-08 10:21:02 +00:00
Synku
9cc230a151 Update 'contrib/gitian/gitian-build.py' 2020-11-08 10:20:10 +00:00
Synku
67cd6d08a7 Update 'contrib/gitian/gitian-android.yml' 2020-11-08 10:17:51 +00:00
Synku
3e24ab3479 Update 'README.md' 2020-11-05 03:01:30 +00:00
Synku
8f3da88154 Update 'README.md' 2020-11-05 02:58:59 +00:00
Synku
4836b78551 Update 'src/cryptonote_config.h'
kek
2020-11-05 02:43:27 +00:00
Synku
416d71be3c Update 'src/cryptonote_config.h' 2020-11-05 02:36:34 +00:00
jwinterm
e49e6ae142 Merge pull request 'Fix CLI and unrestricted RPC relay_tx with stempool' (#347) from wowario/wownero:relay_tx into master
Reviewed-on: https://git.wownero.com/wownero/wownero/pulls/347
2020-10-30 03:15:03 +00:00
jwinterm
5731efa127 Merge pull request 'cryptonote_core: Fix missing override warnings' (#343) from wowario/wownero:warnings into master
Reviewed-on: https://git.wownero.com/wownero/wownero/pulls/343
2020-10-30 03:14:36 +00:00
Lee Clagett
26a64f99d3 Fix CLI and unrestricted RPC relay_tx with stempool 2020-10-29 07:29:00 +03:00
Nathan Dorfman
e47fbe1476 cryptonote_core: Fix missing override warnings 2020-10-28 16:31:38 +03:00
wowario
4cc5e174d9 Update 'README.md' 2020-10-22 14:14:13 +00:00
jwinterm
7bdf566225 Merge pull request 'update version and README' (#339) from wowario/wownero:version into master
Reviewed-on: https://git.wownero.com/wownero/wownero/pulls/339
2020-10-19 18:13:45 +00:00
jwinterm
6b80ac2ae7 Merge pull request 'update checkpoints' (#338) from wowario/wownero:checkpoints into master
Reviewed-on: https://git.wownero.com/wownero/wownero/pulls/338
2020-10-19 18:13:23 +00:00
jwinterm
4d15c0aa13 Merge pull request 'increase fake outs' (#337) from wowario/wownero:fake-outs into master
Reviewed-on: https://git.wownero.com/wownero/wownero/pulls/337
2020-10-19 18:12:58 +00:00
jwinterm
8345e5b7bc Merge pull request 'upstream' (#336) from wowario/wownero:upstream into master
Reviewed-on: https://git.wownero.com/wownero/wownero/pulls/336
2020-10-19 18:12:35 +00:00
wowario
12d81b4af1 update version and README 2020-10-19 20:38:20 +03:00
wowario
e2260ab8ab update checkpoints 2020-10-19 20:12:13 +03:00
wowario
e28f22ba2f increase fake outs 2020-10-19 19:15:52 +03:00
iamamyth
80a21da5ba functional_tests: rewrite mining code, clearer timeout info 2020-10-19 11:32:06 +03:00
moneromooo-monero
94b5378a3b fuzz_tests: fix build error in signature fuzz test 2020-10-19 11:31:35 +03:00
moneromooo-monero
cfc8640492 bump default number of connections from 8 to 12 2020-10-19 11:27:03 +03:00
xiphon
69e41b9d4e wallet2: wait for propagation timeout before marking tx as failed 2020-10-19 11:26:40 +03:00
Howard Chu
bcc824cac3 Allow setting start block on export
And make import honor the starting block# recorded in a bootstrap file
2020-10-19 11:26:05 +03:00
xiphon
46b4016134 wallet2_api: implement stop() to interrupt refresh() loop once 2020-10-19 11:25:40 +03:00
dsc
8b73fabd2a Allow AddressBook description edits via wallet/api interface 2020-10-14 12:12:44 +03:00
TheCharlatan
b6dee49900 Depends: Bump qt to 5.15.1 2020-10-14 12:12:21 +03:00
xiphon
1bf5b86967 build: ARM - disable stack trace due to segfault in libunwind 2020-10-14 12:08:29 +03:00
Alexis Enston
dc0ac9c252 fix next_seed_height regression in getblocktemplate rpc 2020-10-14 12:06:28 +03:00
xiphon
2051c5f078 core_rpc_server: on_get_blocks - forward bootstrap daemon error 2020-10-14 12:05:46 +03:00
Howard Chu
51169a6c2d Force CMAKE_SKIP_RPATH=ON
Fix empty RPATH token issue. Only affects Linux and FreeBSD.
2020-10-14 12:05:06 +03:00
xiphon
b8396218a3 Dandelion++: skip desynced peers in stem phase 2020-10-14 12:04:33 +03:00
moneromooo-monero
17c5e8f949 wallet2: fix missing m_state field in wallet serialization 2020-10-14 12:04:04 +03:00
xiphon
3e8bf154eb cmake: Version - use CMAKE_CURRENT_LIST_DIR 2020-10-14 12:03:13 +03:00
Howard Chu
498436c9b4 Fix lgamma/signgam dependency
This is a new indirect dependency due to the use of poisson_distribution,
introduced in PR#6354 commit 67ade8005
2020-10-14 12:01:44 +03:00
wowario
9a58ac48d2 update checkpoints.dat 2020-09-30 17:01:14 +03:00
wowario
90b7699717 bump version to v0.9.0.2 2020-09-30 16:36:03 +03:00
jwinterm
1917bd3d53 Merge pull request 'change log level find tx meta error' (#334) from wowario/wownero:meta into master
Reviewed-on: https://git.wownero.com/wownero/wownero/pulls/334
2020-09-28 00:56:28 +00:00
jwinterm
cb654bbc27 Merge pull request 'fix requested_outputs_count' (#333) from wowario/wownero:outs into master
Reviewed-on: https://git.wownero.com/wownero/wownero/pulls/333
2020-09-28 00:55:58 +00:00
wowario
ec60b05faa change log level find tx meta error 2020-09-26 19:50:43 +03:00
jwinterm
58e1f2f02a Merge pull request 'upstream' (#332) from wowario/wownero:upstream into master
Reviewed-on: https://git.wownero.com/wownero/wownero/pulls/332
2020-09-26 14:28:01 +00:00
wowario
af941bed58 fix requested_outputs_count
Signed-off-by: wowario <wowario@protonmail.com>
2020-09-26 12:51:05 +03:00
moneromooo-monero
10c30ea5aa link libzmq against libgssapi_krb5 if found 2020-09-26 07:11:56 +03:00
moneromooo-monero
83fe535888 fix a couple bugs found by OSS-fuzz
- index out of bounds when importing outputs
- accessing invalid CLSAG data
2020-09-26 07:11:39 +03:00
xiphon
e52e01a445 daemon: Windows - fix FAT32 warning, trailing backslash is required 2020-09-26 07:11:22 +03:00
jwinterm
284ec84502 Merge pull request 'cryptonote_protocol: don't synced pruned blocks before HF_VERSION_SMALLER_BP' (#330) from wowario/wownero:dev-v0.9 into master
Reviewed-on: https://git.wownero.com/wownero/wownero/pulls/330
2020-09-26 02:54:04 +00:00
wowario
86f12066f2 cryptonote_protocol: don't synced pruned blocks before HF_VERSION_SMALLER_BP 2020-09-25 13:26:25 +03:00
jwinterm
c336e15f0c Merge pull request 'rpc: Add unlock height to getblocktemplate' (#328) from asymptotically/wownero:getblocktemplate-height into master
Reviewed-on: https://git.wownero.com/wownero/wownero/pulls/328
2020-09-22 18:15:50 +00:00
jwinterm
e09d17ba1f Merge pull request 'wowify gitian 0.9' (#327) from qvqc/wownero:master into master
Reviewed-on: https://git.wownero.com/wownero/wownero/pulls/327
2020-09-22 18:14:09 +00:00
Matt Smith
9364b49ecb rpc: Add unlock height to getblocktemplate
Signed-off-by: Matt Smith <matt@offtopica.uk>
2020-09-22 18:11:34 +01:00
qvqc
5cd3a15491 wowify gitian 0.9 2020-09-22 12:10:26 -04:00
jwinterm
b303931b23 Merge pull request 'dev-v0.9' (#325) from dev-v0.9 into master
Reviewed-on: https://git.wownero.com/wownero/wownero/pulls/325
2020-09-22 15:15:44 +00:00
jwinterm
7b4e1b0859 Merge pull request 'nudge estimate_blockchain_height' (#324) from wowario/wownero:height into dev-v0.9
Reviewed-on: https://git.wownero.com/wownero/wownero/pulls/324
2020-09-22 14:57:43 +00:00
jwinterm
8fb16a3280 Merge pull request 'refactor diff' (#323) from wowario/wownero:diff into dev-v0.9
Reviewed-on: https://git.wownero.com/wownero/wownero/pulls/323
2020-09-22 14:57:24 +00:00
jwinterm
4e097c26a2 Merge pull request 'refactor difficulty_blocks_count and timestamp check' (#322) from wowario/wownero:dev-v0.9 into dev-v0.9
Reviewed-on: https://git.wownero.com/wownero/wownero/pulls/322
2020-09-22 14:56:59 +00:00
wowario
2aabc5863e nudge estimate_blockchain_height 2020-09-22 07:07:59 +03:00
wowario
2a6d817ea1 declare version 2020-09-21 23:47:19 +03:00
wowario
f6533856df refactor diff 2020-09-21 23:31:57 +03:00
wowario
32497a641c fix timestamp check 2020-09-20 23:06:54 +03:00
jwinterm
aaa015b3e7 Merge pull request 'rebase v0.9' (#321) from wowario/wownero:dev-v0.9 into dev-v0.9
Reviewed-on: https://git.wownero.com/wownero/wownero/pulls/321
2020-09-20 14:30:53 +00:00
wowario
9c35901592 testnet dynamic unlock 2020-09-20 14:56:00 +03:00
wowario
f9c0871877 set testnet 2020-09-20 08:00:06 +03:00
wowario
96d1d08f48 add fork height 2020-09-20 07:59:57 +03:00
wowario
2e8fae1b4c disable sanity_checks 2020-09-19 17:44:50 +03:00
wowario
d99c27e24d support old BP 2020-09-19 17:44:50 +03:00
qvqc
48eeca2077 update public and seed nodes 2020-09-19 17:44:50 +03:00
Matt Smith
96ae690083 cmake: Use job pool feature to limit concurrent jobs
Add two new options, WOWNERO_PARALLEL_COMPILE_JOBS and
WOWNERO_PARALLEL_LINK_JOBS to try and prevent running out of memory when
building everything.

Requires >= cmake 3.0.0, and the use of the Ninja generator.

Useful links:

* https://cmake.org/cmake/help/latest/prop_gbl/JOB_POOLS.html
* https://reviews.llvm.org/D6304
2020-09-19 17:44:50 +03:00
wowario
b9974f7bff Dynamic Unlock from HF 16 2020-09-19 17:44:50 +03:00
wowario
389a02d93f v0.9 ASCII art 2020-09-19 17:44:50 +03:00
Matt Smith
a3c9befbb5 utils: Add AppArmor profiles
Add AppArmor profiles to lock down daemon and cli wallet.
2020-09-19 17:44:49 +03:00
Matt Smith
08a0e737f9 readme: Add Gentoo install instructions 2020-09-19 17:44:49 +03:00
Suzyo Nyirenda
1396426d59 update ppa keyserver keys 2020-09-19 17:44:49 +03:00
qvqc
93cc82423e WOW'up translations 2020-09-19 17:44:49 +03:00
wowario
572d7ea5ef initial commit 2020-09-19 17:44:34 +03:00
415 changed files with 286344 additions and 13366 deletions

10
.drone.yml Normal file
View File

@@ -0,0 +1,10 @@
---
kind: pipeline
type: docker
name: linux-build
steps:
- name: linux-build
image: wownero/wow-dependencies:v1.0
commands:
- make -j2 release-static-linux-x86_64

1
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1 @@
custom: https://dev-funding.webui.wowkira.com

View File

@@ -1,44 +1,21 @@
name: ci/gh-actions/cli
name: continuous-integration/gh-actions/cli
on: [push, pull_request]
# The below variables reduce repetitions across similar targets
env:
REMOVE_BUNDLED_BOOST : rm -rf /usr/local/share/boost
APT_INSTALL_LINUX: '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 libprotobuf-dev protobuf-compiler ccache'
APT_SET_CONF: |
echo "Acquire::Retries \"3\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
echo "Acquire::http::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
echo "Acquire::ftp::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
jobs:
build-macos:
runs-on: macOS-latest
env:
CCACHE_COMPRESS: 1
CCACHE_TEMPDIR: /tmp/.ccache-temp
steps:
- uses: actions/checkout@v1
with:
submodules: recursive
- uses: actions/cache@v2
with:
path: /Users/runner/Library/Caches/ccache
key: ccache-macos-build-${{ github.sha }}
restore-keys: ccache-macos-build-
- name: install dependencies
run: HOMEBREW_NO_AUTO_UPDATE=1 brew install boost hidapi zmq libpgm miniupnpc ldns expat libunwind-headers protobuf ccache
- name: update brew and install dependencies
run: brew update && brew install boost hidapi zmq libpgm miniupnpc ldns expat libunwind-headers protobuf
- name: build
run: |
ccache --max-size=150M
make -j3
run: make -j3
build-windows:
runs-on: windows-latest
env:
CCACHE_COMPRESS: 1
CCACHE_TEMPDIR: C:\Users\runneradmin\.ccache-temp
CCACHE_DIR: C:\Users\runneradmin\.ccache
defaults:
run:
shell: msys2 {0}
@@ -46,128 +23,74 @@ jobs:
- uses: actions/checkout@v1
with:
submodules: recursive
- uses: actions/cache@v2
with:
path: C:\Users\runneradmin\.ccache
key: ccache-windows-build-${{ github.sha }}
restore-keys: ccache-windows-build-
- uses: eine/setup-msys2@v2
- uses: eine/setup-msys2@v1
with:
update: true
install: mingw-w64-x86_64-toolchain make mingw-w64-x86_64-cmake mingw-w64-x86_64-ccache 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
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: |
ccache --max-size=150M
make release-static-win64 -j2
run: make release-static-win64 -j2
build-ubuntu:
runs-on: ubuntu-latest
env:
CCACHE_COMPRESS: 1
CCACHE_TEMPDIR: /tmp/.ccache-temp
steps:
- uses: actions/checkout@v1
with:
submodules: recursive
- uses: actions/cache@v2
with:
path: ~/.ccache
key: ccache-ubuntu-build-${{ github.sha }}
restore-keys: ccache-ubuntu-build-
- name: remove bundled boost
run: ${{env.REMOVE_BUNDLED_BOOST}}
run: sudo rm -rf /usr/local/share/boost
- name: set apt conf
run: ${{env.APT_SET_CONF}}
run: |
echo "Acquire::Retries \"3\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
echo "Acquire::http::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
echo "Acquire::ftp::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
- name: update apt
run: sudo apt update
- name: install monero dependencies
run: ${{env.APT_INSTALL_LINUX}}
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 libprotobuf-dev protobuf-compiler
- name: build
run: |
ccache --max-size=150M
make -j3
run: make -j3
libwallet-ubuntu:
runs-on: ubuntu-latest
env:
CCACHE_COMPRESS: 1
CCACHE_TEMPDIR: /tmp/.ccache-temp
steps:
- uses: actions/checkout@v1
with:
submodules: recursive
- uses: actions/cache@v2
with:
path: ~/.ccache
key: ccache-ubuntu-libwallet-${{ github.sha }}
restore-keys: ccache-ubuntu-libwallet-
- name: remove bundled boost
run: ${{env.REMOVE_BUNDLED_BOOST}}
run: sudo rm -rf /usr/local/share/boost
- name: set apt conf
run: ${{env.APT_SET_CONF}}
run: |
echo "Acquire::Retries \"3\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
echo "Acquire::http::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
echo "Acquire::ftp::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
- name: update apt
run: sudo apt update
- name: install monero dependencies
run: ${{env.APT_INSTALL_LINUX}}
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 libprotobuf-dev protobuf-compiler
- name: build
run: |
ccache --max-size=150M
cmake -DBUILD_GUI_DEPS=ON
make -j3
run: cmake -DBUILD_GUI_DEPS=ON && make -j3
test-ubuntu:
needs: build-ubuntu
runs-on: ubuntu-latest
env:
CCACHE_COMPRESS: 1
CCACHE_TEMPDIR: /tmp/.ccache-temp
steps:
- uses: actions/checkout@v1
with:
submodules: recursive
- name: ccache
uses: actions/cache@v2
with:
path: ~/.ccache
key: test-ubuntu-ccache-${{ github.sha }}
restore-keys: test-ubuntu-ccache-
- name: remove bundled boost
run: ${{env.REMOVE_BUNDLED_BOOST}}
run: sudo rm -rf /usr/local/share/boost
- name: set apt conf
run: ${{env.APT_SET_CONF}}
run: |
echo "Acquire::Retries \"3\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
echo "Acquire::http::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
echo "Acquire::ftp::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
- name: update apt
run: sudo apt update
- name: install monero dependencies
run: ${{env.APT_INSTALL_LINUX}}
- name: install Python dependencies
run: pip install requests psutil monotonic
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 libprotobuf-dev protobuf-compiler
- name: install requests
run: pip install requests
- name: tests
env:
CTEST_OUTPUT_ON_FAILURE: ON
run: |
ccache --max-size=150M
DIR_BUILD="build/ci/release"
DIR_SRC="`pwd`"
mkdir -p "${DIR_BUILD}" && cd "${DIR_BUILD}"
cmake -S "${DIR_SRC}" -D ARCH="default" -D BUILD_SHARED_LIBS=ON -D BUILD_TESTS=ON -D CMAKE_BUILD_TYPE=release && make -j3 && make test
# ARCH="default" (not "native") ensures, that a different execution host can execute binaries compiled elsewhere.
# BUILD_SHARED_LIBS=ON speeds up the linkage part a bit, reduces size, and is the only place where the dynamic linkage is tested.
source-archive:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v1
with:
submodules: recursive
- name: archive
run: |
pip install git-archive-all
export VERSION="monero-$(git describe)"
export OUTPUT="$VERSION.tar"
echo "OUTPUT=$OUTPUT" >> $GITHUB_ENV
/home/runner/.local/bin/git-archive-all --prefix "$VERSION/" --force-submodules "$OUTPUT"
- uses: actions/upload-artifact@v2
with:
name: ${{ env.OUTPUT }}
path: /home/runner/work/monero/monero/${{ env.OUTPUT }}
run: make release-test -j3

View File

@@ -1,85 +0,0 @@
name: ci/gh-actions/depends
on: [push, pull_request]
jobs:
build-macos:
runs-on: ubuntu-18.04
env:
CCACHE_COMPRESS: 1
CCACHE_TEMPDIR: /tmp/.ccache-temp
strategy:
fail-fast: false
matrix:
toolchain:
- name: "RISCV 64bit"
host: "riscv64-linux-gnu"
packages: "python3 gperf g++-riscv64-linux-gnu"
- name: "ARM v7"
host: "arm-linux-gnueabihf"
packages: "python3 gperf g++-arm-linux-gnueabihf"
- name: "ARM v8"
host: "aarch64-linux-gnu"
packages: "python3 gperf g++-aarch64-linux-gnu"
- name: "i686 Win"
host: "i686-w64-mingw32"
packages: "python3 g++-mingw-w64-i686 qttools5-dev-tools"
- name: "i686 Linux"
host: "i686-pc-linux-gnu"
packages: "gperf cmake g++-multilib python3-zmq"
- name: "Win64"
host: "x86_64-w64-mingw32"
packages: "cmake python3 g++-mingw-w64-x86-64 qttools5-dev-tools"
- name: "x86_64 Linux"
host: "x86_64-unknown-linux-gnu"
packages: "gperf cmake python3-zmq libdbus-1-dev libharfbuzz-dev"
- name: "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"
- name: "x86_64 Freebsd"
host: "x86_64-unknown-freebsd"
packages: "clang-8 gperf cmake python3-zmq libdbus-1-dev libharfbuzz-dev"
name: ${{ matrix.toolchain.name }}
steps:
- uses: actions/checkout@v1
with:
submodules: recursive
- name: ccache
uses: actions/cache@v2
with:
path: |
~/.ccache
contrib/depends/built
contrib/depends/sdk-sources
key: ccache-${{ matrix.toolchain.host }}-${{ github.sha }}
restore-keys: ccache-${{ matrix.toolchain.host }}-
- name: set apt conf
run: |
echo "Acquire::Retries \"3\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
echo "Acquire::http::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
echo "Acquire::ftp::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
- name: install dependencies
run: sudo apt update; sudo apt -y install build-essential libtool cmake autotools-dev automake pkg-config bsdmainutils curl git ca-certificates ccache ${{ matrix.toolchain.packages }}
- name: prepare apple-darwin11
if: ${{ matrix.toolchain.host == 'x86_64-apple-darwin11' }}
run: |
mkdir -p contrib/depends/SDKs contrib/depends/sdk-sources
if [ ! -f contrib/depends/sdk-sources/MacOSX${{ matrix.toolchain.osx_sdk }}.sdk.tar.gz ]; then curl --location --fail https://bitcoincore.org/depends-sources/sdks/MacOSX${{ matrix.toolchain.osx_sdk }}.sdk.tar.gz -o contrib/depends/sdk-sources/MacOSX${{ matrix.toolchain.osx_sdk }}.sdk.tar.gz; fi
if [ -f contrib/depends/sdk-sources/MacOSX${{ matrix.toolchain.osx_sdk }}.sdk.tar.gz ]; then tar -C contrib/depends/SDKs -xf contrib/depends/sdk-sources/MacOSX${{ matrix.toolchain.osx_sdk }}.sdk.tar.gz; fi
- name: prepare w64-mingw32
if: ${{ matrix.toolchain.host == 'x86_64-w64-mingw32' || matrix.toolchain.host == 'i686-w64-mingw32' }}
run: |
sudo update-alternatives --set ${{ matrix.toolchain.host }}-g++ $(which ${{ matrix.toolchain.host }}-g++-posix)
sudo update-alternatives --set ${{ matrix.toolchain.host }}-gcc $(which ${{ matrix.toolchain.host }}-gcc-posix)
- name: build
run: |
ccache --max-size=150M
make depends target=${{ matrix.toolchain.host }} -j2
- uses: actions/upload-artifact@v2
if: ${{ matrix.toolchain.host == 'x86_64-w64-mingw32' || matrix.toolchain.host == 'x86_64-apple-darwin11' || matrix.toolchain.host == 'x86_64-unknown-linux-gnu' }}
with:
name: ${{ matrix.toolchain.name }}
path: |
/home/runner/work/monero/monero/build/${{ matrix.toolchain.host }}/release/bin/monero-wallet-cli*
/home/runner/work/monero/monero/build/${{ matrix.toolchain.host }}/release/bin/monerod*

3
.gitignore vendored
View File

@@ -23,7 +23,6 @@ cscope.po.out
external/miniupnpc/Makefile
miniupnpcstrings.h
version/
ClangBuildAnalyzerSession.txt
# Created by https://www.gitignore.io
### C++ ###
@@ -110,5 +109,3 @@ nbproject
/testnet
__pycache__/
*.pyc
*.log

17
.gitmodules vendored
View File

@@ -1,18 +1,19 @@
[submodule "external/unbound"]
path = external/unbound
url = https://github.com/monero-project/unbound
url = https://git.wownero.com/wownero/unbound
branch = monero
[submodule "external/miniupnp"]
path = external/miniupnp
url = https://github.com/miniupnp/miniupnp
url = https://git.wownero.com/wownero/miniupnp
branch = monero
[submodule "external/rapidjson"]
path = external/rapidjson
url = https://github.com/Tencent/rapidjson
[submodule "external/supercop"]
path = external/supercop
url = https://github.com/monero-project/supercop
branch = monero
url = https://git.wownero.com/wownero/rapidjson
[submodule "external/RandomWOW"]
path = external/RandomWOW
url = https://git.wownero.com/wownero/RandomWOW
branch = 1.1.9-wow
branch = 1.1.8-wow
[submodule "external/supercop"]
path = external/supercop
url = https://git.wownero.com/wownero/supercop
branch = monero

66
.travis.yml Normal file
View File

@@ -0,0 +1,66 @@
sudo: required
dist: trusty
os: linux
language: minimal
cache:
directories:
- contrib/depends/built
- contrib/depends/sdk-sources
- $HOME/.ccache
env:
global:
- MAKEJOBS=-j3
- CCACHE_SIZE=100M
- CCACHE_TEMPDIR=/tmp/.ccache-temp
- CCACHE_COMPRESS=1
- CCACHE_DIR=$HOME/.ccache
- BASE_OUTDIR=$TRAVIS_BUILD_DIR/out
- SDK_URL=https://bitcoincore.org/depends-sources/sdks
- DOCKER_PACKAGES="build-essential libtool cmake autotools-dev automake pkg-config bsdmainutils curl git ca-certificates ccache"
matrix:
# RISCV 64bit
- HOST=riscv64-linux-gnu PACKAGES="python3 gperf g++-riscv64-linux-gnu"
# ARM v7
- HOST=arm-linux-gnueabihf PACKAGES="python3 gperf g++-arm-linux-gnueabihf"
# ARM v8
- HOST=aarch64-linux-gnu PACKAGES="python3 gperf g++-aarch64-linux-gnu"
# i686 Win
- HOST=i686-w64-mingw32 DEP_OPTS="NO_QT=1" PACKAGES="python3 g++-mingw-w64-i686 qttools5-dev-tools" MAKEJOBS=-j2
# i686 Linux
- HOST=i686-pc-linux-gnu PACKAGES="gperf cmake g++-multilib python3-zmq"
# Win64
- HOST=x86_64-w64-mingw32 DEP_OPTS="NO_QT=1" PACKAGES="cmake python3 g++-mingw-w64-x86-64 qttools5-dev-tools"
# x86_64 Linux
- 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")
install:
- env | grep -E '^(CCACHE_|DISPLAY|CONFIG_SHELL)' | tee /tmp/env
- if [[ $HOST = *-mingw32 ]]; then DOCKER_ADMIN="--cap-add SYS_ADMIN"; fi
- DOCKER_ID=$(docker run $DOCKER_ADMIN -idt --mount type=bind,src=$TRAVIS_BUILD_DIR,dst=$TRAVIS_BUILD_DIR --mount type=bind,src=$CCACHE_DIR,dst=$CCACHE_DIR -w $TRAVIS_BUILD_DIR --env-file /tmp/env ubuntu:18.04)
- DOCKER_EXEC="docker exec $DOCKER_ID"
- if [ -n "$DPKG_ADD_ARCH" ]; then $DOCKER_EXEC dpkg --add-architecture "$DPKG_ADD_ARCH" ; fi
- travis_retry $DOCKER_EXEC apt-get update
- travis_retry $DOCKER_EXEC apt-get install --no-install-recommends --no-upgrade -qq $PACKAGES $DOCKER_PACKAGES
before_script:
- mkdir -p contrib/depends/SDKs contrib/depends/sdk-sources
- if [ -n "$OSX_SDK" -a ! -f contrib/depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then curl --location --fail $SDK_URL/MacOSX${OSX_SDK}.sdk.tar.gz -o contrib/depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi
- if [ -n "$OSX_SDK" -a -f contrib/depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then tar -C contrib/depends/SDKs -xf contrib/depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi
- if [[ $HOST = *-mingw32 ]]; then $DOCKER_EXEC bash -c "update-alternatives --set $HOST-g++ \$(which $HOST-g++-posix)"; fi
- if [[ $HOST = *-mingw32 ]]; then $DOCKER_EXEC bash -c "update-alternatives --set $HOST-gcc \$(which $HOST-gcc-posix)"; fi
- if [ -z "$NO_DEPENDS" ]; then $DOCKER_EXEC bash -c "make $MAKEJOBS -C contrib/depends HOST=$HOST $DEP_OPTS"; fi
script:
- git submodule init && git submodule update
- export TRAVIS_COMMIT_LOG=`git log --format=fuller -1`
- OUTDIR=$BASE_OUTDIR/$TRAVIS_PULL_REQUEST/$TRAVIS_JOB_NUMBER-$HOST
- if [ -z "$NO_DEPENDS" ]; then $DOCKER_EXEC ccache --max-size=$CCACHE_SIZE; fi
- $DOCKER_EXEC bash -c "mkdir build && cd build && cmake -DCMAKE_TOOLCHAIN_FILE=$TRAVIS_BUILD_DIR/contrib/depends/$HOST/share/toolchain.cmake .. && make $MAKEJOBS"
- export LD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/contrib/depends/$HOST/lib
after_script:
- echo $TRAVIS_COMMIT_RANGE
- echo $TRAVIS_COMMIT_LOG

View File

@@ -36,6 +36,10 @@ with additional exclusive IPv4 address(es).
## Usage
Anonymity networks have no seed nodes (the feature is still considered
experimental), so a user must specify an address. If configured properly,
additional peers can be found through typical p2p peerlist sharing.
### Outbound Connections
Connecting to an anonymous address requires the command line option
@@ -50,9 +54,8 @@ separate process. On most systems the configuration will look like:
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
".b32.i2p" p2p addresses can be forwarded to a socks proxy at IP 127.0.0.1 port
9000 with the default max outgoing connections.
If desired, peers can be manually specified:
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

View File

@@ -43,7 +43,7 @@ if (IOS)
INCLUDE(CmakeLists_IOS.txt)
endif()
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 2.8.7)
message(STATUS "CMake version ${CMAKE_VERSION}")
project(monero)
@@ -54,41 +54,6 @@ if (USE_CCACHE)
else()
message(STATUS "ccache deselected")
endif()
option (USE_COMPILATION_TIME_PROFILER "Use compilation time profiler (for CLang >= 9 only)" OFF)
if (USE_COMPILATION_TIME_PROFILER)
if (NOT "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
message(FATAL_ERROR "The flag USE_COMPILATION_TIME_PROFILER is meant to be set only for CLang compiler!")
endif()
add_compile_options("-ftime-trace")
endif()
if (${CMAKE_VERSION} VERSION_GREATER "3.0.0" AND CMAKE_MAKE_PROGRAM MATCHES "ninja")
set(MONERO_PARALLEL_COMPILE_JOBS "" CACHE STRING "The maximum number of concurrent compilation jobs.")
if (MONERO_PARALLEL_COMPILE_JOBS)
set_property(GLOBAL APPEND PROPERTY JOB_POOLS compile_job_pool=${MONERO_PARALLEL_COMPILE_JOBS})
set(CMAKE_JOB_POOL_COMPILE compile_job_pool)
endif ()
set(MONERO_PARALLEL_LINK_JOBS "" CACHE STRING "The maximum number of concurrent link jobs.")
if (MONERO_PARALLEL_LINK_JOBS)
set_property(GLOBAL APPEND PROPERTY JOB_POOLS link_job_pool=${MONERO_PARALLEL_LINK_JOBS})
set(CMAKE_JOB_POOL_LINK link_job_pool)
endif ()
endif ()
option (USE_CLANG_TIDY_C "Lint the code with clang-tidy - variant C" OFF)
option (USE_CLANG_TIDY_CXX "Lint the code with clang-tidy - variant C++" OFF)
if (USE_CLANG_TIDY_C AND USE_CLANG_TIDY_CXX)
message(FATAL_ERROR "Enabling both USE_CLANG_TIDY_C and USE_CLANG_TIDY_CXX simultaneously crashes clang-tidy.")
endif()
if (USE_CLANG_TIDY_C OR USE_CLANG_TIDY_CXX)
include(SetClangTidy)
endif()
if (USE_CLANG_TIDY_C)
monero_clang_tidy("C")
elseif (USE_CLANG_TIDY_CXX)
monero_clang_tidy("CXX")
endif()
# Job pool feature requires Ninja.
if (${CMAKE_VERSION} VERSION_GREATER "3.0.0")
@@ -161,48 +126,6 @@ function (add_definition_if_library_exists library function header var)
endif()
endfunction()
option(RELINK_TARGETS "Relink targets, when just a dependant .so changed, but not its header?" OFF)
function (monero_set_target_no_relink target)
if (RELINK_TARGETS MATCHES OFF)
# Will not relink the target, when just its dependant .so has changed, but not it's interface
set_target_properties("${target}" PROPERTIES LINK_DEPENDS_NO_SHARED true)
endif()
endfunction()
option(STRIP_TARGETS "Strip symbols from targets?" OFF)
function (monero_set_target_strip target)
if (STRIP_TARGETS)
set_target_properties("${target}" PROPERTIES LINK_FLAGS_RELEASE -s)
set_target_properties("${target}" PROPERTIES LINK_FLAGS_DEBUG -s)
# Stripping from Debug might make sense if you're low on disk space, but want to test if debug version builds properly.
endif()
endfunction()
function (monero_add_minimal_executable name)
source_group("${name}"
FILES
${ARGN})
add_executable("${name}"
${ARGN})
monero_set_target_no_relink("${name}")
monero_set_target_strip ("${name}")
endfunction()
# Finds all headers in a directory and its subdirs, to be able to search for them and autosave in IDEs.
#
# Parameters:
# - headers_found: Output variable, which will hold the found headers
# - module_root_dir: The search path for the headers. Typically it will be the module's root dir, so "${CMAKE_CURRENT_SOURCE_DIR}" or a derivative of it.
macro (monero_find_all_headers headers_found module_root_dir)
file(GLOB ${headers_found}
"${module_root_dir}/*.h*" # h* will include hpps as well.
"${module_root_dir}/**/*.h*" # Any number of subdirs will be included.
"${module_root_dir}/*.inl" # .inl is typically template code and is being treated as headers (it's being included).
"${module_root_dir}/**/*.inl"
)
endmacro()
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)
message(STATUS "Setting default build type: ${CMAKE_BUILD_TYPE}")
@@ -531,7 +454,7 @@ if (CMAKE_SYSTEM_NAME MATCHES "(SunOS|Solaris)")
endif ()
if (APPLE AND NOT IOS)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=default -std=c++11")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=x86-64 -fvisibility=default -std=c++11")
if (NOT OPENSSL_ROOT_DIR)
EXECUTE_PROCESS(COMMAND brew --prefix openssl
OUTPUT_VARIABLE OPENSSL_ROOT_DIR
@@ -560,44 +483,6 @@ add_definitions(-DAUTO_INITIALIZE_EASYLOGGINGPP)
set(MONERO_GENERATED_HEADERS_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated_include")
include_directories(${MONERO_GENERATED_HEADERS_DIR})
option(COVERAGE "Enable profiling for test coverage report" OFF)
if(COVERAGE)
message(STATUS "Building with profiling for test coverage report")
endif()
macro (monero_enable_coverage)
if(COVERAGE)
foreach(COV_FLAG -fprofile-arcs -ftest-coverage --coverage)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COV_FLAG}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COV_FLAG}")
endforeach()
endif()
endmacro()
function (monero_add_library name)
monero_add_library_with_deps(NAME "${name}" SOURCES ${ARGN})
endfunction()
function (monero_add_library_with_deps)
cmake_parse_arguments(MONERO_ADD_LIBRARY "" "NAME" "DEPENDS;SOURCES" ${ARGN})
source_group("${MONERO_ADD_LIBRARY_NAME}" FILES ${MONERO_ADD_LIBRARY_SOURCES})
# Define a ("virtual") object library and an actual library that links those
# objects together. The virtual libraries can be arbitrarily combined to link
# any subset of objects into one library archive. This is used for releasing
# libwallet, which combines multiple components.
set(objlib obj_${MONERO_ADD_LIBRARY_NAME})
add_library(${objlib} OBJECT ${MONERO_ADD_LIBRARY_SOURCES})
add_library("${MONERO_ADD_LIBRARY_NAME}" $<TARGET_OBJECTS:${objlib}>)
monero_set_target_no_relink("${MONERO_ADD_LIBRARY_NAME}")
monero_set_target_strip ("${MONERO_ADD_LIBRARY_NAME}")
if (MONERO_ADD_LIBRARY_DEPENDS)
add_dependencies(${objlib} ${MONERO_ADD_LIBRARY_DEPENDS})
endif()
set_property(TARGET "${MONERO_ADD_LIBRARY_NAME}" PROPERTY FOLDER "libs")
target_compile_definitions(${objlib}
PRIVATE $<TARGET_PROPERTY:${MONERO_ADD_LIBRARY_NAME},INTERFACE_COMPILE_DEFINITIONS>)
endfunction ()
# Generate header for embedded translations
# Generate header for embedded translations, use target toolchain if depends, otherwise use the
# lrelease and lupdate binaries from the host
@@ -607,7 +492,7 @@ ExternalProject_Add(generate_translations_header
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/translations"
STAMP_DIR ${LRELEASE_PATH}
CMAKE_ARGS -DLRELEASE_PATH=${LRELEASE_PATH}
INSTALL_COMMAND ${CMAKE_COMMAND} -E echo "")
INSTALL_COMMAND cmake -E echo "")
include_directories("${CMAKE_CURRENT_BINARY_DIR}/translations")
add_subdirectory(external)
@@ -639,17 +524,6 @@ endif()
# Trezor support check
include(CheckTrezor)
# As of OpenBSD 6.8, -march=<anything> breaks the build
function(set_default_arch)
if (OPENBSD)
set(ARCH default)
else()
set(ARCH native)
endif()
set(ARCH ${ARCH} CACHE STRING "CPU to build for: -march value or 'default' to not pass -march at all")
endfunction()
if(MSVC)
add_definitions("/bigobj /MP /W3 /GS- /D_CRT_SECURE_NO_WARNINGS /wd4996 /wd4345 /D_WIN32_WINNT=0x0600 /DWIN32_LEAN_AND_MEAN /DGTEST_HAS_TR1_TUPLE=0 /FIinline_c.h /D__SSE4_1__")
# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Dinline=__inline")
@@ -663,7 +537,7 @@ if(MSVC)
else()
include(TestCXXAcceptsFlag)
if (NOT ARCH)
set_default_arch()
set(ARCH native CACHE STRING "CPU to build for: -march value or 'default' to not pass -march at all")
endif()
message(STATUS "Building on ${CMAKE_SYSTEM_PROCESSOR} for ${ARCH}")
if(ARCH STREQUAL "default")
@@ -725,8 +599,8 @@ else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ARCH_FLAG}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARCH_FLAG}")
set(WARNINGS "-Wall -Wextra -Wpointer-arith -Wundef -Wvla -Wwrite-strings -Wno-error=extra -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-error=unused-variable -Wno-error=undef -Wno-error=uninitialized")
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
set(WARNINGS "-Wall -Wextra -Wpointer-arith -Wundef -Wvla -Wwrite-strings -Wno-error=extra -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-unused-variable -Wno-error=unused-variable -Wno-error=undef -Wno-error=uninitialized")
if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
if(ARM)
set(WARNINGS "${WARNINGS} -Wno-error=inline-asm")
endif()
@@ -761,7 +635,13 @@ else()
set(STATIC_ASSERT_CPP_FLAG "-Dstatic_assert=_Static_assert")
endif()
monero_enable_coverage()
option(COVERAGE "Enable profiling for test coverage report" 0)
if(COVERAGE)
message(STATUS "Building with profiling for test coverage report")
set(COVERAGE_FLAGS "-fprofile-arcs -ftest-coverage --coverage")
endif()
# With GCC 6.1.1 the compiled binary malfunctions due to aliasing. Until that
# is fixed in the code (Issue #847), force compiler to be conservative.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-strict-aliasing")
@@ -804,16 +684,10 @@ else()
endif()
# linker
if (NOT SANITIZE AND NOT OSSFUZZ AND NOT (WIN32 AND (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND (CMAKE_C_COMPILER_VERSION VERSION_LESS 9.1 OR NOT STATIC))))
if (NOT SANITIZE AND NOT OSSFUZZ AND NOT (WIN32 AND (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_LESS 9.1)))
# PIE executables randomly crash at startup with ASAN
# Windows binaries die on startup with PIE when compiled with GCC <9.x
# Windows dynamically-linked binaries die on startup with PIE regardless of GCC version
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
# Clang does not support -pie flag
add_linker_flag_if_supported("-Wl,-pie" LD_SECURITY_FLAGS)
else()
add_linker_flag_if_supported("-pie" LD_SECURITY_FLAGS)
endif()
add_linker_flag_if_supported(-pie LD_SECURITY_FLAGS)
endif()
add_linker_flag_if_supported(-Wl,-z,relro LD_SECURITY_FLAGS)
add_linker_flag_if_supported(-Wl,-z,now LD_SECURITY_FLAGS)
@@ -839,19 +713,12 @@ else()
add_linker_flag_if_supported(-Wl,--high-entropy-va LD_SECURITY_FLAGS)
endif()
# Warnings, that when ignored are so severe, that they can segfault or even UB any application.
# Treat them as errors.
add_c_flag_if_supported( -Werror=switch C_SECURITY_FLAGS)
add_cxx_flag_if_supported(-Werror=switch CXX_SECURITY_FLAGS)
add_c_flag_if_supported( -Werror=return-type C_SECURITY_FLAGS)
add_cxx_flag_if_supported(-Werror=return-type CXX_SECURITY_FLAGS)
message(STATUS "Using C security hardening flags: ${C_SECURITY_FLAGS}")
message(STATUS "Using C++ security hardening flags: ${CXX_SECURITY_FLAGS}")
message(STATUS "Using linker security hardening flags: ${LD_SECURITY_FLAGS}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -D_GNU_SOURCE ${MINGW_FLAG} ${STATIC_ASSERT_FLAG} ${WARNINGS} ${C_WARNINGS} ${PIC_FLAG} ${C_SECURITY_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -D_GNU_SOURCE ${MINGW_FLAG} ${STATIC_ASSERT_CPP_FLAG} ${WARNINGS} ${CXX_WARNINGS} ${PIC_FLAG} ${CXX_SECURITY_FLAGS}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -D_GNU_SOURCE ${MINGW_FLAG} ${STATIC_ASSERT_FLAG} ${WARNINGS} ${C_WARNINGS} ${COVERAGE_FLAGS} ${PIC_FLAG} ${C_SECURITY_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -D_GNU_SOURCE ${MINGW_FLAG} ${STATIC_ASSERT_CPP_FLAG} ${WARNINGS} ${CXX_WARNINGS} ${COVERAGE_FLAGS} ${PIC_FLAG} ${CXX_SECURITY_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${LD_SECURITY_FLAGS} ${LD_BACKCOMPAT_FLAGS}")
# With GCC 6.1.1 the compiled binary malfunctions due to aliasing. Until that
@@ -969,7 +836,7 @@ else()
endif()
set(USE_LTO ${USE_LTO_DEFAULT} CACHE BOOL "Use Link-Time Optimization (Release mode only)")
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# There is a clang bug that does not allow to compile code that uses AES-NI intrinsics if -flto is enabled, so explicitly disable
set(USE_LTO false)
endif()
@@ -1076,12 +943,10 @@ list(APPEND EXTRA_LIBRARIES ${CMAKE_DL_LIBS})
if (HIDAPI_FOUND OR LibUSB_COMPILE_TEST_PASSED)
if (APPLE)
if(DEPENDS)
list(APPEND EXTRA_LIBRARIES "-framework Foundation -framework AppKit -framework IOKit")
list(APPEND EXTRA_LIBRARIES "-framework Foundation -framework IOKit")
else()
find_library(COREFOUNDATION CoreFoundation)
find_library(APPKIT AppKit)
find_library(IOKIT IOKit)
list(APPEND EXTRA_LIBRARIES ${APPKIT})
list(APPEND EXTRA_LIBRARIES ${IOKIT})
list(APPEND EXTRA_LIBRARIES ${COREFOUNDATION})
endif()
@@ -1116,7 +981,7 @@ if(ANDROID)
set(ATOMIC libatomic.a)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=user-defined-warnings")
endif()
if(CMAKE_C_COMPILER_ID MATCHES "Clang" AND ARCH_WIDTH EQUAL "32" AND NOT IOS AND NOT FREEBSD)
if(CMAKE_C_COMPILER_ID STREQUAL "Clang" AND ARCH_WIDTH EQUAL "32" AND NOT IOS AND NOT FREEBSD)
find_library(ATOMIC atomic)
if (ATOMIC_FOUND)
list(APPEND EXTRA_LIBRARIES ${ATOMIC})

View File

@@ -1,18 +1,28 @@
# Multistage docker build, requires docker 17.05
ARG DEBIAN_VERSION="${DEBIAN_VERSION:-stable-slim}"
FROM debian:${DEBIAN_VERSION} as git-wow
# builder stage
FROM ubuntu:16.04 as builder
WORKDIR /data
RUN set -ex && \
apt-get update && \
apt-get --no-install-recommends --yes install \
#Cmake
ARG CMAKE_VERSION=3.14.6
ARG CMAKE_VERSION_DOT=v3.14
ARG CMAKE_HASH=4e8ea11cabe459308671b476469eace1622e770317a15951d7b55a82ccaaccb9
## Boost
ARG BOOST_VERSION=1_70_0
ARG BOOST_VERSION_DOT=1.70.0
ARG BOOST_HASH=430ae8354789de4fd19ee52f3b1f739e1fba576f0aded0897c3c2bc00fb38778
ENV CFLAGS='-fPIC -O2 -g'
ENV CXXFLAGS='-fPIC -O2 -g'
ENV LDFLAGS='-static-libstdc++'
ENV BASE_DIR /usr/local
RUN apt-get update -qq && apt-get --no-install-recommends -yqq install \
ca-certificates \
cmake \
g++ \
make \
pkg-config \
graphviz \
doxygen \
git \
curl \
libtool-bin \
@@ -21,191 +31,193 @@ RUN set -ex && \
bzip2 \
xsltproc \
gperf \
unzip
WORKDIR /usr/local
ENV CFLAGS='-fPIC'
ENV CXXFLAGS='-fPIC'
#Cmake
ARG CMAKE_VERSION=3.14.6
ARG CMAKE_VERSION_DOT=v3.14
ARG CMAKE_HASH=4e8ea11cabe459308671b476469eace1622e770317a15951d7b55a82ccaaccb9
RUN set -ex \
&& curl -s -O https://cmake.org/files/${CMAKE_VERSION_DOT}/cmake-${CMAKE_VERSION}.tar.gz \
unzip > /dev/null \
&& cd /data || exit 1 \
&& echo "\e[32mbuilding: Cmake\e[39m" \
&& set -ex \
&& curl -s -O https://cmake.org/files/${CMAKE_VERSION_DOT}/cmake-${CMAKE_VERSION}.tar.gz > /dev/null \
&& echo "${CMAKE_HASH} cmake-${CMAKE_VERSION}.tar.gz" | sha256sum -c \
&& tar -xzf cmake-${CMAKE_VERSION}.tar.gz \
&& cd cmake-${CMAKE_VERSION} \
&& ./configure \
&& make \
&& make install
## Boost
ARG BOOST_VERSION=1_70_0
ARG BOOST_VERSION_DOT=1.70.0
ARG BOOST_HASH=430ae8354789de4fd19ee52f3b1f739e1fba576f0aded0897c3c2bc00fb38778
RUN set -ex \
&& curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://downloads.sourceforge.net/project/boost/boost/${BOOST_VERSION_DOT}/boost_${BOOST_VERSION}.tar.bz2 \
&& tar -xzf cmake-${CMAKE_VERSION}.tar.gz > /dev/null \
&& cd cmake-${CMAKE_VERSION} || exit 1 \
&& echo "\e[32mmatrix style build text redirected to /dev/null. This will take some time. Go ahead make some coffee and check your emails.\e[39m" \
&& ./configure --prefix=$BASE_DIR > /dev/null \
&& make > /dev/null \
&& make install > /dev/null \
&& cd /data || exit 1 \
&& rm -rf /data/cmake-${CMAKE_VERSION} \
&& rm -rf /data/cmake-${CMAKE_VERSION}.tar.gz \
&& echo "\e[32mbuilding: Boost\e[39m" \
&& set -ex \
&& curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://dl.bintray.com/boostorg/release/${BOOST_VERSION_DOT}/source/boost_${BOOST_VERSION}.tar.bz2 > /dev/null \
&& echo "${BOOST_HASH} boost_${BOOST_VERSION}.tar.bz2" | sha256sum -c \
&& tar -xvf boost_${BOOST_VERSION}.tar.bz2 \
&& cd boost_${BOOST_VERSION} \
&& ./bootstrap.sh \
&& ./b2 --build-type=minimal link=static runtime-link=static --with-chrono --with-date_time --with-filesystem --with-program_options --with-regex --with-serialization --with-system --with-thread --with-locale threading=multi threadapi=pthread cflags="$CFLAGS" cxxflags="$CXXFLAGS" stage
ENV BOOST_ROOT /usr/local/boost_${BOOST_VERSION}
&& tar -xvf boost_${BOOST_VERSION}.tar.bz2 > /dev/null \
&& cd boost_${BOOST_VERSION} || exit 1 \
&& ./bootstrap.sh > /dev/null \
&& ./b2 -a install --prefix=$BASE_DIR --build-type=minimal link=static runtime-link=static --with-chrono --with-date_time --with-filesystem --with-program_options --with-regex --with-serialization --with-system --with-thread --with-locale threading=multi threadapi=pthread cflags="$CFLAGS" cxxflags="$CXXFLAGS" stage > /dev/null \
&& cd /data || exit 1 \
&& rm -rf /data/boost_${BOOST_VERSION} \
&& rm -rf /data/boost_${BOOST_VERSION}.tar.bz2
WORKDIR /data
ENV BASE_DIR /usr/local
# OpenSSL
ARG OPENSSL_VERSION=1.1.1i
ARG OPENSSL_HASH=e8be6a35fe41d10603c3cc635e93289ed00bf34b79671a3a4de64fcee00d5242
RUN set -ex \
&& curl -s -O https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz \
&& echo "${OPENSSL_HASH} openssl-${OPENSSL_VERSION}.tar.gz" | sha256sum -c \
&& tar -xzf openssl-${OPENSSL_VERSION}.tar.gz \
&& cd openssl-${OPENSSL_VERSION} \
&& ./Configure linux-x86_64 no-shared --static "$CFLAGS" \
&& make build_generated \
&& make libcrypto.a \
&& make install
ENV OPENSSL_ROOT_DIR=/usr/local/openssl-${OPENSSL_VERSION}
ARG OPENSSL_VERSION=1.1.1
ARG OPENSSL_FIX=g
ARG OPENSSL_HASH=ddb04774f1e32f0c49751e21b67216ac87852ceb056b75209af2443400636d46
# 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
RUN set -ex \
&& curl -s -O https://ftp.gnu.org/gnu/readline/readline-${READLINE_VERSION}.tar.gz \
&& echo "${READLINE_HASH} readline-${READLINE_VERSION}.tar.gz" | sha256sum -c \
&& tar -xzf readline-${READLINE_VERSION}.tar.gz \
&& cd readline-${READLINE_VERSION} \
&& ./configure \
&& make \
&& make install
# Sodium
ARG SODIUM_VERSION=1.0.18
ARG SODIUM_HASH=4f5e89fa84ce1d178a6765b8b46f2b6f91216677
RUN set -ex \
&& git clone https://github.com/jedisct1/libsodium.git -b ${SODIUM_VERSION} \
&& cd libsodium \
ENV CFLAGS='-fPIC -O2 -g'
ENV CXXFLAGS='-fPIC -O2 -g'
ENV LDFLAGS='-static-libstdc++'
RUN echo "\e[32mbuilding: Openssl\e[39m" \
&& set -ex \
&& curl -s -O https://www.openssl.org/source/openssl-${OPENSSL_VERSION}${OPENSSL_FIX}.tar.gz > /dev/null \
# && curl -s -O https://www.openssl.org/source/old/${OPENSSL_VERSION}/openssl-${OPENSSL_VERSION}${OPENSSL_FIX}.tar.gz > /dev/null \
&& echo "${OPENSSL_HASH} openssl-${OPENSSL_VERSION}${OPENSSL_FIX}.tar.gz" | sha256sum -c \
&& tar -xzf openssl-${OPENSSL_VERSION}${OPENSSL_FIX}.tar.gz > /dev/null \
&& cd openssl-${OPENSSL_VERSION}${OPENSSL_FIX} || exit 1 \
&& ./Configure --prefix=$BASE_DIR linux-x86_64 no-shared --static "$CFLAGS" > /dev/null \
&& make build_generated > /dev/null \
&& make libcrypto.a > /dev/null \
&& echo "\e[32mblah, blah, shared libraries from the glib, something, something. Don't worry about it.\e[39m" \
&& make install > /dev/null \
&& cd /data || exit 1 \
&& rm -rf /data/openssl-${OPENSSL_VERSION}${OPENSSL_FIX} \
&& rm -rf /data/openssl-${OPENSSL_VERSION}${OPENSSL_FIX}.tar.gz \
&& echo "\e[32mbuilding: ZMQ\e[39m" \
&& set -ex \
&& git clone --branch ${ZMQ_VERSION} --single-branch --depth 1 https://github.com/zeromq/libzmq.git > /dev/null \
&& cd libzmq || exit 1 \
&& test `git rev-parse HEAD` = ${ZMQ_HASH} || exit 1 \
&& ./autogen.sh > /dev/null \
&& ./configure --prefix=$BASE_DIR --enable-libunwind=no --enable-static --disable-shared > /dev/null \
&& make > /dev/null \
&& make install > /dev/null \
&& ldconfig > /dev/null \
&& cd /data || exit 1 \
&& rm -rf /data/libzmq \
&& echo "\e[32mbuilding: zmq.hpp\e[39m" \
&& set -ex \
&& git clone --branch ${CPPZMQ_VERSION} --single-branch --depth 1 https://github.com/zeromq/cppzmq.git > /dev/null \
&& cd cppzmq || exit 1 \
&& test `git rev-parse HEAD` = ${CPPZMQ_HASH} || exit 1 \
&& mv *.hpp $BASE_DIR/include \
&& cd /data || exit 1 \
&& rm -rf /data/cppzmq \
&& echo "\e[32mbuilding: Readline\e[39m" \
&& set -ex \
&& curl -s -O https://ftp.gnu.org/gnu/readline/readline-${READLINE_VERSION}.tar.gz > /dev/null \
&& echo "${READLINE_HASH} readline-${READLINE_VERSION}.tar.gz" | sha256sum -c \
&& tar -xzf readline-${READLINE_VERSION}.tar.gz > /dev/null \
&& cd readline-${READLINE_VERSION} || exit 1 \
&& ./configure --prefix=$BASE_DIR > /dev/null \
&& make > /dev/null \
&& make install > /dev/null \
&& cd /data || exit 1 \
&& rm -rf /data/readline-${READLINE_VERSION} \
&& rm -rf readline-${READLINE_VERSION}.tar.gz \
&& echo "\e[32mbuilding: Sodium\e[39m" \
&& set -ex \
&& git clone --branch ${SODIUM_VERSION} --single-branch --depth 1 https://github.com/jedisct1/libsodium.git > /dev/null \
&& cd libsodium || exit 1 \
&& test `git rev-parse HEAD` = ${SODIUM_HASH} || exit 1 \
&& ./autogen.sh \
&& ./configure \
&& make \
&& make check \
&& make install
&& ./configure --prefix=$BASE_DIR > /dev/null \
&& make > /dev/null \
&& make check > /dev/null \
&& make install > /dev/null \
&& cd /data || exit 1 \
&& rm -rf /data/libsodium
WORKDIR /data
ENV BASE_DIR /usr/local
# Udev
ARG UDEV_VERSION=v3.2.10
ARG UDEV_HASH=be7068512c7512fa67c64fbff3472ab140c277c8
RUN set -ex \
&& git clone https://github.com/gentoo/eudev -b ${UDEV_VERSION} \
&& cd eudev \
&& test `git rev-parse HEAD` = ${UDEV_HASH} || exit 1 \
&& ./autogen.sh \
&& ./configure --disable-gudev --disable-introspection --disable-hwdb --disable-manpages --disable-shared \
&& make \
&& make install
ARG UDEV_VERSION=v3.2.8
ARG UDEV_HASH=d69f3f28348123ab7fa0ebac63ec2fd16800c5e0
# 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 \
ENV CFLAGS='-fPIC -O2 -g'
ENV CXXFLAGS='-fPIC -O2 -g'
ENV LDFLAGS='-static-libstdc++'
RUN echo "\e[32mbuilding: Udev\e[39m" \
&& set -ex \
&& git clone --branch ${UDEV_VERSION} --single-branch --depth 1 https://github.com/gentoo/eudev > /dev/null \
&& cd eudev || exit 1 \
&& test `git rev-parse HEAD` = ${UDEV_HASH} || exit 1 \
&& ./autogen.sh \
&& ./configure --enable-static --disable-shared \
&& make \
&& make install \
&& ldconfig
WORKDIR /src
COPY . .
&& ./configure --prefix=$BASE_DIR --disable-gudev --disable-introspection --disable-hwdb --disable-manpages --disable-shared > /dev/null \
&& make > /dev/null \
&& make install > /dev/null \
&& cd /data || exit 1 \
&& rm -rf /data/eudev \
&& echo "\e[32mbuilding: Libusb. Ahh, a dependency that shouldn't have been included in the codebase. Hardware wallets are way overrated.\e[39m" \
&& set -ex \
&& git clone --branch ${USB_VERSION} --single-branch --depth 1 https://github.com/libusb/libusb.git > /dev/null \
&& cd libusb || exit 1 \
&& test `git rev-parse HEAD` = ${USB_HASH} || exit 1 \
&& ./autogen.sh > /dev/null \
&& ./configure --prefix=$BASE_DIR --disable-shared > /dev/null \
&& make > /dev/null \
&& make install > /dev/null \
&& cd /data || exit 1 \
&& rm -rf /data/libusb \
&& echo "\e[32mbuilding: Hidapi\e[39m" \
&& set -ex \
&& git clone --branch ${HIDAPI_VERSION} --single-branch --depth 1 https://github.com/signal11/hidapi > /dev/null \
&& cd hidapi || exit 1 \
&& test `git rev-parse HEAD` = ${HIDAPI_HASH} || exit 1 \
&& ./bootstrap \
&& ./configure --prefix=$BASE_DIR --enable-static --disable-shared > /dev/null \
&& make > /dev/null \
&& make install > /dev/null \
&& cd /data || exit 1 \
&& rm -rf /data/hidapi \
&& echo "\e[32mbuilding: Protobuf <- fuck you protobuf, you worthless piece of shit!\e[39m" \
&& set -ex \
&& git clone --branch ${PROTOBUF_VERSION} --single-branch --depth 1 https://github.com/protocolbuffers/protobuf > /dev/null \
&& cd protobuf || exit 1 \
&& test `git rev-parse HEAD` = ${PROTOBUF_HASH} || exit 1 \
&& git submodule update --init --recursive > /dev/null \
&& ./autogen.sh > /dev/null \
&& ./configure --prefix=$BASE_DIR --enable-static --disable-shared > /dev/null \
&& make > /dev/null \
&& make install > /dev/null \
&& ldconfig \
&& cd /data || exit 1 \
&& rm -rf /data/protobuf
WORKDIR /home
ENV USE_SINGLE_BUILDDIR=1
ARG NPROC
RUN set -ex && \
git submodule init && git submodule update && \
rm -rf build && \
if [ -z "$NPROC" ] ; \
then make -j$(nproc) release-static ; \
else make -j$NPROC release-static ; \
fi
# runtime stage
FROM ubuntu:16.04
RUN set -ex && \
apt-get update && \
apt-get --no-install-recommends --yes install ca-certificates && \
apt-get clean && \
rm -rf /var/lib/apt
COPY --from=builder /src/build/release/bin /usr/local/bin/
# 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
# Contains the blockchain
VOLUME /home/wownero/.wownero
# Generate your wallet via accessing the container and run:
# cd /wallet
# wownero-wallet-cli
VOLUME /wallet
EXPOSE 34567
EXPOSE 34568
# switch to user wownero
USER wownero
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"]
# Wownero
RUN echo "\e[32mbuilding: Wownero\e[39m" \
&& set -ex \
&& git clone https://git.wownero.com/wownero/wownero \
&& cd wownero \
&& make -j2 release-static-linux-x86_64 \
&& echo "\e[32mdone building Wownero, binaries located in: /home/wownero/build/release/bin\e[39m"

View File

@@ -68,7 +68,7 @@ OUTPUT_DIRECTORY = doc
# performance problems for the file system.
# The default value is: NO.
CREATE_SUBDIRS = YES
CREATE_SUBDIRS = NO
# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
# characters to appear in the names of generated files. If set to NO, non-ASCII
@@ -754,7 +754,7 @@ WARN_LOGFILE =
# spaces.
# Note: If this tag is empty the current directory is searched.
INPUT = .
INPUT = src
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
@@ -1552,7 +1552,7 @@ EXTRA_SEARCH_MAPPINGS =
# If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output.
# The default value is: YES.
GENERATE_LATEX = NO
GENERATE_LATEX = YES
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of

View File

@@ -10,7 +10,7 @@ extensibility.
One of the goals of this document is to clearly indicate what is being sent
"on the wire" to identify metadata that could de-anonymize users over I2P/Tor.
These issues will be addressed as they are found. See `ANONMITY_NETWORKS.md` in
the `docs` folder for any outstanding issues.
the top-level folder for any outstanding issues.
> This document does not currently list all data being sent by the monero
> protocol, that portion is a work-in-progress. Please take the time to do it

View File

@@ -1,4 +1,4 @@
Copyright (c) 2014-2021, The Monero Project
Copyright (c) 2014-2020, The Monero Project
All rights reserved.

64
PKGBUILD Normal file
View File

@@ -0,0 +1,64 @@
# Maintainer: wowario <wowario[at]protonmail[dot]com>
pkgname=wownero-git
pkgver=0.8.0.0
pkgrel=1
pkgdesc="Wownero: a fairly launched privacy-centric meme coin with no premine and a finite supply"
license=('BSD')
arch=('x86_64')
url="https://wownero.org/"
depends=('boost-libs' 'libunwind' 'openssl' 'readline' 'zeromq' 'pcsclite' 'hidapi' 'protobuf')
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')
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/RandomWOW.url "$srcdir/RandomWOW"
git submodule update
}
build() {
cd "${pkgname}"
mkdir -p build && cd build
cmake -D BUILD_TESTS=OFF -D CMAKE_BUILD_TYPE=release -D ARCH=default ../
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"
}
# vim: ts=2 sw=2 et:

View File

@@ -1,37 +1,51 @@
[![Build Status](https://ci.wownero.com/api/badges/wownero/wownero/status.svg)](https://ci.wownero.com/wownero/wownero)
# ~~Mo~~Wownero - Such privacy! Many coins! Wow! 🐕
Copyright (c) 2014-2021 The Monero Project.
Copyright (c) 2014-2020 The Monero Project.
Portions Copyright (c) 2012-2013 The Cryptonote developers.
## Resources
- IRC: [OFTC #wownero](https://webchat.oftc.net/?channels=wownero)
- Web: [wownero.org](https://wownero.org)
- Web: [wownero.org](http://wownero.org)
- Twitter: [@w0wn3r0](https://twitter.com/w0wn3r0)
- Reddit: [/r/wownero](https://www.reddit.com/r/wownero)
- Mail: [wownero@protonmail.com](mailto:wownero@protonmail.com)
- Git: [git.wownero.com/wownero/wownero](https://git.wownero.com/wownero/wownero)
- GitHub: [git.wownero.com/wownero/wownero](https://git.wownero.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: [funding.wownero.com](https://funding.wownero.com)
- Wownero Forum: [forum.wownero.com](https://forum.wownero.com)
- Discord: [discord.gg/ykZyAzJhDK](https://discord.com/invite/ykZyAzJhDK)
- Discord: [discord.gg/DSC9TWx](https://discord.gg/DSC9TWx)
- Telegram: [t.me/wownero](https://t.me/wownero)
- Wowlet Desktop Wallet: [git.wownero.com/wowlet/wowlet](https://git.wownero.com/wowlet/wowlet/releases)
- Feather-WOW Desktop Wallet: [featherwallet.org/wownero](https://featherwallet.org/wownero)
- WOW Stash Web Wallet: [wowstash.app](https://wowstash.app)
- Public Node Status: [monero.fail](https://monero.fail/?crypto=wownero)
- Map of Nodes: [wownero.fyi](https://wownero.fyi)
- Wownero Memes: [suchwow.xyz](https://suchwow.xyz/posts/top)
- XMR/WOW Swap: [nero Swap](https://neroswap.com)
- Mining Pools: [miningpoolstats.stream](https://miningpoolstats.stream/wownero)
- Market Info: [coinmarketcap.com](https://coinmarketcap.com/currencies/wownero), [coingecko.com](https://www.coingecko.com/en/coins/wownero/usd)
### Blockchain Explorers
- https://explore.wownero.com
- http://wow5eqtzqvsg5jctqzg5g7uk3u62sfqiacj5x6lo4by7bvnj6jkvubyd.onion
- https://wownero.club
- https://explorer.wownero.fyi
### Free Public Nodes
- global.wownodes.com:34568 (Global)
- node.suchwow.xyz:34568 (US)
- wow.pwned.systems:34568 (NL)
- wowbux.org:34568 (CA)
- super.fast.node.xmr.pm:34568 (DE)
- wow.pwned.systems (NL)
- wowbuxx535x4exuexja2xfezpwcyznxkofui4ndjiectj4yuh2xheiid.onion:34568
### Tor Peers
- wowp2p5gelm6vhl2d5tvfqills63jilgy6hkvlrqljooov5ktaxgqdad.onion
- f3moshycuklu3mb3wnlfjwn26nsgzreqtfzfuyjjk46u7jqxlhf7d5id.onion
## Introduction
## INCOMING ALIEN TRANSMISSION
do this:
sudo apt update && sudo apt install build-essential cmake pkg-config libboost-all-dev libssl-dev libzmq3-dev libunbound-dev libsodium-dev libunwind8-dev liblzma-dev libreadline6-dev libldns-dev libexpat1-dev libpgm-dev libhidapi-dev libusb-1.0-0-dev libprotobuf-dev protobuf-compiler libudev-dev git -y git clone https://git.wownero.com/Synku/wowzero.git && cd wowzero make -j2
## END TRANSMISSION
Wownero is a privacy-centric memecoin that was fairly launched on April 1, 2018 with no pre-mine, stealth-mine or ICO. Wownero has a maximum supply of around 184 million WOW with a slow and steady emission over 50 years. It is a fork of Monero, but with its own genesis block, so there is no degradation of privacy due to ring signatures using different participants for the same tx outputs on opposing forks.
## Supporting the project
@@ -41,29 +55,12 @@ Wownero is a 100% community-sponsored endeavor. Supporting services are also gra
[<img src="https://git.wownero.com/wownero/meta/raw/branch/master/images/macstadium.png"
alt="MacStadium"
height="100">](https://www.macstadium.com)
[<img src="https://git.wownero.com/wownero/meta/raw/branch/master/images/jetbrains.png"
alt="JetBrains"
height="100">](https://www.jetbrains.com)
Developers are volunteers doing this mostly for shits and giggles. If you would like to support our shenanigans and stimulant addictions, please consider donating to [WFS proposals](https://funding.wownero.com/proposals) or the dev slush fund.
### Donation Addresses
WOW: `Wo3MWeKwtA918DU4c69hVSNgejdWFCRCuWjShRY66mJkU2Hv58eygJWDJS1MNa2Ge5M1WjUkGHuLqHkweDxwZZU42d16v94mP`
- view key: `e62e40bfd5ca7e3a7f199602a3c97df511780489e1c1861884b00c28abaea406`
XMR: `44SQVPGLufPasUcuUQSZiF5c9BFzjcP8ucDxzzFDgLf1VkCEFaidJ3u2AhSKMhPLKA3jc2iS8wQHFcaigM6fXmo6AnFRn5B`
- view key: `cb83681c31db0c79adf18f25b2a6d05f86db1109385b4928930e2acf49a3ed0b`
BTC: `bc1qcw9zglp3fxyl25zswemw7jczlqryms2lsmu464`
### Open Collective
Open Collective is an online funding platform for open source software and collaborative communities. The platform brings together legal entities that act as a “Fiscal Host”, “Collectives” (unincorporated, community-based projects), and individuals interested in supporting projects with donations. Fiscal hosts hold donations for collectives in trust and handle all the taxes and legal stuff.
Wownero is hosted by Open Collective Europe, a Brussels-based non-profit that hosts many other collectives, such as Manjaro, EndeavourOS, Xfce, and peertube.social. If you would like donate to the Wownero Project using this method, you can check out our [Wownero - Open Collective](https://opencollective.com/wownero) page.
WOW: `Wo3JCG4kKCLBQeqF2SeNQmU9oc1Ga4e7QcjHoGYVXnHrF3rcWWba8kB5h12DHFopUUMNKC4hxyhnZ7FGAhdB2eAe38wZ98KbM`
## Release staging and Contributing
@@ -73,7 +70,7 @@ If you have a fix or code change, feel free to submit it as a pull request. Ahea
Things to Do, Work in Progress, and Help Wanted tasks are tracked in the [Meta](https://git.wownero.com/wownero/meta/issues) repo.
Join `#wownero-dev` on IRC OFTC to participate in development conversation.
Join `#wownero-dev` on IRC freenode to participate in development conversation.
## Scheduled software upgrades
@@ -90,8 +87,7 @@ Dates are provided in the format YYYY-MM-DD.
| 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
| - | 2020-06-28 | Hallucinogenic Hypnotoad | v0.8.0.0 | v0.8.0.2 | Dandelion++ support
| 253,999 | 2020-10-09 | Illiterate Illuminati | v0.9.0.0 | v0.9.3.3 | Dynamic coinbase unlock (up to 1 mo.), Deterministic unlock times, Enforce maximum coinbase amount, show_qr_code wallet command, CLSAG
| 331,170 | 2021-07-04 | Junkie Jeff | v0.10.0.0 | v0.10.0.1 | Bulletproofs+, Miner Block Header Signing, Vote by Block, Change coinbase unlock time to 1 day, Reset difficulty and switch back to Monero's difficulty algorithm
| 253,999 | 2020-10-09 | Illiterate Illuminati | v0.9.0.0 | v0.9.1.0 | Dynamic coinbase unlock (up to 1 mo.), Deterministic unlock times, Enforce maximum coinbase amount, show_qr_code wallet command, CLSAG
X's indicate that these details have not been determined as of commit date.

View File

View File

@@ -15,7 +15,6 @@ macro(CHECK_LINKER_FLAG flag VARIABLE)
${_cle_source}
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} ${flag}
CMAKE_FLAGS
"-DCMAKE_EXE_LINKER_FLAGS=${flag}"
OUTPUT_VARIABLE OUTPUT)
unset(_cle_source)
set(CMAKE_C_FLAGS ${saved_CMAKE_C_FLAGS})

View File

@@ -91,7 +91,7 @@ endif()
# Protobuf compilation test
if(Protobuf_FOUND AND USE_DEVICE_TREZOR AND TREZOR_PYTHON)
execute_process(COMMAND ${Protobuf_PROTOC_EXECUTABLE} -I "${CMAKE_CURRENT_LIST_DIR}" -I "${Protobuf_INCLUDE_DIR}" "${CMAKE_CURRENT_LIST_DIR}/test-protobuf.proto" --cpp_out ${CMAKE_BINARY_DIR} RESULT_VARIABLE RET OUTPUT_VARIABLE OUT ERROR_VARIABLE ERR)
execute_process(COMMAND ${Protobuf_PROTOC_EXECUTABLE} -I "${CMAKE_SOURCE_DIR}/cmake" -I "${Protobuf_INCLUDE_DIR}" "${CMAKE_SOURCE_DIR}/cmake/test-protobuf.proto" --cpp_out ${CMAKE_BINARY_DIR} RESULT_VARIABLE RET OUTPUT_VARIABLE OUT ERROR_VARIABLE ERR)
if(RET)
message(STATUS "Protobuf test generation failed: ${OUT} ${ERR}")
endif()
@@ -100,7 +100,7 @@ if(Protobuf_FOUND AND USE_DEVICE_TREZOR AND TREZOR_PYTHON)
"${CMAKE_BINARY_DIR}"
SOURCES
"${CMAKE_BINARY_DIR}/test-protobuf.pb.cc"
"${CMAKE_CURRENT_LIST_DIR}/test-protobuf.cpp"
"${CMAKE_SOURCE_DIR}/cmake/test-protobuf.cpp"
CMAKE_FLAGS
"-DINCLUDE_DIRECTORIES=${Protobuf_INCLUDE_DIR};${CMAKE_BINARY_DIR}"
"-DCMAKE_CXX_STANDARD=11"

View File

@@ -42,19 +42,12 @@
find_program(CCACHE_FOUND ccache)
if (CCACHE_FOUND)
# Try to compile a test program with ccache, in order to verify if it really works. (needed on exotic setups)
set(TEST_PROJECT "${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/CMakeTmp")
file(WRITE "${TEST_PROJECT}/CMakeLists.txt" [=[
cmake_minimum_required(VERSION 3.5)
project(test)
option (CCACHE "")
file(WRITE "${CMAKE_SOURCE_DIR}/test.cpp" "int main() { return 0; }")
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE}")
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK "${CCACHE}")
add_executable(test test.cpp)
]=])
try_compile(RET "${TEST_PROJECT}/build" "${TEST_PROJECT}" "test" CMAKE_FLAGS -DCCACHE="${CCACHE_FOUND}")
unset(TEST_PROJECT)
if (${RET})
# Create a temporary file with a simple program.
set(TEMP_CPP_FILE "${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/CMakeTmp/test-program.cpp")
file(WRITE "${TEMP_CPP_FILE}" "int main() { return 0; }")
# And run the found ccache on it.
execute_process(COMMAND "${CCACHE_FOUND}" "${CMAKE_CXX_COMPILER}" "${TEMP_CPP_FILE}" RESULT_VARIABLE RET)
if (${RET} EQUAL 0)
# Success
message(STATUS "Found usable ccache: ${CCACHE_FOUND}")
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_FOUND}")

View File

@@ -134,7 +134,7 @@ if ( LibUSB_FOUND )
try_compile(LibUSB_COMPILE_TEST_PASSED
${CMAKE_BINARY_DIR}
"${CMAKE_CURRENT_LIST_DIR}/test-libusb-version.c"
"${CMAKE_SOURCE_DIR}/cmake/test-libusb-version.c"
CMAKE_FLAGS
"-DINCLUDE_DIRECTORIES=${LibUSB_INCLUDE_DIRS}"
"-DLINK_DIRECTORIES=${LibUSB_LIBRARIES}"

View File

@@ -48,21 +48,29 @@ function (get_version_tag_from_git GIT)
message(STATUS "You are currently on commit ${COMMIT}")
# Get all the tags
execute_process(COMMAND "${GIT}" tag -l --points-at HEAD
execute_process(COMMAND "${GIT}" rev-list --tags --max-count=1 --abbrev-commit
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
RESULT_VARIABLE RET
OUTPUT_VARIABLE TAG
OUTPUT_VARIABLE TAGGEDCOMMIT
OUTPUT_STRIP_TRAILING_WHITESPACE)
# Check if we're building that tagged commit or a different one
if(TAG)
message(STATUS "You are building a tagged release")
set(VERSIONTAG "release")
set(VERSION_IS_RELEASE "true")
else()
message(STATUS "You are ahead of or behind a tagged release")
if(NOT TAGGEDCOMMIT)
message(WARNING "Cannot determine most recent tag. Make sure that you are building either from a Git working tree or from a source archive.")
set(VERSIONTAG "${COMMIT}")
set(VERSION_IS_RELEASE "false")
else()
message(STATUS "The most recent tag was at ${TAGGEDCOMMIT}")
# Check if we're building that tagged commit or a different one
if(COMMIT STREQUAL TAGGEDCOMMIT)
message(STATUS "You are building a tagged release")
set(VERSIONTAG "release")
set(VERSION_IS_RELEASE "true")
else()
message(STATUS "You are ahead of or behind a tagged release")
set(VERSIONTAG "${COMMIT}")
set(VERSION_IS_RELEASE "false")
endif()
endif()
endif()

View File

@@ -1,72 +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.
# https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_CLANG_TIDY.html
# This module sets the following variables:
# CMAKE_C_CLANG_TIDY
# CMAKE_CXX_CLANG_TIDY
# when clang-tidy is found in PATH. Afterwards, the code is being linted by the tool.
# The checks to be enabled can be manipulated with the variable MONERO_CLANG_TIDY_CHECKS
macro (monero_clang_tidy LANGUAGE)
set(TOOL_NAME "clang-tidy")
set(MONERO_CLANG_TIDY_MIN_VERSION "3.6")
if(${CMAKE_VERSION} VERSION_LESS "${MONERO_CLANG_TIDY_MIN_VERSION}")
message(FATAL_ERROR "Sorry, ${TOOL_NAME} is available for CMake from version ${MONERO_CLANG_TIDY_MIN_VERSION}")
else()
message(STATUS "Trying to enable ${TOOL_NAME}")
find_program(MONERO_CLANG_BIN ${TOOL_NAME})
if(NOT MONERO_CLANG_BIN)
message(FATAL_ERROR "${TOOL_NAME} not found! Try running: sudo apt install ${TOOL_NAME}")
else()
message(STATUS "Found ${MONERO_CLANG_BIN}")
set(MONERO_CLANG_TIDY_CHECKS
-header-filter=.; # By default the headers are excluded. This line enables them.
-checks=*; # Currently enabling all checks
# An example of selectively enabling checks:
#-checks=bugprone-*,cppcoreguidelines-avoid-goto # Have to be in one line :(
)
# Current list of checks is avaibale under:
# https://clang.llvm.org/extra/clang-tidy/
if (${LANGUAGE} STREQUAL "C")
set(CMAKE_C_CLANG_TIDY
${MONERO_CLANG_BIN}; # Mind the semicolon
${MONERO_CLANG_TIDY_CHECKS}
)
elseif (${LANGUAGE} STREQUAL "CXX")
set(CMAKE_CXX_CLANG_TIDY
${MONERO_CLANG_BIN}; # Mind the semicolon
${MONERO_CLANG_TIDY_CHECKS}
)
else()
message(FATAL_ERROR "${TOOL_NAME}: Unsupported language: ${LANGUAGE}")
endif()
endif()
endif()
endmacro()

View File

@@ -26,6 +26,5 @@
# 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.
monero_enable_coverage()
add_subdirectory(epee)

View File

@@ -27,7 +27,6 @@ brew "miniupnpc"
brew "readline"
brew "ldns"
brew "expat"
brew "ccache"
brew "doxygen"
brew "graphviz"
brew "libunwind-headers"

View File

@@ -10,8 +10,8 @@ HOST ?= $(BUILD)
PATCHES_PATH = $(BASEDIR)/patches
BASEDIR = $(CURDIR)
HASH_LENGTH:=11
DOWNLOAD_CONNECT_TIMEOUT:=30
DOWNLOAD_RETRIES:=5
DOWNLOAD_CONNECT_TIMEOUT:=10
DOWNLOAD_RETRIES:=3
HOST_ID_SALT ?= salt
BUILD_ID_SALT ?= salt

View File

@@ -1,6 +1,6 @@
package=boost
$(package)_version=1_64_0
$(package)_download_path=https://downloads.sourceforge.net/project/boost/boost/1.64.0/
$(package)_download_path=https://dl.bintray.com/boostorg/release/1.64.0/source/
$(package)_file_name=$(package)_$($(package)_version).tar.bz2
$(package)_sha256_hash=7bcc5caace97baa948931d712ea5f37038dbb1c5d89b43ad4def4ed7cb683332
$(package)_dependencies=libiconv

View File

@@ -1,31 +1,36 @@
package=openssl
$(package)_version=1.1.1k
$(package)_download_path=https://www.openssl.org/source
$(package)_version=1.0.2r
$(package)_download_path=https://ftp.openssl.org/source/old/1.0.2
$(package)_file_name=$(package)-$($(package)_version).tar.gz
$(package)_sha256_hash=892a0875b9872acd04a9fde79b1f943075d5ea162415de3047c327df33fbaee5
$(package)_sha256_hash=ae51d08bba8a83958e894946f15303ff894d75c2b8bbd44a852b64e3fe11d0d6
$(package)_patches=fix_arflags.patch
define $(package)_set_vars
$(package)_config_env=AR="$($(package)_ar)" ARFLAGS=$($(package)_arflags) RANLIB="$($(package)_ranlib)" CC="$($(package)_cc)"
$(package)_config_env_arm_android=ANDROID_NDK_HOME="$(host_prefix)/native" PATH="$(host_prefix)/native/bin" CC=clang AR=ar RANLIB=ranlib
$(package)_config_env_aarch64_android=ANDROID_NDK_HOME="$(host_prefix)/native" PATH="$(host_prefix)/native/bin" CC=clang AR=ar RANLIB=ranlib
$(package)_build_env_arm_android=ANDROID_NDK_HOME="$(host_prefix)/native"
$(package)_build_env_aarch64_android=ANDROID_NDK_HOME="$(host_prefix)/native"
$(package)_config_opts=--prefix=$(host_prefix) --openssldir=$(host_prefix)/etc/openssl
$(package)_config_opts+=no-capieng
$(package)_config_opts+=no-dso
$(package)_config_opts+=no-dtls1
$(package)_config_opts+=no-ec_nistp_64_gcc_128
$(package)_config_opts+=no-gost
$(package)_config_opts+=no-gmp
$(package)_config_opts+=no-heartbeats
$(package)_config_opts+=no-jpake
$(package)_config_opts+=no-krb5
$(package)_config_opts+=no-libunbound
$(package)_config_opts+=no-md2
$(package)_config_opts+=no-rc5
$(package)_config_opts+=no-rdrand
$(package)_config_opts+=no-rfc3779
$(package)_config_opts+=no-rsax
$(package)_config_opts+=no-sctp
$(package)_config_opts+=no-sha0
$(package)_config_opts+=no-shared
$(package)_config_opts+=no-ssl-trace
$(package)_config_opts+=no-ssl2
$(package)_config_opts+=no-ssl3
$(package)_config_opts+=no-static_engine
$(package)_config_opts+=no-store
$(package)_config_opts+=no-unit-test
$(package)_config_opts+=no-weak-ssl-ciphers
$(package)_config_opts+=no-zlib
@@ -37,8 +42,8 @@ $(package)_config_opts_x86_64_linux=linux-x86_64
$(package)_config_opts_i686_linux=linux-generic32
$(package)_config_opts_arm_linux=linux-generic32
$(package)_config_opts_aarch64_linux=linux-generic64
$(package)_config_opts_arm_android=--static android-arm
$(package)_config_opts_aarch64_android=--static android-arm64
$(package)_config_opts_arm_android=--static android-armv7 no-asm
$(package)_config_opts_aarch64_android=--static android no-asm
$(package)_config_opts_riscv64_linux=linux-generic64
$(package)_config_opts_mipsel_linux=linux-generic32
$(package)_config_opts_mips_linux=linux-generic32
@@ -50,8 +55,10 @@ $(package)_config_opts_x86_64_freebsd=BSD-x86_64
endef
define $(package)_preprocess_cmds
sed -i.old 's|"engines", "apps", "test", "util", "tools", "fuzz"|"engines", "tools"|' Configure && \
sed -i -e 's|cflags --sysroot.*",|cflags",|' Configurations/15-android.conf
sed -i.old "/define DATE/d" util/mkbuildinf.pl && \
sed -i.old "s|engines apps test|engines|" Makefile.org && \
sed -i -e "s/-mandroid //" Configure && \
patch < $($(package)_patch_dir)/fix_arflags.patch
endef
define $(package)_config_cmds
@@ -63,7 +70,7 @@ define $(package)_build_cmds
endef
define $(package)_stage_cmds
$(MAKE) DESTDIR=$($(package)_staging_dir) -j1 install_sw
$(MAKE) INSTALL_PREFIX=$($(package)_staging_dir) -j1 install_sw
endef
define $(package)_postprocess_cmds

View File

@@ -0,0 +1,24 @@
--- Makefile.org.O 2019-02-26 14:20:20.000000000 +0000
+++ Makefile.org 2019-11-15 13:05:54.370086856 +0000
@@ -63,8 +63,8 @@
PEX_LIBS=
EX_LIBS=
EXE_EXT=
-ARFLAGS=
-AR=ar $(ARFLAGS) r
+ARFLAGS= r
+AR=ar $(ARFLAGS)
RANLIB= ranlib
RC= windres
NM= nm
--- Configure.O 2019-02-26 14:20:20.000000000 +0000
+++ Configure 2019-11-16 07:43:14.933990774 +0000
@@ -1251,7 +1251,7 @@
my $shared_extension = $fields[$idx_shared_extension];
my $ranlib = $ENV{'RANLIB'} || $fields[$idx_ranlib];
my $ar = $ENV{'AR'} || "ar";
-my $arflags = $fields[$idx_arflags];
+my $arflags = $ENV{'ARFLAGS'} || $fields[$idx_arflags];
my $windres = $ENV{'RC'} || $ENV{'WINDRES'} || "windres";
my $multilib = $fields[$idx_multilib];

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 2.8)
set(Boost_USE_MULTITHREADED ON)
#set(Boost_DEBUG 1)
find_package(Boost COMPONENTS system filesystem thread date_time chrono regex )

View File

@@ -112,7 +112,7 @@ namespace epee
explicit byte_slice(std::string&& buffer);
//! Convert `stream` into a slice with zero allocations.
explicit byte_slice(byte_stream&& stream, bool shrink = true);
explicit byte_slice(byte_stream&& stream) noexcept;
byte_slice(byte_slice&& source) noexcept;
~byte_slice() noexcept = default;

View File

@@ -58,6 +58,7 @@ namespace epee
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);
@@ -74,17 +75,29 @@ namespace epee
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)
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_; }
@@ -175,7 +188,7 @@ namespace epee
void put_n(const std::uint8_t ch, const std::size_t count)
{
check(count);
std::memset(tellp(), ch, count);
std::memset(tellp(), count, ch);
next_write_ += count;
}

View File

@@ -24,23 +24,211 @@
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#ifndef _FILE_IO_UTILS_H_
#define _FILE_IO_UTILS_H_
#include <string>
#include <ctime>
#include <fstream>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
#ifdef WIN32
#include <windows.h>
#include "string_tools.h"
#endif
// On Windows there is a problem with non-ASCII characters in path and file names
// as far as support by the standard components used is concerned:
// The various file stream classes, e.g. std::ifstream and std::ofstream, are
// part of the GNU C++ Library / libstdc++. On the most basic level they use the
// fopen() call as defined / made accessible to programs compiled within MSYS2
// by the stdio.h header file maintained by the MinGW project.
// The critical point: The implementation of fopen() is part of MSVCRT, the
// Microsoft Visual C/C++ Runtime Library, and this method does NOT offer any
// Unicode support.
// Monero code that would want to continue to use the normal file stream classes
// but WITH Unicode support could therefore not solve this problem on its own,
// but 2 different projects from 2 different maintaining groups would need changes
// in this particular direction - something probably difficult to achieve and
// with a long time to wait until all new versions / releases arrive.
// Implemented solution approach: Circumvent the problem by stopping to use std
// file stream classes on Windows and directly use Unicode-capable WIN32 API
// calls. Most of the code doing so is concentrated in this header file here.
namespace epee
{
namespace file_io_utils
{
bool is_file_exist(const std::string& path);
bool save_string_to_file(const std::string& path_to_file, const std::string& str);
bool get_file_time(const std::string& path_to_file, time_t& ft);
bool set_file_time(const std::string& path_to_file, const time_t& ft);
bool load_file_to_string(const std::string& path_to_file, std::string& target_str, size_t max_size = 1000000000);
bool append_string_to_file(const std::string& path_to_file, const std::string& str);
bool get_file_size(const std::string& path_to_file, uint64_t &size);
inline
bool is_file_exist(const std::string& path)
{
boost::filesystem::path p(path);
return boost::filesystem::exists(p);
}
inline
bool save_string_to_file(const std::string& path_to_file, const std::string& str)
{
#ifdef WIN32
std::wstring wide_path;
try { wide_path = string_tools::utf8_to_utf16(path_to_file); } catch (...) { return false; }
HANDLE file_handle = CreateFileW(wide_path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (file_handle == INVALID_HANDLE_VALUE)
return false;
DWORD bytes_written;
DWORD bytes_to_write = (DWORD)str.size();
BOOL result = WriteFile(file_handle, str.data(), bytes_to_write, &bytes_written, NULL);
CloseHandle(file_handle);
if (bytes_written != bytes_to_write)
result = FALSE;
return result;
#else
try
{
std::ofstream fstream;
fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
fstream.open(path_to_file, std::ios_base::binary | std::ios_base::out | std::ios_base::trunc);
fstream << str;
fstream.close();
return true;
}
catch(...)
{
return false;
}
#endif
}
inline
bool get_file_time(const std::string& path_to_file, time_t& ft)
{
boost::system::error_code ec;
ft = boost::filesystem::last_write_time(boost::filesystem::path(path_to_file), ec);
if(!ec)
return true;
else
return false;
}
inline
bool set_file_time(const std::string& path_to_file, const time_t& ft)
{
boost::system::error_code ec;
boost::filesystem::last_write_time(boost::filesystem::path(path_to_file), ft, ec);
if(!ec)
return true;
else
return false;
}
inline
bool load_file_to_string(const std::string& path_to_file, std::string& target_str, size_t max_size = 1000000000)
{
#ifdef WIN32
std::wstring wide_path;
try { wide_path = string_tools::utf8_to_utf16(path_to_file); } catch (...) { return false; }
HANDLE file_handle = CreateFileW(wide_path.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (file_handle == INVALID_HANDLE_VALUE)
return false;
DWORD file_size = GetFileSize(file_handle, NULL);
if ((file_size == INVALID_FILE_SIZE) || (uint64_t)file_size > (uint64_t)max_size) {
CloseHandle(file_handle);
return false;
}
target_str.resize(file_size);
DWORD bytes_read;
BOOL result = ReadFile(file_handle, &target_str[0], file_size, &bytes_read, NULL);
CloseHandle(file_handle);
if (bytes_read != file_size)
result = FALSE;
return result;
#else
try
{
std::ifstream fstream;
fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
fstream.open(path_to_file, std::ios_base::binary | std::ios_base::in | std::ios::ate);
std::ifstream::pos_type file_size = fstream.tellg();
if((uint64_t)file_size > (uint64_t)max_size) // ensure a large domain for comparison, and negative -> too large
return false;//don't go crazy
size_t file_size_t = static_cast<size_t>(file_size);
target_str.resize(file_size_t);
fstream.seekg (0, std::ios::beg);
fstream.read((char*)target_str.data(), target_str.size());
fstream.close();
return true;
}
catch(...)
{
return false;
}
#endif
}
inline
bool append_string_to_file(const std::string& path_to_file, const std::string& str)
{
// No special Windows implementation because so far not used in Monero code
try
{
std::ofstream fstream;
fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
fstream.open(path_to_file.c_str(), std::ios_base::binary | std::ios_base::out | std::ios_base::app);
fstream << str;
fstream.close();
return true;
}
catch(...)
{
return false;
}
}
inline
bool get_file_size(const std::string& path_to_file, uint64_t &size)
{
#ifdef WIN32
std::wstring wide_path;
try { wide_path = string_tools::utf8_to_utf16(path_to_file); } catch (...) { return false; }
HANDLE file_handle = CreateFileW(wide_path.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (file_handle == INVALID_HANDLE_VALUE)
return false;
LARGE_INTEGER file_size;
BOOL result = GetFileSizeEx(file_handle, &file_size);
CloseHandle(file_handle);
if (result) {
size = file_size.QuadPart;
}
return size;
#else
try
{
std::ifstream fstream;
fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
fstream.open(path_to_file, std::ios_base::binary | std::ios_base::in | std::ios::ate);
size = fstream.tellg();
fstream.close();
return true;
}
catch(...)
{
return false;
}
#endif
}
}
}

View File

@@ -32,7 +32,6 @@
#ifdef __cplusplus
#include <array>
#include <cstddef>
extern "C" {
#endif

View File

@@ -28,11 +28,9 @@
#pragma once
#include <boost/utility/value_init.hpp>
#include <boost/shared_ptr.hpp>
#include <limits>
#include <functional>
#include <vector>
#include <boost/thread.hpp>
#include <boost/utility/value_init.hpp>
namespace epee
{
#define STD_TRY_BEGIN() try {
@@ -97,7 +95,16 @@ namespace misc_utils
return memcmp(&_Left, &_Right, sizeof(_Left)) < 0;
}
bool sleep_no_w(long ms );
inline
bool sleep_no_w(long ms )
{
boost::this_thread::sleep(
boost::get_system_time() +
boost::posix_time::milliseconds( std::max<long>(ms,0) ) );
return true;
}
template <typename T>
T get_mid(const T &a, const T &b)

View File

@@ -41,7 +41,7 @@
#define MAX_LOG_FILES 50
#define MCLOG_TYPE(level, cat, color, type, x) do { \
if (el::Loggers::allowed(level, cat)) { \
if (ELPP->vRegistry()->allowed(level, cat)) { \
el::base::Writer(level, color, __FILE__, __LINE__, ELPP_FUNC, type).construct(cat) << x; \
} \
} while (0)
@@ -89,7 +89,7 @@
#define IFLOG(level, cat, color, type, init, x) \
do { \
if (el::Loggers::allowed(level, cat)) { \
if (ELPP->vRegistry()->allowed(level, cat)) { \
init; \
el::base::Writer(level, color, __FILE__, __LINE__, ELPP_FUNC, type).construct(cat) << x; \
} \

View File

@@ -47,7 +47,7 @@
#endif
#include <iostream>
#include <ctime>
#include <boost/lexical_cast.hpp>
#pragma once
namespace epee
@@ -115,7 +115,15 @@ namespace misc_utils
}
std::string get_thread_string_id();
inline std::string get_thread_string_id()
{
#if defined(_WIN32)
return boost::lexical_cast<std::string>(GetCurrentThreadId());
#elif defined(__GNUC__)
return boost::lexical_cast<std::string>(pthread_self());
#endif
}
inline bool get_gmt_time(time_t t, struct tm &tm)
{

View File

@@ -70,7 +70,7 @@ namespace http
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 boost::string_ref body, std::chrono::milliseconds timeout, const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list()) = 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;

View File

@@ -265,12 +265,6 @@ namespace net_utils
template<class t_callback>
bool connect_async(const std::string& adr, const std::string& port, uint32_t conn_timeot, const t_callback &cb, const std::string& bind_ip = "0.0.0.0", epee::net_utils::ssl_support_t ssl_support = epee::net_utils::ssl_support_t::e_ssl_support_autodetect);
boost::asio::ssl::context& get_ssl_context() noexcept
{
assert(m_state != nullptr);
return m_state->ssl_context;
}
typename t_protocol_handler::config_type& get_config_object()
{
assert(m_state != nullptr); // always set in constructor

View File

@@ -40,9 +40,8 @@
#include <boost/date_time/posix_time/posix_time.hpp> // TODO
#include <boost/thread/condition_variable.hpp> // TODO
#include <boost/make_shared.hpp>
#include <boost/thread.hpp>
#include "warnings.h"
#include "string_tools_lexical.h"
#include "string_tools.h"
#include "misc_language.h"
#include "net/local_ip.h"
#include "pragma_comp_defs.h"
@@ -208,6 +207,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
buffer_ssl_init_fill = 0;
if (is_income && m_ssl_support != epee::net_utils::ssl_support_t::e_ssl_support_disabled)
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,
@@ -270,6 +270,8 @@ PRAGMA_WARNING_DISABLE_VS(4355)
//_dbg3("[sock " << socket().native_handle() << "] add_ref, m_peer_number=" << mI->m_peer_number);
CRITICAL_REGION_LOCAL(self->m_self_refs_lock);
//_dbg3("[sock " << socket().native_handle() << "] add_ref 2, m_peer_number=" << mI->m_peer_number);
if(m_was_shutdown)
return false;
++m_reference_count;
m_self_ref = std::move(self);
return true;
@@ -332,9 +334,6 @@ PRAGMA_WARNING_DISABLE_VS(4355)
TRY_ENTRY();
//_info("[sock " << socket().native_handle() << "] Async read calledback.");
if (m_was_shutdown)
return;
if (!e)
{
double current_speed_down;
@@ -361,9 +360,6 @@ PRAGMA_WARNING_DISABLE_VS(4355)
CRITICAL_REGION_LOCAL( epee::net_utils::network_throttle_manager::m_lock_get_global_throttle_in );
delay = epee::net_utils::network_throttle_manager::get_global_throttle_in().get_sleep_time_after_tick( bytes_transferred );
}
if (m_was_shutdown)
return;
delay *= 0.5;
long int ms = (long int)(delay * 100);
@@ -435,9 +431,6 @@ PRAGMA_WARNING_DISABLE_VS(4355)
std::size_t bytes_transferred)
{
TRY_ENTRY();
if (m_was_shutdown) return;
if (e)
{
// offload the error case
@@ -445,11 +438,13 @@ PRAGMA_WARNING_DISABLE_VS(4355)
return;
}
reset_timer(get_timeout_from_bytes_read(bytes_transferred), false);
buffer_ssl_init_fill += bytes_transferred;
MTRACE("we now have " << buffer_ssl_init_fill << "/" << get_ssl_magic_size() << " bytes needed to detect SSL");
if (buffer_ssl_init_fill < get_ssl_magic_size())
if (buffer_ssl_init_fill <= get_ssl_magic_size())
{
socket().async_receive(boost::asio::buffer(buffer_.data() + buffer_ssl_init_fill, buffer_.size() - buffer_ssl_init_fill),
boost::asio::socket_base::message_peek,
strand_.wrap(
boost::bind(&connection<t_protocol_handler>::handle_receive, connection<t_protocol_handler>::shared_from_this(),
boost::asio::placeholders::error,
@@ -475,7 +470,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
if (m_ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_enabled)
{
// Handshake
if (!handshake(boost::asio::ssl::stream_base::server, boost::asio::const_buffer(buffer_.data(), buffer_ssl_init_fill)))
if (!handshake(boost::asio::ssl::stream_base::server))
{
MERROR("SSL handshake failed");
boost::interprocess::ipcdetail::atomic_write32(&m_want_close_connection, 1);
@@ -490,11 +485,6 @@ PRAGMA_WARNING_DISABLE_VS(4355)
return;
}
}
else
{
handle_read(e, buffer_ssl_init_fill);
return;
}
async_read_some(boost::asio::buffer(buffer_),
strand_.wrap(
@@ -561,7 +551,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
{ // LOCK: chunking
epee::critical_region_t<decltype(m_chunking_lock)> send_guard(m_chunking_lock); // *** critical ***
MDEBUG("do_send() will SPLIT into small chunks, from packet="<<message_size<<" B for ptr="<<(const void*)message_data);
MDEBUG("do_send() will SPLIT into small chunks, from packet="<<message_size<<" B for ptr="<<message_data);
// 01234567890
// ^^^^ (pos=0, len=4) ; pos:=pos+len, pos=4
// ^^^^ (pos=4, len=4) ; pos:=pos+len, pos=8
@@ -574,14 +564,14 @@ PRAGMA_WARNING_DISABLE_VS(4355)
while (!message.empty()) {
byte_slice chunk = message.take_slice(chunksize_good);
MDEBUG("chunk_start="<<(void*)chunk.data()<<" ptr="<<(const void*)message_data<<" pos="<<(chunk.data() - message_data));
MDEBUG("chunk_start="<<(void*)chunk.data()<<" ptr="<<message_data<<" pos="<<(chunk.data() - message_data));
MDEBUG("part of " << message.size() << ": pos="<<(chunk.data() - message_data) << " len="<<chunk.size());
bool ok = do_send_chunk(std::move(chunk)); // <====== ***
all_ok = all_ok && ok;
if (!all_ok) {
MDEBUG("do_send() DONE ***FAILED*** from packet="<<message_size<<" B for ptr="<<(const void*)message_data);
MDEBUG("do_send() DONE ***FAILED*** from packet="<<message_size<<" B for ptr="<<message_data);
MDEBUG("do_send() SEND was aborted in middle of big package - this is mostly harmless "
<< " (e.g. peer closed connection) but if it causes trouble tell us at #monero-dev. " << message_size);
return false; // partial failure in sending
@@ -589,7 +579,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
// (in catch block, or uniq pointer) delete buf;
} // each chunk
MDEBUG("do_send() DONE SPLIT from packet="<<message_size<<" B for ptr="<<(const void*)message_data);
MDEBUG("do_send() DONE SPLIT from packet="<<message_size<<" B for ptr="<<message_data);
MDEBUG("do_send() m_connection_type = " << m_connection_type);
@@ -661,8 +651,6 @@ PRAGMA_WARNING_DISABLE_VS(4355)
boost::this_thread::sleep(boost::posix_time::milliseconds( ms ) );
m_send_que_lock.lock();
_dbg1("sleep for queue: " << ms);
if (m_was_shutdown)
return false;
if (retry > retry_limit) {
MWARNING("send que size is more than ABSTRACT_SERVER_SEND_QUE_MAX_COUNT(" << ABSTRACT_SERVER_SEND_QUE_MAX_COUNT << "), shutting down connection");
@@ -760,8 +748,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)
{
const auto tms = ms.total_milliseconds();
if (tms < 0 || (add && tms == 0))
if (ms.total_milliseconds() < 0)
{
MWARNING("Ignoring negative timeout " << ms);
return;

View File

@@ -132,10 +132,10 @@ class connection_basic { // not-templated base class for rapid developmet of som
ssl_support_t get_ssl_support() const { return m_ssl_support; }
void disable_ssl() { m_ssl_support = epee::net_utils::ssl_support_t::e_ssl_support_disabled; }
bool handshake(boost::asio::ssl::stream_base::handshake_type type, boost::asio::const_buffer buffer = {})
bool handshake(boost::asio::ssl::stream_base::handshake_type type)
{
//m_state != nullptr verified in constructor
return m_state->ssl_options().handshake(socket_, type, buffer);
return m_state->ssl_options().handshake(socket_, type);
}
template<typename MutableBufferSequence, typename ReadHandler>

View File

@@ -27,13 +27,14 @@
#pragma once
#include "memwipe.h"
#include <boost/lexical_cast.hpp>
#include <boost/regex.hpp>
#include <boost/utility/string_ref.hpp>
#include <string>
#include <utility>
#include <list>
#include "memwipe.h"
#include "string_tools.h"
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "net.http"
@@ -65,9 +66,34 @@ namespace net_utils
typedef std::list<std::pair<std::string, std::string> > fields_list;
std::string get_value_from_fields_list(const std::string& param_name, const net_utils::http::fields_list& fields);
inline
std::string get_value_from_fields_list(const std::string& param_name, const net_utils::http::fields_list& fields)
{
fields_list::const_iterator it = fields.begin();
for(; it != fields.end(); it++)
if(!string_tools::compare_no_case(param_name, it->first))
break;
std::string get_value_from_uri_line(const std::string& param_name, const std::string& uri);
if(it==fields.end())
return std::string();
return it->second;
}
inline
std::string get_value_from_uri_line(const std::string& param_name, const std::string& uri)
{
std::string buff = "([\\?|&])";
buff += param_name + "=([^&]*)";
boost::regex match_param(buff.c_str(), boost::regex::icase | boost::regex::normal);
boost::smatch result;
if(boost::regex_search(uri, result, match_param, boost::match_default) && result[0].matched)
{
return result[2];
}
return std::string();
}
static inline void add_field(std::string& out, const boost::string_ref name, const boost::string_ref value)
{

View File

@@ -30,6 +30,7 @@
#include <ctype.h>
#include <boost/shared_ptr.hpp>
#include <boost/regex.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/optional/optional.hpp>
#include <boost/utility/string_ref.hpp>
//#include <mbstring.h>
@@ -45,7 +46,6 @@
#endif
#include "string_tools.h"
#include "string_tools_lexical.h"
#include "reg_exp_definer.h"
#include "abstract_http_client.h"
#include "http_base.h"
@@ -233,7 +233,7 @@ namespace net_utils
}
//---------------------------------------------------------------------------
inline bool invoke(const boost::string_ref uri, const boost::string_ref method, const boost::string_ref 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()) override
{
CRITICAL_REGION_LOCAL(m_lock);
if(!is_connected())

View File

@@ -74,13 +74,7 @@
uint64_t ticks = misc_utils::get_tick_count(); \
boost::value_initialized<command_type::request> req; \
bool parse_res = epee::serialization::load_t_from_json(static_cast<command_type::request&>(req), query_info.m_body); \
if (!parse_res) \
{ \
MERROR("Failed to parse json: \r\n" << query_info.m_body); \
response_info.m_response_code = 400; \
response_info.m_response_comment = "Bad request"; \
return true; \
} \
CHECK_AND_ASSERT_MES(parse_res, false, "Failed to parse json: \r\n" << query_info.m_body); \
uint64_t ticks1 = epee::misc_utils::get_tick_count(); \
boost::value_initialized<command_type::response> resp;\
MINFO(m_conn_context << "calling " << s_pattern); \
@@ -110,13 +104,7 @@
uint64_t ticks = misc_utils::get_tick_count(); \
boost::value_initialized<command_type::request> req; \
bool parse_res = epee::serialization::load_t_from_binary(static_cast<command_type::request&>(req), epee::strspan<uint8_t>(query_info.m_body)); \
if (!parse_res) \
{ \
MERROR("Failed to parse bin body data, body size=" << query_info.m_body.size()); \
response_info.m_response_code = 400; \
response_info.m_response_comment = "Bad request"; \
return true; \
} \
CHECK_AND_ASSERT_MES(parse_res, false, "Failed to parse bin body data, body size=" << query_info.m_body.size()); \
uint64_t ticks1 = misc_utils::get_tick_count(); \
boost::value_initialized<command_type::response> resp;\
MINFO(m_conn_context << "calling " << s_pattern); \
@@ -130,10 +118,8 @@
return true; \
} \
uint64_t ticks2 = misc_utils::get_tick_count(); \
epee::byte_slice buffer; \
epee::serialization::store_t_to_binary(static_cast<command_type::response&>(resp), buffer, 64 * 1024); \
epee::serialization::store_t_to_binary(static_cast<command_type::response&>(resp), response_info.m_body); \
uint64_t ticks3 = epee::misc_utils::get_tick_count(); \
response_info.m_body.assign(reinterpret_cast<const char*>(buffer.data()), buffer.size()); \
response_info.m_mime_tipe = " application/octet-stream"; \
response_info.m_header_info.m_content_type = " application/octet-stream"; \
MDEBUG( s_pattern << "() processed with " << ticks1-ticks << "/"<< ticks2-ticks1 << "/" << ticks3-ticks2 << "ms"); \

View File

@@ -31,7 +31,7 @@
#include <cstdint>
#include "byte_stream.h"
#include "byte_slice.h"
#include "net_utils_base.h"
#include "span.h"
@@ -39,7 +39,6 @@
namespace epee
{
class byte_slice;
namespace levin
{
#pragma pack(push)
@@ -73,8 +72,7 @@ namespace levin
#define LEVIN_DEFAULT_TIMEOUT_PRECONFIGURED 0
#define LEVIN_INITIAL_MAX_PACKET_SIZE 256*1024 // 256 KiB before handshake
#define LEVIN_DEFAULT_MAX_PACKET_SIZE 100000000 //100MB by default after handshake
#define LEVIN_DEFAULT_MAX_PACKET_SIZE 100000000 //100MB by default
#define LEVIN_PACKET_REQUEST 0x00000001
#define LEVIN_PACKET_RESPONSE 0x00000002
@@ -84,12 +82,11 @@ namespace levin
#define LEVIN_PROTOCOL_VER_0 0
#define LEVIN_PROTOCOL_VER_1 1
template<class t_connection_context = net_utils::connection_context_base>
struct levin_commands_handler
{
virtual int invoke(int command, const epee::span<const uint8_t> in_buff, byte_stream& buff_out, t_connection_context& context)=0;
virtual int invoke(int command, const epee::span<const uint8_t> in_buff, std::string& buff_out, t_connection_context& context)=0;
virtual int notify(int command, const epee::span<const uint8_t> in_buff, t_connection_context& context)=0;
virtual void callback(t_connection_context& context){};
@@ -127,41 +124,12 @@ namespace levin
}
}
//! Provides space for levin (p2p) header, so that payload can be sent without copy
class message_writer
{
byte_slice finalize(uint32_t command, uint32_t flags, uint32_t return_code, bool expect_response);
public:
using header = bucket_head2;
explicit message_writer(std::size_t reserve = 8192);
message_writer(const message_writer&) = delete;
message_writer(message_writer&&) = default;
~message_writer() = default;
message_writer& operator=(const message_writer&) = delete;
message_writer& operator=(message_writer&&) = default;
//! \return Size of payload (excludes header size).
std::size_t payload_size() const noexcept
{
return buffer.size() < sizeof(header) ? 0 : buffer.size() - sizeof(header);
}
byte_slice finalize_invoke(uint32_t command) { return finalize(command, LEVIN_PACKET_REQUEST, 0, true); }
byte_slice finalize_notify(uint32_t command) { return finalize(command, LEVIN_PACKET_REQUEST, 0, false); }
byte_slice finalize_response(uint32_t command, uint32_t return_code)
{
return finalize(command, LEVIN_PACKET_RESPONSE, return_code, false);
}
//! Has space for levin header until a finalize method is used
byte_stream buffer;
};
//! \return Intialized levin header.
bucket_head2 make_header(uint32_t command, uint64_t msg_size, uint32_t flags, bool expect_response) noexcept;
//! \return A levin notification message.
byte_slice make_notify(int command, epee::span<const std::uint8_t> payload);
/*! Generate a dummy levin message.
\param noise_bytes Total size of the returned `byte_slice`.
@@ -171,11 +139,12 @@ namespace levin
/*! Generate 1+ levin messages that are identical to the noise message size.
\param noise_size Each levin message will be identical to this value.
\param noise Each levin message will be identical to the size of this
message. The bytes from this message will be used for padding.
\return `nullptr` if `noise.size()` is less than the levin header size.
Otherwise, a levin notification message OR 2+ levin fragment messages.
Each message is `noise.size()` in length. */
byte_slice make_fragmented_notify(const std::size_t noise_size, int command, message_writer message);
byte_slice make_fragmented_notify(const byte_slice& noise, int command, epee::span<const std::uint8_t> payload);
}
}

View File

@@ -51,21 +51,6 @@
#define MIN_BYTES_WANTED 512
#endif
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);
on_levin_traffic(context, initiator, sent, error, bytes, buf);
}
namespace epee
{
namespace levin
@@ -99,14 +84,14 @@ class async_protocol_handler_config
public:
typedef t_connection_context connection_context;
uint64_t m_initial_max_packet_size;
uint64_t m_max_packet_size;
uint64_t m_max_packet_size;
uint64_t m_invoke_timeout;
int invoke(int command, message_writer in_msg, std::string& buff_out, boost::uuids::uuid connection_id);
int invoke(int command, const epee::span<const uint8_t> in_buff, std::string& buff_out, boost::uuids::uuid connection_id);
template<class callback_t>
int invoke_async(int command, message_writer in_msg, boost::uuids::uuid connection_id, const callback_t &cb, size_t timeout = LEVIN_DEFAULT_TIMEOUT_PRECONFIGURED);
int invoke_async(int command, const epee::span<const uint8_t> in_buff, boost::uuids::uuid connection_id, const callback_t &cb, size_t timeout = LEVIN_DEFAULT_TIMEOUT_PRECONFIGURED);
int notify(int command, const epee::span<const uint8_t> in_buff, boost::uuids::uuid connection_id);
int send(epee::byte_slice message, const boost::uuids::uuid& connection_id);
bool close(boost::uuids::uuid connection_id);
bool update_connection_context(const t_connection_context& contxt);
@@ -120,7 +105,7 @@ public:
size_t get_in_connections_count();
void set_handler(levin_commands_handler<t_connection_context>* handler, void (*destroy)(levin_commands_handler<t_connection_context>*) = NULL);
async_protocol_handler_config():m_pcommands_handler(NULL), m_pcommands_handler_destroy(NULL), m_initial_max_packet_size(LEVIN_INITIAL_MAX_PACKET_SIZE), m_max_packet_size(LEVIN_DEFAULT_MAX_PACKET_SIZE), m_invoke_timeout(LEVIN_DEFAULT_TIMEOUT_PRECONFIGURED)
async_protocol_handler_config():m_pcommands_handler(NULL), m_pcommands_handler_destroy(NULL), m_max_packet_size(LEVIN_DEFAULT_MAX_PACKET_SIZE), m_invoke_timeout(LEVIN_DEFAULT_TIMEOUT_PRECONFIGURED)
{}
~async_protocol_handler_config() { set_handler(NULL, NULL); }
void del_out_connections(size_t count);
@@ -136,17 +121,12 @@ class async_protocol_handler
{
std::string m_fragment_buffer;
bool send_message(byte_slice message)
bool send_message(uint32_t command, epee::span<const uint8_t> in_buff, uint32_t flags, bool expect_response)
{
if (message.size() < sizeof(message_writer::header))
const bucket_head2 head = make_header(command, in_buff.size(), flags, expect_response);
if(!m_pservice_endpoint->do_send(byte_slice{as_byte_span(head), in_buff}))
return false;
message_writer::header head;
std::memcpy(std::addressof(head), message.data(), sizeof(head));
if(!m_pservice_endpoint->do_send(std::move(message)))
return false;
on_levin_traffic(m_connection_context, true, true, false, head.m_cb, head.m_command);
MDEBUG(m_connection_context << "LEVIN_PACKET_SENT. [len=" << head.m_cb
<< ", flags" << head.m_flags
<< ", r?=" << head.m_have_to_return_data
@@ -165,6 +145,7 @@ public:
stream_state_body
};
std::atomic<bool> m_deletion_initiated;
std::atomic<bool> m_protocol_released;
volatile uint32_t m_invoke_buf_ready;
@@ -181,7 +162,6 @@ public:
net_utils::i_service_endpoint* m_pservice_endpoint;
config_type& m_config;
t_connection_context& m_connection_context;
std::atomic<uint64_t> m_max_packet_size;
net_utils::buffer m_cache_in_buffer;
stream_state m_state;
@@ -309,12 +289,12 @@ public:
m_current_head(bucket_head2()),
m_pservice_endpoint(psnd_hndlr),
m_config(config),
m_connection_context(conn_context),
m_max_packet_size(config.m_initial_max_packet_size),
m_connection_context(conn_context),
m_cache_in_buffer(4 * 1024),
m_state(stream_state_head)
{
m_close_called = 0;
m_deletion_initiated = false;
m_protocol_released = false;
m_wait_count = 0;
m_oponent_protocol_ver = 0;
@@ -327,6 +307,7 @@ public:
try
{
m_deletion_initiated = true;
if(m_connection_initialized)
{
m_config.del_connection(this);
@@ -418,14 +399,13 @@ public:
}
// these should never fail, but do runtime check for safety
const uint64_t max_packet_size = m_max_packet_size;
CHECK_AND_ASSERT_MES(max_packet_size >= m_cache_in_buffer.size(), false, "Bad m_cache_in_buffer.size()");
CHECK_AND_ASSERT_MES(max_packet_size - m_cache_in_buffer.size() >= m_fragment_buffer.size(), false, "Bad m_cache_in_buffer.size() + m_fragment_buffer.size()");
CHECK_AND_ASSERT_MES(m_config.m_max_packet_size >= m_cache_in_buffer.size(), false, "Bad m_cache_in_buffer.size()");
CHECK_AND_ASSERT_MES(m_config.m_max_packet_size - m_cache_in_buffer.size() >= m_fragment_buffer.size(), false, "Bad m_cache_in_buffer.size() + m_fragment_buffer.size()");
// flipped to subtraction; prevent overflow since m_max_packet_size is variable and public
if(cb > max_packet_size - m_cache_in_buffer.size() - m_fragment_buffer.size())
if(cb > m_config.m_max_packet_size - m_cache_in_buffer.size() - m_fragment_buffer.size())
{
MWARNING(m_connection_context << "Maximum packet size exceed!, m_max_packet_size = " << max_packet_size
MWARNING(m_connection_context << "Maximum packet size exceed!, m_max_packet_size = " << m_config.m_max_packet_size
<< ", packet received " << m_cache_in_buffer.size() + cb
<< ", connection will be closed.");
return false;
@@ -450,7 +430,7 @@ public:
//async call scenario
boost::shared_ptr<invoke_response_handler_base> response_handler = m_invoke_response_handlers.front();
response_handler->reset_timer();
MDEBUG(m_connection_context << "LEVIN_PACKET partial msg received. len=" << cb << ", current total " << m_cache_in_buffer.size() << "/" << m_current_head.m_cb << " (" << (100.0f * m_cache_in_buffer.size() / (m_current_head.m_cb ? m_current_head.m_cb : 1)) << "%)");
MDEBUG(m_connection_context << "LEVIN_PACKET partial msg received. len=" << cb);
}
}
break;
@@ -485,14 +465,6 @@ public:
temp = std::move(m_fragment_buffer);
m_fragment_buffer.clear();
std::memcpy(std::addressof(m_current_head), std::addressof(temp[0]), sizeof(bucket_head2));
const size_t max_bytes = m_connection_context.get_max_bytes(m_current_head.m_command);
if(m_current_head.m_cb > std::min<size_t>(max_packet_size, max_bytes))
{
MERROR(m_connection_context << "Maximum packet size exceed!, m_max_packet_size = " << std::min<size_t>(max_packet_size, max_bytes)
<< ", packet header received " << m_current_head.m_cb << ", command " << m_current_head.m_command
<< ", connection will be closed.");
return false;
}
buff_to_invoke = {reinterpret_cast<const uint8_t*>(temp.data()) + sizeof(bucket_head2), temp.size() - sizeof(bucket_head2)};
}
@@ -542,17 +514,23 @@ public:
{
if(m_current_head.m_have_to_return_data)
{
levin::message_writer return_message{32 * 1024};
std::string return_buff;
const uint32_t return_code = m_config.m_pcommands_handler->invoke(
m_current_head.m_command, buff_to_invoke, return_message.buffer, m_connection_context
m_current_head.m_command, buff_to_invoke, return_buff, m_connection_context
);
// peer_id remains unset if dropped
if (m_current_head.m_command == m_connection_context.handshake_command() && m_connection_context.handshake_complete())
m_max_packet_size = m_config.m_max_packet_size;
bucket_head2 head = make_header(m_current_head.m_command, return_buff.size(), LEVIN_PACKET_RESPONSE, false);
head.m_return_code = SWAP32LE(return_code);
return_buff.insert(0, reinterpret_cast<const char*>(&head), sizeof(head));
if(!send_message(return_message.finalize_response(m_current_head.m_command, return_code)))
if(!m_pservice_endpoint->do_send(byte_slice{std::move(return_buff)}))
return false;
MDEBUG(m_connection_context << "LEVIN_PACKET_SENT. [len=" << head.m_cb
<< ", flags" << head.m_flags
<< ", r?=" << head.m_have_to_return_data
<<", cmd = " << head.m_command
<< ", ver=" << head.m_protocol_version);
}
else
m_config.m_pcommands_handler->notify(m_current_head.m_command, buff_to_invoke, m_connection_context);
@@ -599,11 +577,10 @@ public:
m_cache_in_buffer.erase(sizeof(bucket_head2));
m_state = stream_state_body;
m_oponent_protocol_ver = m_current_head.m_protocol_version;
const size_t max_bytes = m_connection_context.get_max_bytes(m_current_head.m_command);
if(m_current_head.m_cb > std::min<size_t>(max_packet_size, max_bytes))
if(m_current_head.m_cb > m_config.m_max_packet_size)
{
LOG_ERROR_CC(m_connection_context, "Maximum packet size exceed!, m_max_packet_size = " << std::min<size_t>(max_packet_size, max_bytes)
<< ", packet header received " << m_current_head.m_cb << ", command " << m_current_head.m_command
LOG_ERROR_CC(m_connection_context, "Maximum packet size exceed!, m_max_packet_size = " << m_config.m_max_packet_size
<< ", packet header received " << m_current_head.m_cb
<< ", connection will be closed.");
return false;
}
@@ -629,7 +606,7 @@ public:
}
template<class callback_t>
bool async_invoke(int command, message_writer in_msg, const callback_t &cb, size_t timeout = LEVIN_DEFAULT_TIMEOUT_PRECONFIGURED)
bool async_invoke(int command, const epee::span<const uint8_t> in_buff, const callback_t &cb, size_t timeout = LEVIN_DEFAULT_TIMEOUT_PRECONFIGURED)
{
misc_utils::auto_scope_leave_caller scope_exit_handler = misc_utils::create_scope_leave_handler(
boost::bind(&async_protocol_handler::finish_outer_call, this));
@@ -640,15 +617,24 @@ public:
int err_code = LEVIN_OK;
do
{
if(m_deletion_initiated)
{
err_code = LEVIN_ERROR_CONNECTION_DESTROYED;
break;
}
CRITICAL_REGION_LOCAL(m_call_lock);
if(m_deletion_initiated)
{
err_code = LEVIN_ERROR_CONNECTION_DESTROYED;
break;
}
boost::interprocess::ipcdetail::atomic_write32(&m_invoke_buf_ready, 0);
CRITICAL_REGION_BEGIN(m_invoke_response_handlers_lock);
if (command == m_connection_context.handshake_command())
m_max_packet_size = m_config.m_max_packet_size;
if(!send_message(in_msg.finalize_invoke(command)))
if(!send_message(command, in_buff, LEVIN_PACKET_REQUEST, true))
{
LOG_ERROR_CC(m_connection_context, "Failed to do_send");
err_code = LEVIN_ERROR_CONNECTION;
@@ -674,19 +660,22 @@ public:
return true;
}
int invoke(int command, message_writer in_msg, std::string& buff_out)
int invoke(int command, const epee::span<const uint8_t> in_buff, std::string& buff_out)
{
misc_utils::auto_scope_leave_caller scope_exit_handler = misc_utils::create_scope_leave_handler(
boost::bind(&async_protocol_handler::finish_outer_call, this));
if(m_deletion_initiated)
return LEVIN_ERROR_CONNECTION_DESTROYED;
CRITICAL_REGION_LOCAL(m_call_lock);
if(m_deletion_initiated)
return LEVIN_ERROR_CONNECTION_DESTROYED;
boost::interprocess::ipcdetail::atomic_write32(&m_invoke_buf_ready, 0);
if (command == m_connection_context.handshake_command())
m_max_packet_size = m_config.m_max_packet_size;
if (!send_message(in_msg.finalize_invoke(command)))
if (!send_message(command, in_buff, LEVIN_PACKET_REQUEST, true))
{
LOG_ERROR_CC(m_connection_context, "Failed to send request");
return LEVIN_ERROR_CONNECTION;
@@ -695,7 +684,7 @@ public:
uint64_t ticks_start = misc_utils::get_tick_count();
size_t prev_size = 0;
while(!boost::interprocess::ipcdetail::atomic_read32(&m_invoke_buf_ready) && !m_protocol_released)
while(!boost::interprocess::ipcdetail::atomic_read32(&m_invoke_buf_ready) && !m_deletion_initiated && !m_protocol_released)
{
if(m_cache_in_buffer.size() - prev_size >= MIN_BYTES_WANTED)
{
@@ -712,7 +701,7 @@ public:
return LEVIN_ERROR_CONNECTION_DESTROYED;
}
if(m_protocol_released)
if(m_deletion_initiated || m_protocol_released)
return LEVIN_ERROR_CONNECTION_DESTROYED;
CRITICAL_REGION_BEGIN(m_local_inv_buff_lock);
@@ -723,9 +712,31 @@ public:
return m_invoke_result_code;
}
/*! Sends `message` without adding a levin header. The message must have been
created with `make_noise_notify`, `make_fragmented_notify`, or
`message_writer::finalize_notify`. See additional instructions for
int notify(int command, const epee::span<const uint8_t> in_buff)
{
misc_utils::auto_scope_leave_caller scope_exit_handler = misc_utils::create_scope_leave_handler(
boost::bind(&async_protocol_handler::finish_outer_call, this));
if(m_deletion_initiated)
return LEVIN_ERROR_CONNECTION_DESTROYED;
CRITICAL_REGION_LOCAL(m_call_lock);
if(m_deletion_initiated)
return LEVIN_ERROR_CONNECTION_DESTROYED;
if (!send_message(command, in_buff, LEVIN_PACKET_REQUEST, false))
{
LOG_ERROR_CC(m_connection_context, "Failed to send notify message");
return -1;
}
return 1;
}
/*! Sends `message` without adding a levin header. The message must have
been created with `make_notify`, `make_noise_notify` or
`make_fragmented_notify`. See additional instructions for
`make_fragmented_notify`.
\return 1 on success */
@@ -735,11 +746,17 @@ public:
boost::bind(&async_protocol_handler::finish_outer_call, this)
);
if (!send_message(std::move(message)))
if(m_deletion_initiated)
return LEVIN_ERROR_CONNECTION_DESTROYED;
const std::size_t length = message.size();
if (!m_pservice_endpoint->do_send(std::move(message)))
{
LOG_ERROR_CC(m_connection_context, "Failed to send message, dropping it");
return -1;
}
MDEBUG(m_connection_context << "LEVIN_PACKET_SENT. [len=" << (length - sizeof(bucket_head2)) << ", r?=0]");
return 1;
}
//------------------------------------------------------------------------------------------
@@ -760,32 +777,36 @@ void async_protocol_handler_config<t_connection_context>::del_connection(async_p
template<class t_connection_context>
void async_protocol_handler_config<t_connection_context>::delete_connections(size_t count, bool incoming)
{
std::vector<typename connections_map::mapped_type> connections;
auto scope_exit_handler = misc_utils::create_scope_leave_handler([&connections]{
for (auto &aph: connections)
aph->finish_outer_call();
});
std::vector <boost::uuids::uuid> connections;
CRITICAL_REGION_BEGIN(m_connects_lock);
for (auto& c: m_connects)
{
if (c.second->m_connection_context.m_is_income == incoming)
if (c.second->start_outer_call())
connections.push_back(c.second);
connections.push_back(c.first);
}
// close random connections from the provided set
// TODO or better just keep removing random elements (performance)
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
shuffle(connections.begin(), connections.end(), std::default_random_engine(seed));
for (size_t i = 0; i < connections.size() && i < count; ++i)
m_connects.erase(connections[i]->get_connection_id());
while (count > 0 && connections.size() > 0)
{
try
{
auto i = connections.end() - 1;
async_protocol_handler<t_connection_context> *conn = m_connects.at(*i);
del_connection(conn);
conn->close();
connections.erase(i);
}
catch (const std::out_of_range &e)
{
MWARNING("Connection not found in m_connects, continuing");
}
--count;
}
CRITICAL_REGION_END();
for (size_t i = 0; i < connections.size() && i < count; ++i)
connections[i]->close();
}
//------------------------------------------------------------------------------------------
template<class t_connection_context>
@@ -829,53 +850,41 @@ int async_protocol_handler_config<t_connection_context>::find_and_lock_connectio
}
//------------------------------------------------------------------------------------------
template<class t_connection_context>
int async_protocol_handler_config<t_connection_context>::invoke(int command, message_writer in_msg, std::string& buff_out, boost::uuids::uuid connection_id)
int async_protocol_handler_config<t_connection_context>::invoke(int command, const epee::span<const uint8_t> in_buff, std::string& buff_out, boost::uuids::uuid connection_id)
{
async_protocol_handler<t_connection_context>* aph;
int r = find_and_lock_connection(connection_id, aph);
return LEVIN_OK == r ? aph->invoke(command, std::move(in_msg), buff_out) : r;
return LEVIN_OK == r ? aph->invoke(command, in_buff, buff_out) : r;
}
//------------------------------------------------------------------------------------------
template<class t_connection_context> template<class callback_t>
int async_protocol_handler_config<t_connection_context>::invoke_async(int command, message_writer in_msg, boost::uuids::uuid connection_id, const callback_t &cb, size_t timeout)
int async_protocol_handler_config<t_connection_context>::invoke_async(int command, const epee::span<const uint8_t> in_buff, boost::uuids::uuid connection_id, const callback_t &cb, size_t timeout)
{
async_protocol_handler<t_connection_context>* aph;
int r = find_and_lock_connection(connection_id, aph);
return LEVIN_OK == r ? aph->async_invoke(command, std::move(in_msg), cb, timeout) : r;
return LEVIN_OK == r ? aph->async_invoke(command, in_buff, cb, timeout) : r;
}
//------------------------------------------------------------------------------------------
template<class t_connection_context> template<class callback_t>
bool async_protocol_handler_config<t_connection_context>::foreach_connection(const callback_t &cb)
{
std::vector<typename connections_map::mapped_type> conn;
auto scope_exit_handler = misc_utils::create_scope_leave_handler([&conn]{
for (auto &aph: conn)
aph->finish_outer_call();
});
CRITICAL_REGION_BEGIN(m_connects_lock);
conn.reserve(m_connects.size());
for (auto &e: m_connects)
if (e.second->start_outer_call())
conn.push_back(e.second);
CRITICAL_REGION_END()
for (auto &aph: conn)
if (!cb(aph->get_context_ref()))
CRITICAL_REGION_LOCAL(m_connects_lock);
for(auto& c: m_connects)
{
async_protocol_handler<t_connection_context>* aph = c.second;
if(!cb(aph->get_context_ref()))
return false;
}
return true;
}
//------------------------------------------------------------------------------------------
template<class t_connection_context> template<class callback_t>
bool async_protocol_handler_config<t_connection_context>::for_connection(const boost::uuids::uuid &connection_id, const callback_t &cb)
{
async_protocol_handler<t_connection_context>* aph = nullptr;
if (find_and_lock_connection(connection_id, aph) != LEVIN_OK)
CRITICAL_REGION_LOCAL(m_connects_lock);
async_protocol_handler<t_connection_context>* aph = find_connection(connection_id);
if (!aph)
return false;
auto scope_exit_handler = misc_utils::create_scope_leave_handler(
boost::bind(&async_protocol_handler<t_connection_context>::finish_outer_call, aph));
if(!cb(aph->get_context_ref()))
return false;
return true;
@@ -920,6 +929,14 @@ void async_protocol_handler_config<t_connection_context>::set_handler(levin_comm
}
//------------------------------------------------------------------------------------------
template<class t_connection_context>
int async_protocol_handler_config<t_connection_context>::notify(int command, const epee::span<const uint8_t> in_buff, boost::uuids::uuid connection_id)
{
async_protocol_handler<t_connection_context>* aph;
int r = find_and_lock_connection(connection_id, aph);
return LEVIN_OK == r ? aph->notify(command, in_buff) : r;
}
//------------------------------------------------------------------------------------------
template<class t_connection_context>
int async_protocol_handler_config<t_connection_context>::send(byte_slice message, const boost::uuids::uuid& connection_id)
{
async_protocol_handler<t_connection_context>* aph;
@@ -930,14 +947,12 @@ int async_protocol_handler_config<t_connection_context>::send(byte_slice message
template<class t_connection_context>
bool async_protocol_handler_config<t_connection_context>::close(boost::uuids::uuid connection_id)
{
async_protocol_handler<t_connection_context>* aph = nullptr;
if (find_and_lock_connection(connection_id, aph) != LEVIN_OK)
CRITICAL_REGION_LOCAL(m_connects_lock);
async_protocol_handler<t_connection_context>* aph = find_connection(connection_id);
if (!aph)
return false;
auto scope_exit_handler = misc_utils::create_scope_leave_handler(
boost::bind(&async_protocol_handler<t_connection_context>::finish_outer_call, aph));
if (!aph->close())
return false;
CRITICAL_REGION_LOCAL(m_connects_lock);
m_connects.erase(connection_id);
return true;
}

View File

@@ -44,7 +44,6 @@
#include <boost/lambda/lambda.hpp>
#include <boost/interprocess/detail/atomic.hpp>
#include <boost/system/error_code.hpp>
#include <boost/utility/string_ref.hpp>
#include <functional>
#include "net/net_utils_base.h"
#include "net/net_ssl.h"
@@ -179,7 +178,7 @@ namespace net_utils
// SSL Options
if (m_ssl_options.support == epee::net_utils::ssl_support_t::e_ssl_support_enabled || m_ssl_options.support == epee::net_utils::ssl_support_t::e_ssl_support_autodetect)
{
if (!m_ssl_options.handshake(*m_ssl_socket, boost::asio::ssl::stream_base::client, {}, addr, timeout))
if (!m_ssl_options.handshake(*m_ssl_socket, boost::asio::ssl::stream_base::client, addr, timeout))
{
if (m_ssl_options.support == epee::net_utils::ssl_support_t::e_ssl_support_autodetect)
{
@@ -281,7 +280,7 @@ namespace net_utils
inline
bool send(const boost::string_ref buff, std::chrono::milliseconds timeout)
bool send(const std::string& buff, std::chrono::milliseconds timeout)
{
try
@@ -299,7 +298,7 @@ namespace net_utils
// object is used as a callback and will update the ec variable when the
// operation completes. The blocking_udp_client.cpp example shows how you
// can use boost::bind rather than boost::lambda.
async_write(buff.data(), buff.size(), ec);
async_write(buff.c_str(), buff.size(), ec);
// Block until the asynchronous operation has completed.
while (ec == boost::asio::error::would_block)

View File

@@ -24,9 +24,12 @@
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#pragma once
#pragma once
#include "http_base.h"
#include "reg_exp_definer.h"
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "net"
@@ -35,8 +38,173 @@ namespace epee
{
namespace net_utils
{
bool parse_uri(const std::string uri, http::uri_content& content);
bool parse_url_ipv6(const std::string url_str, http::url_content& content);
bool parse_url(const std::string url_str, http::url_content& content);
inline bool parse_uri_query(const std::string& query, std::list<std::pair<std::string, std::string> >& params)
{
enum state
{
st_param_name,
st_param_val
};
state st = st_param_name;
std::string::const_iterator start_it = query.begin();
std::pair<std::string, std::string> e;
for(std::string::const_iterator it = query.begin(); it != query.end(); it++)
{
switch(st)
{
case st_param_name:
if(*it == '=')
{
e.first.assign(start_it, it);
start_it = it;++start_it;
st = st_param_val;
}
break;
case st_param_val:
if(*it == '&')
{
e.second.assign(start_it, it);
start_it = it;++start_it;
params.push_back(e);
e.first.clear();e.second.clear();
st = st_param_name;
}
break;
default:
LOG_ERROR("Unknown state " << (int)st);
return false;
}
}
if(st == st_param_name)
{
if(start_it != query.end())
{
e.first.assign(start_it, query.end());
params.push_back(e);
}
}else
{
if(start_it != query.end())
e.second.assign(start_it, query.end());
if(e.first.size())
params.push_back(e);
}
return true;
}
inline
bool parse_uri(const std::string uri, http::uri_content& content)
{
///iframe_test.html?api_url=http://api.vk.com/api.php&api_id=3289090&api_settings=1&viewer_id=562964060&viewer_type=0&sid=0aad8d1c5713130f9ca0076f2b7b47e532877424961367d81e7fa92455f069be7e21bc3193cbd0be11895&secret=368ebbc0ef&access_token=668bc03f43981d883f73876ffff4aa8564254b359cc745dfa1b3cde7bdab2e94105d8f6d8250717569c0a7&user_id=0&group_id=0&is_app_user=1&auth_key=d2f7a895ca5ff3fdb2a2a8ae23fe679a&language=0&parent_language=0&ad_info=ElsdCQBaQlxiAQRdFUVUXiN2AVBzBx5pU1BXIgZUJlIEAWcgAUoLQg==&referrer=unknown&lc_name=9834b6a3&hash=
content.m_query_params.clear();
STATIC_REGEXP_EXPR_1(rexp_match_uri, "^([^?#]*)(\\?([^#]*))?(#(.*))?", boost::regex::icase | boost::regex::normal);
boost::smatch result;
if(!(boost::regex_search(uri, result, rexp_match_uri, boost::match_default) && result[0].matched))
{
LOG_PRINT_L1("[PARSE URI] regex not matched for uri: " << uri);
content.m_path = uri;
return true;
}
if(result[1].matched)
{
content.m_path = result[1];
}
if(result[3].matched)
{
content.m_query = result[3];
}
if(result[5].matched)
{
content.m_fragment = result[5];
}
if(content.m_query.size())
{
parse_uri_query(content.m_query, content.m_query_params);
}
return true;
}
inline
bool parse_url_ipv6(const std::string url_str, http::url_content& content)
{
STATIC_REGEXP_EXPR_1(rexp_match_uri, "^((.*?)://)?(\\[(.*)\\](:(\\d+))?)(.*)?", boost::regex::icase | boost::regex::normal);
// 12 3 4 5 6 7
content.port = 0;
boost::smatch result;
if(!(boost::regex_search(url_str, result, rexp_match_uri, boost::match_default) && result[0].matched))
{
LOG_PRINT_L1("[PARSE URI] regex not matched for uri: " << rexp_match_uri);
//content.m_path = uri;
return false;
}
if(result[2].matched)
{
content.schema = result[2];
}
if(result[4].matched)
{
content.host = result[4];
}
else // if host not matched, matching should be considered failed
{
return false;
}
if(result[6].matched)
{
content.port = boost::lexical_cast<uint64_t>(result[6]);
}
if(result[7].matched)
{
content.uri = result[7];
return parse_uri(result[7], content.m_uri_content);
}
return true;
}
inline
bool parse_url(const std::string url_str, http::url_content& content)
{
if (parse_url_ipv6(url_str, content)) return true;
///iframe_test.html?api_url=http://api.vk.com/api.php&api_id=3289090&api_settings=1&viewer_id=562964060&viewer_type=0&sid=0aad8d1c5713130f9ca0076f2b7b47e532877424961367d81e7fa92455f069be7e21bc3193cbd0be11895&secret=368ebbc0ef&access_token=668bc03f43981d883f73876ffff4aa8564254b359cc745dfa1b3cde7bdab2e94105d8f6d8250717569c0a7&user_id=0&group_id=0&is_app_user=1&auth_key=d2f7a895ca5ff3fdb2a2a8ae23fe679a&language=0&parent_language=0&ad_info=ElsdCQBaQlxiAQRdFUVUXiN2AVBzBx5pU1BXIgZUJlIEAWcgAUoLQg==&referrer=unknown&lc_name=9834b6a3&hash=
//STATIC_REGEXP_EXPR_1(rexp_match_uri, "^([^?#]*)(\\?([^#]*))?(#(.*))?", boost::regex::icase | boost::regex::normal);
STATIC_REGEXP_EXPR_1(rexp_match_uri, "^((.*?)://)?(([^/:]*)(:(\\d+))?)(.*)?", boost::regex::icase | boost::regex::normal);
// 12 34 5 6 7
content.port = 0;
boost::smatch result;
if(!(boost::regex_search(url_str, result, rexp_match_uri, boost::match_default) && result[0].matched))
{
LOG_PRINT_L1("[PARSE URI] regex not matched for uri: " << rexp_match_uri);
//content.m_path = uri;
return true;
}
if(result[2].matched)
{
content.schema = result[2];
}
if(result[4].matched)
{
content.host = result[4];
}
if(result[6].matched)
{
content.port = boost::lexical_cast<uint64_t>(result[6]);
}
if(result[7].matched)
{
content.uri = result[7];
return parse_uri(result[7], content.m_uri_content);
}
return true;
}
}
}

View File

@@ -36,7 +36,6 @@
#include <boost/utility/string_ref.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/ssl.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/system/error_code.hpp>
#define SSL_FINGERPRINT_SIZE 32
@@ -133,7 +132,6 @@ namespace net_utils
bool handshake(
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> &socket,
boost::asio::ssl::stream_base::handshake_type type,
boost::asio::const_buffer buffer = {},
const std::string& host = {},
std::chrono::milliseconds timeout = std::chrono::seconds(15)) const;
};
@@ -145,9 +143,6 @@ namespace net_utils
bool create_ec_ssl_certificate(EVP_PKEY *&pkey, X509 *&cert);
bool create_rsa_ssl_certificate(EVP_PKEY *&pkey, X509 *&cert);
//! Store private key for `ssl` at `base + ".key"` unencrypted and certificate for `ssl` at `base + ".crt"`.
boost::system::error_code store_ssl_keys(boost::asio::ssl::context& ssl, const boost::filesystem::path& base);
}
}

View File

@@ -29,7 +29,6 @@
#define _REG_EXP_DEFINER_H_
#include <boost/interprocess/detail/atomic.hpp>
#include <boost/regex.hpp>
#include "syncobj.h"
namespace epee

View File

@@ -141,6 +141,7 @@ public:
rolling_median_t(rolling_median_t &&m)
{
free(data);
memcpy(this, &m, sizeof(rolling_median_t));
m.data = NULL;
}

View File

@@ -73,8 +73,7 @@ public: \
template<bool is_store, class t_storage> \
bool serialize_map(t_storage& stg, typename t_storage::hsection hparent_section) \
{ \
decltype(*this) &this_ref = *this; \
(void) this_ref; // Suppress unused var warnings. Sometimes this var is used, sometimes not.
decltype(*this) &this_ref = *this;
#define KV_SERIALIZE_N(varialble, val_name) \
epee::serialization::selector<is_store>::serialize(this_ref.varialble, stg, hparent_section, val_name);

View File

@@ -31,6 +31,7 @@
#include <algorithm>
#include <cstdint>
#include <memory>
#include <string>
#include <type_traits>
namespace epee
@@ -166,11 +167,10 @@ namespace epee
}
//! make a span from a std::string
template<typename T, typename U>
span<const T> strspan(const U&s) noexcept
template<typename T>
span<const T> strspan(const std::string &s) noexcept
{
static_assert(std::is_same<typename U::value_type, char>(), "unexpected source type");
static_assert(std::is_same<T, char>() || std::is_same<T, unsigned char>() || std::is_same<T, int8_t>() || std::is_same<T, uint8_t>(), "Unexpected destination type");
static_assert(std::is_same<T, char>() || std::is_same<T, unsigned char>() || std::is_same<T, int8_t>() || std::is_same<T, uint8_t>(), "Unexpected type");
return {reinterpret_cast<const T*>(s.data()), s.size()};
}
}

View File

@@ -29,7 +29,6 @@
#include <boost/utility/string_ref.hpp>
#include <chrono>
#include <string>
#include "byte_slice.h"
#include "portable_storage_template_helper.h"
#include "net/http_base.h"
#include "net/http_server_handlers_map2.h"
@@ -75,12 +74,12 @@ 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")
{
byte_slice req_param;
if(!serialization::store_t_to_binary(out_struct, req_param, 16 * 1024))
std::string req_param;
if(!serialization::store_t_to_binary(out_struct, req_param))
return false;
const http::http_response_info* pri = NULL;
if(!transport.invoke(uri, method, boost::string_ref{reinterpret_cast<const char*>(req_param.data()), req_param.size()}, timeout, std::addressof(pri)))
if(!transport.invoke(uri, method, req_param, timeout, std::addressof(pri)))
{
LOG_PRINT_L1("Failed to invoke http request to " << uri);
return false;
@@ -98,12 +97,7 @@ namespace epee
return false;
}
static const constexpr epee::serialization::portable_storage::limits_t default_http_bin_limits = {
65536 * 3, // objects
65536 * 3, // fields
65536 * 3, // strings
};
return serialization::load_t_from_binary(result_struct, epee::strspan<uint8_t>(pri->m_body), &default_http_bin_limits);
return serialization::load_t_from_binary(result_struct, epee::strspan<uint8_t>(pri->m_body));
}
template<class t_request, class t_response, class t_transport>

View File

@@ -27,29 +27,29 @@
#pragma once
#include "portable_storage_template_helper.h"
#include <boost/utility/string_ref.hpp>
#include <boost/utility/value_init.hpp>
#include <functional>
#include "byte_slice.h"
#include "span.h"
#include "net/levin_base.h"
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "net"
template<typename context_t>
void on_levin_traffic(const context_t &context, bool initiator, bool sent, bool error, size_t bytes, const char *category);
template<typename context_t>
void on_levin_traffic(const context_t &context, bool initiator, bool sent, bool error, size_t bytes, int command);
namespace
{
static const constexpr epee::serialization::portable_storage::limits_t default_levin_limits = {
8192, // objects
16384, // fields
16384, // strings
};
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
@@ -75,7 +75,7 @@ namespace epee
return false;
}
serialization::portable_storage stg_ret;
if(!stg_ret.load_from_binary(buff_to_recv, &default_levin_limits))
if(!stg_ret.load_from_binary(buff_to_recv))
{
LOG_ERROR("Failed to load_from_binary on command " << command);
return false;
@@ -110,18 +110,18 @@ namespace epee
const boost::uuids::uuid &conn_id = context.m_connection_id;
typename serialization::portable_storage stg;
out_struct.store(stg);
levin::message_writer to_send{16 * 1024};
std::string buff_to_recv;
stg.store_to_binary(to_send.buffer);
std::string buff_to_send, buff_to_recv;
stg.store_to_binary(buff_to_send);
int res = transport.invoke(command, std::move(to_send), buff_to_recv, conn_id);
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 )
{
LOG_PRINT_L1("Failed to invoke command " << command << " return code " << res);
return false;
}
typename serialization::portable_storage stg_ret;
if(!stg_ret.load_from_binary(buff_to_recv, &default_levin_limits))
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);
@@ -137,9 +137,10 @@ namespace epee
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
levin::message_writer to_send{16 * 1024};
stg.store_to_binary(to_send.buffer);
int res = transport.invoke_async(command, std::move(to_send), conn_id, [cb, command](int code, const epee::span<const uint8_t> buff, typename t_transport::connection_context& context)->bool
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 )
@@ -151,7 +152,7 @@ namespace epee
return false;
}
serialization::portable_storage stg_ret;
if(!stg_ret.load_from_binary(buff, &default_levin_limits))
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);
@@ -183,10 +184,11 @@ namespace epee
const boost::uuids::uuid &conn_id = context.m_connection_id;
serialization::portable_storage stg;
out_struct.store(stg);
levin::message_writer to_send;
stg.store_to_binary(to_send.buffer);
std::string buff_to_send;
stg.store_to_binary(buff_to_send);
int res = transport.send(to_send.finalize_notify(command), conn_id);
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 )
{
MERROR("Failed to notify command " << command << " return code " << res);
@@ -197,10 +199,10 @@ namespace epee
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
template<class t_owner, class t_in_type, class t_out_type, class t_context, class callback_t>
int buff_to_t_adapter(int command, const epee::span<const uint8_t> in_buff, byte_stream& buff_out, callback_t cb, t_context& context )
int buff_to_t_adapter(int command, const epee::span<const uint8_t> in_buff, std::string& buff_out, callback_t cb, t_context& context )
{
serialization::portable_storage strg;
if(!strg.load_from_binary(in_buff, &default_levin_limits))
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);
@@ -225,6 +227,7 @@ 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;
}
@@ -233,7 +236,7 @@ namespace epee
int buff_to_t_adapter(t_owner* powner, int command, const epee::span<const uint8_t> in_buff, callback_t cb, t_context& context)
{
serialization::portable_storage strg;
if(!strg.load_from_binary(in_buff, &default_levin_limits))
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);
@@ -251,7 +254,7 @@ namespace epee
}
#define CHAIN_LEVIN_INVOKE_MAP2(context_type) \
int invoke(int command, const epee::span<const uint8_t> in_buff, epee::byte_stream& buff_out, context_type& context) \
int invoke(int command, const epee::span<const uint8_t> in_buff, std::string& buff_out, context_type& context) \
{ \
bool handled = false; \
return handle_invoke_map(false, command, in_buff, buff_out, context, handled); \
@@ -260,13 +263,13 @@ namespace epee
#define CHAIN_LEVIN_NOTIFY_MAP2(context_type) \
int notify(int command, const epee::span<const uint8_t> in_buff, context_type& context) \
{ \
bool handled = false; epee::byte_stream fake_str; \
return handle_invoke_map(true, command, in_buff, fake_str, context, handled); \
bool handled = false; std::string fake_str;\
return handle_invoke_map(true, command, in_buff, fake_str, context, handled); \
}
#define CHAIN_LEVIN_INVOKE_MAP() \
int invoke(int command, const epee::span<const uint8_t> in_buff, epee::byte_stream& buff_out, epee::net_utils::connection_context_base& context) \
int invoke(int command, const epee::span<const uint8_t> in_buff, std::string& buff_out, epee::net_utils::connection_context_base& context) \
{ \
bool handled = false; \
return handle_invoke_map(false, command, in_buff, buff_out, context, handled); \
@@ -286,7 +289,7 @@ namespace epee
}
#define BEGIN_INVOKE_MAP2(owner_type) \
template <class t_context> int handle_invoke_map(bool is_notify, int command, const epee::span<const uint8_t> in_buff, epee::byte_stream& buff_out, t_context& context, bool& handled) \
template <class t_context> int handle_invoke_map(bool is_notify, int command, const epee::span<const uint8_t> in_buff, std::string& buff_out, t_context& context, bool& handled) \
{ \
try { \
typedef owner_type internal_owner_type_name;

View File

@@ -28,8 +28,13 @@
#pragma once
#include <boost/utility/string_ref_fwd.hpp>
#include <string>
#include <algorithm>
#include <boost/utility/string_ref.hpp>
#include "misc_log_ex.h"
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "serialization"
namespace epee
{
@@ -92,7 +97,46 @@ namespace misc_utils
return lut[(uint8_t)c] & 1;
}
std::string transform_to_escape_sequence(const std::string& src);
inline std::string transform_to_escape_sequence(const std::string& src)
{
static const char escaped[] = "\b\f\n\r\t\v\"\\/";
std::string::const_iterator it = std::find_first_of(src.begin(), src.end(), escaped, escaped + sizeof(escaped));
if (it == src.end())
return src;
std::string res;
res.reserve(2 * src.size());
res.assign(src.begin(), it);
for(; it!=src.end(); ++it)
{
switch(*it)
{
case '\b': //Backspace (ascii code 08)
res+="\\b"; break;
case '\f': //Form feed (ascii code 0C)
res+="\\f"; break;
case '\n': //New line
res+="\\n"; break;
case '\r': //Carriage return
res+="\\r"; break;
case '\t': //Tab
res+="\\t"; break;
case '\v': //Vertical tab
res+="\\v"; break;
//case '\'': //Apostrophe or single quote
// res+="\\'"; break;
case '"': //Double quote
res+="\\\""; break;
case '\\': //Backslash caracter
res+="\\\\"; break;
case '/': //Backslash caracter
res+="\\/"; break;
default:
res.push_back(*it);
}
}
return res;
}
/*
\b Backspace (ascii code 08)
@@ -106,7 +150,98 @@ namespace misc_utils
\\ Backslash character
*/
void match_string2(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string& val);
inline void match_string2(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string& val)
{
bool escape_mode = false;
std::string::const_iterator it = star_end_string;
++it;
std::string::const_iterator fi = it;
while (fi != buf_end && ((lut[(uint8_t)*fi] & 32)) == 0)
++fi;
val.assign(it, fi);
it = fi;
for(;it != buf_end;it++)
{
if(escape_mode/*prev_ch == '\\'*/)
{
switch(*it)
{
case 'b': //Backspace (ascii code 08)
val.push_back(0x08);break;
case 'f': //Form feed (ascii code 0C)
val.push_back(0x0C);break;
case 'n': //New line
val.push_back('\n');break;
case 'r': //Carriage return
val.push_back('\r');break;
case 't': //Tab
val.push_back('\t');break;
case 'v': //Vertical tab
val.push_back('\v');break;
case '\'': //Apostrophe or single quote
val.push_back('\'');break;
case '"': //Double quote
val.push_back('"');break;
case '\\': //Backslash character
val.push_back('\\');break;
case '/': //Slash character
val.push_back('/');break;
case 'u': //Unicode code point
if (buf_end - it < 4)
{
ASSERT_MES_AND_THROW("Invalid Unicode escape sequence");
}
else
{
uint32_t dst = 0;
for (int i = 0; i < 4; ++i)
{
const unsigned char tmp = isx[(unsigned char)*++it];
CHECK_AND_ASSERT_THROW_MES(tmp != 0xff, "Bad Unicode encoding");
dst = dst << 4 | tmp;
}
// encode as UTF-8
if (dst <= 0x7f)
{
val.push_back(dst);
}
else if (dst <= 0x7ff)
{
val.push_back(0xc0 | (dst >> 6));
val.push_back(0x80 | (dst & 0x3f));
}
else if (dst <= 0xffff)
{
val.push_back(0xe0 | (dst >> 12));
val.push_back(0x80 | ((dst >> 6) & 0x3f));
val.push_back(0x80 | (dst & 0x3f));
}
else
{
ASSERT_MES_AND_THROW("Unicode code point is out or range");
}
}
break;
default:
val.push_back(*it);
LOG_PRINT_L0("Unknown escape sequence :\"\\" << *it << "\"");
}
escape_mode = false;
}else if(*it == '"')
{
star_end_string = it;
return;
}else if(*it == '\\')
{
escape_mode = true;
}
else
{
val.push_back(*it);
}
}
ASSERT_MES_AND_THROW("Failed to match string in json entry: " << std::string(star_end_string, buf_end));
}
inline bool match_string(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string& val)
{
try
@@ -120,7 +255,42 @@ namespace misc_utils
return false;
}
}
void match_number2(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, boost::string_ref& val, bool& is_float_val, bool& is_signed_val);
inline void match_number2(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, boost::string_ref& val, bool& is_float_val, bool& is_signed_val)
{
val.clear();
uint8_t float_flag = 0;
is_signed_val = false;
size_t chars = 0;
std::string::const_iterator it = star_end_string;
if (it != buf_end && *it == '-')
{
is_signed_val = true;
++chars;
++it;
}
for(;it != buf_end;it++)
{
const uint8_t flags = lut[(uint8_t)*it];
if (flags & 16)
{
float_flag |= flags;
++chars;
}
else
{
val = boost::string_ref(&*star_end_string, chars);
if(val.size())
{
star_end_string = --it;
is_float_val = !!(float_flag & 2);
return;
}
else
ASSERT_MES_AND_THROW("wrong number in json entry: " << std::string(star_end_string, buf_end));
}
}
ASSERT_MES_AND_THROW("wrong number in json entry: " << std::string(star_end_string, buf_end));
}
inline bool match_number(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, boost::string_ref& val)
{
try
@@ -134,7 +304,25 @@ namespace misc_utils
return false;
}
}
void match_word2(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, boost::string_ref& val);
inline void match_word2(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, boost::string_ref& val)
{
val.clear();
for(std::string::const_iterator it = star_end_string;it != buf_end;it++)
{
if (!(lut[(uint8_t)*it] & 4))
{
val = boost::string_ref(&*star_end_string, std::distance(star_end_string, it));
if(val.size())
{
star_end_string = --it;
return;
}else
ASSERT_MES_AND_THROW("failed to match word number in json entry: " << std::string(star_end_string, buf_end));
}
}
ASSERT_MES_AND_THROW("failed to match word number in json entry: " << std::string(star_end_string, buf_end));
}
inline bool match_word(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, boost::string_ref& val)
{
try
@@ -147,8 +335,44 @@ namespace misc_utils
return false;
}
}
bool match_word_with_extrasymb(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string& val);
bool match_word_til_equal_mark(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string::const_iterator& word_end);
inline bool match_word_with_extrasymb(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string& val)
{
val.clear();
for(std::string::const_iterator it = star_end_string;it != buf_end;it++)
{
if(!isalnum(*it) && *it != '-' && *it != '_')
{
val.assign(star_end_string, it);
if(val.size())
{
star_end_string = --it;
return true;
}else
return false;
}
}
return false;
}
inline bool match_word_til_equal_mark(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string::const_iterator& word_end)
{
word_end = star_end_string;
for(std::string::const_iterator it = star_end_string;it != buf_end;it++)
{
if(isspace(*it))
{
continue;
}else if( *it == '=' )
{
star_end_string = it;
word_end = it;
return true;
}
}
return false;
}
}
}
}

View File

@@ -24,19 +24,24 @@
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#pragma once
#include "portable_storage_base.h"
#include "portable_storage_val_converters.h"
#include "misc_log_ex.h"
#include "span.h"
#include <type_traits>
#include <boost/mpl/contains.hpp>
#include "misc_language.h"
#include "portable_storage_base.h"
#include "portable_storage_to_bin.h"
#include "portable_storage_from_bin.h"
#include "portable_storage_to_json.h"
#include "portable_storage_from_json.h"
#include "portable_storage_val_converters.h"
#include "span.h"
#include "int-util.h"
namespace epee
{
class byte_slice;
class byte_stream;
namespace serialization
{
/************************************************************************/
@@ -49,13 +54,6 @@ namespace epee
typedef epee::serialization::harray harray;
typedef storage_entry meta_entry;
struct limits_t
{
size_t n_objects;
size_t n_fields;
size_t n_strings; // not counting field names
};
portable_storage(){}
virtual ~portable_storage(){}
hsection open_section(const std::string& section_name, hsection hparent_section, bool create_if_notexist = false);
@@ -85,14 +83,9 @@ namespace epee
bool delete_entry(const std::string& pentry_name, hsection hparent_section = nullptr);
//-------------------------------------------------------------------------------
bool store_to_binary(byte_slice& target, std::size_t initial_buffer_size = 8192);
bool store_to_binary(byte_stream& ss);
bool load_from_binary(const epee::span<const uint8_t> target, const limits_t *limits = nullptr);
bool load_from_binary(const std::string& target, const limits_t *limits = nullptr)
{
return load_from_binary(epee::strspan<uint8_t>(target), limits);
}
bool store_to_binary(binarybuffer& target);
bool load_from_binary(const epee::span<const uint8_t> target);
bool load_from_binary(const std::string& target) { return load_from_binary(epee::strspan<uint8_t>(target)); }
template<class trace_policy>
bool dump_as_xml(std::string& targetObj, const std::string& root_name = "");
bool dump_as_json(std::string& targetObj, size_t indent = 0, bool insert_newlines = true);
@@ -117,13 +110,99 @@ namespace epee
};
#pragma pack(pop)
};
inline
bool portable_storage::dump_as_json(std::string& buff, size_t indent, bool insert_newlines)
{
TRY_ENTRY();
std::stringstream ss;
epee::serialization::dump_as_json(ss, m_root, indent, insert_newlines);
buff = ss.str();
return true;
CATCH_ENTRY("portable_storage::dump_as_json", false)
}
inline
bool portable_storage::load_from_json(const std::string& source)
{
TRY_ENTRY();
return json::load_from_json(source, *this);
CATCH_ENTRY("portable_storage::load_from_json", false)
}
template<class trace_policy>
bool portable_storage::dump_as_xml(std::string& targetObj, const std::string& root_name)
{
return false;//TODO: don't think i ever again will use xml - ambiguous and "overtagged" format
}
}
inline
bool portable_storage::store_to_binary(binarybuffer& target)
{
TRY_ENTRY();
std::stringstream ss;
storage_block_header sbh = AUTO_VAL_INIT(sbh);
sbh.m_signature_a = SWAP32LE(PORTABLE_STORAGE_SIGNATUREA);
sbh.m_signature_b = SWAP32LE(PORTABLE_STORAGE_SIGNATUREB);
sbh.m_ver = PORTABLE_STORAGE_FORMAT_VER;
ss.write((const char*)&sbh, sizeof(storage_block_header));
pack_entry_to_buff(ss, m_root);
target = ss.str();
return true;
CATCH_ENTRY("portable_storage::store_to_binary", false)
}
inline
bool portable_storage::load_from_binary(const epee::span<const uint8_t> source)
{
m_root.m_entries.clear();
if(source.size() < sizeof(storage_block_header))
{
LOG_ERROR("portable_storage: wrong binary format, packet size = " << source.size() << " less than expected sizeof(storage_block_header)=" << sizeof(storage_block_header));
return false;
}
storage_block_header* pbuff = (storage_block_header*)source.data();
if(pbuff->m_signature_a != SWAP32LE(PORTABLE_STORAGE_SIGNATUREA) ||
pbuff->m_signature_b != SWAP32LE(PORTABLE_STORAGE_SIGNATUREB)
)
{
LOG_ERROR("portable_storage: wrong binary format - signature mismatch");
return false;
}
if(pbuff->m_ver != PORTABLE_STORAGE_FORMAT_VER)
{
LOG_ERROR("portable_storage: wrong binary format - unknown format ver = " << pbuff->m_ver);
return false;
}
TRY_ENTRY();
throwable_buffer_reader buf_reader(source.data()+sizeof(storage_block_header), source.size()-sizeof(storage_block_header));
buf_reader.read(m_root);
return true;//TODO:
CATCH_ENTRY("portable_storage::load_from_binary", false);
}
//---------------------------------------------------------------------------------------------------------------
inline
hsection portable_storage::open_section(const std::string& section_name, hsection hparent_section, bool create_if_notexist)
{
TRY_ENTRY();
hparent_section = hparent_section ? hparent_section:&m_root;
storage_entry* pentry = find_storage_entry(section_name, hparent_section);
if(!pentry)
{
if(!create_if_notexist)
return nullptr;
return insert_new_section(section_name, hparent_section);
}
CHECK_AND_ASSERT(pentry , nullptr);
//check that section_entry we find is real "CSSection"
if(pentry->type() != typeid(section))
{
if(create_if_notexist)
*pentry = storage_entry(section());//replace
else
return nullptr;
}
return &boost::get<section>(*pentry);
CATCH_ENTRY("portable_storage::open_section", nullptr);
}
//---------------------------------------------------------------------------------------------------------------
template<class to_type>
struct get_value_visitor: boost::static_visitor<void>
{
@@ -149,6 +228,20 @@ namespace epee
//CATCH_ENTRY("portable_storage::template<>get_value", false);
}
//---------------------------------------------------------------------------------------------------------------
inline
bool portable_storage::get_value(const std::string& value_name, storage_entry& val, hsection hparent_section)
{
//TRY_ENTRY();
if(!hparent_section) hparent_section = &m_root;
storage_entry* pentry = find_storage_entry(value_name, hparent_section);
if(!pentry)
return false;
val = *pentry;
return true;
//CATCH_ENTRY("portable_storage::template<>get_value", false);
}
//---------------------------------------------------------------------------------------------------------------
template<class t_value>
bool portable_storage::set_value(const std::string& value_name, t_value&& v, hsection hparent_section)
{
@@ -170,18 +263,40 @@ namespace epee
CATCH_ENTRY("portable_storage::template<>set_value", false);
}
//---------------------------------------------------------------------------------------------------------------
inline
storage_entry* portable_storage::find_storage_entry(const std::string& pentry_name, hsection psection)
{
TRY_ENTRY();
CHECK_AND_ASSERT(psection, nullptr);
auto it = psection->m_entries.find(pentry_name);
if(it == psection->m_entries.end())
return nullptr;
return &it->second;
CATCH_ENTRY("portable_storage::find_storage_entry", nullptr);
}
//---------------------------------------------------------------------------------------------------------------
template<class entry_type>
storage_entry* portable_storage::insert_new_entry_get_storage_entry(const std::string& pentry_name, hsection psection, entry_type&& entry)
{
static_assert(std::is_rvalue_reference<entry_type&&>(), "unexpected copy of value");
TRY_ENTRY();
CHECK_AND_ASSERT(psection, nullptr);
CHECK_AND_ASSERT(!pentry_name.empty(), nullptr);
auto ins_res = psection->m_entries.emplace(pentry_name, std::forward<entry_type>(entry));
return &ins_res.first->second;
CATCH_ENTRY("portable_storage::insert_new_entry_get_storage_entry", nullptr);
}
//---------------------------------------------------------------------------------------------------------------
inline
hsection portable_storage::insert_new_section(const std::string& pentry_name, hsection psection)
{
TRY_ENTRY();
storage_entry* pse = insert_new_entry_get_storage_entry(pentry_name, psection, section());
if(!pse) return nullptr;
return &boost::get<section>(*pse);
CATCH_ENTRY("portable_storage::insert_new_section", nullptr);
}
//---------------------------------------------------------------------------------------------------------------
template<class to_type>
struct get_first_value_visitor: boost::static_visitor<bool>
{
@@ -235,6 +350,7 @@ namespace epee
}
};
template<class t_value>
bool portable_storage::get_next_value(harray hval_array, t_value& target)
{
@@ -292,5 +408,83 @@ namespace epee
return true;
CATCH_ENTRY("portable_storage::insert_next_value", false);
}
//---------------------------------------------------------------------------------------------------------------
//sections
inline
harray portable_storage::get_first_section(const std::string& sec_name, hsection& h_child_section, hsection hparent_section)
{
TRY_ENTRY();
if(!hparent_section) hparent_section = &m_root;
storage_entry* pentry = find_storage_entry(sec_name, hparent_section);
if(!pentry)
return nullptr;
if(pentry->type() != typeid(array_entry))
return nullptr;
array_entry& ar_entry = boost::get<array_entry>(*pentry);
if(ar_entry.type() != typeid(array_entry_t<section>))
return nullptr;
array_entry_t<section>& sec_array = boost::get<array_entry_t<section>>(ar_entry);
section* psec = sec_array.get_first_val();
if(!psec)
return nullptr;
h_child_section = psec;
return &ar_entry;
CATCH_ENTRY("portable_storage::get_first_section", nullptr);
}
//---------------------------------------------------------------------------------------------------------------
inline
bool portable_storage::get_next_section(harray hsec_array, hsection& h_child_section)
{
TRY_ENTRY();
CHECK_AND_ASSERT(hsec_array, false);
if(hsec_array->type() != typeid(array_entry_t<section>))
return false;
array_entry_t<section>& sec_array = boost::get<array_entry_t<section>>(*hsec_array);
h_child_section = sec_array.get_next_val();
if(!h_child_section)
return false;
return true;
CATCH_ENTRY("portable_storage::get_next_section", false);
}
//---------------------------------------------------------------------------------------------------------------
inline
harray portable_storage::insert_first_section(const std::string& sec_name, hsection& hinserted_childsection, hsection hparent_section)
{
TRY_ENTRY();
if(!hparent_section) hparent_section = &m_root;
storage_entry* pentry = find_storage_entry(sec_name, hparent_section);
if(!pentry)
{
pentry = insert_new_entry_get_storage_entry(sec_name, hparent_section, array_entry(array_entry_t<section>()));
if(!pentry)
return nullptr;
}
if(pentry->type() != typeid(array_entry))
*pentry = storage_entry(array_entry(array_entry_t<section>()));
array_entry& ar_entry = boost::get<array_entry>(*pentry);
if(ar_entry.type() != typeid(array_entry_t<section>))
ar_entry = array_entry(array_entry_t<section>());
array_entry_t<section>& sec_array = boost::get<array_entry_t<section>>(ar_entry);
hinserted_childsection = &sec_array.insert_first_val(section());
return &ar_entry;
CATCH_ENTRY("portable_storage::insert_first_section", nullptr);
}
//---------------------------------------------------------------------------------------------------------------
inline
bool portable_storage::insert_next_section(harray hsec_array, hsection& hinserted_childsection)
{
TRY_ENTRY();
CHECK_AND_ASSERT(hsec_array, false);
CHECK_AND_ASSERT_MES(hsec_array->type() == typeid(array_entry_t<section>),
false, "unexpected type(not 'section') in insert_next_section, type: " << hsec_array->type().name());
array_entry_t<section>& sec_array = boost::get<array_entry_t<section>>(*hsec_array);
hinserted_childsection = &sec_array.insert_next_value(section());
return true;
CATCH_ENTRY("portable_storage::insert_next_section", false);
}
//---------------------------------------------------------------------------------------------------------------
}
}

View File

@@ -29,10 +29,10 @@
#pragma once
#include <boost/variant.hpp>
#include <boost/any.hpp>
#include <string>
#include <vector>
#include <deque>
#include <map>
#define PORTABLE_STORAGE_SIGNATUREA 0x01011101
#define PORTABLE_STORAGE_SIGNATUREB 0x01020101 // bender's nightmare

View File

@@ -29,7 +29,6 @@
#pragma once
#include "misc_language.h"
#include "misc_log_ex.h"
#include "portable_storage_base.h"
#include "portable_storage_bin_utils.h"
@@ -43,24 +42,6 @@ namespace epee
{
namespace serialization
{
template<typename T>
struct ps_min_bytes {
static constexpr const size_t strict = 4096; // actual low bound
};
template<> struct ps_min_bytes<uint64_t> { static constexpr const size_t strict = 8; };
template<> struct ps_min_bytes<int64_t> { static constexpr const size_t strict = 8; };
template<> struct ps_min_bytes<uint32_t> { static constexpr const size_t strict = 4; };
template<> struct ps_min_bytes<int32_t> { static constexpr const size_t strict = 4; };
template<> struct ps_min_bytes<uint16_t> { static constexpr const size_t strict = 2; };
template<> struct ps_min_bytes<int16_t> { static constexpr const size_t strict = 2; };
template<> struct ps_min_bytes<uint8_t> { static constexpr const size_t strict = 1; };
template<> struct ps_min_bytes<int8_t> { static constexpr const size_t strict = 1; };
template<> struct ps_min_bytes<double> { static constexpr const size_t strict = 8; };
template<> struct ps_min_bytes<bool> { static constexpr const size_t strict = 1; };
template<> struct ps_min_bytes<std::string> { static constexpr const size_t strict = 2; };
template<> struct ps_min_bytes<section> { static constexpr const size_t strict = 1; };
template<> struct ps_min_bytes<array_entry> { static constexpr const size_t strict = 1; };
struct throwable_buffer_reader
{
throwable_buffer_reader(const void* ptr, size_t sz);
@@ -80,9 +61,6 @@ namespace epee
void read(section& sec);
void read(std::string& str);
void read(array_entry &ae);
template<class t_type>
size_t min_bytes() const;
void set_limits(size_t objects, size_t fields, size_t strings);
private:
struct recursuion_limitation_guard
{
@@ -103,13 +81,6 @@ namespace epee
const uint8_t* m_ptr;
size_t m_count;
size_t m_recursion_count;
size_t m_objects;
size_t m_fields;
size_t m_strings;
size_t max_objects;
size_t max_fields;
size_t max_strings;
};
inline throwable_buffer_reader::throwable_buffer_reader(const void* ptr, size_t sz)
@@ -121,12 +92,6 @@ namespace epee
m_ptr = (uint8_t*)ptr;
m_count = sz;
m_recursion_count = 0;
m_objects = 0;
m_fields = 0;
m_strings = 0;
max_objects = std::numeric_limits<size_t>::max();
max_fields = std::numeric_limits<size_t>::max();
max_strings = std::numeric_limits<size_t>::max();
}
inline
void throwable_buffer_reader::read(void* target, size_t count)
@@ -143,7 +108,6 @@ namespace epee
RECURSION_LIMITATION();
uint8_t name_len = 0;
read(name_len);
CHECK_AND_ASSERT_THROW_MES(name_len > 0, "Section name is missing");
sce_name.resize(name_len);
read((void*)sce_name.data(), name_len);
}
@@ -174,18 +138,7 @@ namespace epee
//for pod types
array_entry_t<type_name> sa;
size_t size = read_varint();
CHECK_AND_ASSERT_THROW_MES(size <= m_count / ps_min_bytes<type_name>::strict, "Size sanity check failed");
if (std::is_same<type_name, section>())
{
CHECK_AND_ASSERT_THROW_MES(size <= max_objects - m_objects, "Too many objects");
m_objects += size;
}
else if (std::is_same<type_name, std::string>())
{
CHECK_AND_ASSERT_THROW_MES(size <= max_strings - m_strings, "Too many strings");
m_strings += size;
}
CHECK_AND_ASSERT_THROW_MES(size <= m_count, "Size sanity check failed");
sa.reserve(size);
//TODO: add some optimization here later
while(size--)
@@ -251,8 +204,6 @@ namespace epee
inline storage_entry throwable_buffer_reader::read_se<std::string>()
{
RECURSION_LIMITATION();
CHECK_AND_ASSERT_THROW_MES(m_strings + 1 <= max_strings, "Too many strings");
m_strings += 1;
return storage_entry(read<std::string>());
}
@@ -261,8 +212,6 @@ namespace epee
inline storage_entry throwable_buffer_reader::read_se<section>()
{
RECURSION_LIMITATION();
CHECK_AND_ASSERT_THROW_MES(m_objects < max_objects, "Too many objects");
++m_objects;
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));
section& section_entry = boost::get<section>(se);
@@ -314,16 +263,12 @@ namespace epee
RECURSION_LIMITATION();
sec.m_entries.clear();
size_t count = read_varint();
CHECK_AND_ASSERT_THROW_MES(count <= max_fields - m_fields, "Too many object fields");
m_fields += count;
while(count--)
{
//read section name string
std::string sec_name;
read_sec_name(sec_name);
const auto insert_loc = sec.m_entries.lower_bound(sec_name);
CHECK_AND_ASSERT_THROW_MES(insert_loc == sec.m_entries.end() || insert_loc->first != sec_name, "duplicate key: " << sec_name);
sec.m_entries.emplace_hint(insert_loc, std::move(sec_name), load_storage_entry());
sec.m_entries.emplace(std::move(sec_name), load_storage_entry());
}
}
inline
@@ -344,12 +289,5 @@ namespace epee
RECURSION_LIMITATION();
CHECK_AND_ASSERT_THROW_MES(false, "Reading array entry is not supported");
}
inline
void throwable_buffer_reader::set_limits(size_t objects, size_t fields, size_t strings)
{
max_objects = objects;
max_fields = fields;
max_strings = strings;
}
}
}

View File

@@ -26,7 +26,6 @@
#pragma once
#include <boost/lexical_cast.hpp>
#include <boost/utility/string_ref.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include "parserse_base_utils.h"
#include "file_io_utils.h"

View File

@@ -28,16 +28,12 @@
#include <string>
#include "byte_slice.h"
#include "parserse_base_utils.h" /// TODO: (mj-xmr) This will be reduced in an another PR
#include "parserse_base_utils.h"
#include "portable_storage.h"
#include "file_io_utils.h"
#include "span.h"
namespace epee
{
class byte_stream;
namespace serialization
{
//-----------------------------------------------------------------------------------------------------------
@@ -88,10 +84,10 @@ namespace epee
}
//-----------------------------------------------------------------------------------------------------------
template<class t_struct>
bool load_t_from_binary(t_struct& out, const epee::span<const uint8_t> binary_buff, const epee::serialization::portable_storage::limits_t *limits = NULL)
bool load_t_from_binary(t_struct& out, const epee::span<const uint8_t> binary_buff)
{
portable_storage ps;
bool rs = ps.load_from_binary(binary_buff, limits);
bool rs = ps.load_from_binary(binary_buff);
if(!rs)
return false;
@@ -115,28 +111,19 @@ namespace epee
}
//-----------------------------------------------------------------------------------------------------------
template<class t_struct>
bool store_t_to_binary(t_struct& str_in, byte_slice& binary_buff, size_t initial_buffer_size = 8192)
{
portable_storage ps;
str_in.store(ps);
return ps.store_to_binary(binary_buff, initial_buffer_size);
}
//-----------------------------------------------------------------------------------------------------------
template<class t_struct>
byte_slice store_t_to_binary(t_struct& str_in, size_t initial_buffer_size = 8192)
{
byte_slice binary_buff;
store_t_to_binary(str_in, binary_buff, initial_buffer_size);
return binary_buff;
}
//-----------------------------------------------------------------------------------------------------------
template<class t_struct>
bool store_t_to_binary(t_struct& str_in, byte_stream& binary_buff)
bool store_t_to_binary(t_struct& str_in, std::string& binary_buff, size_t indent = 0)
{
portable_storage ps;
str_in.store(ps);
return ps.store_to_binary(binary_buff);
}
//-----------------------------------------------------------------------------------------------------------
template<class t_struct>
std::string store_t_to_binary(t_struct& str_in, size_t indent = 0)
{
std::string binary_buff;
store_t_to_binary(str_in, binary_buff, indent);
return binary_buff;
}
}
}

View File

@@ -32,7 +32,6 @@
#include "misc_language.h"
#include "portable_storage_base.h"
#include "portable_storage_bin_utils.h"
#include "misc_log_ex.h"
namespace epee
{
@@ -212,7 +211,6 @@ namespace epee
for(const section_pair& se: sec.m_entries)
{
CHECK_AND_ASSERT_THROW_MES(se.first.size() < std::numeric_limits<uint8_t>::max(), "storage_entry_name is too long: " << se.first.size() << ", val: " << se.first);
CHECK_AND_ASSERT_THROW_MES(!se.first.empty(), "storage_entry_name is empty");
uint8_t len = static_cast<uint8_t>(se.first.size());
strm.write((const char*)&len, sizeof(len));
strm.write(se.first.data(), size_t(len));

View File

@@ -28,17 +28,12 @@
#pragma once
#include <time.h>
#include <boost/regex.hpp>
#include "misc_language.h"
#include "portable_storage_base.h"
#include "parserse_base_utils.h"
#include "warnings.h"
#include "misc_log_ex.h"
#include <boost/lexical_cast.hpp>
#include <typeinfo>
#include <iomanip>
namespace epee
{

View File

@@ -24,16 +24,33 @@
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#ifndef _STRING_TOOLS_H_
#define _STRING_TOOLS_H_
#include "hex.h"
#include "mlocker.h"
// Previously pulled in by ASIO, further cleanup still required ...
#ifdef _WIN32
# include <winsock2.h>
# include <windows.h>
#endif
#include <boost/utility/string_ref.hpp>
#include <sstream>
#include <string.h>
#include <locale>
#include <cstdlib>
#include <string>
#include <cstdint>
#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"
#include "memwipe.h"
#include "mlocker.h"
#include "span.h"
#include "warnings.h"
#ifndef OUT
#define OUT
@@ -57,28 +74,182 @@ namespace string_tools
{
return from_hex::to_string(res, s);
}
std::string get_ip_string_from_int32(uint32_t ip);
bool get_ip_int32_from_string(uint32_t& ip, const std::string& ip_str);
bool parse_peer_from_string(uint32_t& ip, uint16_t& port, const std::string& addres);
std::string num_to_string_fast(int64_t val);
bool compare_no_case(const std::string& str1, const std::string& str2);
std::string& get_current_module_name();
std::string& get_current_module_folder();
#ifdef _WIN32
std::string get_current_module_path();
#endif
bool set_module_name_and_folder(const std::string& path_to_process_);
bool trim_left(std::string& str);
bool trim_right(std::string& str);
//----------------------------------------------------------------------------
inline std::string& trim(std::string& str)
PUSH_WARNINGS
DISABLE_GCC_WARNING(maybe-uninitialized)
template<class XType>
inline bool get_xtype_from_string(OUT XType& val, const std::string& str_id)
{
trim_left(str);
trim_right(str);
return str;
if (std::is_integral<XType>::value && !std::numeric_limits<XType>::is_signed && !std::is_same<XType, bool>::value)
{
for (char c : str_id)
{
if (!epee::misc_utils::parse::isdigit(c))
return false;
}
}
try
{
val = boost::lexical_cast<XType>(str_id);
return true;
}
catch(const std::exception& /*e*/)
{
//const char* pmsg = e.what();
return false;
}
catch(...)
{
return false;
}
return true;
}
POP_WARNINGS
//----------------------------------------------------------------------------
template<class XType>
inline bool xtype_to_string(const XType& val, std::string& str)
{
try
{
str = boost::lexical_cast<std::string>(val);
}
catch(...)
{
return false;
}
return true;
}
//----------------------------------------------------------------------------
std::string get_ip_string_from_int32(uint32_t ip);
//----------------------------------------------------------------------------
bool get_ip_int32_from_string(uint32_t& ip, const std::string& ip_str);
//----------------------------------------------------------------------------
inline bool parse_peer_from_string(uint32_t& ip, uint16_t& port, const std::string& addres)
{
//parse ip and address
std::string::size_type p = addres.find(':');
std::string ip_str, port_str;
if(p == std::string::npos)
{
port = 0;
ip_str = addres;
}
else
{
ip_str = addres.substr(0, p);
port_str = addres.substr(p+1, addres.size());
}
if(!get_ip_int32_from_string(ip, ip_str))
{
return false;
}
if(p != std::string::npos && !get_xtype_from_string(port, port_str))
{
return false;
}
return true;
}
inline std::string num_to_string_fast(int64_t val)
{
/*
char buff[30] = {0};
i64toa_s(val, buff, sizeof(buff)-1, 10);
return buff;*/
return boost::lexical_cast<std::string>(val);
}
//----------------------------------------------------------------------------
template<typename T>
inline std::string to_string_hex(const T &val)
{
static_assert(std::is_arithmetic<T>::value, "only arithmetic types");
std::stringstream ss;
ss << std::hex << val;
std::string s;
ss >> s;
return s;
}
//----------------------------------------------------------------------------
inline bool compare_no_case(const std::string& str1, const std::string& str2)
{
return !boost::iequals(str1, str2);
}
//----------------------------------------------------------------------------
inline std::string& get_current_module_name()
{
static std::string module_name;
return module_name;
}
//----------------------------------------------------------------------------
inline std::string& get_current_module_folder()
{
static std::string module_folder;
return module_folder;
}
//----------------------------------------------------------------------------
#ifdef _WIN32
inline std::string get_current_module_path()
{
char pname [5000] = {0};
GetModuleFileNameA( NULL, pname, sizeof(pname));
pname[sizeof(pname)-1] = 0; //be happy ;)
return pname;
}
#endif
//----------------------------------------------------------------------------
inline bool set_module_name_and_folder(const std::string& path_to_process_)
{
std::string path_to_process = path_to_process_;
#ifdef _WIN32
path_to_process = get_current_module_path();
#endif
std::string::size_type a = path_to_process.rfind( '\\' );
if(a == std::string::npos )
{
a = path_to_process.rfind( '/' );
}
if ( a != std::string::npos )
{
get_current_module_name() = path_to_process.substr(a+1, path_to_process.size());
get_current_module_folder() = path_to_process.substr(0, a);
return true;
}else
return false;
}
//----------------------------------------------------------------------------
inline bool trim_left(std::string& str)
{
for(std::string::iterator it = str.begin(); it!= str.end() && isspace(static_cast<unsigned char>(*it));)
str.erase(str.begin());
return true;
}
//----------------------------------------------------------------------------
inline bool trim_right(std::string& str)
{
for(std::string::reverse_iterator it = str.rbegin(); it!= str.rend() && isspace(static_cast<unsigned char>(*it));)
str.erase( --((it++).base()));
return true;
}
//----------------------------------------------------------------------------
inline std::string& trim(std::string& str)
{
trim_left(str);
trim_right(str);
return str;
}
//----------------------------------------------------------------------------
inline std::string trim(const std::string& str_)
{
@@ -87,8 +258,18 @@ namespace string_tools
trim_right(str);
return str;
}
std::string pad_string(std::string s, size_t n, char c = ' ', bool prepend = false);
//----------------------------------------------------------------------------
inline std::string pad_string(std::string s, size_t n, char c = ' ', bool prepend = false)
{
if (s.size() < n)
{
if (prepend)
s = std::string(n - s.size(), c) + s;
else
s.append(n - s.size(), c);
}
return s;
}
//----------------------------------------------------------------------------
template<class t_pod_type>
std::string pod_to_hex(const t_pod_type& s)
@@ -115,25 +296,64 @@ namespace string_tools
{
return hex_to_pod(hex_str, unwrap(s));
}
//----------------------------------------------------------------------------
template<typename T>
inline std::string to_string_hex(const T &val)
{
static_assert(std::is_arithmetic<T>::value, "only arithmetic types");
std::stringstream ss;
ss << std::hex << val;
std::string s;
ss >> s;
return s;
}
//----------------------------------------------------------------------------
bool validate_hex(uint64_t length, const std::string& str);
std::string get_extension(const std::string& str);
std::string cut_off_extension(const std::string& str);
//----------------------------------------------------------------------------
inline std::string get_extension(const std::string& str)
{
std::string res;
std::string::size_type pos = str.rfind('.');
if(std::string::npos == pos)
return res;
res = str.substr(pos+1, str.size()-pos);
return res;
}
//----------------------------------------------------------------------------
inline std::string cut_off_extension(const std::string& str)
{
std::string res;
std::string::size_type pos = str.rfind('.');
if(std::string::npos == pos)
return str;
res = str.substr(0, pos);
return res;
}
//----------------------------------------------------------------------------
#ifdef _WIN32
std::wstring utf8_to_utf16(const std::string& str);
std::string utf16_to_utf8(const std::wstring& wstr);
inline std::wstring utf8_to_utf16(const std::string& str)
{
if (str.empty())
return {};
int wstr_size = MultiByteToWideChar(CP_UTF8, 0, &str[0], str.size(), NULL, 0);
if (wstr_size == 0)
{
throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
}
std::wstring wstr(wstr_size, wchar_t{});
if (!MultiByteToWideChar(CP_UTF8, 0, &str[0], str.size(), &wstr[0], wstr_size))
{
throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
}
return wstr;
}
inline std::string utf16_to_utf8(const std::wstring& wstr)
{
if (wstr.empty())
return {};
int str_size = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], wstr.size(), NULL, 0, NULL, NULL);
if (str_size == 0)
{
throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
}
std::string str(str_size, char{});
if (!WideCharToMultiByte(CP_UTF8, 0, &wstr[0], wstr.size(), &str[0], str_size, NULL, NULL))
{
throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
}
return str;
}
#endif
}
}

View File

@@ -1,91 +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.
//
#ifndef _STRING_TOOLS_LEXICAL_H_
#define _STRING_TOOLS_LEXICAL_H_
#include "warnings.h"
#include "storages/parserse_base_utils.h"
#include <boost/lexical_cast.hpp> // A heavy header, that was extracted from the rest
#ifndef OUT
#define OUT
#endif
namespace epee
{
namespace string_tools
{
PUSH_WARNINGS
DISABLE_GCC_WARNING(maybe-uninitialized)
template<class XType>
inline bool get_xtype_from_string(OUT XType& val, const std::string& str_id)
{
if (std::is_integral<XType>::value && !std::numeric_limits<XType>::is_signed && !std::is_same<XType, bool>::value)
{
for (char c : str_id)
{
if (!epee::misc_utils::parse::isdigit(c))
return false;
}
}
try
{
val = boost::lexical_cast<XType>(str_id);
return true;
}
catch(const std::exception& /*e*/)
{
//const char* pmsg = e.what();
return false;
}
catch(...)
{
return false;
}
return true;
}
POP_WARNINGS
template<class XType>
inline bool xtype_to_string(const XType& val, std::string& str)
{
try
{
str = boost::lexical_cast<std::string>(val);
}
catch(...)
{
return false;
}
return true;
}
}
}
#endif //_STRING_TOOLS_LEXICAL_H_

View File

@@ -28,6 +28,8 @@
#ifndef _TINY_INI_H_
#define _TINY_INI_H_
#include <boost/regex.hpp>
#include <boost/lexical_cast.hpp>
#include "string_tools.h"
namespace epee
@@ -35,8 +37,20 @@ namespace epee
namespace tiny_ini
{
bool get_param_value(const std::string& param_name, const std::string& ini_entry, std::string& res);
inline std::string get_param_value(const std::string& param_name, const std::string& ini_entry)
inline
bool get_param_value(const std::string& param_name, const std::string& ini_entry, std::string& res)
{
std::string expr_str = std::string() + "^("+ param_name +") *=(.*?)$";
const boost::regex match_ini_entry( expr_str, boost::regex::icase | boost::regex::normal);
boost::smatch result;
if(!boost::regex_search(ini_entry, result, match_ini_entry, boost::match_default))
return false;
res = result[2];
string_tools::trim(res);
return true;
}
inline
std::string get_param_value(const std::string& param_name, const std::string& ini_entry)
{
std::string buff;
get_param_value(param_name, ini_entry, buff);

View File

@@ -26,25 +26,13 @@
# 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.
set(EPEE_INCLUDE_DIR_BASE "${CMAKE_CURRENT_SOURCE_DIR}/../include")
# Add headers to the file list, to be able to search for them and autosave in IDEs.
monero_find_all_headers(EPEE_HEADERS_PUBLIC "${EPEE_INCLUDE_DIR_BASE}")
monero_add_library(epee 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 parserse_base_utils.cpp
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
int-util.cpp portable_storage.cpp
misc_language.cpp
misc_os_dependent.cpp
file_io_utils.cpp
net_parse_helpers.cpp
http_base.cpp
tiny_ini.cpp
${EPEE_HEADERS_PUBLIC}
)
int-util.cpp)
if (USE_READLINE AND (GNU_READLINE_FOUND OR (DEPENDS AND NOT MINGW)))
monero_add_library(epee_readline readline_buffer.cpp)
add_library(epee_readline STATIC readline_buffer.cpp)
endif()
if(HAVE_C11)
@@ -72,9 +60,8 @@ target_link_libraries(epee
${Boost_CHRONO_LIBRARY}
${Boost_FILESYSTEM_LIBRARY}
${Boost_THREAD_LIBRARY}
${Boost_REGEX_LIBRARY}
${OPENSSL_LIBRARIES}
PRIVATE
${OPENSSL_LIBRARIES}
${EXTRA_LIBRARIES})
if (USE_READLINE AND (GNU_READLINE_FOUND OR (DEPENDS AND NOT MINGW)))
@@ -84,9 +71,3 @@ if (USE_READLINE AND (GNU_READLINE_FOUND OR (DEPENDS AND NOT MINGW)))
PRIVATE
${GNU_READLINE_LIBRARY})
endif()
target_include_directories(epee
PUBLIC
"${EPEE_INCLUDE_DIR_BASE}"
"${OPENSSL_INCLUDE_DIR}")

View File

@@ -1,7 +1,6 @@
#include "net/abstract_http_client.h"
#include "net/http_base.h"
#include "net/net_parse_helpers.h"
#include "misc_log_ex.h"
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "net.http"

View File

@@ -36,11 +36,6 @@
#include "byte_slice.h"
#include "byte_stream.h"
namespace
{
const std::size_t page_size = 4096;
}
namespace epee
{
struct byte_slice_data
@@ -151,7 +146,7 @@ namespace epee
: byte_slice()
{
std::size_t space_needed = 0;
for (const auto& source : sources)
for (const auto source : sources)
space_needed += source.size();
if (space_needed)
@@ -160,7 +155,7 @@ namespace epee
span<std::uint8_t> out{reinterpret_cast<std::uint8_t*>(storage.get() + 1), space_needed};
portion_ = {out.data(), out.size()};
for (const auto& source : sources)
for (const auto source : sources)
{
std::memcpy(out.data(), source.data(), source.size());
if (out.remove_prefix(source.size()) < source.size())
@@ -178,27 +173,16 @@ namespace epee
: byte_slice(adapt_buffer{}, std::move(buffer))
{}
byte_slice::byte_slice(byte_stream&& stream, const bool shrink)
byte_slice::byte_slice(byte_stream&& stream) noexcept
: storage_(nullptr), portion_(stream.data(), stream.size())
{
if (portion_.size())
if (stream.size())
{
byte_buffer buf;
if (shrink && page_size <= stream.available())
{
buf = byte_buffer_resize(stream.take_buffer(), portion_.size());
if (!buf)
throw std::bad_alloc{};
portion_ = {buf.get(), portion_.size()};
}
else // no need to shrink buffer
buf = stream.take_buffer();
std::uint8_t* const data = buf.release() - sizeof(raw_byte_slice);
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 // empty stream
else
portion_ = nullptr;
}

View File

@@ -34,11 +34,6 @@
#include <iostream>
namespace
{
constexpr const std::size_t minimum_increase = 4096;
}
namespace epee
{
void byte_stream::overflow(const std::size_t requested)
@@ -51,7 +46,7 @@ namespace epee
const std::size_t len = size();
const std::size_t cap = capacity();
const std::size_t increase = std::max(std::max(need, cap), minimum_increase);
const std::size_t increase = std::max(need, increase_size());
next_write_ = nullptr;
end_ = nullptr;
@@ -67,7 +62,8 @@ namespace epee
byte_stream::byte_stream(byte_stream&& rhs) noexcept
: buffer_(std::move(rhs.buffer_)),
next_write_(rhs.next_write_),
end_(rhs.end_)
end_(rhs.end_),
increase_size_(rhs.increase_size_)
{
rhs.next_write_ = nullptr;
rhs.end_ = nullptr;
@@ -80,6 +76,7 @@ namespace epee
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;
}

View File

@@ -1,231 +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.
//
#include "file_io_utils.h"
#include <fstream>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
#ifdef WIN32
#include <windows.h>
#include "string_tools.h"
#endif
// On Windows there is a problem with non-ASCII characters in path and file names
// as far as support by the standard components used is concerned:
// The various file stream classes, e.g. std::ifstream and std::ofstream, are
// part of the GNU C++ Library / libstdc++. On the most basic level they use the
// fopen() call as defined / made accessible to programs compiled within MSYS2
// by the stdio.h header file maintained by the MinGW project.
// The critical point: The implementation of fopen() is part of MSVCRT, the
// Microsoft Visual C/C++ Runtime Library, and this method does NOT offer any
// Unicode support.
// Monero code that would want to continue to use the normal file stream classes
// but WITH Unicode support could therefore not solve this problem on its own,
// but 2 different projects from 2 different maintaining groups would need changes
// in this particular direction - something probably difficult to achieve and
// with a long time to wait until all new versions / releases arrive.
// Implemented solution approach: Circumvent the problem by stopping to use std
// file stream classes on Windows and directly use Unicode-capable WIN32 API
// calls. Most of the code doing so is concentrated in this header file here.
namespace epee
{
namespace file_io_utils
{
bool is_file_exist(const std::string& path)
{
boost::filesystem::path p(path);
return boost::filesystem::exists(p);
}
bool save_string_to_file(const std::string& path_to_file, const std::string& str)
{
#ifdef WIN32
std::wstring wide_path;
try { wide_path = string_tools::utf8_to_utf16(path_to_file); } catch (...) { return false; }
HANDLE file_handle = CreateFileW(wide_path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (file_handle == INVALID_HANDLE_VALUE)
return false;
DWORD bytes_written;
DWORD bytes_to_write = (DWORD)str.size();
BOOL result = WriteFile(file_handle, str.data(), bytes_to_write, &bytes_written, NULL);
CloseHandle(file_handle);
if (bytes_written != bytes_to_write)
result = FALSE;
return result;
#else
try
{
std::ofstream fstream;
fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
fstream.open(path_to_file, std::ios_base::binary | std::ios_base::out | std::ios_base::trunc);
fstream << str;
fstream.close();
return true;
}
catch(...)
{
return false;
}
#endif
}
bool get_file_time(const std::string& path_to_file, time_t& ft)
{
boost::system::error_code ec;
ft = boost::filesystem::last_write_time(boost::filesystem::path(path_to_file), ec);
if(!ec)
return true;
else
return false;
}
bool set_file_time(const std::string& path_to_file, const time_t& ft)
{
boost::system::error_code ec;
boost::filesystem::last_write_time(boost::filesystem::path(path_to_file), ft, ec);
if(!ec)
return true;
else
return false;
}
bool load_file_to_string(const std::string& path_to_file, std::string& target_str, size_t max_size)
{
#ifdef WIN32
std::wstring wide_path;
try { wide_path = string_tools::utf8_to_utf16(path_to_file); } catch (...) { return false; }
HANDLE file_handle = CreateFileW(wide_path.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (file_handle == INVALID_HANDLE_VALUE)
return false;
DWORD file_size = GetFileSize(file_handle, NULL);
if ((file_size == INVALID_FILE_SIZE) || (uint64_t)file_size > (uint64_t)max_size) {
CloseHandle(file_handle);
return false;
}
target_str.resize(file_size);
DWORD bytes_read;
BOOL result = ReadFile(file_handle, &target_str[0], file_size, &bytes_read, NULL);
CloseHandle(file_handle);
if (bytes_read != file_size)
result = FALSE;
return result;
#else
try
{
std::ifstream fstream;
fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
fstream.open(path_to_file, std::ios_base::binary | std::ios_base::in | std::ios::ate);
std::ifstream::pos_type file_size = fstream.tellg();
if((uint64_t)file_size > (uint64_t)max_size) // ensure a large domain for comparison, and negative -> too large
return false;//don't go crazy
size_t file_size_t = static_cast<size_t>(file_size);
target_str.resize(file_size_t);
fstream.seekg (0, std::ios::beg);
fstream.read((char*)target_str.data(), target_str.size());
fstream.close();
return true;
}
catch(...)
{
return false;
}
#endif
}
bool append_string_to_file(const std::string& path_to_file, const std::string& str)
{
// No special Windows implementation because so far not used in Monero code
try
{
std::ofstream fstream;
fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
fstream.open(path_to_file.c_str(), std::ios_base::binary | std::ios_base::out | std::ios_base::app);
fstream << str;
fstream.close();
return true;
}
catch(...)
{
return false;
}
}
bool get_file_size(const std::string& path_to_file, uint64_t &size)
{
#ifdef WIN32
std::wstring wide_path;
try { wide_path = string_tools::utf8_to_utf16(path_to_file); } catch (...) { return false; }
HANDLE file_handle = CreateFileW(wide_path.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (file_handle == INVALID_HANDLE_VALUE)
return false;
LARGE_INTEGER file_size;
BOOL result = GetFileSizeEx(file_handle, &file_size);
CloseHandle(file_handle);
if (result) {
size = file_size.QuadPart;
}
return size;
#else
try
{
std::ifstream fstream;
fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
fstream.open(path_to_file, std::ios_base::binary | std::ios_base::in | std::ios::ate);
size = fstream.tellg();
fstream.close();
return true;
}
catch(...)
{
return false;
}
#endif
}
}
}

View File

@@ -1,71 +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.
//
#include "net/http_base.h"
#include "memwipe.h"
#include "string_tools.h"
#include <boost/regex.hpp>
#include <string>
#include <utility>
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "net.http"
namespace epee
{
namespace net_utils
{
namespace http
{
std::string get_value_from_fields_list(const std::string& param_name, const net_utils::http::fields_list& fields)
{
fields_list::const_iterator it = fields.begin();
for(; it != fields.end(); it++)
if(!string_tools::compare_no_case(param_name, it->first))
break;
if(it==fields.end())
return std::string();
return it->second;
}
std::string get_value_from_uri_line(const std::string& param_name, const std::string& uri)
{
std::string buff = "([\\?|&])";
buff += param_name + "=([^&]*)";
boost::regex match_param(buff.c_str(), boost::regex::icase | boost::regex::normal);
boost::smatch result;
if(boost::regex_search(uri, result, match_param, boost::match_default) && result[0].matched)
{
return result[2];
}
return std::string();
}
}
}
}

View File

@@ -34,25 +34,6 @@ namespace epee
{
namespace levin
{
message_writer::message_writer(const std::size_t reserve)
: buffer()
{
buffer.reserve(reserve);
buffer.put_n(0, sizeof(header));
}
byte_slice message_writer::finalize(const uint32_t command, const uint32_t flags, const uint32_t return_code, const bool expect_response)
{
if (buffer.size() < sizeof(header))
throw std::runtime_error{"levin_writer::finalize already called"};
header head = make_header(command, payload_size(), flags, expect_response);
head.m_return_code = SWAP32LE(return_code);
std::memcpy(buffer.tellp() - buffer.size(), std::addressof(head), sizeof(head));
return byte_slice{std::move(buffer)};
}
bucket_head2 make_header(uint32_t command, uint64_t msg_size, uint32_t flags, bool expect_response) noexcept
{
bucket_head2 head = {0};
@@ -66,6 +47,12 @@ namespace levin
return head;
}
byte_slice make_notify(int command, epee::span<const std::uint8_t> payload)
{
const bucket_head2 head = make_header(command, payload.size(), LEVIN_PACKET_REQUEST, false);
return byte_slice{epee::as_byte_span(head), payload};
}
byte_slice make_noise_notify(const std::size_t noise_bytes)
{
static constexpr const std::uint32_t flags =
@@ -81,40 +68,46 @@ namespace levin
return byte_slice{std::move(buffer)};
}
byte_slice make_fragmented_notify(const std::size_t noise_size, const int command, message_writer message)
byte_slice make_fragmented_notify(const byte_slice& noise_message, int command, epee::span<const std::uint8_t> payload)
{
const size_t noise_size = noise_message.size();
if (noise_size < sizeof(bucket_head2) * 2)
return nullptr;
if (message.buffer.size() <= noise_size)
if (payload.size() <= noise_size - sizeof(bucket_head2))
{
/* The entire message can be sent at once, and the levin binary parser
will ignore extra bytes. So just pad with zeroes and otherwise send
a "normal", not fragmented message. */
const size_t padding = noise_size - sizeof(bucket_head2) - payload.size();
const span<const uint8_t> padding_bytes{noise_message.end() - padding, padding};
message.buffer.put_n(0, noise_size - message.buffer.size());
return message.finalize_notify(command);
const bucket_head2 head = make_header(command, noise_size - sizeof(bucket_head2), LEVIN_PACKET_REQUEST, false);
return byte_slice{as_byte_span(head), payload, padding_bytes};
}
// fragment message
const byte_slice payload_bytes = message.finalize_notify(command);
span<const std::uint8_t> payload = to_span(payload_bytes);
const size_t payload_space = noise_size - sizeof(bucket_head2);
const size_t expected_fragments = ((payload.size() - 2) / payload_space) + 1;
byte_stream buffer{};
buffer.reserve(expected_fragments * noise_size);
std::string buffer{};
buffer.reserve((expected_fragments + 1) * noise_size); // +1 here overselects for internal bucket_head2 value
bucket_head2 head = make_header(0, payload_space, LEVIN_PACKET_BEGIN, false);
buffer.write(as_byte_span(head));
bucket_head2 head = make_header(0, noise_size - sizeof(bucket_head2), LEVIN_PACKET_BEGIN, false);
buffer.append(reinterpret_cast<const char*>(&head), sizeof(head));
// internal levin header is in payload already
head.m_command = command;
head.m_flags = LEVIN_PACKET_REQUEST;
head.m_cb = payload.size();
buffer.append(reinterpret_cast<const char*>(&head), sizeof(head));
size_t copy_size = payload.remove_prefix(payload_space);
buffer.write(payload.data() - copy_size, copy_size);
size_t copy_size = payload.remove_prefix(payload_space - sizeof(bucket_head2));
buffer.append(reinterpret_cast<const char*>(payload.data()) - copy_size, copy_size);
head.m_command = 0;
head.m_flags = 0;
head.m_cb = noise_size - sizeof(bucket_head2);
while (!payload.empty())
{
copy_size = payload.remove_prefix(payload_space);
@@ -122,12 +115,12 @@ namespace levin
if (payload.empty())
head.m_flags = LEVIN_PACKET_END;
buffer.write(as_byte_span(head));
buffer.write(payload.data() - copy_size, copy_size);
buffer.append(reinterpret_cast<const char*>(&head), sizeof(head));
buffer.append(reinterpret_cast<const char*>(payload.data()) - copy_size, copy_size);
}
const size_t padding = noise_size - copy_size - sizeof(bucket_head2);
buffer.put_n(0, padding);
buffer.append(reinterpret_cast<const char*>(noise_message.end()) - padding, padding);
return byte_slice{std::move(buffer)};
}

View File

@@ -1,44 +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.
//
#include "misc_language.h"
#include <boost/thread.hpp>
namespace epee
{
namespace misc_utils
{
bool sleep_no_w(long ms )
{
boost::this_thread::sleep(
boost::get_system_time() +
boost::posix_time::milliseconds( std::max<long>(ms,0) ) );
return true;
}
}
}

View File

@@ -1,44 +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.
//
#include "misc_os_dependent.h"
#include <boost/lexical_cast.hpp>
namespace epee
{
namespace misc_utils
{
// TODO: (vtnerd) This function is weird since boost::this_thread::get_id() exists but returns a different value.
std::string get_thread_string_id()
{
#if defined(_WIN32)
return boost::lexical_cast<std::string>(GetCurrentThreadId());
#elif defined(__GNUC__)
return boost::lexical_cast<std::string>(pthread_self());
#endif
}
}
}

View File

@@ -1,206 +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.
//
#include "net/net_parse_helpers.h"
#include "net/http_base.h"
#include "misc_log_ex.h"
#include "reg_exp_definer.h"
#include <boost/lexical_cast.hpp>
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "net"
namespace epee
{
namespace net_utils
{
static bool parse_uri_query(const std::string& query, std::list<std::pair<std::string, std::string> >& params)
{
enum state
{
st_param_name,
st_param_val
};
state st = st_param_name;
std::string::const_iterator start_it = query.begin();
std::pair<std::string, std::string> e;
for(std::string::const_iterator it = query.begin(); it != query.end(); it++)
{
switch(st)
{
case st_param_name:
if(*it == '=')
{
e.first.assign(start_it, it);
start_it = it;++start_it;
st = st_param_val;
}
break;
case st_param_val:
if(*it == '&')
{
e.second.assign(start_it, it);
start_it = it;++start_it;
params.push_back(e);
e.first.clear();e.second.clear();
st = st_param_name;
}
break;
default:
LOG_ERROR("Unknown state " << (int)st);
return false;
}
}
if(st == st_param_name)
{
if(start_it != query.end())
{
e.first.assign(start_it, query.end());
params.push_back(e);
}
}else
{
if(start_it != query.end())
e.second.assign(start_it, query.end());
if(e.first.size())
params.push_back(e);
}
return true;
}
bool parse_uri(const std::string uri, http::uri_content& content)
{
///iframe_test.html?api_url=http://api.vk.com/api.php&api_id=3289090&api_settings=1&viewer_id=562964060&viewer_type=0&sid=0aad8d1c5713130f9ca0076f2b7b47e532877424961367d81e7fa92455f069be7e21bc3193cbd0be11895&secret=368ebbc0ef&access_token=668bc03f43981d883f73876ffff4aa8564254b359cc745dfa1b3cde7bdab2e94105d8f6d8250717569c0a7&user_id=0&group_id=0&is_app_user=1&auth_key=d2f7a895ca5ff3fdb2a2a8ae23fe679a&language=0&parent_language=0&ad_info=ElsdCQBaQlxiAQRdFUVUXiN2AVBzBx5pU1BXIgZUJlIEAWcgAUoLQg==&referrer=unknown&lc_name=9834b6a3&hash=
content.m_query_params.clear();
STATIC_REGEXP_EXPR_1(rexp_match_uri, "^([^?#]*)(\\?([^#]*))?(#(.*))?", boost::regex::icase | boost::regex::normal);
boost::smatch result;
if(!(boost::regex_search(uri, result, rexp_match_uri, boost::match_default) && result[0].matched))
{
LOG_PRINT_L1("[PARSE URI] regex not matched for uri: " << uri);
content.m_path = uri;
return true;
}
if(result[1].matched)
{
content.m_path = result[1];
}
if(result[3].matched)
{
content.m_query = result[3];
}
if(result[5].matched)
{
content.m_fragment = result[5];
}
if(content.m_query.size())
{
parse_uri_query(content.m_query, content.m_query_params);
}
return true;
}
bool parse_url_ipv6(const std::string url_str, http::url_content& content)
{
STATIC_REGEXP_EXPR_1(rexp_match_uri, "^(([^:]*?)://)?(\\[(.*)\\](:(\\d+))?)(.*)?", boost::regex::icase | boost::regex::normal);
// 12 3 4 5 6 7
content.port = 0;
boost::smatch result;
if(!(boost::regex_search(url_str, result, rexp_match_uri, boost::match_default) && result[0].matched))
{
LOG_PRINT_L1("[PARSE URI] regex not matched for uri: " << rexp_match_uri);
//content.m_path = uri;
return false;
}
if(result[2].matched)
{
content.schema = result[2];
}
if(result[4].matched)
{
content.host = result[4];
}
else // if host not matched, matching should be considered failed
{
return false;
}
if(result[6].matched)
{
content.port = boost::lexical_cast<uint64_t>(result[6]);
}
if(result[7].matched)
{
content.uri = result[7];
return parse_uri(result[7], content.m_uri_content);
}
return true;
}
bool parse_url(const std::string url_str, http::url_content& content)
{
if (parse_url_ipv6(url_str, content)) return true;
///iframe_test.html?api_url=http://api.vk.com/api.php&api_id=3289090&api_settings=1&viewer_id=562964060&viewer_type=0&sid=0aad8d1c5713130f9ca0076f2b7b47e532877424961367d81e7fa92455f069be7e21bc3193cbd0be11895&secret=368ebbc0ef&access_token=668bc03f43981d883f73876ffff4aa8564254b359cc745dfa1b3cde7bdab2e94105d8f6d8250717569c0a7&user_id=0&group_id=0&is_app_user=1&auth_key=d2f7a895ca5ff3fdb2a2a8ae23fe679a&language=0&parent_language=0&ad_info=ElsdCQBaQlxiAQRdFUVUXiN2AVBzBx5pU1BXIgZUJlIEAWcgAUoLQg==&referrer=unknown&lc_name=9834b6a3&hash=
//STATIC_REGEXP_EXPR_1(rexp_match_uri, "^([^?#]*)(\\?([^#]*))?(#(.*))?", boost::regex::icase | boost::regex::normal);
STATIC_REGEXP_EXPR_1(rexp_match_uri, "^(([^:]*?)://)?(([^/:]*)(:(\\d+))?)(.*)?", boost::regex::icase | boost::regex::normal);
// 12 34 5 6 7
content.port = 0;
boost::smatch result;
if(!(boost::regex_search(url_str, result, rexp_match_uri, boost::match_default) && result[0].matched))
{
LOG_PRINT_L1("[PARSE URI] regex not matched for uri: " << rexp_match_uri);
//content.m_path = uri;
return true;
}
if(result[2].matched)
{
content.schema = result[2];
}
if(result[4].matched)
{
content.host = result[4];
}
if(result[6].matched)
{
content.port = boost::lexical_cast<uint64_t>(result[6]);
}
if(result[7].matched)
{
content.uri = result[7];
return parse_uri(result[7], content.m_uri_content);
}
return true;
}
}
}

View File

@@ -29,8 +29,6 @@
#include <string.h>
#include <thread>
#include <boost/asio/ssl.hpp>
#include <boost/cerrno.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/lambda/lambda.hpp>
#include <openssl/ssl.h>
#include <openssl/pem.h>
@@ -475,7 +473,6 @@ bool ssl_options_t::has_fingerprint(boost::asio::ssl::verify_context &ctx) const
bool ssl_options_t::handshake(
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> &socket,
boost::asio::ssl::stream_base::handshake_type type,
boost::asio::const_buffer buffer,
const std::string& host,
std::chrono::milliseconds timeout) const
{
@@ -533,7 +530,7 @@ bool ssl_options_t::handshake(
});
boost::system::error_code ec = boost::asio::error::would_block;
socket.async_handshake(type, boost::asio::buffer(buffer), boost::lambda::var(ec) = boost::lambda::_1);
socket.async_handshake(type, boost::lambda::var(ec) = boost::lambda::_1);
if (io_service.stopped())
{
io_service.reset();
@@ -569,51 +566,6 @@ bool ssl_support_from_string(ssl_support_t &ssl, boost::string_ref s)
return true;
}
boost::system::error_code store_ssl_keys(boost::asio::ssl::context& ssl, const boost::filesystem::path& base)
{
EVP_PKEY* ssl_key = nullptr;
X509* ssl_cert = nullptr;
const auto ctx = ssl.native_handle();
CHECK_AND_ASSERT_MES(ctx, boost::system::error_code(EINVAL, boost::system::system_category()), "Context is null");
CHECK_AND_ASSERT_MES(base.has_filename(), boost::system::error_code(EINVAL, boost::system::system_category()), "Need filename");
if (!(ssl_key = SSL_CTX_get0_privatekey(ctx)) || !(ssl_cert = SSL_CTX_get0_certificate(ctx)))
return {EINVAL, boost::system::system_category()};
using file_closer = int(std::FILE*);
boost::system::error_code error{};
std::unique_ptr<std::FILE, file_closer*> file{nullptr, std::fclose};
// write key file unencrypted
{
const boost::filesystem::path key_file{base.string() + ".key"};
file.reset(std::fopen(key_file.string().c_str(), "wb"));
if (!file)
return {errno, boost::system::system_category()};
boost::filesystem::permissions(key_file, boost::filesystem::owner_read, error);
if (error)
return error;
if (!PEM_write_PrivateKey(file.get(), ssl_key, nullptr, nullptr, 0, nullptr, nullptr))
return boost::asio::error::ssl_errors(ERR_get_error());
if (std::fclose(file.release()) != 0)
return {errno, boost::system::system_category()};
}
// write certificate file in standard SSL X.509 unencrypted
const boost::filesystem::path cert_file{base.string() + ".crt"};
file.reset(std::fopen(cert_file.string().c_str(), "wb"));
if (!file)
return {errno, boost::system::system_category()};
const auto cert_perms = (boost::filesystem::owner_read | boost::filesystem::group_read | boost::filesystem::others_read);
boost::filesystem::permissions(cert_file, cert_perms, error);
if (error)
return error;
if (!PEM_write_X509(file.get(), ssl_cert))
return boost::asio::error::ssl_errors(ERR_get_error());
if (std::fclose(file.release()) != 0)
return {errno, boost::system::system_category()};
return error;
}
} // namespace
} // namespace

View File

@@ -6,17 +6,6 @@
#include "string_tools.h"
#include "net/local_ip.h"
static inline uint32_t make_address_v4_from_v6(const boost::asio::ip::address_v6& a)
{
const auto &bytes = a.to_bytes();
uint32_t v4 = 0;
v4 = (v4 << 8) | bytes[12];
v4 = (v4 << 8) | bytes[13];
v4 = (v4 << 8) | bytes[14];
v4 = (v4 << 8) | bytes[15];
return htonl(v4);
}
namespace epee { namespace net_utils
{
bool ipv4_network_address::equal(const ipv4_network_address& other) const noexcept
@@ -94,28 +83,8 @@ namespace epee { namespace net_utils
network_address::interface const* const other_self = other.self.get();
if (self_ == other_self) return true;
if (!self_ || !other_self) return false;
if (typeid(*self_) == typeid(*other_self))
return self_->is_same_host(*other_self);
const auto this_id = get_type_id();
if (this_id == ipv4_network_address::get_type_id() && other.get_type_id() == ipv6_network_address::get_type_id())
{
const boost::asio::ip::address_v6 &actual_ip = other.as<const epee::net_utils::ipv6_network_address>().ip();
if (actual_ip.is_v4_mapped())
{
const uint32_t v4ip = make_address_v4_from_v6(actual_ip);
return is_same_host(ipv4_network_address(v4ip, 0));
}
}
else if (this_id == ipv6_network_address::get_type_id() && other.get_type_id() == ipv4_network_address::get_type_id())
{
const boost::asio::ip::address_v6 &actual_ip = this->as<const epee::net_utils::ipv6_network_address>().ip();
if (actual_ip.is_v4_mapped())
{
const uint32_t v4ip = make_address_v4_from_v6(actual_ip);
return other.is_same_host(ipv4_network_address(v4ip, 0));
}
}
return false;
if (typeid(*self_) != typeid(*other_self)) return false;
return self_->is_same_host(*other_self);
}
std::string print_connection_context(const connection_context_base& ctx)

View File

@@ -1,282 +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.
//
#include "storages/parserse_base_utils.h"
#include "misc_log_ex.h"
#include <boost/utility/string_ref.hpp>
#include <algorithm>
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "serialization"
namespace epee
{
namespace misc_utils
{
namespace parse
{
std::string transform_to_escape_sequence(const std::string& src)
{
static const char escaped[] = "\b\f\n\r\t\v\"\\/";
std::string::const_iterator it = std::find_first_of(src.begin(), src.end(), escaped, escaped + sizeof(escaped));
if (it == src.end())
return src;
std::string res;
res.reserve(2 * src.size());
res.assign(src.begin(), it);
for(; it!=src.end(); ++it)
{
switch(*it)
{
case '\b': //Backspace (ascii code 08)
res+="\\b"; break;
case '\f': //Form feed (ascii code 0C)
res+="\\f"; break;
case '\n': //New line
res+="\\n"; break;
case '\r': //Carriage return
res+="\\r"; break;
case '\t': //Tab
res+="\\t"; break;
case '\v': //Vertical tab
res+="\\v"; break;
//case '\'': //Apostrophe or single quote
// res+="\\'"; break;
case '"': //Double quote
res+="\\\""; break;
case '\\': //Backslash caracter
res+="\\\\"; break;
case '/': //Backslash caracter
res+="\\/"; break;
default:
res.push_back(*it);
}
}
return res;
}
/*
\b Backspace (ascii code 08)
\f Form feed (ascii code 0C)
\n New line
\r Carriage return
\t Tab
\v Vertical tab
\' Apostrophe or single quote
\" Double quote
\\ Backslash character
*/
void match_string2(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string& val)
{
bool escape_mode = false;
std::string::const_iterator it = star_end_string;
++it;
std::string::const_iterator fi = it;
while (fi != buf_end && ((lut[(uint8_t)*fi] & 32)) == 0)
++fi;
val.assign(it, fi);
it = fi;
for(;it != buf_end;it++)
{
if(escape_mode/*prev_ch == '\\'*/)
{
switch(*it)
{
case 'b': //Backspace (ascii code 08)
val.push_back(0x08);break;
case 'f': //Form feed (ascii code 0C)
val.push_back(0x0C);break;
case 'n': //New line
val.push_back('\n');break;
case 'r': //Carriage return
val.push_back('\r');break;
case 't': //Tab
val.push_back('\t');break;
case 'v': //Vertical tab
val.push_back('\v');break;
case '\'': //Apostrophe or single quote
val.push_back('\'');break;
case '"': //Double quote
val.push_back('"');break;
case '\\': //Backslash character
val.push_back('\\');break;
case '/': //Slash character
val.push_back('/');break;
case 'u': //Unicode code point
if (buf_end - it < 4)
{
ASSERT_MES_AND_THROW("Invalid Unicode escape sequence");
}
else
{
uint32_t dst = 0;
for (int i = 0; i < 4; ++i)
{
const unsigned char tmp = isx[(unsigned char)*++it];
CHECK_AND_ASSERT_THROW_MES(tmp != 0xff, "Bad Unicode encoding");
dst = dst << 4 | tmp;
}
// encode as UTF-8
if (dst <= 0x7f)
{
val.push_back(dst);
}
else if (dst <= 0x7ff)
{
val.push_back(0xc0 | (dst >> 6));
val.push_back(0x80 | (dst & 0x3f));
}
else if (dst <= 0xffff)
{
val.push_back(0xe0 | (dst >> 12));
val.push_back(0x80 | ((dst >> 6) & 0x3f));
val.push_back(0x80 | (dst & 0x3f));
}
else
{
ASSERT_MES_AND_THROW("Unicode code point is out or range");
}
}
break;
default:
val.push_back(*it);
LOG_PRINT_L0("Unknown escape sequence :\"\\" << *it << "\"");
}
escape_mode = false;
}else if(*it == '"')
{
star_end_string = it;
return;
}else if(*it == '\\')
{
escape_mode = true;
}
else
{
val.push_back(*it);
}
}
ASSERT_MES_AND_THROW("Failed to match string in json entry: " << std::string(star_end_string, buf_end));
}
void match_number2(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, boost::string_ref& val, bool& is_float_val, bool& is_signed_val)
{
val.clear();
uint8_t float_flag = 0;
is_signed_val = false;
size_t chars = 0;
std::string::const_iterator it = star_end_string;
if (it != buf_end && *it == '-')
{
is_signed_val = true;
++chars;
++it;
}
for(;it != buf_end;it++)
{
const uint8_t flags = lut[(uint8_t)*it];
if (flags & 16)
{
float_flag |= flags;
++chars;
}
else
{
val = boost::string_ref(&*star_end_string, chars);
if(val.size())
{
star_end_string = --it;
is_float_val = !!(float_flag & 2);
return;
}
else
ASSERT_MES_AND_THROW("wrong number in json entry: " << std::string(star_end_string, buf_end));
}
}
ASSERT_MES_AND_THROW("wrong number in json entry: " << std::string(star_end_string, buf_end));
}
void match_word2(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, boost::string_ref& val)
{
val.clear();
for(std::string::const_iterator it = star_end_string;it != buf_end;it++)
{
if (!(lut[(uint8_t)*it] & 4))
{
val = boost::string_ref(&*star_end_string, std::distance(star_end_string, it));
if(val.size())
{
star_end_string = --it;
return;
}else
ASSERT_MES_AND_THROW("failed to match word number in json entry: " << std::string(star_end_string, buf_end));
}
}
ASSERT_MES_AND_THROW("failed to match word number in json entry: " << std::string(star_end_string, buf_end));
}
bool match_word_with_extrasymb(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string& val)
{
val.clear();
for(std::string::const_iterator it = star_end_string;it != buf_end;it++)
{
if(!isalnum(*it) && *it != '-' && *it != '_')
{
val.assign(star_end_string, it);
if(val.size())
{
star_end_string = --it;
return true;
}else
return false;
}
}
return false;
}
bool match_word_til_equal_mark(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string::const_iterator& word_end)
{
word_end = star_end_string;
for(std::string::const_iterator it = star_end_string;it != buf_end;it++)
{
if(isspace(*it))
{
continue;
}else if( *it == '=' )
{
star_end_string = it;
word_end = it;
return true;
}
}
return false;
}
}
}
}

View File

@@ -1,247 +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.
//
#include "byte_slice.h"
#include "byte_stream.h"
#include "misc_log_ex.h"
#include "span.h"
#include "storages/portable_storage.h"
#include "storages/portable_storage_to_json.h"
#include "storages/portable_storage_from_json.h"
#include "storages/portable_storage_to_bin.h"
#include "storages/portable_storage_from_bin.h"
#include <boost/utility/string_ref.hpp>
#include <string>
#include <sstream>
namespace epee
{
namespace serialization
{
bool portable_storage::store_to_binary(byte_slice& target, const std::size_t initial_buffer_size)
{
TRY_ENTRY();
byte_stream ss;
ss.reserve(initial_buffer_size);
store_to_binary(ss);
target = epee::byte_slice{std::move(ss)};
return true;
CATCH_ENTRY("portable_storage::store_to_binary", false);
}
bool portable_storage::store_to_binary(byte_stream& ss)
{
TRY_ENTRY();
storage_block_header sbh{};
sbh.m_signature_a = SWAP32LE(PORTABLE_STORAGE_SIGNATUREA);
sbh.m_signature_b = SWAP32LE(PORTABLE_STORAGE_SIGNATUREB);
sbh.m_ver = PORTABLE_STORAGE_FORMAT_VER;
ss.write(epee::as_byte_span(sbh));
pack_entry_to_buff(ss, m_root);
return true;
CATCH_ENTRY("portable_storage::store_to_binary", false);
}
bool portable_storage::dump_as_json(std::string& buff, size_t indent, bool insert_newlines)
{
TRY_ENTRY();
std::stringstream ss;
epee::serialization::dump_as_json(ss, m_root, indent, insert_newlines);
buff = ss.str();
return true;
CATCH_ENTRY("portable_storage::dump_as_json", false)
}
bool portable_storage::load_from_json(const std::string& source)
{
TRY_ENTRY();
return json::load_from_json(source, *this);
CATCH_ENTRY("portable_storage::load_from_json", false)
}
bool portable_storage::load_from_binary(const epee::span<const uint8_t> source, const limits_t *limits)
{
m_root.m_entries.clear();
if(source.size() < sizeof(storage_block_header))
{
LOG_ERROR("portable_storage: wrong binary format, packet size = " << source.size() << " less than expected sizeof(storage_block_header)=" << sizeof(storage_block_header));
return false;
}
storage_block_header* pbuff = (storage_block_header*)source.data();
if(pbuff->m_signature_a != SWAP32LE(PORTABLE_STORAGE_SIGNATUREA) ||
pbuff->m_signature_b != SWAP32LE(PORTABLE_STORAGE_SIGNATUREB)
)
{
LOG_ERROR("portable_storage: wrong binary format - signature mismatch");
return false;
}
if(pbuff->m_ver != PORTABLE_STORAGE_FORMAT_VER)
{
LOG_ERROR("portable_storage: wrong binary format - unknown format ver = " << pbuff->m_ver);
return false;
}
TRY_ENTRY();
throwable_buffer_reader buf_reader(source.data()+sizeof(storage_block_header), source.size()-sizeof(storage_block_header));
if (limits)
buf_reader.set_limits(limits->n_objects, limits->n_fields, limits->n_strings);
buf_reader.read(m_root);
return true;//TODO:
CATCH_ENTRY("portable_storage::load_from_binary", false);
}
hsection portable_storage::open_section(const std::string& section_name, hsection hparent_section, bool create_if_notexist)
{
TRY_ENTRY();
hparent_section = hparent_section ? hparent_section:&m_root;
storage_entry* pentry = find_storage_entry(section_name, hparent_section);
if(!pentry)
{
if(!create_if_notexist)
return nullptr;
return insert_new_section(section_name, hparent_section);
}
CHECK_AND_ASSERT(pentry , nullptr);
//check that section_entry we find is real "CSSection"
if(pentry->type() != typeid(section))
{
if(create_if_notexist)
*pentry = storage_entry(section());//replace
else
return nullptr;
}
return &boost::get<section>(*pentry);
CATCH_ENTRY("portable_storage::open_section", nullptr);
}
bool portable_storage::get_value(const std::string& value_name, storage_entry& val, hsection hparent_section)
{
//TRY_ENTRY();
if(!hparent_section) hparent_section = &m_root;
storage_entry* pentry = find_storage_entry(value_name, hparent_section);
if(!pentry)
return false;
val = *pentry;
return true;
//CATCH_ENTRY("portable_storage::template<>get_value", false);
}
storage_entry* portable_storage::find_storage_entry(const std::string& pentry_name, hsection psection)
{
TRY_ENTRY();
CHECK_AND_ASSERT(psection, nullptr);
auto it = psection->m_entries.find(pentry_name);
if(it == psection->m_entries.end())
return nullptr;
return &it->second;
CATCH_ENTRY("portable_storage::find_storage_entry", nullptr);
}
hsection portable_storage::insert_new_section(const std::string& pentry_name, hsection psection)
{
TRY_ENTRY();
storage_entry* pse = insert_new_entry_get_storage_entry(pentry_name, psection, section());
if(!pse) return nullptr;
return &boost::get<section>(*pse);
CATCH_ENTRY("portable_storage::insert_new_section", nullptr);
}
harray portable_storage::get_first_section(const std::string& sec_name, hsection& h_child_section, hsection hparent_section)
{
TRY_ENTRY();
if(!hparent_section) hparent_section = &m_root;
storage_entry* pentry = find_storage_entry(sec_name, hparent_section);
if(!pentry)
return nullptr;
if(pentry->type() != typeid(array_entry))
return nullptr;
array_entry& ar_entry = boost::get<array_entry>(*pentry);
if(ar_entry.type() != typeid(array_entry_t<section>))
return nullptr;
array_entry_t<section>& sec_array = boost::get<array_entry_t<section>>(ar_entry);
section* psec = sec_array.get_first_val();
if(!psec)
return nullptr;
h_child_section = psec;
return &ar_entry;
CATCH_ENTRY("portable_storage::get_first_section", nullptr);
}
bool portable_storage::get_next_section(harray hsec_array, hsection& h_child_section)
{
TRY_ENTRY();
CHECK_AND_ASSERT(hsec_array, false);
if(hsec_array->type() != typeid(array_entry_t<section>))
return false;
array_entry_t<section>& sec_array = boost::get<array_entry_t<section>>(*hsec_array);
h_child_section = sec_array.get_next_val();
if(!h_child_section)
return false;
return true;
CATCH_ENTRY("portable_storage::get_next_section", false);
}
harray portable_storage::insert_first_section(const std::string& sec_name, hsection& hinserted_childsection, hsection hparent_section)
{
TRY_ENTRY();
if(!hparent_section) hparent_section = &m_root;
storage_entry* pentry = find_storage_entry(sec_name, hparent_section);
if(!pentry)
{
pentry = insert_new_entry_get_storage_entry(sec_name, hparent_section, array_entry(array_entry_t<section>()));
if(!pentry)
return nullptr;
}
if(pentry->type() != typeid(array_entry))
*pentry = storage_entry(array_entry(array_entry_t<section>()));
array_entry& ar_entry = boost::get<array_entry>(*pentry);
if(ar_entry.type() != typeid(array_entry_t<section>))
ar_entry = array_entry(array_entry_t<section>());
array_entry_t<section>& sec_array = boost::get<array_entry_t<section>>(ar_entry);
hinserted_childsection = &sec_array.insert_first_val(section());
return &ar_entry;
CATCH_ENTRY("portable_storage::insert_first_section", nullptr);
}
bool portable_storage::insert_next_section(harray hsec_array, hsection& hinserted_childsection)
{
TRY_ENTRY();
CHECK_AND_ASSERT(hsec_array, false);
CHECK_AND_ASSERT_MES(hsec_array->type() == typeid(array_entry_t<section>),
false, "unexpected type(not 'section') in insert_next_section, type: " << hsec_array->type().name());
array_entry_t<section>& sec_array = boost::get<array_entry_t<section>>(*hsec_array);
hinserted_childsection = &sec_array.insert_next_value(section());
return true;
CATCH_ENTRY("portable_storage::insert_next_section", false);
}
}
}

View File

@@ -6,7 +6,6 @@
#include <boost/thread/lock_guard.hpp>
#include <boost/algorithm/string.hpp>
static bool same_as_last_line(const std::string&);
static void install_line_handler();
static void remove_line_handler();
@@ -52,7 +51,6 @@ rdln::readline_buffer::readline_buffer()
void rdln::readline_buffer::start()
{
boost::lock_guard<boost::mutex> lock(sync_mutex);
if(m_cout_buf != NULL)
return;
m_cout_buf = std::cout.rdbuf();
@@ -62,7 +60,6 @@ void rdln::readline_buffer::start()
void rdln::readline_buffer::stop()
{
boost::lock_guard<boost::mutex> lock(sync_mutex);
if(m_cout_buf == NULL)
return;
std::cout.rdbuf(m_cout_buf);
@@ -91,9 +88,9 @@ rdln::linestatus rdln::readline_buffer::get_line(std::string& line) const
void rdln::readline_buffer::set_prompt(const std::string& prompt)
{
boost::lock_guard<boost::mutex> lock(sync_mutex);
if(m_cout_buf == NULL)
return;
boost::lock_guard<boost::mutex> lock(sync_mutex);
rl_set_prompt(std::string(m_prompt_length, ' ').c_str());
rl_redisplay();
rl_set_prompt(prompt.c_str());
@@ -116,12 +113,6 @@ const std::vector<std::string>& rdln::readline_buffer::get_completions()
int rdln::readline_buffer::sync()
{
boost::lock_guard<boost::mutex> lock(sync_mutex);
if (m_cout_buf == nullptr)
{
return -1;
}
#if RL_READLINE_VERSION < 0x0700
char lbuf[2] = {0,0};
char *line = NULL;
@@ -176,11 +167,8 @@ static void handle_line(char* line)
boost::trim_right(test_line);
if(!test_line.empty())
{
if (!same_as_last_line(test_line))
{
add_history(test_line.c_str());
history_set_pos(history_length);
}
add_history(test_line.c_str());
history_set_pos(history_length);
if (test_line == "exit" || test_line == "q")
exit = true;
}
@@ -196,16 +184,6 @@ static void handle_line(char* line)
return;
}
// same_as_last_line returns true, if the last line in the history is
// equal to test_line.
static bool same_as_last_line(const std::string& test_line)
{
// Note that state->offset == state->length, when a new line was entered.
HISTORY_STATE* state = history_get_history_state();
return state->length > 0
&& test_line.compare(state->entries[state->length-1]->line) == 0;
}
static char* completion_matches(const char* text, int state)
{
static size_t list_index;

View File

@@ -25,29 +25,6 @@
//
#include "string_tools.h"
#include "string_tools_lexical.h"
// Previously pulled in by ASIO, further cleanup still required ...
#ifdef _WIN32
# include <winsock2.h>
# include <windows.h>
#endif
#include <locale>
#include <cstdlib>
#include <string>
#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"
#include "memwipe.h"
#include "mlocker.h"
#include "span.h"
#include "warnings.h"
#include <ctype.h>
@@ -91,180 +68,6 @@ namespace string_tools
return false;
return true;
}
//----------------------------------------------------------------------------
bool parse_peer_from_string(uint32_t& ip, uint16_t& port, const std::string& addres)
{
//parse ip and address
std::string::size_type p = addres.find(':');
std::string ip_str, port_str;
if(p == std::string::npos)
{
port = 0;
ip_str = addres;
}
else
{
ip_str = addres.substr(0, p);
port_str = addres.substr(p+1, addres.size());
}
if(!get_ip_int32_from_string(ip, ip_str))
{
return false;
}
if(p != std::string::npos && !get_xtype_from_string(port, port_str))
{
return false;
}
return true;
}
std::string num_to_string_fast(int64_t val)
{
/*
char buff[30] = {0};
i64toa_s(val, buff, sizeof(buff)-1, 10);
return buff;*/
return boost::lexical_cast<std::string>(val);
}
bool compare_no_case(const std::string& str1, const std::string& str2)
{
return !boost::iequals(str1, str2);
}
//----------------------------------------------------------------------------
std::string& get_current_module_name()
{
static std::string module_name;
return module_name;
}
//----------------------------------------------------------------------------
std::string& get_current_module_folder()
{
static std::string module_folder;
return module_folder;
}
#ifdef _WIN32
std::string get_current_module_path()
{
char pname [5000] = {0};
GetModuleFileNameA( NULL, pname, sizeof(pname));
pname[sizeof(pname)-1] = 0; //be happy ;)
return pname;
}
#endif
bool set_module_name_and_folder(const std::string& path_to_process_)
{
std::string path_to_process = path_to_process_;
#ifdef _WIN32
path_to_process = get_current_module_path();
#endif
std::string::size_type a = path_to_process.rfind( '\\' );
if(a == std::string::npos )
{
a = path_to_process.rfind( '/' );
}
if ( a != std::string::npos )
{
get_current_module_name() = path_to_process.substr(a+1, path_to_process.size());
get_current_module_folder() = path_to_process.substr(0, a);
return true;
}else
return false;
}
//----------------------------------------------------------------------------
bool trim_left(std::string& str)
{
for(std::string::iterator it = str.begin(); it!= str.end() && isspace(static_cast<unsigned char>(*it));)
str.erase(str.begin());
return true;
}
//----------------------------------------------------------------------------
bool trim_right(std::string& str)
{
for(std::string::reverse_iterator it = str.rbegin(); it!= str.rend() && isspace(static_cast<unsigned char>(*it));)
str.erase( --((it++).base()));
return true;
}
//----------------------------------------------------------------------------
std::string pad_string(std::string s, size_t n, char c, bool prepend)
{
if (s.size() < n)
{
if (prepend)
s = std::string(n - s.size(), c) + s;
else
s.append(n - s.size(), c);
}
return s;
}
std::string get_extension(const std::string& str)
{
std::string res;
std::string::size_type pos = str.rfind('.');
if(std::string::npos == pos)
return res;
res = str.substr(pos+1, str.size()-pos);
return res;
}
//----------------------------------------------------------------------------
std::string cut_off_extension(const std::string& str)
{
std::string res;
std::string::size_type pos = str.rfind('.');
if(std::string::npos == pos)
return str;
res = str.substr(0, pos);
return res;
}
//----------------------------------------------------------------------------
#ifdef _WIN32
std::wstring utf8_to_utf16(const std::string& str)
{
if (str.empty())
return {};
int wstr_size = MultiByteToWideChar(CP_UTF8, 0, &str[0], str.size(), NULL, 0);
if (wstr_size == 0)
{
throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
}
std::wstring wstr(wstr_size, wchar_t{});
if (!MultiByteToWideChar(CP_UTF8, 0, &str[0], str.size(), &wstr[0], wstr_size))
{
throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
}
return wstr;
}
std::string utf16_to_utf8(const std::wstring& wstr)
{
if (wstr.empty())
return {};
int str_size = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], wstr.size(), NULL, 0, NULL, NULL);
if (str_size == 0)
{
throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
}
std::string str(str_size, char{});
if (!WideCharToMultiByte(CP_UTF8, 0, &wstr[0], wstr.size(), &str[0], str_size, NULL, NULL))
{
throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
}
return str;
}
#endif
}
}

View File

@@ -1,46 +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.
//
#include "string_tools.h"
#include <boost/regex.hpp>
namespace epee
{
namespace tiny_ini
{
bool get_param_value(const std::string& param_name, const std::string& ini_entry, std::string& res)
{
std::string expr_str = std::string() + "^("+ param_name +") *=(.*?)$";
const boost::regex match_ini_entry( expr_str, boost::regex::icase | boost::regex::normal);
boost::smatch result;
if(!boost::regex_search(ini_entry, result, match_ini_entry, boost::match_default))
return false;
res = result[2];
string_tools::trim(res);
return true;
}
}
}

View File

@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 2.8)
set(Boost_USE_MULTITHREADED ON)

View File

@@ -14,8 +14,8 @@ then
exit 1
fi
case "$type" in
block|transaction|signature|cold-outputs|cold-transaction|load-from-binary|load-from-json|base58|parse-url|http-client|levin|bulletproof|utf8) ;;
*) echo "usage: $0 block|transaction|signature|cold-outputs|cold-transaction|load-from-binary|load-from-json|base58|parse-url|http-client|levin|bulletproof|utf8"; exit 1 ;;
block|transaction|signature|cold-outputs|cold-transaction|load-from-binary|load-from-json|base58|parse-url|http-client|levin|bulletproof) ;;
*) echo "usage: $0 block|transaction|signature|cold-outputs|cold-transaction|load-from-binary|load-from-json|base58|parse-url|http-client|levin|bulletproof"; exit 1 ;;
esac
if test -d "fuzz-out/$type"

View File

@@ -36,10 +36,6 @@ This guide explains how to set up the environment, and how to start the builds.
You need to create a new user called `gitianuser` and be logged in as that user. The user needs `sudo` access.
```bash
sudo adduser gitianuser
sudo usermod -aG sudo gitianuser
```
LXC
---
@@ -87,7 +83,7 @@ Docker
Prepare for building with docker:
```bash
sudo bash -c 'apt-get update && apt-get upgrade -y && apt-get install git curl docker.io'
sudo apt-get install git make curl docker.io
```
Consider adding `gitianuser` to the `docker` group after reading about [the security implications](https://docs.docker.com/v17.09/engine/installation/linux/linux-postinstall/):
@@ -100,12 +96,13 @@ sudo usermod -aG docker gitianuser
Optionally add yourself to the docker group. Note that this will give docker root access to your system.
```bash
sudo usermod -aG docker $USER
sudo usermod -aG docker gitianuser
```
Manual Building
-------------------
The instructions below use the automated script [gitian-build.py](gitian-build.py) which only works in Ubuntu.
=======
The script automatically installs some packages with apt. If you are not running it on a debian-like system, pass `--no-apt` along with the other
arguments to it. It calls all available .yml descriptors, which in turn pass the build configurations for different platforms to gitian.
@@ -125,23 +122,17 @@ cp monero/contrib/gitian/gitian-build.py .
### Setup the required environment
Common setup part:
```bash
su - gitianuser
GH_USER=YOUR_GITHUB_USER_NAME
VERSION=v0.17.2.0
```
Where `GH_USER` is your Github user name and `VERSION` is the version tag you want to build.
Setup for LXC:
```bash
GH_USER=fluffypony
VERSION=v0.17.0.0
./gitian-build.py --setup $GH_USER $VERSION
```
Where `GH_USER` is your Github user name and `VERSION` is the version tag you want to build.
Setup for docker:
```bash
@@ -154,10 +145,8 @@ fork the [gitian.sigs repository](https://github.com/monero-project/gitian.sigs)
or pass the signed assert file back to your build machine.
```bash
git clone https://github.com/monero-project/gitian.sigs/
pushd gitian.sigs
git remote add $GH_USER https://github.com/$GH_USER/gitian.sigs
popd
git clone git@github.com:monero-project/gitian.sigs.git
git remote add $GH_USER git@github.com:$GH_USER/gitian.sigs.git
```
Build the binaries
@@ -165,26 +154,13 @@ Build the binaries
**Note:** if you intend to build MacOS binaries, please follow [these instructions](https://github.com/bitcoin-core/docs/blob/master/gitian-building/gitian-building-mac-os-sdk.md) to get the required SDK.
Currently working MacOS solution:
```bash
curl -O https://bitcoincore.org/depends-sources/sdks/MacOSX10.11.sdk.tar.gz
mv MacOSX10.11.sdk.tar.gz builder/inputs
```
To build the most recent tag (pass in `--docker` if using docker):
```bash
./gitian-build.py --detach-sign --no-commit --build $GH_USER $VERSION
```
To speed up the build, use `-j 5 --memory 10000` as the first arguments, where `5` is the number of CPU's you allocated to the VM plus one, and 10000 is a little bit less than then the MB's of RAM you allocated. If there is memory corruption on your machine, try to tweak these values. A good rule of thumb is, that Monero currently needs about 2 GB of RAM per core.
A full example for `docker` would look like the following:
```bash
./gitian-build.py -j 5 --memory 10000 --docker --detach-sign --no-commit --build $GH_USER $VERSION
```
To speed up the build, use `-j 5 --memory 5000` as the first arguments, where `5` is the number of CPU's you allocated to the VM plus one, and 5000 is a little bit less than then the MB's of RAM you allocated. If there is memory corruption on your machine, try to tweak these values.
If all went well, this produces a number of (uncommitted) `.assert` files in the gitian.sigs directory.
@@ -195,22 +171,6 @@ Take a look in the assert files and note the SHA256 checksums listed there.
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.
An example script to verify the checksums would be:
```bash
pushd out/${VERSION}
for ASSERT in ../../sigs/${VERSION}-*/*/*.assert; do
if ! sha256sum --ignore-missing -c "${ASSERT}" ; then
echo "FAILED for ${ASSERT} ! Please inspect manually."
fi
done
popd
```
Don't ignore the incorrect formatting of the found assert files. These files you'll have to compare manually (currently OSX and FreeBSD).
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.
@@ -221,7 +181,13 @@ Signing assert files
If you chose to do detached signing using `--detach-sign` above (recommended), you need to copy these uncommitted changes to your host machine, then sign them using your gpg key like so:
```bash
for ASSERT in sigs/${VERSION}-*/*/*.assert; do gpg --detach-sign ${ASSERT}; done
GH_USER=fluffypony
VERSION=v0.17.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
```
This will create a `.sig` file for each `.assert` file above (2 files for each platform).
@@ -234,7 +200,6 @@ Make a pull request (both the `.assert` and `.assert.sig` files) to the
[monero-project/gitian.sigs](https://github.com/monero-project/gitian.sigs/) repository:
```bash
cd gitian.sigs
git checkout -b $VERSION
# add your assert and sig files...
git commit -S -a -m "Add $GH_USER $VERSION"

View File

@@ -1,5 +1,5 @@
---
name: "wownero-android-0.10"
name: "wowzero-android-0.9"
enable_cache: true
suites:
- "bionic"
@@ -32,8 +32,8 @@ packages:
- "python3-zmq"
- "unzip"
remotes:
- "url": "https://git.wownero.com/wownero/wownero.git"
"dir": "wownero"
- "url": "https://git.wownero.com/synku/wowzero.git"
"dir": "wowzero"
files: []
script: |
@@ -75,7 +75,7 @@ script: |
then
ABI=$i"eabi"
fi
NDKDIR="${BUILD_DIR}/wownero/contrib/depends/$i/native/bin"
NDKDIR="${BUILD_DIR}/wowzero/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 wowzero
# 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=wowzero-${i}-${version}
mv bin ${DISTNAME}
find ${DISTNAME}/ | sort | tar --no-recursion --owner=0 --group=0 -c -T - | bzip2 -9 > ${OUTDIR}/${DISTNAME}.tar.bz2
cd ..

View File

@@ -31,8 +31,8 @@ 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('wowzero'):
subprocess.check_call(['git', 'clone', args.url, 'wowzero'])
os.chdir('..')
make_image_prog = ['bin/make-base-vm', '--suite', 'bionic', '--arch', 'amd64']
if args.docker:
@@ -67,10 +67,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])
infile = 'inputs/wowzero/contrib/gitian/gitian-' + tag_name + '.yml'
subprocess.check_call(['bin/gbuild', '-j', args.jobs, '-m', args.memory, '--commit', 'wowzero='+args.commit, '--url', 'wowzero='+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)
subprocess.check_call('mv build/out/wowzero-*.' + 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')
@@ -94,7 +94,11 @@ def build():
os.chdir('builder')
os.makedirs('inputs', exist_ok=True)
subprocess.check_call(['make', '-C', 'inputs/wownero/contrib/depends', 'download', 'SOURCES_PATH=' + os.getcwd() + '/cache/common'])
subprocess.check_call(['wget', '-N', '-P', 'inputs', 'https://downloads.sourceforge.net/project/osslsigncode/osslsigncode/osslsigncode-1.7.1.tar.gz'])
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/wowzero/contrib/depends', 'download', 'SOURCES_PATH=' + os.getcwd() + '/cache/common'])
rebuild()
@@ -105,7 +109,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/wowzero/contrib/gitian/gitian-'+v[1]+'.yml'])
os.chdir(workdir)
def main():
@@ -114,7 +118,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://git.wownero.com/wownero/wownero', help='Specify the URL of the repository. Default is %(default)s')
parser.add_argument('-u', '--url', dest='url', default='https://git.wownero.com/synku/wowzero', 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')
@@ -186,8 +190,8 @@ def main():
if args.setup:
setup()
os.makedirs('builder/inputs/wownero', exist_ok=True)
os.chdir('builder/inputs/wownero')
os.makedirs('builder/inputs/wowzero', exist_ok=True)
os.chdir('builder/inputs/wowzero')
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()

View File

@@ -1,5 +1,5 @@
---
name: "wownero-freebsd-0.10"
name: "wowzero-freebsd-0.9"
enable_cache: true
suites:
- "bionic"
@@ -32,8 +32,8 @@ packages:
- "libprotobuf-dev"
- "python3-zmq"
remotes:
- "url": "https://git.wownero.com/wownero/wownero.git"
"dir": "wownero"
- "url": "https://git.wownero.com/synku/wowzero.git"
"dir": "wowzero"
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 wowzero
# 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=wowzero-${i}-${version}
mv bin ${DISTNAME}
find ${DISTNAME}/ | sort | tar --no-recursion --owner=0 --group=0 -c -T - | bzip2 -9 > ${OUTDIR}/${DISTNAME}.tar.bz2
cd ..

View File

@@ -1,5 +1,5 @@
---
name: "wownero-linux-0.10"
name: "wowzero-linux-0.9"
enable_cache: true
suites:
- "bionic"
@@ -43,13 +43,13 @@ packages:
- "libprotobuf-dev"
- "python3-zmq"
remotes:
- "url": "https://git.wownero.com/wownero/wownero.git"
"dir": "wownero"
- "url": "https://git.wownero.com/synku/wowzero.git"
"dir": "wowzero"
files: []
script: |
WRAP_DIR=$HOME/wrapped
HOSTS="x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu i686-linux-gnu"
HOSTS="x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu"
FAKETIME_HOST_PROGS=""
FAKETIME_PROGS="date"
HOST_CFLAGS="-O2 -g"
@@ -120,7 +120,7 @@ script: |
export SOURCE_DATE_EPOCH=`date -d 2000-01-01T12:00:00 +%s`
git config --global core.abbrev 9
cd wownero
cd wowzero
# Set the version string that gets added to the tar archive name
version="`git describe`"
if [[ $version == *"-"*"-"* ]]; then
@@ -169,7 +169,7 @@ script: |
chmod 755 bin/*
cp ../LICENSE bin
chmod 644 bin/LICENSE
DISTNAME=wownero-${i}-${version}
DISTNAME=wowzero-${i}-${version}
mv bin ${DISTNAME}
find ${DISTNAME}/ | sort | tar --no-recursion --owner=0 --group=0 -c -T - | bzip2 -9 > ${OUTDIR}/${DISTNAME}.tar.bz2
cd ..

View File

@@ -1,5 +1,5 @@
---
name: "wownero-osx-0.10"
name: "wowzero-osx-0.9"
enable_cache: true
suites:
- "bionic"
@@ -24,8 +24,8 @@ packages:
- "python-dev"
- "python-setuptools"
remotes:
- "url": "https://git.wownero.com/wownero/wownero.git"
"dir": "wownero"
- "url": "https://git.wownero.com/synku/wowzero.git"
"dir": "wowzero"
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 wowzero
# 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=wowzero-${i}-${version}
mv bin ${DISTNAME}
find ${DISTNAME}/ | sort | tar --no-recursion --owner=0 --group=0 -c -T - | bzip2 -9 > ${OUTDIR}/${DISTNAME}.tar.bz2
cd ..

View File

@@ -1,5 +1,5 @@
---
name: "wownero-win-0.10"
name: "wowzero-win-0.9"
enable_cache: true
suites:
- "bionic"
@@ -36,12 +36,12 @@ alternatives:
package: "x86_64-w64-mingw32-gcc"
path: "/usr/bin/x86_64-w64-mingw32-gcc-posix"
remotes:
- "url": "https://git.wownero.com/wownero/wownero.git"
"dir": "wownero"
- "url": "https://git.wownero.com/synku/wowzero.git"
"dir": "wowzero"
files: []
script: |
WRAP_DIR=$HOME/wrapped
HOSTS="i686-w64-mingw32 x86_64-w64-mingw32"
HOSTS="x86_64-w64-mingw32"
FAKETIME_HOST_PROGS="windres objcopy"
FAKETIME_PROGS="date zip"
HOST_CFLAGS="-O2 -g"
@@ -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 wowzero
# 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=wowzero-${i}-${version}
mv bin ${DISTNAME}
find ${DISTNAME}/ | sort | zip -X@ ${OUTDIR}/${DISTNAME}.zip
cd .. && rm -rf build

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -0,0 +1,76 @@
name: wownero
version: 0.5.0.0
summary: "Wownero: the secure, private, untraceable cryptocurrency http://wownero.org"
description: |
Wownero: a fairly launched privacy-centric meme coin with no premine and a finite supply.
grade: devel
confinement: strict
apps:
wownerod:
daemon: forking
command: |
wownerod-wrapper --detach --data-dir ${SNAP_COMMON} --config-file ${SNAP_USER_DATA}/etc/wownerod.conf
plugs:
- network
- network-bind
wownero-wallet-rpc:
command: |
wownero-wallet-rpc --log-file ${SNAP_USER_DATA}
plugs:
- home
- network
- network-bind
wownero-wallet-cli:
command: |
wownero-wallet-cli --log-file ${SNAP_USER_DATA}
plugs:
- home
- network
parts:
cmake-build:
plugin: cmake
configflags:
- -DBDB_STATIC=1
- -DBoost_USE_STATIC_LIBS=1
- -DBoost_USE_STATIC_RUNTIME=1
- -DARCH=default
source: .
build-packages:
- gcc
- pkg-config
- libunbound-dev
- libevent-dev
- libboost-all-dev
- libzmqpp-dev
- libzmq3-dev
- libsodium-dev
- libdb-dev
- libunwind-dev
- libminiupnpc-dev
- libldns-dev
- libexpat1-dev
- libreadline6-dev
- bison
- doxygen
- graphviz
stage-packages:
- libminiupnpc10
- libunbound2
- libunwind8
prime:
- bin
- usr/lib/
- -usr/lib/gcc
- -usr/share
dist-files:
plugin: dump
source: .
organize:
contrib/snap/wownerod.conf: etc/wownerod.conf
contrib/snap/wownerod-wrapper: bin/wownerod-wrapper
prime:
- etc
- bin

8
contrib/snap/wownerod-wrapper Executable file
View File

@@ -0,0 +1,8 @@
#!/bin/sh
if [ ! -d "$SNAP_USER_DATA/etc" ]; then
mkdir $SNAP_USER_DATA/etc/
cp -R $SNAP/etc/wownerod.conf $SNAP_USER_DATA/etc/wownerod.conf
fi
exec "$SNAP/bin/wownerod" "$@"

View File

@@ -0,0 +1,10 @@
# Configuration for monerod
# Syntax: any command line option may be specified as 'clioptionname=value'.
# Boolean options such as 'no-igd' are specified as 'no-igd=1'.
# See 'monerod --help' for all available options.
# Overridden by snap:
# data-dir=/var/lib/wownero
# log-file=/var/log/wownero/wownero.log
log-level=0

View File

@@ -1,93 +0,0 @@
#!/bin/bash
DIR=$(realpath $(dirname $0))
echo "Checking wownerod..."
monerod=""
for dir in \
. \
"$DIR" \
"$DIR/../.." \
"$DIR/build/release/bin" \
"$DIR/../../build/release/bin" \
"$DIR/build/Linux/master/release/bin" \
"$DIR/../../build/Linux/master/release/bin" \
"$DIR/build/Windows/master/release/bin" \
"$DIR/../../build/Windows/master/release/bin"
do
if test -x "$dir/wownerod"
then
monerod="$dir/wownerod"
break
fi
done
if test -z "$wownerod"
then
echo "wownerod not found"
exit 1
fi
echo "Found: $wownerod"
TORDIR="$DIR/wownero-over-tor"
TORRC="$TORDIR/torrc"
HOSTNAMEFILE="$TORDIR/hostname"
echo "Creating configuration..."
mkdir -p "$TORDIR"
chmod 700 "$TORDIR"
rm -f "$TORRC"
cat << EOF > "$TORRC"
ControlSocket $TORDIR/control
ControlSocketsGroupWritable 1
CookieAuthentication 1
CookieAuthFile $TORDIR/control.authcookie
CookieAuthFileGroupReadable 1
HiddenServiceDir $TORDIR
HiddenServicePort 38083 127.0.0.1:38083
EOF
echo "Starting Tor..."
nohup tor -f "$TORRC" 2> "$TORDIR/tor.stderr" 1> "$TORDIR/tor.stdout" &
ready=0
for i in `seq 10`
do
sleep 1
if test -f "$HOSTNAMEFILE"
then
ready=1
break
fi
done
if test "$ready" = 0
then
echo "Error starting Tor"
cat "$TORDIR/tor.stdout"
exit 1
fi
echo "Starting wownerod..."
HOSTNAME=$(cat "$HOSTNAMEFILE")
"$monerod" \
--anonymous-inbound "$HOSTNAME":38083,127.0.0.1:38083,25 --tx-proxy tor,127.0.0.1:9050,10 \
--add-priority-node zbjkbsxc5munw3qusl7j2hpcmikhqocdf4pqhnhtpzw5nt5jrmofptid.onion:38083 \
--add-priority-node 2xmrnode5itf65lz.onion:38083 \
--detach
ready=0
for i in `seq 10`
do
sleep 1
status=$("$wownerod" status)
echo "$status" | grep -q "Height:"
if test $? = 0
then
ready=1
break
fi
done
if test "$ready" = 0
then
echo "Error starting wownerod"
tail -n 400 "$HOME/.wownero/wownero.log" | grep -Ev stacktrace\|"Error: Couldn't connect to daemon:"\|"src/daemon/main.cpp:.*Wownero\ \'" | tail -n 20
exit 1
fi
echo "Ready. Your Tor hidden service is $HOSTNAME"

View File

@@ -1,86 +0,0 @@
# Compiling, debugging and testing efficiently
This document describes ways of compiling, debugging and testing efficiently for various use cases.
The intented audience are developers, who want to leverage newly added tricks to Monero via `CMake`. The document will lower the entry point for these developers.
Before reading this document, please consult section "Build instructions" in the main README.md.
Some information from README.md will be repeated here, but the aim is to go beyond it.
## Basic compilation
Monero can be compiled via the main `Makefile`, using one of several targets listed there.
The targets are actually presets for `CMake` calls with various options, plus `make` commands for building or in some cases `make test` for testing.
It is possible to extract these `CMake` calls and modify them for your specific needs. For example, a minimal external cmake command to compile Monero, executed from within a newly created build directory could look like:
`cmake -S "$DIR_SRC" -DCMAKE_BUILD_TYPE=Release && make`
where the variable `DIR_SRC` is expected to store the path to the Monero source code.
## Use cases
### Test Driven Development (TDD) - shared libraries for release builds
Building shared libraries spares a lot of disk space and linkage time. By default only the debug builds produce shared libraries. If you'd like to produce dynamic libraries for the release build for the same reasons as it's being done for the debug version, then you need to add the `BUILD_SHARED_LIBS=ON` flag to the `CMake` call, like the following:
`cmake -S "$DIR_SRC" -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON && make`
A perfect use case for the above call is following the Test Driven Development (TDD) principles. In a nutshell, you'd first write a couple of tests, which describe the (new) requirements of the class/method that you're about to write or modify. The tests will typically compile for quite a long time, so ideally write them once. After you're done with the tests, the only thing left to do is to keep modifying the implementation for as long as the tests are failing. If the implementation is contained properly within a .cpp file, then the only time cost to be paid will be compiling the single source file and generating the implementation's shared library. The test itself will not have to be touched and will pick up the new version of the implementation (via the shared library) upon the next execution of the test.
### Project generation for IDEs
CMake allows to generate project files for many IDEs. The list of supported project files can be obtained by writing in the console:
`cmake -G`
For instance, in order to generate Makefiles and project files for the Code::Blocks IDE, this part of the call would look like the following:
`cmake -G "CodeBlocks - Unix Makefiles" (...)`
The additional artifact of the above call is the `monero.cbp` Code::Blocks project file in the build directory.
### Debugging in Code::Blocks (CB)
First prepare the build directory for debugging using the following example command, assuming, that the path to the source dir is being held in the DIR_SRC variable, and using 2 cores:
`cmake -S "$DIR_SRC" -G "CodeBlocks - Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTS=ON && make -j 2`
After a successful build, open the `monero.cbp` with CB. From the CB's menu bar select the target, that you want debug. Assuming these are unit tests:
`Build -> Select target -> Select target -> unit_tests`
In order to lower the turnaround times, we will run a specific portion of code of interest, without having to go through all the time costly initialization and execution of unrelated parts. For this we'll use GTest's capabilities of test filtering. From the build directory run the following command to learn all the registered tests:
`tests/unit_tests/unit_tests --gtest_list_tests`
For example, if you're only interested in logging, you'd find in the list the label `logging.` and its subtests. To execute all the logging tests, you'd write in the console:
`tests/unit_tests/unit_tests --gtest_filter="logging.*"`
This parameter is what we need to transfer to CB, in order to reflect the same behaviour in the CB's debugger. From the main menu select:
`Project -> Set program's arguments...`
Then in the `Program's arguments` textbox you'd write in this case:
`--gtest_filter="logging.*"`
Verify if the expected UTs are being properly executed with `F9` or select:
`Build -> Build and run`
If everything looks fine, then after setting some breakpoints of your choice, the target is ready for debugging in CB via:
`Debug -> Start/Continue`
## To be done (and merged):
### Multihost parallel compilation
https://github.com/monero-project/monero/pull/7160
### Faster core_tests with caching
https://github.com/monero-project/monero/pull/5821
### Precompiled headers
https://github.com/monero-project/monero/pull/7216
### Unity builds
https://github.com/monero-project/monero/pull/7217

View File

@@ -1,68 +0,0 @@
- [ ] Security audit
- [ ] Code audit
- [ ] Ledger integration
- [ ] Implemented in Monero codebase (if needed)
- [ ] Ledger app integration coded by Ledger
- [ ] Ledger Monero app update available
- [ ] Trezor integration
- [ ] Implemented in Monero codebase (if needed)
- [ ] Trezor app integration coded by Trezor
- [ ] Trezor firmware update available (if needed)
- [ ] Fork height set
- [ ] Monero-announce mailer notice
- [ ] Twitter announcement
- [ ] Reddit announcement
- [ ] Getmonero.org announcement
- [ ] Notify wallets
- [ ] MyMonero
- [ ] Coinomi
- [ ] Exa Wallet
- [ ] Wookey Wallet
- [ ] X Wallet
- [ ] Guarda
- [ ] ZelCore
- [ ] Cake Wallet
- [ ] Monerujo
- [ ] Edge Wallet
- [ ] Exodus
- [ ] XMRWallet
- [ ] Notify exchanges
- [ ] https://web.getmonero.org/community/merchants/#exchanges
- [ ] Notify 3rd party payment processors
- [ ] https://web.getmonero.org/community/merchants/#payment-gateways
- [ ] Notify mining pools
- [ ] https://miningpoolstats.stream/monero
- [ ] Release tagged
- [ ] Update src/version.cpp.in with new version AND new name (if necessary)
- [ ] Update Gitian YML files in contrib/gitian/ to the new version number
- [ ] Update README.md with new fork table entry (or at least update the Recommended Monero version)
- [ ] Update contrib/gitian/README.md so that the instructions reflect the current version
- [ ] Update src/checkpoints/checkpoints.cpp with a recent hardcoded checkpoint
- [ ] Update src/blocks/checkpoints.dat with ./monero-blockchain-export --output-file checkpoints.dat --block-stop <recent block height> --blocksdat
- [ ] Update expected_block_hashes_hash in src/cryptonote_core/blockchain.cpp with checkpoints.dat sha256 hash
- [ ] Testnet forked
- [ ] Testnet testing/verification
- [ ] Ledger
- [ ] Trezor
- [ ] Release-specific testing
- [ ] RPC testing/update RPC documentation
- [ ] CLI reproducible builds validated
- [ ] CLI released
- [ ] https://web.getmonero.org/downloads/ updated
- [ ] Update hashes.txt on website
- [ ] Update downloads.yml on website
- [ ] Update auto-update DNS records
- [ ] Update redirects on downloads box
- [ ] Update seed nodes
- [ ] GUI released
- [ ] https://web.getmonero.org/downloads/ updated
- [ ] Update hashes.txt on website
- [ ] Update hashes.txt.sig on website
- [ ] Update downloads.yml on website
- [ ] Update auto-update DNS records
- [ ] Update redirects on downloads box
- [ ] Release Announcements
- [ ] Monero-announce mailer notice
- [ ] Twitter announcement
- [ ] Reddit announcement
- [ ] Getmonero.org announcement

Some files were not shown because too many files have changed in this diff Show More