Compare commits
247 Commits
Author | SHA1 | Date |
---|---|---|
wowario | 589efde6b3 | |
jeffro256 | cb63c922f8 | |
jeffro256 | eeec04520d | |
selsta | 3605ec6419 | |
dsc | dad8e3cadd | |
wowario | c2d9ac9d16 | |
wowario | e707dafd04 | |
dsc | aa19aa8fc3 | |
dsc | 269fd51d34 | |
dsc | ea1ff89671 | |
wowario | a46db6fbf9 | |
wowario | 1fb180a69b | |
wowario | cf5bfd0cc4 | |
wowario | 6a5303f21b | |
wowario | 5a127e006e | |
wowario | 93e542dc55 | |
wowario | cae358334e | |
_XxFedexX_ | f0e9542c06 | |
wowario | 2f3f3b7a6e | |
wowario | b414a0659d | |
thotbot | 3f78176f3d | |
moneromooo-monero | f438928ed8 | |
wowario | b07e533a8f | |
hinto-janaiyo | 8ccfd46a41 | |
thotbot | e60954b619 | |
thotbot | 1ed861bff8 | |
thotbot | 8b467e98a4 | |
thotbot | 4f8ad5bfac | |
thotbot | 3234b5fe62 | |
thotbot | e6cc37e9b0 | |
thotbot | fcffffdd5d | |
wowario | 77ca74ba54 | |
wowario | 8d78cedaec | |
wowario | e8bec95650 | |
w0wΔri0 | 36dc60fdfd | |
wowario | f742aed6a3 | |
wowario | b602ab02ee | |
wowario | f409249b78 | |
wowario | 0bb22452ac | |
wowario | 8337a81ef5 | |
wowario | 6ca2369b67 | |
wowario | 934cd71608 | |
wowario | b2906602a4 | |
wowario | df381eaa84 | |
wowario | 83a0e91e23 | |
wowario | 26d039db0a | |
wowario | 662a2993d3 | |
wowario | 65570252f2 | |
wowario | eff55d073c | |
wowario | d1441bc034 | |
wowario | 5e50141c4a | |
wowario | 8c081b4b02 | |
wowario | 917970cebf | |
wowario | c7190cdd0f | |
wowario | a177241046 | |
wowario | e224b4af93 | |
wowario | 0c4915d707 | |
wowario | ff34adf8b7 | |
wowario | 48841789cb | |
wowario | 2ddaa7835c | |
wowario | aa7564806d | |
wowario | a0a90ada1a | |
wowario | 7b9bfb73b1 | |
wowario | 642beba4af | |
wowario | cf8e878869 | |
wowario | 6afdd7894a | |
wowario | 7f01ebbf29 | |
wowario | 6fee906b1c | |
wowario | 0fd82de0be | |
wowario | 68f1f2b2c3 | |
wowario | ddf990f394 | |
wowario | 196a3756d6 | |
wowario | 4ed9b68d59 | |
wowario | 37195f2128 | |
wowario | e71bef4496 | |
wowario | a04690c66b | |
wowario | 9c3fb6c243 | |
wowario | 463de38ef5 | |
wowario | c474334f41 | |
wowario | ce3a67ed21 | |
wowario | fb39891031 | |
wowario | 1c44d89030 | |
wowario | da6a2dc2c5 | |
wowario | d6a3511d59 | |
wowario | 6b8e245aea | |
wowario | 917edfbec9 | |
wowario | 5964374c4b | |
wowario | a5d50332ca | |
wowario | 73f52ea6b9 | |
wowario | 1cae37348a | |
wowario | 2b78ff8117 | |
wowario | e5016a6f8e | |
wowario | a93dcc1962 | |
wowario | a25032cc1e | |
wowario | 2a4e1c6913 | |
wowario | 3271844ab5 | |
wowario | 7af83ced4c | |
luigi1111 | ef3e18b51b | |
SChernykh | b5b72ae05c | |
luigi1111 | 5eb3fc29bb | |
luigi1111 | c225a1f25b | |
luigi1111 | ff15cb2f04 | |
jeffro256 | eeb7c7c546 | |
SChernykh | 36ee12bd8d | |
selsta | 32b3a56313 | |
luigi1111 | b23116424d | |
jeffro256 | 7807f569e4 | |
luigi1111 | 68e40ea2a7 | |
luigi1111 | c6ff0d3820 | |
luigi1111 | 0d2f515ecc | |
luigi1111 | 522d82276e | |
luigi1111 | 4f6f6d9e27 | |
luigi1111 | 3872753202 | |
luigi1111 | 13ed9d501b | |
luigi1111 | b335433204 | |
luigi1111 | 8a1e49664e | |
luigi1111 | 2f912f8a58 | |
luigi1111 | 81f113dd8c | |
luigi1111 | f9a7f2a136 | |
selsta | c97c2ec01c | |
jeffro256 | 51d7a6921c | |
selsta | f2360a725e | |
selsta | 0cc8f7aaa3 | |
tobtoht | b987870553 | |
tobtoht | 3aabfcfce5 | |
tobtoht | 8322f9c4f5 | |
woodser | fbd0b19fc8 | |
jeffro256 | 33e3f72d24 | |
Lee *!* Clagett | 052df1b28c | |
Lee Clagett | 98ee46f249 | |
Lee *!* Clagett | f5b86342e8 | |
jeffro256 | dfb990e8bb | |
luigi1111 | 8eab181fe1 | |
luigi1111 | 9a70f43440 | |
Lee Clagett | 47d8899c90 | |
luigi1111 | c09062087e | |
luigi1111 | 9a5f8431b4 | |
luigi1111 | 79107ff68f | |
luigi1111 | 646c3fb0d9 | |
luigi1111 | c193c5e85d | |
luigi1111 | d5c667a5ad | |
luigi1111 | 2fe5a5e073 | |
luigi1111 | 95e4fc3602 | |
SChernykh | e7d51e5583 | |
Lee *!* Clagett | fe746dca4e | |
jeffro256 | fe47806afb | |
moneromooo-monero | 6c38c21dfd | |
Jeffrey Ryan | 5435202450 | |
luigi1111 | d9b765a3af | |
luigi1111 | 72d2a610cd | |
luigi1111 | 2e9542d01a | |
jeffro256 | 0f75585f64 | |
luigi1111 | eb4df0aa1c | |
jeffro256 | eae62a07e0 | |
jeffro256 | 14ae81246d | |
selsta | 5b0c27430f | |
tevador | 09a88cc00e | |
j-berman | bdebf680bd | |
jeffro256 | e0b2123c32 | |
luigi1111 | 2656cdf505 | |
luigi1111 | 1c12d305d6 | |
luigi1111 | 83d0d2338f | |
Boog900 | 69de381526 | |
Boog900 | 810f6a6cd2 | |
selsta | fbcd8da082 | |
selsta | 03d51b7cc4 | |
luigi1111 | f9b81a589e | |
luigi1111 | 41157dbc82 | |
j-berman | 9a89e2d9e4 | |
Crypto City | 1df5630f23 | |
selsta | 3f9140e754 | |
jeff | 205c80427b | |
tobtoht | 0c04018718 | |
luigi1111 | 533bbc3208 | |
luigi1111 | 6e7bd68b18 | |
luigi1111 | 031d318ca2 | |
luigi1111 | 61e664a258 | |
selsta | 64ed9385a2 | |
jeffro256 | ba98269ca5 | |
jeffro256 | 7dbb14b02a | |
moneromooo-monero | 356e6877dc | |
moneromooo-monero | 633e1b7359 | |
luigi1111 | eac1b86bb2 | |
luigi1111 | 3bebcc4a7d | |
luigi1111 | 9d5c5b5634 | |
luigi1111 | 894adef295 | |
luigi1111 | 6c7640eb74 | |
jeffro256 | 78348bcddd | |
j-berman | b51f4a9244 | |
jeffro256 | ed05ac6872 | |
j-berman | f137a35984 | |
rbrunner7 | 23f782b211 | |
luigi1111 | ab826008d6 | |
luigi1111 | 4dc727b3f6 | |
luigi1111 | 1eb1162923 | |
luigi1111 | 3be6c1389e | |
luigi1111 | 5a99b2dfbe | |
luigi1111 | bd962882d1 | |
luigi1111 | f173bf6e72 | |
luigi1111 | a41453c256 | |
jeffro256 | 842478c5a9 | |
luigi1111 | 17ea7665d7 | |
luigi1111 | 9f8ae9649a | |
luigi1111 | 11b5139506 | |
luigi1111 | 54f0f9eb96 | |
luigi1111 | 5c900bb69f | |
luigi1111 | 60e9426ef2 | |
Crypto City | 835896ea24 | |
Crypto City | 62bb95b25f | |
moneromooo-monero | 1924c170d4 | |
Lee *!* Clagett | aed36a25d6 | |
Lee Clagett | c6530d2f5d | |
jeffro256 | dc24312bc3 | |
j-berman | 438554e1ab | |
SChernykh | 26025cb294 | |
jeffro256 | cfc62277c0 | |
jeffro256 | aa139f0334 | |
tobtoht | a4a58eb886 | |
tobtoht | 8dc4abdafe | |
luigi1111 | 1ce32d8536 | |
Crypto City | 1fad8cc919 | |
tobtoht | f983ac7780 | |
SChernykh | 1d1d5fb74c | |
luigi1111 | 2f45d5c615 | |
luigi1111 | e06129bb4d | |
luigi1111 | a371e60a30 | |
luigi1111 | 2f62dd5b78 | |
jeffro256 | 059b975388 | |
SChernykh | c742fa4c6e | |
selsta | 4f1262bae9 | |
luigi1111 | 4f47fd2626 | |
Crypto City | 132804811d | |
luigi1111 | 25645e5d23 | |
luigi1111 | 0e2c2ddd9c | |
moneromooo-monero | c4cfaa4567 | |
moneromooo-monero | f0e326be58 | |
luigi1111 | 225e5ba571 | |
luigi1111 | 66f57299a2 | |
luigi1111 | d7821a02c4 | |
luigi1111 | b4519c6bbd | |
selsta | cdeb286359 | |
tevador | 5900ed3706 | |
Jeffrey Ryan | c59e0096b6 | |
Francois Beutin | 14de562a6f | |
j-berman | 65e13dbef1 | |
almalh | ad80f1b357 | |
selsta | 77d883e507 |
|
@ -27,10 +27,10 @@ jobs:
|
|||
env:
|
||||
CCACHE_TEMPDIR: /tmp/.ccache-temp
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
- uses: actions/cache@v2
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: /Users/runner/Library/Caches/ccache
|
||||
key: ccache-${{ runner.os }}-build-${{ github.sha }}
|
||||
|
@ -51,15 +51,15 @@ jobs:
|
|||
run:
|
||||
shell: msys2 {0}
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
- uses: actions/cache@v2
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: C:\Users\runneradmin\.ccache
|
||||
key: ccache-${{ runner.os }}-build-${{ github.sha }}
|
||||
restore-keys: ccache-${{ runner.os }}-build-
|
||||
- uses: eine/setup-msys2@v2
|
||||
- uses: msys2/setup-msys2@v2
|
||||
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 mingw-w64-x86_64-unbound git
|
||||
|
@ -79,10 +79,10 @@ jobs:
|
|||
matrix:
|
||||
os: [ubuntu-22.04, ubuntu-20.04]
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
- uses: actions/cache@v2
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.ccache
|
||||
key: ccache-${{ runner.os }}-build-${{ matrix.os }}-${{ github.sha }}
|
||||
|
@ -105,10 +105,10 @@ jobs:
|
|||
env:
|
||||
CCACHE_TEMPDIR: /tmp/.ccache-temp
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
- uses: actions/cache@v2
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.ccache
|
||||
key: ccache-${{ runner.os }}-libwallet-${{ github.sha }}
|
||||
|
@ -133,11 +133,11 @@ jobs:
|
|||
env:
|
||||
CCACHE_TEMPDIR: /tmp/.ccache-temp
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: ccache
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.ccache
|
||||
key: ccache-${{ runner.os }}-build-ubuntu-latest-${{ github.sha }}
|
||||
|
@ -151,7 +151,7 @@ jobs:
|
|||
- name: install monero dependencies
|
||||
run: ${{env.APT_INSTALL_LINUX}}
|
||||
- name: install Python dependencies
|
||||
run: pip install requests psutil monotonic zmq
|
||||
run: pip install requests psutil monotonic zmq deepdiff
|
||||
- name: tests
|
||||
env:
|
||||
CTEST_OUTPUT_ON_FAILURE: ON
|
||||
|
@ -167,8 +167,9 @@ jobs:
|
|||
source-archive:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: recursive
|
||||
- name: archive
|
||||
run: |
|
||||
|
@ -177,7 +178,7 @@ jobs:
|
|||
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
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ env.OUTPUT }}
|
||||
path: /home/runner/work/monero/monero/${{ env.OUTPUT }}
|
||||
|
|
|
@ -57,19 +57,20 @@ jobs:
|
|||
packages: "clang-8 gperf cmake python3-zmq libdbus-1-dev libharfbuzz-dev"
|
||||
name: ${{ matrix.toolchain.name }}
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: recursive
|
||||
# Most volatile cache
|
||||
- name: ccache
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.ccache
|
||||
key: ccache-${{ matrix.toolchain.host }}-${{ github.sha }}
|
||||
restore-keys: ccache-${{ matrix.toolchain.host }}-
|
||||
# Less volatile cache
|
||||
- name: depends cache
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: contrib/depends/built
|
||||
key: depends-${{ matrix.toolchain.host }}-${{ hashFiles('contrib/depends/packages/*') }}
|
||||
|
@ -78,7 +79,7 @@ jobs:
|
|||
depends-${{ matrix.toolchain.host }}-
|
||||
# Static cache
|
||||
- name: OSX SDK cache
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: contrib/depends/sdk-sources
|
||||
key: sdk-${{ matrix.toolchain.host }}-${{ matrix.toolchain.osx_sdk }}
|
||||
|
@ -96,7 +97,7 @@ jobs:
|
|||
run: |
|
||||
${{env.CCACHE_SETTINGS}}
|
||||
make depends target=${{ matrix.toolchain.host }} -j2
|
||||
- uses: actions/upload-artifact@v2
|
||||
- uses: actions/upload-artifact@v3
|
||||
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 }}
|
||||
|
|
|
@ -42,7 +42,7 @@ jobs:
|
|||
echo \`\`\` >> $GITHUB_STEP_SUMMARY
|
||||
shasum -a256 * >> $GITHUB_STEP_SUMMARY
|
||||
echo \`\`\` >> $GITHUB_STEP_SUMMARY
|
||||
- uses: actions/upload-artifact@v3.1.0
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ matrix.operating-system.name }}
|
||||
path: |
|
||||
|
|
|
@ -5,12 +5,15 @@
|
|||
path = external/rapidjson
|
||||
url = https://github.com/Tencent/rapidjson
|
||||
[submodule "external/trezor-common"]
|
||||
active = false
|
||||
path = external/trezor-common
|
||||
url = https://github.com/trezor/trezor-common.git
|
||||
[submodule "external/randomx"]
|
||||
path = external/randomx
|
||||
url = https://github.com/tevador/RandomX
|
||||
[submodule "external/supercop"]
|
||||
path = external/supercop
|
||||
url = https://github.com/monero-project/supercop
|
||||
branch = monero
|
||||
[submodule "external/randomwow"]
|
||||
path = external/randomwow
|
||||
url = https://git.wownero.com/wownero/RandomWOW
|
||||
branch = 1.2.1-wow
|
||||
|
||||
|
|
|
@ -359,15 +359,16 @@ if(NOT MANUAL_SUBMODULES)
|
|||
if (upToDate)
|
||||
message(STATUS "Submodule '${relative_path}' is up-to-date")
|
||||
else()
|
||||
message(FATAL_ERROR "Submodule '${relative_path}' is not up-to-date. Please update all submodules with\ngit submodule update --init --force\nor run cmake with -DMANUAL_SUBMODULES=1\n")
|
||||
message(STATUS "Initializing submodules")
|
||||
execute_process(COMMAND git "submodule" "update" "--init" "--recursive" WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
||||
endif()
|
||||
endfunction ()
|
||||
|
||||
message(STATUS "Checking submodules")
|
||||
check_submodule(external/miniupnp)
|
||||
check_submodule(external/rapidjson)
|
||||
check_submodule(external/trezor-common)
|
||||
check_submodule(external/randomx)
|
||||
#check_submodule(external/trezor-common)
|
||||
check_submodule(external/randomwow)
|
||||
check_submodule(external/supercop)
|
||||
endif()
|
||||
endif()
|
||||
|
@ -405,7 +406,7 @@ option(BOOST_IGNORE_SYSTEM_PATHS "Ignore boost system paths for local boost inst
|
|||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
enable_testing()
|
||||
|
||||
option(BUILD_DOCUMENTATION "Build the Doxygen documentation." ON)
|
||||
option(BUILD_DOCUMENTATION "Build the Doxygen documentation." OFF)
|
||||
option(BUILD_TESTS "Build tests." OFF)
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set(DEFAULT_BUILD_DEBUG_UTILITIES ON)
|
||||
|
|
26
Dockerfile
26
Dockerfile
|
@ -41,26 +41,26 @@ RUN set -ex && \
|
|||
rm -rf /var/lib/apt
|
||||
COPY --from=builder /src/build/x86_64-linux-gnu/release/bin /usr/local/bin/
|
||||
|
||||
# Create monero user
|
||||
RUN adduser --system --group --disabled-password monero && \
|
||||
mkdir -p /wallet /home/monero/.bitmonero && \
|
||||
chown -R monero:monero /home/monero/.bitmonero && \
|
||||
chown -R monero:monero /wallet
|
||||
# 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/monero/.bitmonero
|
||||
VOLUME /home/wownero/.wownero
|
||||
|
||||
# Generate your wallet via accessing the container and run:
|
||||
# cd /wallet
|
||||
# monero-wallet-cli
|
||||
# wownero-wallet-cli
|
||||
VOLUME /wallet
|
||||
|
||||
EXPOSE 18080
|
||||
EXPOSE 18081
|
||||
EXPOSE 34567
|
||||
EXPOSE 34568
|
||||
|
||||
# switch to user monero
|
||||
USER monero
|
||||
# switch to user wownero
|
||||
USER wownero
|
||||
|
||||
ENTRYPOINT ["monerod"]
|
||||
CMD ["--p2p-bind-ip=0.0.0.0", "--p2p-bind-port=18080", "--rpc-bind-ip=0.0.0.0", "--rpc-bind-port=18081", "--non-interactive", "--confirm-external-bind"]
|
||||
ENTRYPOINT ["wownerod"]
|
||||
CMD ["--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"]
|
||||
|
||||
|
|
4
Makefile
4
Makefile
|
@ -100,11 +100,11 @@ release-test:
|
|||
|
||||
release-all:
|
||||
mkdir -p $(builddir)/release
|
||||
cd $(builddir)/release && cmake -D BUILD_TESTS=ON -D CMAKE_BUILD_TYPE=Release $(topdir) && $(MAKE)
|
||||
cd $(builddir)/release && cmake -D BUILD_TESTS=OFF -D USE_DEVICE_TREZOR=OFF -D CMAKE_BUILD_TYPE=Release $(topdir) && $(MAKE)
|
||||
|
||||
release-static:
|
||||
mkdir -p $(builddir)/release
|
||||
cd $(builddir)/release && cmake -D STATIC=ON -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=Release $(topdir) && $(MAKE)
|
||||
cd $(builddir)/release && cmake -D BUILD_TESTS=OFF -D USE_DEVICE_TREZOR=OFF -D STATIC=ON -D BUILD_64=ON -D CMAKE_BUILD_TYPE=Release $(topdir) && $(MAKE)
|
||||
|
||||
coverage:
|
||||
mkdir -p $(builddir)/debug
|
||||
|
|
|
@ -145,7 +145,7 @@ $(1)_build_env+=PATH="$(build_prefix)/bin:$(PATH)"
|
|||
$(1)_stage_env+=PATH="$(build_prefix)/bin:$(PATH)"
|
||||
$(1)_autoconf=./configure --host=$($($(1)_type)_host) --prefix=$($($(1)_type)_prefix) $$($(1)_config_opts) CC="$$($(1)_cc)" CXX="$$($(1)_cxx)"
|
||||
|
||||
ifneq ($(1),libusb)
|
||||
ifeq ($(filter $(1),libusb unbound),)
|
||||
$(1)_autoconf += --disable-dependency-tracking
|
||||
endif
|
||||
ifneq ($($(1)_nm),)
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
package=expat
|
||||
$(package)_version=2.4.1
|
||||
$(package)_download_path=https://github.com/libexpat/libexpat/releases/download/R_2_4_1
|
||||
$(package)_version=2.6.0
|
||||
$(package)_download_path=https://github.com/libexpat/libexpat/releases/download/R_$(subst .,_,$($(package)_version))/
|
||||
$(package)_file_name=$(package)-$($(package)_version).tar.bz2
|
||||
$(package)_sha256_hash=2f9b6a580b94577b150a7d5617ad4643a4301a6616ff459307df3e225bcfbf40
|
||||
$(package)_sha256_hash=ff60e6a6b6ce570ae012dc7b73169c7fdf4b6bf08c12ed0ec6f55736b78d85ba
|
||||
|
||||
define $(package)_set_vars
|
||||
$(package)_config_opts=--enable-static
|
||||
$(package)_config_opts=--disable-shared
|
||||
$(package)_config_opts=--disable-shared --without-docbook --without-tests --without-examples
|
||||
$(package)_config_opts+=--enable-option-checking --without-xmlwf --with-pic
|
||||
$(package)_config_opts+=--prefix=$(host_prefix)
|
||||
endef
|
||||
|
||||
|
@ -23,6 +23,6 @@ define $(package)_stage_cmds
|
|||
endef
|
||||
|
||||
define $(package)_postprocess_cmds
|
||||
rm lib/*.la
|
||||
rm -rf share lib/cmake lib/*.la
|
||||
endef
|
||||
|
||||
|
|
|
@ -1,20 +1,19 @@
|
|||
package=openssl
|
||||
$(package)_version=1.1.1t
|
||||
$(package)_version=3.0.13
|
||||
$(package)_download_path=https://www.openssl.org/source
|
||||
$(package)_file_name=$(package)-$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=8dee9b24bdb1dcbf0c3d1e9b02fb8f6bf22165e807f45adeb7c9677536859d3b
|
||||
$(package)_sha256_hash=88525753f79d3bec27d2fa7c66aa0b92b3aa9498dafd93d7cfa4b3780cdae313
|
||||
|
||||
define $(package)_set_vars
|
||||
$(package)_config_env=AR="$($(package)_ar)" ARFLAGS=$($(package)_arflags) RANLIB="$($(package)_ranlib)" CC="$($(package)_cc)"
|
||||
$(package)_config_env_android=ANDROID_NDK_HOME="$(host_prefix)/native" PATH="$(host_prefix)/native/bin" CC=clang AR=ar RANLIB=ranlib
|
||||
$(package)_build_env_android=ANDROID_NDK_HOME="$(host_prefix)/native"
|
||||
$(package)_config_opts=--prefix=$(host_prefix) --openssldir=$(host_prefix)/etc/openssl
|
||||
$(package)_config_env_android=ANDROID_NDK_ROOT="$(host_prefix)/native" PATH="$(host_prefix)/native/bin" CC=clang AR=ar RANLIB=ranlib
|
||||
$(package)_build_env_android=ANDROID_NDK_ROOT="$(host_prefix)/native"
|
||||
$(package)_config_opts=--prefix=$(host_prefix) --openssldir=$(host_prefix)/etc/openssl --libdir=$(host_prefix)/lib
|
||||
$(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-heartbeats
|
||||
$(package)_config_opts+=no-md2
|
||||
$(package)_config_opts+=no-rc5
|
||||
$(package)_config_opts+=no-rdrand
|
||||
|
@ -22,8 +21,8 @@ $(package)_config_opts+=no-rfc3779
|
|||
$(package)_config_opts+=no-sctp
|
||||
$(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-tests
|
||||
$(package)_config_opts+=no-unit-test
|
||||
$(package)_config_opts+=no-weak-ssl-ciphers
|
||||
$(package)_config_opts+=no-zlib
|
||||
|
@ -49,7 +48,7 @@ $(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.old 's|crypto ssl apps util tools fuzz providers doc|crypto ssl util tools providers|' build.info
|
||||
endef
|
||||
|
||||
define $(package)_config_cmds
|
||||
|
|
|
@ -1,17 +1,21 @@
|
|||
package=unbound
|
||||
$(package)_version=1.15.0
|
||||
$(package)_version=1.19.1
|
||||
$(package)_download_path=https://www.nlnetlabs.nl/downloads/$(package)/
|
||||
$(package)_file_name=$(package)-$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=a480dc6c8937447b98d161fe911ffc76cfaffa2da18788781314e81339f1126f
|
||||
$(package)_sha256_hash=bc1d576f3dd846a0739adc41ffaa702404c6767d2b6082deb9f2f97cbb24a3a9
|
||||
$(package)_dependencies=openssl expat
|
||||
$(package)_patches=disable-glibc-reallocarray.patch
|
||||
|
||||
|
||||
define $(package)_set_vars
|
||||
$(package)_config_opts=--disable-shared --enable-static --without-pyunbound --prefix=$(host_prefix) --with-libexpat=$(host_prefix) --with-ssl=$(host_prefix) --with-libevent=no --without-pythonmodule --disable-flto --with-pthreads --with-libunbound-only
|
||||
$(package)_config_opts=--disable-shared --enable-static --without-pyunbound --prefix=$(host_prefix)
|
||||
$(package)_config_opts+=--with-libexpat=$(host_prefix) --with-ssl=$(host_prefix) --with-libevent=no
|
||||
$(package)_config_opts+=--without-pythonmodule --disable-flto --with-pthreads --with-libunbound-only
|
||||
$(package)_config_opts_linux=--with-pic
|
||||
$(package)_config_opts_w64=--enable-static-exe --sysconfdir=/etc --prefix=$(host_prefix) --target=$(host_prefix)
|
||||
$(package)_config_opts_x86_64_darwin=ac_cv_func_SHA384_Init=yes
|
||||
$(package)_build_opts_mingw32=LDFLAGS="$($(package)_ldflags) -lpthread"
|
||||
$(package)_cflags_mingw32+="-D_WIN32_WINNT=0x600"
|
||||
endef
|
||||
|
||||
define $(package)_preprocess_cmds
|
||||
|
@ -30,6 +34,3 @@ endef
|
|||
define $(package)_stage_cmds
|
||||
$(MAKE) DESTDIR=$($(package)_staging_dir) install
|
||||
endef
|
||||
|
||||
define $(package)_postprocess_cmds
|
||||
endef
|
||||
|
|
|
@ -144,8 +144,11 @@ elseif(ARCHITECTURE STREQUAL "aarch64")
|
|||
endif()
|
||||
|
||||
if(ARCHITECTURE STREQUAL "riscv64")
|
||||
set(NO_AES ON)
|
||||
set(ARCH "rv64imafdc")
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
set(BUILD_TAG "linux-riscv64")
|
||||
endif()
|
||||
set(ARCH_ID "riscv64")
|
||||
set(ARCH "rv64gc")
|
||||
endif()
|
||||
|
||||
if(ARCHITECTURE STREQUAL "i686")
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include <string>
|
||||
#include <ctime>
|
||||
#include <cstdint>
|
||||
|
||||
namespace epee
|
||||
{
|
||||
|
|
|
@ -583,11 +583,8 @@ namespace net_utils
|
|||
break;
|
||||
}
|
||||
}
|
||||
else if (ec.value())
|
||||
terminate();
|
||||
else {
|
||||
cancel_timer();
|
||||
on_interrupted();
|
||||
terminate();
|
||||
}
|
||||
};
|
||||
m_strand.post(
|
||||
|
|
|
@ -147,6 +147,16 @@ namespace epee
|
|||
return {reinterpret_cast<const std::uint8_t*>(src.data()), src.size_bytes()};
|
||||
}
|
||||
|
||||
//! \return `span<std::uint8_t>` from a STL compatible `src`.
|
||||
template<typename T>
|
||||
constexpr span<std::uint8_t> to_mut_byte_span(T& src)
|
||||
{
|
||||
using value_type = typename T::value_type;
|
||||
static_assert(!std::is_empty<value_type>(), "empty value types will not work -> sizeof == 1");
|
||||
static_assert(!has_padding<value_type>(), "source value type may have padding");
|
||||
return {reinterpret_cast<std::uint8_t*>(src.data()), src.size() * sizeof(value_type)};
|
||||
}
|
||||
|
||||
//! \return `span<const std::uint8_t>` which represents the bytes at `&src`.
|
||||
template<typename T>
|
||||
span<const std::uint8_t> as_byte_span(const T& src) noexcept
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include <boost/utility/string_ref_fwd.hpp>
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
|
||||
namespace epee
|
||||
{
|
||||
|
|
|
@ -33,6 +33,9 @@
|
|||
#include "portable_storage_base.h"
|
||||
#include "portable_storage_bin_utils.h"
|
||||
|
||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
#define MONERO_DEFAULT_LOG_CATEGORY "serialization"
|
||||
|
||||
#ifdef EPEE_PORTABLE_STORAGE_RECURSION_LIMIT
|
||||
#define EPEE_PORTABLE_STORAGE_RECURSION_LIMIT_INTERNAL EPEE_PORTABLE_STORAGE_RECURSION_LIMIT
|
||||
#else
|
||||
|
|
|
@ -31,6 +31,9 @@
|
|||
#include "parserse_base_utils.h"
|
||||
#include "file_io_utils.h"
|
||||
|
||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
#define MONERO_DEFAULT_LOG_CATEGORY "serialization"
|
||||
|
||||
#define EPEE_JSON_RECURSION_LIMIT_INTERNAL 100
|
||||
|
||||
namespace epee
|
||||
|
|
|
@ -338,11 +338,21 @@ bool is_stdout_a_tty()
|
|||
return is_a_tty.load(std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
static bool is_nocolor()
|
||||
{
|
||||
static const char *no_color_var = getenv("NO_COLOR");
|
||||
static const bool no_color = no_color_var && *no_color_var; // apparently, NO_COLOR=0 means no color too (as per no-color.org)
|
||||
return no_color;
|
||||
}
|
||||
|
||||
void set_console_color(int color, bool bright)
|
||||
{
|
||||
if (!is_stdout_a_tty())
|
||||
return;
|
||||
|
||||
if (is_nocolor())
|
||||
return;
|
||||
|
||||
switch(color)
|
||||
{
|
||||
case console_color_default:
|
||||
|
@ -461,6 +471,9 @@ void reset_console_color() {
|
|||
if (!is_stdout_a_tty())
|
||||
return;
|
||||
|
||||
if (is_nocolor())
|
||||
return;
|
||||
|
||||
#ifdef WIN32
|
||||
HANDLE h_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
SetConsoleTextAttribute(h_stdout, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
|
|
|
@ -496,6 +496,13 @@ void ssl_options_t::configure(
|
|||
const std::string& host) const
|
||||
{
|
||||
socket.next_layer().set_option(boost::asio::ip::tcp::no_delay(true));
|
||||
{
|
||||
// in case server is doing "virtual" domains, set hostname
|
||||
SSL* const ssl_ctx = socket.native_handle();
|
||||
if (type == boost::asio::ssl::stream_base::client && !host.empty() && ssl_ctx)
|
||||
SSL_set_tlsext_host_name(ssl_ctx, host.c_str());
|
||||
}
|
||||
|
||||
|
||||
/* Using system-wide CA store for client verification is funky - there is
|
||||
no expected hostname for server to verify against. If server doesn't have
|
||||
|
@ -513,11 +520,7 @@ void ssl_options_t::configure(
|
|||
{
|
||||
socket.set_verify_mode(boost::asio::ssl::verify_peer | boost::asio::ssl::verify_fail_if_no_peer_cert);
|
||||
|
||||
// in case server is doing "virtual" domains, set hostname
|
||||
SSL* const ssl_ctx = socket.native_handle();
|
||||
if (type == boost::asio::ssl::stream_base::client && !host.empty() && ssl_ctx)
|
||||
SSL_set_tlsext_host_name(ssl_ctx, host.c_str());
|
||||
|
||||
|
||||
socket.set_verify_callback([&](const bool preverified, boost::asio::ssl::verify_context &ctx)
|
||||
{
|
||||
// preverified means it passed system or user CA check. System CA is never loaded
|
||||
|
|
|
@ -238,6 +238,10 @@ static char** attempted_completion(const char* text, int start, int end)
|
|||
|
||||
static void install_line_handler()
|
||||
{
|
||||
#if RL_READLINE_VERSION >= 0x0801
|
||||
rl_variable_bind("enable-bracketed-paste", "off");
|
||||
#endif
|
||||
|
||||
rl_attempted_completion_function = attempted_completion;
|
||||
rl_callback_handler_install("", handle_line);
|
||||
stifle_history(500);
|
||||
|
|
|
@ -57,7 +57,7 @@ The dockrun.sh script will do everything to build the binaries. Just specify the
|
|||
version to build as its only argument, e.g.
|
||||
|
||||
```bash
|
||||
VERSION=v0.18.2.0
|
||||
VERSION=v0.18.3.2
|
||||
./dockrun.sh $VERSION
|
||||
```
|
||||
|
||||
|
|
|
@ -133,7 +133,7 @@ Common setup part:
|
|||
su - gitianuser
|
||||
|
||||
GH_USER=YOUR_GITHUB_USER_NAME
|
||||
VERSION=v0.18.2.0
|
||||
VERSION=v0.18.3.2
|
||||
```
|
||||
|
||||
Where `GH_USER` is your GitHub user name and `VERSION` is the version tag you want to build.
|
||||
|
|
|
@ -41,10 +41,10 @@ RUN useradd -ms /bin/bash -U ubuntu -G docker
|
|||
USER ubuntu:docker
|
||||
WORKDIR $WORKDIR
|
||||
|
||||
RUN git clone https://github.com/monero-project/gitian.sigs.git sigs; \
|
||||
RUN git clone https://git.wownero.com/wownero/gitian.sigs.git sigs; \
|
||||
git clone https://github.com/devrandom/gitian-builder.git builder; \
|
||||
cd builder; git checkout c0f77ca018cb5332bfd595e0aff0468f77542c23; mkdir -p inputs var; cd inputs; \
|
||||
git clone https://github.com/monero-project/monero
|
||||
git clone https://git.wownero.com/wownero/wownero
|
||||
|
||||
CMD ["sleep", "infinity"]
|
||||
EOF
|
||||
|
@ -109,7 +109,7 @@ if [ "$check" != "sign" ]; then
|
|||
fi
|
||||
|
||||
if [ ! -d sigs ]; then
|
||||
git clone https://github.com/monero-project/gitian.sigs.git sigs
|
||||
git clone https://git.wownero.com/wownero/gitian.sigs.git sigs
|
||||
cd sigs
|
||||
git remote add $GH_USER git@github.com:$GH_USER/gitian.sigs.git
|
||||
cd ..
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
name: "monero-android-0.18"
|
||||
name: "wownero-android-0.11"
|
||||
enable_cache: true
|
||||
suites:
|
||||
- "bionic"
|
||||
|
@ -26,8 +26,8 @@ packages:
|
|||
- "cmake"
|
||||
- "unzip"
|
||||
remotes:
|
||||
- "url": "https://github.com/monero-project/monero.git"
|
||||
"dir": "monero"
|
||||
- "url": "https://git.wownero.com/wownero/wownero.git"
|
||||
"dir": "wownero"
|
||||
files: []
|
||||
script: |
|
||||
|
||||
|
@ -70,7 +70,7 @@ script: |
|
|||
then
|
||||
ABI=$i"eabi"
|
||||
fi
|
||||
NDKDIR="${BUILD_DIR}/monero/contrib/depends/$i/native/bin"
|
||||
NDKDIR="${BUILD_DIR}/wownero/contrib/depends/$i/native/bin"
|
||||
for prog in ${FAKETIME_HOST_PROGS}; do
|
||||
WRAPPER=${WRAP_DIR}/${ABI}-${prog}
|
||||
echo '#!/usr/bin/env bash' > ${WRAPPER}
|
||||
|
@ -92,7 +92,7 @@ script: |
|
|||
export SOURCE_DATE_EPOCH=`date -d 2000-01-01T12:00:00 +%s`
|
||||
|
||||
git config --global core.abbrev 9
|
||||
cd monero
|
||||
cd wownero
|
||||
# Set the version string that gets added to the tar archive name
|
||||
version="`git describe`"
|
||||
if [[ $version == *"-"*"-"* ]]; then
|
||||
|
@ -120,9 +120,9 @@ script: |
|
|||
cmake .. -DCMAKE_TOOLCHAIN_FILE=${BASEPREFIX}/${i}/share/toolchain.cmake -DCMAKE_BUILD_TYPE=Release
|
||||
make ${MAKEOPTS}
|
||||
chmod 755 bin/*
|
||||
cp ../LICENSE ../README.md ../docs/ANONYMITY_NETWORKS.md bin
|
||||
chmod 644 bin/LICENSE bin/*.md
|
||||
DISTNAME=monero-${i}-${version}
|
||||
cp ../utils/conf/wow.conf bin
|
||||
chmod 644 bin/wow.conf
|
||||
DISTNAME=wownero-${i}-${version}
|
||||
mv bin ${DISTNAME}
|
||||
find ${DISTNAME}/ | sort | tar --no-recursion --owner=0 --group=0 -c -T - | bzip2 -9 > ${OUTDIR}/${DISTNAME}.tar.bz2
|
||||
cd ..
|
||||
|
|
|
@ -5,7 +5,7 @@ import os
|
|||
import subprocess
|
||||
import sys
|
||||
|
||||
gsigs = 'https://github.com/monero-project/gitian.sigs.git'
|
||||
gsigs = 'https://git.wownero.com/wownero/gitian.sigs.git'
|
||||
gbrepo = 'https://github.com/devrandom/gitian-builder.git'
|
||||
|
||||
platforms = {'l': ['Linux', 'linux', 'tar.bz2'],
|
||||
|
@ -31,10 +31,10 @@ def setup():
|
|||
subprocess.check_call(['git', 'checkout', 'c0f77ca018cb5332bfd595e0aff0468f77542c23'])
|
||||
os.makedirs('inputs', exist_ok=True)
|
||||
os.chdir('inputs')
|
||||
if os.path.isdir('monero'):
|
||||
# Remove the potentially stale monero dir. Otherwise you might face submodule mismatches.
|
||||
subprocess.check_call(['rm', 'monero', '-fR'])
|
||||
subprocess.check_call(['git', 'clone', args.url, 'monero'])
|
||||
if os.path.isdir('wownero'):
|
||||
# Remove the potentially stale wownero dir. Otherwise you might face submodule mismatches.
|
||||
subprocess.check_call(['rm', 'wownero', '-fR'])
|
||||
subprocess.check_call(['git', 'clone', args.url, 'wownero'])
|
||||
os.chdir('..')
|
||||
make_image_prog = ['bin/make-base-vm', '--suite', 'bionic', '--arch', 'amd64']
|
||||
if args.docker:
|
||||
|
@ -66,10 +66,10 @@ def rebuild():
|
|||
suffix = platforms[i][2]
|
||||
|
||||
print('\nCompiling ' + args.version + ' ' + os_name)
|
||||
infile = 'inputs/monero/contrib/gitian/gitian-' + tag_name + '.yml'
|
||||
subprocess.check_call(['bin/gbuild', '-j', args.jobs, '-m', args.memory, '--commit', 'monero='+args.commit, '--url', 'monero='+args.url, infile])
|
||||
infile = 'inputs/wownero/contrib/gitian/gitian-' + tag_name + '.yml'
|
||||
subprocess.check_call(['bin/gbuild', '-j', args.jobs, '-m', args.memory, '--commit', 'wownero='+args.commit, '--url', 'wownero='+args.url, infile])
|
||||
subprocess.check_call(['bin/gsign', '-p', args.sign_prog, '--signer', args.signer, '--release', args.version+'-'+tag_name, '--destination', '../sigs/', infile])
|
||||
subprocess.check_call('mv build/out/monero-*.' + suffix + ' ../out/'+args.version, shell=True)
|
||||
subprocess.check_call('mv build/out/wownero-*.' + 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')
|
||||
|
@ -93,7 +93,7 @@ def build():
|
|||
os.chdir('builder')
|
||||
os.makedirs('inputs', exist_ok=True)
|
||||
|
||||
subprocess.check_call(['make', '-C', 'inputs/monero/contrib/depends', 'download', 'SOURCES_PATH=' + os.getcwd() + '/cache/common'])
|
||||
subprocess.check_call(['make', '-C', 'inputs/wownero/contrib/depends', 'download', 'SOURCES_PATH=' + os.getcwd() + '/cache/common'])
|
||||
|
||||
rebuild()
|
||||
|
||||
|
@ -104,7 +104,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/monero/contrib/gitian/gitian-'+v[1]+'.yml'])
|
||||
subprocess.check_call(['bin/gverify', '-v', '-d', '../sigs/', '-r', args.version+'-'+v[1], 'inputs/wownero/contrib/gitian/gitian-'+v[1]+'.yml'])
|
||||
os.chdir(workdir)
|
||||
|
||||
def main():
|
||||
|
@ -113,7 +113,7 @@ def main():
|
|||
parser = argparse.ArgumentParser(description='Script for running full Gitian builds.', usage='%(prog)s [options] signer version')
|
||||
parser.add_argument('-c', '--commit', action='store_true', dest='commit', help='Indicate that the version argument is for a commit or branch')
|
||||
parser.add_argument('-p', '--pull', action='store_true', dest='pull', help='Indicate that the version argument is the number of a github repository pull request')
|
||||
parser.add_argument('-u', '--url', dest='url', default='https://github.com/monero-project/monero', help='Specify the URL of the repository. Default is %(default)s')
|
||||
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('-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')
|
||||
|
@ -178,8 +178,8 @@ def main():
|
|||
if args.setup:
|
||||
setup()
|
||||
|
||||
os.makedirs('builder/inputs/monero', exist_ok=True)
|
||||
os.chdir('builder/inputs/monero')
|
||||
os.makedirs('builder/inputs/wownero', exist_ok=True)
|
||||
os.chdir('builder/inputs/wownero')
|
||||
if args.pull:
|
||||
subprocess.check_call(['git', 'fetch', args.url, 'refs/pull/'+args.version+'/merge'])
|
||||
args.commit = subprocess.check_output(['git', 'show', '-s', '--format=%H', 'FETCH_HEAD'], universal_newlines=True).strip()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
name: "monero-freebsd-0.18"
|
||||
name: "wownero-freebsd-0.11"
|
||||
enable_cache: true
|
||||
suites:
|
||||
- "bionic"
|
||||
|
@ -26,8 +26,8 @@ packages:
|
|||
- "python"
|
||||
- "cmake"
|
||||
remotes:
|
||||
- "url": "https://github.com/monero-project/monero.git"
|
||||
"dir": "monero"
|
||||
- "url": "https://git.wownero.com/wownero/wownero.git"
|
||||
"dir": "wownero"
|
||||
files: []
|
||||
script: |
|
||||
|
||||
|
@ -87,7 +87,7 @@ script: |
|
|||
export SOURCE_DATE_EPOCH=`date -d 2000-01-01T12:00:00 +%s`
|
||||
|
||||
git config --global core.abbrev 9
|
||||
cd monero
|
||||
cd wownero
|
||||
# Set the version string that gets added to the tar archive name
|
||||
version="`git describe`"
|
||||
if [[ $version == *"-"*"-"* ]]; then
|
||||
|
@ -117,9 +117,9 @@ script: |
|
|||
cmake .. -DCMAKE_TOOLCHAIN_FILE=${BASEPREFIX}/${i}/share/toolchain.cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_SKIP_RPATH=ON
|
||||
make ${MAKEOPTS}
|
||||
chmod 755 bin/*
|
||||
cp ../LICENSE ../README.md ../docs/ANONYMITY_NETWORKS.md bin
|
||||
chmod 644 bin/LICENSE bin/*.md
|
||||
DISTNAME=monero-${i}-${version}
|
||||
cp ../utils/conf/wow.conf bin
|
||||
chmod 644 bin/wow.conf
|
||||
DISTNAME=wownero-${i}-${version}
|
||||
mv bin ${DISTNAME}
|
||||
find ${DISTNAME}/ | sort | tar --no-recursion --owner=0 --group=0 -c -T - | bzip2 -9 > ${OUTDIR}/${DISTNAME}.tar.bz2
|
||||
cd ..
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
name: "monero-linux-0.18"
|
||||
name: "wownero-linux-0.11"
|
||||
enable_cache: true
|
||||
suites:
|
||||
- "bionic"
|
||||
|
@ -21,6 +21,7 @@ packages:
|
|||
- "g++-7-arm-linux-gnueabihf"
|
||||
- "gcc-arm-linux-gnueabihf"
|
||||
- "g++-arm-linux-gnueabihf"
|
||||
- "g++-riscv64-linux-gnu"
|
||||
- "g++-7-multilib"
|
||||
- "gcc-7-multilib"
|
||||
- "binutils-arm-linux-gnueabihf"
|
||||
|
@ -37,13 +38,13 @@ packages:
|
|||
- "python"
|
||||
- "cmake"
|
||||
remotes:
|
||||
- "url": "https://github.com/monero-project/monero.git"
|
||||
"dir": "monero"
|
||||
- "url": "https://git.wownero.com/wownero/wownero.git"
|
||||
"dir": "wownero"
|
||||
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 i686-linux-gnu riscv64-linux-gnu"
|
||||
FAKETIME_HOST_PROGS=""
|
||||
FAKETIME_PROGS="date"
|
||||
HOST_CFLAGS="-O2 -g"
|
||||
|
@ -115,7 +116,7 @@ script: |
|
|||
export SOURCE_DATE_EPOCH=`date -d 2000-01-01T12:00:00 +%s`
|
||||
|
||||
git config --global core.abbrev 9
|
||||
cd monero
|
||||
cd wownero
|
||||
# Set the version string that gets added to the tar archive name
|
||||
version="`git describe`"
|
||||
if [[ $version == *"-"*"-"* ]]; then
|
||||
|
@ -159,12 +160,18 @@ script: |
|
|||
fi
|
||||
export C_INCLUDE_PATH="$EXTRA_INCLUDES"
|
||||
export CPLUS_INCLUDE_PATH="$EXTRA_INCLUDES"
|
||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=${BASEPREFIX}/${i}/share/toolchain.cmake -DBACKCOMPAT=ON -DCMAKE_SKIP_RPATH=ON
|
||||
# glibc only added riscv support in 2.27, disable backwards compatibility
|
||||
if [ "$i" == "riscv64-linux-gnu" ]; then
|
||||
BACKCOMPAT_OPTION=OFF
|
||||
else
|
||||
BACKCOMPAT_OPTION=ON
|
||||
fi
|
||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=${BASEPREFIX}/${i}/share/toolchain.cmake -DBACKCOMPAT=${BACKCOMPAT_OPTION} -DCMAKE_SKIP_RPATH=ON
|
||||
make ${MAKEOPTS}
|
||||
chmod 755 bin/*
|
||||
cp ../LICENSE ../README.md ../docs/ANONYMITY_NETWORKS.md bin
|
||||
chmod 644 bin/LICENSE bin/*.md
|
||||
DISTNAME=monero-${i}-${version}
|
||||
cp ../utils/conf/wow.conf bin
|
||||
chmod 644 bin/wow.conf
|
||||
DISTNAME=wownero-${i}-${version}
|
||||
mv bin ${DISTNAME}
|
||||
find ${DISTNAME}/ | sort | tar --no-recursion --owner=0 --group=0 -c -T - | bzip2 -9 > ${OUTDIR}/${DISTNAME}.tar.bz2
|
||||
cd ..
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
name: "monero-osx-0.18"
|
||||
name: "wownero-osx-0.11"
|
||||
enable_cache: true
|
||||
suites:
|
||||
- "bionic"
|
||||
|
@ -24,8 +24,8 @@ packages:
|
|||
- "python-dev"
|
||||
- "python-setuptools"
|
||||
remotes:
|
||||
- "url": "https://github.com/monero-project/monero.git"
|
||||
"dir": "monero"
|
||||
- "url": "https://git.wownero.com/wownero/wownero.git"
|
||||
"dir": "wownero"
|
||||
files: []
|
||||
script: |
|
||||
WRAP_DIR=$HOME/wrapped
|
||||
|
@ -77,7 +77,7 @@ script: |
|
|||
export PATH=${WRAP_DIR}:${PATH}
|
||||
|
||||
git config --global core.abbrev 9
|
||||
cd monero
|
||||
cd wownero
|
||||
# Set the version string that gets added to the tar archive name
|
||||
version="`git describe`"
|
||||
if [[ $version == *"-"*"-"* ]]; then
|
||||
|
@ -108,9 +108,9 @@ script: |
|
|||
cmake .. -DCMAKE_TOOLCHAIN_FILE=${BASEPREFIX}/${i}/share/toolchain.cmake
|
||||
make ${MAKEOPTS}
|
||||
chmod 755 bin/*
|
||||
cp ../LICENSE ../README.md ../docs/ANONYMITY_NETWORKS.md bin
|
||||
chmod 644 bin/LICENSE bin/*.md
|
||||
DISTNAME=monero-${i}-${version}
|
||||
cp ../utils/conf/wow.conf bin
|
||||
chmod 644 bin/wow.conf
|
||||
DISTNAME=wownero-${i}-${version}
|
||||
mv bin ${DISTNAME}
|
||||
find ${DISTNAME}/ | sort | tar --no-recursion --owner=0 --group=0 -c -T - | bzip2 -9 > ${OUTDIR}/${DISTNAME}.tar.bz2
|
||||
cd ..
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
name: "monero-win-0.18"
|
||||
name: "wownero-win-0.11"
|
||||
enable_cache: true
|
||||
suites:
|
||||
- "bionic"
|
||||
|
@ -35,8 +35,8 @@ alternatives:
|
|||
package: "x86_64-w64-mingw32-gcc"
|
||||
path: "/usr/bin/x86_64-w64-mingw32-gcc-posix"
|
||||
remotes:
|
||||
- "url": "https://github.com/monero-project/monero.git"
|
||||
"dir": "monero"
|
||||
- "url": "https://git.wownero.com/wownero/wownero.git"
|
||||
"dir": "wownero"
|
||||
files: []
|
||||
script: |
|
||||
WRAP_DIR=$HOME/wrapped
|
||||
|
@ -91,7 +91,7 @@ script: |
|
|||
export SOURCE_DATE_EPOCH=`date -d 2000-01-01T12:00:00 +%s`
|
||||
|
||||
git config --global core.abbrev 9
|
||||
cd monero
|
||||
cd wownero
|
||||
# Set the version string that gets added to the tar archive name
|
||||
version="`git describe`"
|
||||
if [[ $version == *"-"*"-"* ]]; then
|
||||
|
@ -127,8 +127,8 @@ script: |
|
|||
mkdir build && cd build
|
||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=${BASEPREFIX}/${i}/share/toolchain.cmake
|
||||
make ${MAKEOPTS}
|
||||
cp ../LICENSE ../README.md ../docs/ANONYMITY_NETWORKS.md bin
|
||||
DISTNAME=monero-${i}-${version}
|
||||
cp ../utils/conf/wow.conf bin
|
||||
DISTNAME=wownero-${i}-${version}
|
||||
mv bin ${DISTNAME}
|
||||
find ${DISTNAME}/ | sort | zip -X@ ${OUTDIR}/${DISTNAME}.zip
|
||||
cd .. && rm -rf build
|
||||
|
|
|
@ -71,13 +71,13 @@ type, and max connections:
|
|||
|
||||
```
|
||||
--anonymous-inbound rveahdfho7wo4b2m.onion:28083,127.0.0.1:28083,25
|
||||
--anonymous-inbound cmeua5767mz2q5jsaelk2rxhf67agrwuetaso5dzbenyzwlbkg2q.b32.i2p:5000,127.0.0.1:30000
|
||||
--anonymous-inbound cmeua5767mz2q5jsaelk2rxhf67agrwuetaso5dzbenyzwlbkg2q.b32.i2p,127.0.0.1:30000
|
||||
```
|
||||
|
||||
which tells `monerod` that a max of 25 inbound Tor connections are being
|
||||
received at address "rveahdfho7wo4b2m.onion:28083" and forwarded to `monerod`
|
||||
localhost port 28083, and a default max I2P connections are being received at
|
||||
address "cmeua5767mz2q5jsaelk2rxhf67agrwuetaso5dzbenyzwlbkg2q.b32.i2p:5000" and
|
||||
address "cmeua5767mz2q5jsaelk2rxhf67agrwuetaso5dzbenyzwlbkg2q.b32.i2p" and
|
||||
forwarded to `monerod` localhost port 30000.
|
||||
These addresses will be shared with outgoing peers, over the same network type,
|
||||
otherwise the peer will not be notified of the peer address by the proxy.
|
||||
|
|
|
@ -69,4 +69,4 @@ endif()
|
|||
add_subdirectory(db_drivers)
|
||||
add_subdirectory(easylogging++)
|
||||
add_subdirectory(qrcodegen)
|
||||
add_subdirectory(randomx EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(randomwow EXCLUDE_FROM_ALL)
|
||||
|
|
|
@ -149,6 +149,11 @@ static el::Color colorFromLevel(el::Level level)
|
|||
|
||||
static void setConsoleColor(el::Color color, bool bright)
|
||||
{
|
||||
static const char *no_color_var = getenv("NO_COLOR");
|
||||
static const bool no_color = no_color_var && *no_color_var; // apparently, NO_COLOR=0 means no color too (as per no-color.org)
|
||||
if (no_color)
|
||||
return;
|
||||
|
||||
#if ELPP_OS_WINDOWS
|
||||
HANDLE h_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
switch (color)
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 27b099b6dd6fef6e17f58c6dfe00009e9c5df587
|
|
@ -1 +0,0 @@
|
|||
Subproject commit 261d58c77fc5547c0aa7fdfeb58421ba7e0e6e1c
|
|
@ -106,15 +106,15 @@ endif()
|
|||
add_subdirectory(cryptonote_protocol)
|
||||
if(NOT IOS)
|
||||
add_subdirectory(simplewallet)
|
||||
add_subdirectory(gen_multisig)
|
||||
add_subdirectory(gen_ssl_cert)
|
||||
add_subdirectory(daemonizer)
|
||||
add_subdirectory(daemon)
|
||||
add_subdirectory(blockchain_utilities)
|
||||
endif()
|
||||
|
||||
if(BUILD_DEBUG_UTILITIES)
|
||||
add_subdirectory(debug_utilities)
|
||||
add_subdirectory(blockchain_utilities)
|
||||
add_subdirectory(gen_multisig)
|
||||
add_subdirectory(gen_ssl_cert)
|
||||
endif()
|
||||
|
||||
if(PER_BLOCK_CHECKPOINT)
|
||||
|
|
|
@ -241,8 +241,15 @@ void BlockchainDB::add_transaction(const crypto::hash& blk_hash, const std::pair
|
|||
}
|
||||
else
|
||||
{
|
||||
rct::key commitment;
|
||||
if (tx.version > 1)
|
||||
{
|
||||
commitment = tx.rct_signatures.outPk[i].mask;
|
||||
if (rct::is_rct_bulletproof_plus(tx.rct_signatures.type))
|
||||
commitment = rct::scalarmult8(commitment);
|
||||
}
|
||||
amount_output_indices[i] = add_output(tx_hash, tx.vout[i], i, tx.unlock_time,
|
||||
tx.version > 1 ? &tx.rct_signatures.outPk[i].mask : NULL);
|
||||
tx.version > 1 ? &commitment : NULL);
|
||||
}
|
||||
}
|
||||
add_tx_amount_output_indices(tx_id, amount_output_indices);
|
||||
|
@ -446,582 +453,7 @@ void BlockchainDB::fixup()
|
|||
LOG_PRINT_L1("Database is opened read only - skipping fixup check");
|
||||
return;
|
||||
}
|
||||
|
||||
// There was a bug that would cause key images for transactions without
|
||||
// any outputs to not be added to the spent key image set. There are two
|
||||
// instances of such transactions, in blocks 202612 and 685498.
|
||||
// The key images below are those from the inputs in those transactions.
|
||||
// On testnet, there are no such transactions
|
||||
// See commit 533acc30eda7792c802ea8b6417917fa99b8bc2b for the fix
|
||||
static const char * const mainnet_genesis_hex = "418015bb9ae982a1975da7d79277c2705727a56894ba0fb246adaabb1f4632e3";
|
||||
crypto::hash mainnet_genesis_hash;
|
||||
epee::string_tools::hex_to_pod(mainnet_genesis_hex, mainnet_genesis_hash );
|
||||
set_batch_transactions(true);
|
||||
batch_start();
|
||||
|
||||
if (get_block_hash_from_height(0) == mainnet_genesis_hash)
|
||||
{
|
||||
// block 202612 (511 key images in 511 transactions)
|
||||
static const char * const key_images_202612[] =
|
||||
{
|
||||
"51fc647fb27439fbb3672197d2068e4110391edf80d822f58607bd5757cba7f3",
|
||||
"d8cf1c1bd41f13c4553186e130e6e2c1cd80135ddb418f350088926997a95ca9",
|
||||
"95d2556c8acd1457dce7bfd9c83b1d82b821a55a9c9588b04b7b5cf562a65949",
|
||||
"4b5d987fee1bb563a162d23e41741ad73560c003e26a09b6655f09496538daac",
|
||||
"1d25ea86323d1578579d3894a54b99ea1c3e2dca547c6726c44aef67db958b02",
|
||||
"92e46fb70be5d9df39ca83c4fc6ae26c594118314bb75502a9c9752a781d0b33",
|
||||
"924d0cb9060d429be7e59d164a0f80a4dabc3607d44401b26fb93e7182ab435d",
|
||||
"f63e4a23fec860fd4c3734623891330ac1ff5af251e83a0e6247287818b8a72f",
|
||||
"5b14c5ef13738d015619b61dacefc2ade3660d25b35ef96330a8f4e2afc26526",
|
||||
"d5016b012a2fb6ca23fd56ece544d847962264b4aee15efe1465805fd824a8fb",
|
||||
"0a7f3da1d9dd341cd96829e484b07163099763ac7bd60603b7ee14f7dbcb278d",
|
||||
"d716c03d7447d2b693f6f61b6ad36bd57344033fc1a11feaf60d569f40014530",
|
||||
"23154a812e99ce226f6a87087e0812f419aed51289f1c0c359b0b61303b53a36",
|
||||
"03940341e1a99d5b0c68eacfdf5a20df90d7d0a3d6089d39709cdd964490755c",
|
||||
"ef09648814cfe071f5d8e9cfde57247ad09409265c4b6c84697bbb046809bd7e",
|
||||
"8843ec52b0496ca4e895813cfe00bb18ea777d3618e9bd2e200287e888e2f5c7",
|
||||
"8558bf39baf3df62b5d33cdf97163a365e6c44f4d6deef920730b4982b66449f",
|
||||
"504d9380ce581de0af97d5800d5ca9e61d78df368907151ab1e567eb6445332a",
|
||||
"673797763593c23b3ee07b43bd8760365e2c251a8a60a275528ff34a477110cc",
|
||||
"25178c95e4d402c58d79c160d2c52dd3c45db2c78e6aaa8d24d35c64f19d4957",
|
||||
"407c3a05dcc8bdcb0446b5d562cf05b4536fc7337344765215130d5f1e7ee906",
|
||||
"4e7fa771a5455d8ee8295f01181a360cdc6467cc185c2834c7daf9fbf85b6f1d",
|
||||
"6beb64cb024f9c5c988f942177fc9c1ec5ecfa85b7db0f13a17f9f98e8e46fe7",
|
||||
"6406bfc4e486e64c889ea15577d66e5835c65c6a39ec081af8ac5acdc153b4b5",
|
||||
"1b1da638709f9f85898af70ffaa5b88d5a4c9f2663ca92113c400ab25caf553c",
|
||||
"da49407a9e1ed27abd28076a647177157c42517e2542e9b6a4921fdadf4e8742",
|
||||
"3c3fdba2a792fddaeb033605163991a09933e8f05c6c934d718e50a613b64d69",
|
||||
"82c60429171173739fa67c4807cab359620299e6ed2a9da80139b5b1e23c5456",
|
||||
"0a19e5767e1381ac16f57cfa5aabd8463551d19f069f7f3465c11a8583253f3e",
|
||||
"d0fae6ffdd4818399eae6224978f170f696150eaf699f2f218abc00c68530f96",
|
||||
"0937889aeb3af5c64608d9a9f88229a068e53417448f00f9aa5e28c570cca8f8",
|
||||
"d6072d269753020912524961ce8c6930cf35abe5c4b2bdc7fd678338d20a68fb",
|
||||
"0e8bc9b06fcc842bdaa7df029bfd1f252d5defc014d58a006c10ab678ecf543f",
|
||||
"9d42f90520f02c9258be53b123d69ddbce5f33f92a903d3fb4cf3358ff0e07b5",
|
||||
"1cc05416b12cbe719617158773c3e6173435fc64e1ee44310dc696baecaeaa95",
|
||||
"266b15222913c11ef6403ee15dc42c8c0e16bc5fa2f49110447802236e045797",
|
||||
"791b123af3b71ac9497a010610f72207ff8ec642969b5cf0d2891b21e7eee562",
|
||||
"946d4d7b084dc32495f22b35fc30394144c8e0ba04f3ad6e2c2bfb0173a2266d",
|
||||
"2c015cb990c1583228d08b2d5de9227b950c3f57364fc1033bca5c0fbfd08c58",
|
||||
"13fdc41862fd85507f579c69accb9cc6a40f5971bfa41e3caff598a3dcffd2fc",
|
||||
"64b06d9874a83917c583c9439d1c736083377d67fda2961b623f7124663134c3",
|
||||
"2fa49cd19e0aa02989991a4c3760f44be800fe8fb4d58b23aca382e10dc0d2d6",
|
||||
"377628f265f799772e9fb6065be8b6eee200c329f729fe36c25ee179e4d20df9",
|
||||
"ba94fa79134ce383b6a98b04dc6ad3d1b950e410d50a292bc770f9685e59fe91",
|
||||
"875c924329f0733e31fe8d8aed70dc1906335b8a9984932b6368ea24edb39765",
|
||||
"f31f4abb3f5ee42a5aae86d70b3bd9a9c1934933641893864dd333f89719d608",
|
||||
"2bcd629e125514a780f568d3c2e8b12a2e7fbbee06e652bbeed3e7825508e31c",
|
||||
"918b43581163ca1963de21bb9ac401756e75c3f00ac8dcfafc139f1ad5d7d998",
|
||||
"5730dd57fa52749a0d6502b11c9d802ac495875542431310c674a65655b7c2a3",
|
||||
"03f84b990683e569e2f6143bb963a2a8de411e7c4b7923117b94c7afcb4b43ea",
|
||||
"b298c8510d35bd2be0ff0753ad7d98d480f4c6490bb67fb93cd4632ea726e8a7",
|
||||
"0a771afbf9be104c01b89eaeb57073297d35ac8fbbcc0816820fdb9a29d26625",
|
||||
"713d90d6ca1be1a4e05a5f8441dc528c699caa09eda49c09072f5f8291354c2e",
|
||||
"988827f45c19330d9404309f63d536a447803cca7cb182ef005b074def09ab7d",
|
||||
"9dcaa105b4def895f3faee704c250bdc924316f153cb972f3fb565beec0b7942",
|
||||
"1c06c30afe65b59e9e22d6bb454e4209a03efe53cdbf27b3945d5d75b1b90427",
|
||||
"49e08c13d1da209ec1aea7b7fbe0daa648e30febeb2aa5ffbaaabdd71a278ac2",
|
||||
"e1c2e49ab7b829854c46a64772ded35459908e0f563edbcf5c612913b7767046",
|
||||
"e08bb7d133490ca85a6325d46807170cd07618b6a5f6e1d069e44890cc366fab",
|
||||
"5c73ca0691cde2f35b7933d6db33f0b642ec70d0bd3f2b0ebbd97754ca67e248",
|
||||
"6404399151872a521dae767311712225dba65d810ba2feba209204221b5d772d",
|
||||
"4a0c3aa6cef36f44edf08ad8fb1533d7e1186e317da8a3afb3d81af072043233",
|
||||
"104b3e1af37cf10b663a7ec8452ea882082018c4d5be4cd49e7f532e2fea64e5",
|
||||
"e723a46bf9684b4476c3005eb5c26511c58b7eb3c708ddf7470ee30a40834b32",
|
||||
"18e6f0fa3aa779a73ceefabea27bff3202003fd2c558ec5f5d07920528947d57",
|
||||
"c97e73eb593ff39e63307220796cc64974c0c8adac860a2559ab47c49bc0c860",
|
||||
"13c363a962955b00db6d5a68b8307cd900ae9202d9b2deb357b8d433545244ac",
|
||||
"76a488865151fab977d3639bac6cba4ba9b52aa17d28ac3580775ed0bff393e4",
|
||||
"a14de587c9f4cd50bb470ecffd10026de97b9b5e327168a0a8906891d39d4319",
|
||||
"b1d38ee1c4ca8ae2754a719706e6f71865e8c512310061b8d26438fedf78707e",
|
||||
"772bb8a3f74be96fa84be5fa8f9a8ef355e2df54869c2e8ae6ad2bf54ed5057e",
|
||||
"3083a7011da36be63e3f7cacd70ab52e364dd58783302f1cb07535a66b5735f5",
|
||||
"2b1d892e3002aa3201deb4ffe28c0c43b75b8f30c96b5d43f6d5829049ecbd94",
|
||||
"cb738aabe44c6fb17ade284bf27db0169e309bf8cf9c91c4e4e62856619a4c64",
|
||||
"1707e04b792f4953f460f217b9bb94c84cef60736a749fb01277cfe0eaaa48c7",
|
||||
"ab8b6bac9b8a4f00b78acb4bd50ed2758e0fa100964b6f298d2a943eb2af2b30",
|
||||
"dd317193fef72490f3be01293b29e9c2f94eda10824a76ca74bf39dd7cb40ab2",
|
||||
"4fb3d995b087af7517fcb79e71f43bac0c4fbda64d89417a40ca4a708f2e8bc1",
|
||||
"549ba38c31bf926b2cb7e8f7f15d15df6388dce477a3aff0245caa44606849fc",
|
||||
"7585c14ab9abbffb89d0fa9f00c78ecae9f7c9062e5d4f1fae8453b3951fc60b",
|
||||
"953f855323f72461b7167e3df0f4fd746a06f5a7f98aa42acdce2eef822a0b2f",
|
||||
"0931932d57dde94dcfb017179a5a0954b7d671422149738260a365ca44f50eb8",
|
||||
"a3d179d16a4a275a3bb0f260cee9284db243abad637a9dbe92d02940f1c7ee8c",
|
||||
"959843f1e76ff0785dafe312c2ea66380fdc32b9d6180920f05f874c74599a80",
|
||||
"fbc36b3e1718fe6c338968b04caa01a7adb315d206abc63e56768d69e008a65d",
|
||||
"f054de7eac5e2ea48072e7fb4db93594c5f5d2dfa0afe8266042b6adc80dfdca",
|
||||
"39dfc68dc6ba8c457b2995562c867cef2f2cf994e8d6776a6b20869e25053f70",
|
||||
"19ad7ca7629758c22ac83643605c8a32a6665bae8e35dbc9b4ad90343756ebb3",
|
||||
"e89e80ea5c64cf7840f614f26e35a12c9c3091fa873e63b298835d9eda31a9ea",
|
||||
"572c1b9a83c947f62331b83009cc2ec9e62eab7260b49929388e6500c45cd917",
|
||||
"df0b21f679e6c0bf97f7b874e9f07c93c3467b092f3d9e1484e5646fda6eca5f",
|
||||
"8f3b7c0f4b403af62fe83d3cfac3f1e2572af8afa4cea3f3e2e04291efe84cf6",
|
||||
"aae8b8db243009d021d8c9897d52ee8125a17212f0a8b85f681ad8950ae45f0e",
|
||||
"3d45a4957d27447dea83d9ae2ef392a3a86619bfcf8dda2db405a7b304997797",
|
||||
"a5b0a619a8e3030b691bdba1ed951cd54e4bc2063602eae26d9791fb18e60301",
|
||||
"14650df217dd64a2905cd058114e761502dff37d40e80789200bc53af29b265f",
|
||||
"fd6a245ab5e4e6e18d7ba9b37478ce38248f0ab864e5511d2208ae3d25017e5f",
|
||||
"fbe0be6dd42a11feb5db5ae56fcbbac41041ab04a35f1df075580e960c8eeab0",
|
||||
"72f3f1213d9bec92ba9705b447d99cd0a6a446e37a3c1c50bb8ece1090bfe56e",
|
||||
"20df836554e1534f62b2a6df9ce58e11c1b9b4746ce8ee3c462300a8c01f5e76",
|
||||
"5c3d2a81b7331c86420ad32b6e9a212b73b1c3413724a0f91bf073eba18e2f1f",
|
||||
"63264ddfb29cd36fc18f3ee6614c4101ba7229bc5ac375f912590d3f0df982f4",
|
||||
"5ec4eb637761c1c9dbc6aa6649d4410508ef8d25d61ad6caa40c6ee3236d5515",
|
||||
"270c70940536017915e1cdbc003de7279ec1c94cba1ef6130f4236f7e306e4f0",
|
||||
"c1d1d57a7c03f6ddeeab5230a4910db8355e2143f473dea6e1d57c2f8d882b76",
|
||||
"218c030a7fdc9917e9f87e2921e258d34d7740a68b5bee48a392b8a2acf1f347",
|
||||
"ac47861c01c89ea64abee14cf6e1f317859ed56b69ae66377dc63e6575b7b1eb",
|
||||
"23bf549c8a03f9870983c8098e974308ec362354b0dcf636c242a88f24fc2718",
|
||||
"a3ce8b817e5212c851c6b95e693849a396c79b0d04b2a554de9b78933fbea2b7",
|
||||
"7310120c1cc1961b0d3fce13743c8a7075ae426fe6cccaf83600f24cee106236",
|
||||
"8fa0630f193777dcc4f5eccd1ad9ceacf80acdf65e52e4e01bf3a2b2fdd0dac6",
|
||||
"4a5f5c87f67d573d0673f01abaebc26eaa62e6d04627588549cc9e6c142dc994",
|
||||
"78971cccacc645116f9d380c167f955d54b386a22af112233f7de004fc0c8316",
|
||||
"badc67216868e1de1bbe044bf0e6070e6ee0353d05c13fa0c43b1897db5219a2",
|
||||
"c45b2a168bc51cbb615a79f97432cc4bb6b104da9cdc1fc640c930657452f71b",
|
||||
"c17eda13541d14554c5db542155b08b6bf9cb403d425745b662ebc2b2b9b3a3b",
|
||||
"313210cd9d2efc1603f07859bae7bd5fb5914f4a631b943f2f6ff5927a4e681a",
|
||||
"6ee94ec8af4e6828f9b46c590ea55da640ef50e810a247d3e8cdf4b91c42d2c2",
|
||||
"505b7a4d9f1ba6577aa2a941843f86c205b23b1ea21035925e587022e2f0aeed",
|
||||
"98e6a7cd687e8192e300a8202999ec31ad57bc34f656f2ae90d148607ff6d29f",
|
||||
"1be5db002c0a446cc2c1da363e5d08ae045cd8f5e76c8cccd65d5166393c0bdf",
|
||||
"17c02ac6d390c5c735e1e873c40294220e89071fca08a5da396a131fa1ba8670",
|
||||
"2540507c39ae6fdcd90de826077f0ca390da126166a25c15c048a60606a27367",
|
||||
"5ab9328e525c7a017ef4f591d995ad4595d74cbf8ff4112af33b08c70661a304",
|
||||
"9c105587a96c51d81422f64e46016564d22329760648c95dcac7218f3733f915",
|
||||
"525afb1b94a75f1edc2b55c700071e14a2166acda003370047c30dba8ea80278",
|
||||
"745d4a5d9f95ca4efa6261b6bcd4ecacd504b5b901a2ce1353c522a5c0c15dcc",
|
||||
"5a5a568cd87ba34252ba254e6a320e1a7f52f13e7451bb887efb34ff881785f2",
|
||||
"1ec50a80198cd830b51f4f7a0222015a268d9b40f04e7f838c7b8dc7abf63b01",
|
||||
"68836b662d79349cb42f5cef54e6a066157d398cc87d3b13f29fc04e5cf364a5",
|
||||
"658db317f355a9cbd86f673775cac0c308fe14967428fd283a36e300a6a53b2f",
|
||||
"677d79a8c467dd9db38f0ef45c2787dd368f701a6b47bf7a5f06112c38da643e",
|
||||
"2baa455d4066f5d628f9ecd315cb57deca71069db5d0d112ae0aa18a84b6f0d7",
|
||||
"5e7b0889f351560081360ac2b1429b48b2f7d886227f144e3b198e2f1fa56ed9",
|
||||
"c3d317fbf26e15add8b4f8f93df9de9b22297b8e4945ebab9ee249d4f72f4e45",
|
||||
"3c0b705a5c1e31abc7e46d8ff3c148a033f6875454cfb67f8d2a2b9a57a5ba7e",
|
||||
"a0ab74663561af2adc2d38be3569fbe7aa2454346416ac96e5eb26b1e01b1e2f",
|
||||
"53526cffdb74327670566c1dacacffb7d30a43a7f1862ff8bab87737bfa5edb6",
|
||||
"24c5d36ab98d88f87b2c71afb4ea8562e05c7aa0b50f3bc0f9ed50a4cd52989b",
|
||||
"c3ce4de5f94dff65d11e33a865855a4404259cf45263914c884f79db4f35169d",
|
||||
"f1009b6dcf30030cff872d636fb96ed233eb6ecb8ffed003c7da64e4f5a02f4c",
|
||||
"e3729f58614d3b42450d1599d863983ab7e3e5c29fb57aad7958c8923a2627c4",
|
||||
"31cf4792f7b5ce01b217ec80184edd2a7c49c0b21701f5494ee2c9bac67c28ca",
|
||||
"b42a5c9c92a656c5bb2b759ce160fdfd245243aeb1786338faea63b62e9a60ce",
|
||||
"a1efc8d5d0855933d5ac8fe5960c7acacb92fcb09bfbc929e5002f168251e648",
|
||||
"c4322c7f3682ec94b0dcb42f13b498c36cf575d505aacc8ec8bf67a6a2abf4c9",
|
||||
"684ee5aa3c98357aeaddcc30c6620939b52aeef729e24b4a46ccafc44f24d831",
|
||||
"36180f2ae11d105e0efbfbddb94e6b45b08609a383e4e1a8fa3b06d7a8051de9",
|
||||
"96c2d183eacc87581a0b17b8d07878bc10d436728510715109a7565d9972f8b5",
|
||||
"3068c9d04d561c7e29e3f621280b61a61885de0e9ec35a66a3116ca7a9e09627",
|
||||
"2eb94b9673ad6f8f88288fddfceae4baaeccb37bed88a35611d826ba06a5363b",
|
||||
"fc8cd5fae8b81121001f7767dcd5f185c0fdcc88cce1fbb184ddbcfad697ba54",
|
||||
"51521da1ecedea6d588d774eb155d936b32a14913c2f11d989bcc5116e65bf41",
|
||||
"3d23542e597a83dd6307700d79058b920f281c65f832333734d8a0adec510495",
|
||||
"11d2e01913ff0d4bd21970d709d88e63289492c0bbad7bff99c0d36858a841ca",
|
||||
"de674f1eee3068d2bc8c2f2897d8556e5deb872869652f7d3a4e5dbc6f1063c8",
|
||||
"e722d7f728526110c0921791b417afde4af1e87ae48ccc01911786197843104b",
|
||||
"aaba3a4e2a7d20ab76edfbcccefc27acfd509db3638582c28230e73ffd71d340",
|
||||
"1385a7209dafb9622dd4274179832e40c7fae19445383c34ef79adb0e4de0c98",
|
||||
"108408531fca288d74de4a2c596eab8569e355d9ab2f8380f4d24073a6b3fa95",
|
||||
"294476a86fcd39351ae452cdb8af9584067ec4501ec6182d0062bb154559fed3",
|
||||
"e64b175e0284c5cb69c8db46344ed43b5ced8abfe3cbf0c197103cfd116944cd",
|
||||
"cdd73a0f1fa7c14ed2177ae2163035333718847e49dd5cca6775bd20fc7553ad",
|
||||
"d423d2a374bc66a4587a5e3affa327ca75b8116051320759a3b88a868a7b80d4",
|
||||
"f13ad1e5b1315557d5497b58516eb3b0759d909725ddd0eb8a0dee439c6c0a48",
|
||||
"3a600b547a6061186a54e491344fd50cc7d4f0566a386a40aba6545254773728",
|
||||
"37a6f3f221fe17cc04a65aa544d5135e8297ecaf0853ba784dffacb74feb481b",
|
||||
"0ca42d67d0f84b28861d63e919e6ce5ad527447fdc53a03d8497a0241bee9376",
|
||||
"c7dbda42459e6fadb92c416eaef3e04674fc57915a93f3be4e656634c9654075",
|
||||
"0e34d728ae4fe347a5afecdf886fbd4d48a65c5d0dfab807da6ae95b6b2d7a3a",
|
||||
"f1bc69257ed510db5b2ed370010b037f452a29c49e36337264b3011ce2516216",
|
||||
"33f98f6b8a8e202463955998fba3b790199daa893e5471554826cfd9daa5c02f",
|
||||
"f8a0a37a2c9ebd7022d7cded1ee0318fd363020070b4cdaea800e44dcc1300d2",
|
||||
"6862714daedb908a4d86a3a3f1e65ec2c29ae61501b4ddcaf184243dd095d71b",
|
||||
"555cd19a6d21941c1174129b8bbcc70edcf0d6874262ce9e1e542351990d523d",
|
||||
"2cd6b44326828f23a2aa33699754bfa072c4883f39d53616f6a6b74149b664b6",
|
||||
"127f45d2eacb565c21c1030fe8054fd0a3a75705bc368924712aa145d414fa47",
|
||||
"19225e2dae6e1166f21cdab1290194470ded09df9b66f3faad3c1cc9ebcf340f",
|
||||
"b7b3f53f0539b2b4837b8bb9dae0ccbd200c8d36126d9f50199d68a4293a46d3",
|
||||
"6b6323be01f27d6d759d9670825e8ebb9c4cd8016351702328df91cef36cfec8",
|
||||
"020c31cfdfc5b22b10235745b89b311d271cf82f2ba16d03fdf7a8bc8538694b",
|
||||
"62573218530182b79e40d0113b7d281dace6da33bfcd0f9318558de5e5c76f08",
|
||||
"37d928416b15982f5bb8be40c5b62fae0b664e412c25891f8860c4242927e610",
|
||||
"b07ad11134a5c0542d2b418ef3863e8ea8477de68d9310681818ddd40825fdb0",
|
||||
"4af77cb76bab845b56470c95ce7b8cd84ce49a095984c1f3eed67b0ee344316e",
|
||||
"e3fdd4668d8726ba6adc401ac662c0cf6b5c1872082c488ed7da966d425fb1c0",
|
||||
"3dec71c81c7e78e879abc8da8b30e2446edbe98eeb8df9dafe9201ebb4c6a834",
|
||||
"7105467d9c5e855f1362fbddf820ed5e757997862efc9000317d3830a2f60ef3",
|
||||
"2821df94b021d3e77e8d9c0f3972340210f5ea2c0935cbf125cfc578d4d6722f",
|
||||
"114e5807accc337a22598bded30ebf3e0cfd75877e239f10cb043f829c315ab5",
|
||||
"d658a1c0354628cd7312593ab25d5b9083de8f0def6e8425f188101d256cd136",
|
||||
"4818d3be9b2a38fcc8c85d6c46f69b502943f79cf2462dfb0b6499e761bcc836",
|
||||
"92b8c943cb017b5f2d39264640c069f1ecced1d3ce9b3fd755d6df2fddb99458",
|
||||
"6edbd0fdf064fcbccd4a9e7a8ea520b87cb7faf867f7fe8a5f53625beb575119",
|
||||
"bf3b49c477dafb06af65bf09851c0fbef9dbc3152a7268d31b55a8e7a9a95860",
|
||||
"0e234dbadfda1393be2f068182615dbb83736f84f87710b5c7965bdce9f4a26a",
|
||||
"df5ceae34429e47b92bbd5505ba27666552e0eb619997f359c55699c3252b1ff",
|
||||
"08c1c7d940d699a91a83249bd578772e8958ffe23179e6150f07b96f1b47ce1e",
|
||||
"6f919a429270da0022d70062537bdc1b21c43a8abc552d8e366647e5b719d310",
|
||||
"63c66e5fd5d27f6fda87912ce46fa91a5e5b3634ed147fa2986330fc2696d3fa",
|
||||
"bde070b75296bca3aa494e7f549cd2bd1ff003776712bc98a3164b139b2054ab",
|
||||
"66694196dac5b60cf5e0ae05db8f3894fe04d65910686806551f471a0a0472e9",
|
||||
"0d2e97524b7ce4cf30b54e61b2689df036d099c53d42e2977b1671834bac39e7",
|
||||
"e081af76e923455f408127862be5c9baf7de6b19b952aa2a1da997d4dfe594c0",
|
||||
"121bf6ae1596983b703d62fecf60ea7dd3c3909acf1e0911652e7dadb420ed12",
|
||||
"a25e7b17464df71cd84ad08b17c5268520923bc33fe78c21b756f17353ea39a0",
|
||||
"e985f078fb44dbfdf3f4f34388f0f233a4e413e02297ee9a7dcc3fcceacd44f9",
|
||||
"b9184cf45e6e6b112cd863b1719de1bcab2137eb957e8028edca3a204a9ebb96",
|
||||
"157d177d5e4bcce0040eb4bddb681eacf9e2942e1c542a57ce851b4742a9cc4f",
|
||||
"0823e06635c9a1a69fd8833d1e48df98d711c1c47c06f27bb384932db1bbe9ee",
|
||||
"8beeec1fd1bcdecba235b449cc49abca69b6486ed1c0861a2bfb6a43c970b86f",
|
||||
"349f61a1cfc9112e537522858a0edae732a2f8434cf4780d3d2ec1e96f581cca",
|
||||
"587cdf72b5914d364f7e214a70481cf1131ee4a09e6b43e52428d2e56b000c13",
|
||||
"a6aa0c179316534c7b9ffb5f42a2af98d1d3a166bfb413199579f259c7b5e6df",
|
||||
"f9f3bb1ba8da5899b79186008ecfbd416b49f3b86d94045b91e34a40e41d5cff",
|
||||
"0cdda65a60b7b4d94e794c9397e01f69fb29309ce4fac83e7392dbba6bc497f9",
|
||||
"8fa5fce5ad09d43af7218ea5724cff2c4849a59ff73caf3bbca466e3c8538ba8",
|
||||
"8874ef46008753fcc0b77eb7a4a8560e35966bf5a12bcad4203ad2b4c1f8bfbe",
|
||||
"a8ee9a3aa2d0c08a951439ffb0e6d10315fc4776997b275de1ec19663e88c2c2",
|
||||
"9c184cbbff464ab4d5f6bfa78c39bf0880fb93b1574139306a97acb940d415c9",
|
||||
"5493a38c255c91ca49b958ed417f6c57e5bc444779d8f536f290596a31bc63d3",
|
||||
"3e1e82b96cc599d9fc55ae74330692ccbfb538a4cc923975fd8876efe4b81552",
|
||||
"16aaaf820c24c2726e349b0e49bbab72ca6eef7b3a2835de88d0cececa4da684",
|
||||
"7fa52ba349f7203c3dbc2249f9881101a3318d21869dd59f17abf953d234db65",
|
||||
"713d8018bb9ba3ab55c3a110120b9d7593514111075ef05f0fdb233ff2ceddc8",
|
||||
"56063afb495759a0942f1c33f28a4fb8320c6d376cb3c9513249453e45f24a04",
|
||||
"f9a6bacd9e055749b45174ecf3c3db18b78f3474761948a68adf601f54e59660",
|
||||
"7ddd7c6d41572f93fe07c0300c34e455b6d1f4372204933bf45035241c8b060c",
|
||||
"f81021b893a36b201de71330a2ea050b59dbf7560c62fa9cbea9261ab47a0ba2",
|
||||
"a01fbe4114c18fd534ae1621404d25c08e3b6775a2631ff40279bafd8c9304f4",
|
||||
"350fad8ebc938c6eb508a1483f385f577794a002bc1229db70a1b0131d174b9d",
|
||||
"570cb8bce87f532c5051d8c4c864012408e672a7d492669e660251fb1e066bec",
|
||||
"8cb6efbb129c84eba26d894c4293b476a6e9a1fe969c6ad18b554d2a57885f36",
|
||||
"f384a98467bf7f084ca31bea121a4ec76e530f523d3225c21ed25a18544a9916",
|
||||
"da127ab58ce557c2c95c20d6a291c2e5d880fff09dc28927b7bdfec97b995d72",
|
||||
"a4d95b4f74366ec920d0a0c5d81265688cc18733ffc444cac9b01ae2431568aa",
|
||||
"5ae2a71470570733422468bb733d53c85b1c8a6e7e6df5c05941556bcf342d1a",
|
||||
"65a2d161ff0e095d3afe37584dbbe649f1e9cd440755b5a3c5b2a252d5c0b8bc",
|
||||
"25ef70a8e41bb422ed7996a41160294e33238d6af17a532232f0a50b123431a2",
|
||||
"f1f0f76ee901664a65b97104296babb9c7422370e99bb677ae07c2ee420e7f40",
|
||||
"c3c66dda180b0330e75c8139b9f315a8c6b937f55d87d7be42e172bbac60d71e",
|
||||
"5881786695a9e58e19d79f790c7d9243a847c0269c5770bdd01f5149c2a62a88",
|
||||
"f2f816d3c8ebc7df06ab68d39223181aacc7be04364d1d4e69a56c33949bb983",
|
||||
"80a1c3b6b2778d4846ad9fe0bb2dd5afd99aa897f8231bfaac45fde43d602d9f",
|
||||
"72ad67cb043aa5df0c3dcc2464953a66893259d81c9cc7778c12bca3447fbd58",
|
||||
"ad72420a7963b8d4536d8eba00b4b989992247cd8c01660e242a8e71edaf0e19",
|
||||
"999d603d1cf6068e3bb6abe1bca976fa0ab84c4660b29ea8973de8b5cf5fd283",
|
||||
"e137a5910f02a764c3a3d8f1579ac0c7e3cc34e58933216868efe010332c1e6e",
|
||||
"10e0fa2362f59317626ae989bd1f962c583339d8d74d76c3e585243d152b91e8",
|
||||
"1951c652704962f5c6e33a4d4aadfee5d53ce2253644d1ed542da3e278524a07",
|
||||
"c938bccb7ba6c0217d8ba35ed91502aee051c8ae5bff05e88aab3b322aec936f",
|
||||
"4d6386c689785edd5beb55911a3a9fc8914838c8192184199589beef8b6ddf9f",
|
||||
"26f6f45a6468bc4b1f085fd28d63c264ee17564f9e247fc03ee179a0b579dcda",
|
||||
"235b7bb82b72c61acd5979ca5f2ca740aee805a780ba22e11aae5cd34f6ec760",
|
||||
"c027ffb585a1e4844b4907490b621b08c7e40a5e6f93e97bd4bb1b615bba9908",
|
||||
"aa77fc8053d139b998577319de29457b78b1cc8b35a5f3526c0621eaa42ce6e8",
|
||||
"afd0af9a11c5ae2a7c4a4571ce39ad57d8df70ef146ed83ad8eaff97b2387fb8",
|
||||
"a1f8fee9f1da9a2b306489d00edf754187b55e97f4fe6f249432fe6c7f44d6be",
|
||||
"4f12e8a123465a862060efb656299e6bef732e5954b02194308817b243e84d32",
|
||||
"6a1ca62f7d6952ad2eba1c64035260319baf03deabf856ca860744fc886b3d3a",
|
||||
"c72dd1fe890d6e4c1f7325a4f224e85aef6cdca8bf9441d228efaf126e02ba63",
|
||||
"2f6ddcea18d891ef4252e657989de68adcc43c2175d49c0c059c5e49b9dd5aed",
|
||||
"24efac0f240ed183c30398ee40307623f52113598f66c5864c90fc62643a2aec",
|
||||
"6ba3ebc935e7cf7fbb446e7f5c12b19c4455e6894412b0eedee4fc945e429e9a",
|
||||
"3519d6e5bc9649f97d07a07ef5471a553ffce35c7619f4f63e91a2ba38cbb729",
|
||||
"65e073df352fa9917e5c2475167e6c523b68c1406e1b6e81109e2d4cc87c740d",
|
||||
"d73bf816c3648a7d53d34be938c454e515efb0c974d5a225f33635540b2db90d",
|
||||
"bce167790fc86a273db011757d09e2d1148521ce242c2ded58f26cc49993aacb",
|
||||
"2d4286ed4039916f29602e86f47ea4c5b05998c0198509ca7799fcadfb337e8d",
|
||||
"9837c495b1af4f76b09177514a0f3e1dceb509c52b91712f3c7d29dc1b91d09b",
|
||||
"5c848b8291f39759903ce77f151acf40f3ab5afa2d4a45af62b320371c29a697",
|
||||
"b92df5016ee947ce6a21365d3361977f7f2f6c14025a983c44e13d3e8cc72152",
|
||||
"71d2f57222a39b1a7ed2df5e6fb23a964439b5a8e7d49b49d87e5cd5354baa75",
|
||||
"88b44d0198fb15b0c20a97f87e021c744606bfd35eae2874f35c447aa4ac3cd4",
|
||||
"29bb4c2557714119cd684da2867e689e37e3ca9c912db83ab84746816f6092ab",
|
||||
"b1836d98a288752675b133b9018fa1edf174f311921d01926c1e1a5900c21029",
|
||||
"a00645e090c7d96f3155ffbcfc41e526a763b0f53a98151ac4a7d4a5b14066b6",
|
||||
"78aab09919d17773b0d62799b37bd2e2970f72f5d1eb6472489c367b6135374f",
|
||||
"eb6123aeb28608f1c97b2bf62ef69f977cd0658a0ab491deebb1e972caa938c5",
|
||||
"8dd7ef1650b1b30cdf7814ae4d61a237eb0acc3ec3ce0f72b1c25780329c2d7d",
|
||||
"b1998419be3172858b990eea84fe10bb24b76c219cde277cb4305955fc7e0b65",
|
||||
"1b10560016c4bc506eef9056dedc2943a17179081e6eaf85b48d37dc20eac3cc",
|
||||
"1fb1d9d4d408a6734234910f554d272739a0d6fa401918d79b57be62c3f23ba2",
|
||||
"dec878f54ce36788289b61d32de0d9539032aba22cd15522752f729659c7cc5c",
|
||||
"fdbfd0773f5a66637b093dabf812197940d1134619a7e60a931b19915b7dab0a",
|
||||
"21bd2c9aae052a1c187947d2964f2be4afa7b30248409c41a75522e88a4e7977",
|
||||
"59326adab03416ec1d36699c18e5e4fa13ca1f2212d48c23bfdecb0be7263616",
|
||||
"bcf263d39457c0aef8ef42fd98f8131198ec4fb203155dd5bcd759e499a9ca5c",
|
||||
"f1ad083bcd8c7630eef93336d8a971ae8ae37166a6a00ac39684420c5f9afef8",
|
||||
"d82ee2ac41b36e3c1787a01835bf054070486dc20f6565efedbbc37cd3bf5fa5",
|
||||
"eba91a0dcbd3986299b0a3e66c116f77bd3421829291fd769522f01da26f107b",
|
||||
"11016558b7e8c6386c6a3e862691dcba47e33e257f0e7df38901ea7c0eba894c",
|
||||
"04f02795e34a0030e5186c8e700da8a46b1aa6bc0abed6b35c9c1cd6a73776b9",
|
||||
"2628dc8ad7fb731d59456b2755a99c6701467125fa69816c21bfccabc31edf6b",
|
||||
"9b7ca249ee5b45cd264492f30df09f708a7d9caed7beb9a5c6292f22e4c31f85",
|
||||
"5c42e7caedf382092faaf392174792b3cf5f2fe29cb586387ee55611af0617c9",
|
||||
"373f2fd5940a01feb79659c8b9099477f6d3e7b570ebb749c2ac336ea4be583d",
|
||||
"fea22887147adc3a659a14902080b03e86b4b8b16985fdf0bbacaed00d812422",
|
||||
"6a3e51a1443cff62af9fa12fafc8ea78ae74dac7792c9ae0f436f570ab33eb71",
|
||||
"796be21e213d6d0cd6fbe2de1555fb73d1cf9edc041a9f1ff1ad583c4ca92460",
|
||||
"03fcbcb31d3fd17f0eedb45ac5a51678c7c8b2b8498225d05f74e2892f017f72",
|
||||
"d28da07c6c22daf9ae987b3033c33d3140e5a56fa1ffd7dc5c7853d55a45bcc7",
|
||||
"fbb0ce02f50018741a12fc08eea80a18067d7bb0fcd96153d40bb8c808473aae",
|
||||
"2bf7c05a0209b4ea31314f04bd754cd01c58102d7cde8c496c655b6494924354",
|
||||
"1968a9e6e14ae86a1e02e6078fc4631851fce5dbac6aa34f860defd1ccfd0ded",
|
||||
"d886181329c9e06462a1407f547d77b38ff2c868b86d8976aa478e1cbb3d66d4",
|
||||
"0d465e02ff2f8eb0b5fb2fa9a38579c5d66337d4a16b58f8ed28d2d89fc02392",
|
||||
"3196419015289807880ef24b6781734822d654dc260c0560d00bac65eacd5219",
|
||||
"fa08390ddc333a2a12248d5ec3e51fff9b782227069fe5a0afbd8eba967ae8d1",
|
||||
"49ae36a791cb84516688d59a1ed3e5112851d65f265078aa2d433b45fa984c8a",
|
||||
"35daa428e12c59da6730760979aca3444d8b31149c6febd99fbfefa4b2372082",
|
||||
"5ef1d697beba612ff31d1dc139817c313a4e2ad3977775943b635c141ef0f2a1",
|
||||
"674256037ec00edb66b9355fb1d33a30a47a5d1f4bce2dd5475d89f1ea6502db",
|
||||
"7b6f017bc550933af91eec32a79464f540c5e0c208703e175843ee4e9ffc0a50",
|
||||
"bf0eb91da1d18dbb18fd9ff36c837387887ba142961176a44889718b2becb9dc",
|
||||
"3e5ac43a05164b074a2ff6353e9882917c5a3dbe168c2695de895f7decf1a56c",
|
||||
"35e8f004965347c2b18a000a83dd3a8084b8a4bf00522061ed1179aa1107c413",
|
||||
"fccb0fff3a24e555ec96f702ec11d420338910d148fc7b039d67568ad3a0e032",
|
||||
"5cab231048032dbf921b4fafa1951dd2da93bc3740667f31d5a1d5665b141261",
|
||||
"ffedb24be73441fbcd069f7785ebb865870e0f3ed228190732e4ffd5962bb82d",
|
||||
"a4fcfec18adf92f4ed822f64d2da9f5ae630885a1bfa626530f641db99aa7a30",
|
||||
"f98bcee41b0e3deafa1efaa1863750dbfd9bd7430b82529b670867d852230b5d",
|
||||
"8ab8d5fca047a52364a737c1af57bf656c9ad5049f08ef4c5aa252e61aa72123",
|
||||
"91318b39ad94c1d58143586b6d90dd6092a9d7487e321f4976967b6ac445ff43",
|
||||
"fabfbd4569ab018e12d5ffa9b1a40ca8eb2ca60a685817351d90eaa770d5eccb",
|
||||
"bbc5ef34428d980e2401942ceecfe07cdf21bfb1acae0596ea1d43fccf504f69",
|
||||
"26943e4201ea407a5667103fe07ca6e08ef76940f274349b0e2e776bcfb0acb6",
|
||||
"e3b305ffe33e72841f8e2a8688cc5cc27d42aee7624b33b7b6399b42db392437",
|
||||
"17c5a763dd57e6bcc7c4cf2db0eb5cf3e97116b67fe0dd519c97e4a4d55d5a62",
|
||||
"bbd260216879ce86af8318ffcf73c9e063ca76dd8bc35d3b6be45b2b4184888b",
|
||||
"41285591d0595bc42ab663051b410d51af39fe1720592e27acb1a8af72360a76",
|
||||
"f29acd6068ce494d0c0fe294cad91bb8968e3fff3f595a113227ab545c3ca3e6",
|
||||
"ec9013c6394528e7dd788ce7cc085ca79fcdfbb37565999d5b4b5a4e39452ecc",
|
||||
"27829bd7f1a8fcddcad0cc34a3b3fc67d62a2f3e09f8e75d35035c2281e83afd",
|
||||
"666bea9db4e15087204d076294d221d4cf5864f5d94de38f29132b1934a17ace",
|
||||
"a3a30924cad3dbda3446e5a6324e0a1390c70f795d5ecfe17ee5c70b14f7d87d",
|
||||
"19567fe5fdb10711d60aa4d9843e1c49c2a6d2fd1b5cf662e2105606bb7815d3",
|
||||
"b139f1c3a2f15596b9320334e37e4184d5d584c4a81e72d821a7edcad3aa62d5",
|
||||
"08f1531e0e3e8f8bae313b2c60a72d5601bf8b60d7a4d2f60e8481650340d250",
|
||||
"c5895669e1ff182bf1dd6c00dc955265e08ded0952b8ca62a1c63ba11c99f4ca",
|
||||
"84d1c28153f66c1a4eb5fa0df695e936d83294df31a08d8d8e2d4798d19d8ce0",
|
||||
"b8699f6af853fdbe897848feb46a05d733363f304eac4c8c1932e6ea4bc062cb",
|
||||
"10eb3f6c1d0661468d9ed83593e5e9c0b43c6feec6a5405a498194905ea6ed48",
|
||||
"509e215a600d9cadcbf5d62632ba321d7314764218db00ce8c907e425fccc445",
|
||||
"e62119b7be84c8eaad41ba7f4a35da403f4ed96b967a3134e89ee8b78f8792c2",
|
||||
"f790754a95d59ea5ffe6b9b5cc386c600a9e19e8bec997c192764365f1d05376",
|
||||
"990121b5aa4d6badfb7154db4cdbb4512124bc2f442bebac71ea90b5cc86f203",
|
||||
"b6983dedaa891eb14c964d84461e5cd37ed27b61771c64978ba83e3ecea194fa",
|
||||
"00fba1ceaa6aa1e378cd5b22a771d6070250ac37f4e17d7bf1a70b3139e9a860",
|
||||
"429854e7738abf2ecf46909454039e2fc5a080eb9a3c0c5ea13b07426dac3ad9",
|
||||
"ceb3e017944b0dd787be219d8629930b3f2e20e22b12dc88fd838488ebb896f3",
|
||||
"eb9e5d14424c63e675fe771b73ca865f7d38cf334d65e2426e12a0b88c1a2236",
|
||||
"556ee713449e6e59ac4b8b2e8310180c8f6280484e9db23456526cceb9216168",
|
||||
"bc89c3aa889e0144ac526a1f861227430dde7e439cc6a7e9b25c9a049c3ca7b3",
|
||||
"56d070c62ea99be66fff741a8e45fafda5f9ff783e84d5395b251f356ce4e16f",
|
||||
"ace15859c399e5ecd13b1420d3c3703c6a88dfb4a084f7225e7ba40a4b444fc8",
|
||||
"f03f1261ab6eb879fe9c5b0028cd400b3ffdfac4344e4c75f6cde3c05ded1f26",
|
||||
"955b2fda8d0068226f89270028b316b5adac871f1c1c85435479aba14a381b0f",
|
||||
"422509a98d7461a6b8ec87cbb173b2486577b59ea9b269e01c20567b38b3b3b2",
|
||||
"007d4de62ad89a4f5985f0cd9b76a7293acf383b4e9e734e813b9df1d57f986f",
|
||||
"13a04e32948225b7e22aa0137341ebbb811e0743032fac16be9d691a652db2eb",
|
||||
"8244b11d880a52f9f9e1830a822e6eeeaf0b12fc759f8261bc2f490cb0794f3b",
|
||||
"27d3415f8f8fd3048a1ee0d9487256dd1b0f9e31be663778efa5b3add63868ec",
|
||||
"0053f888db916a8905320e253fe2f0666355e6fb6de36f897231920a3edfe39f",
|
||||
"0bc5c0a2ea47fa3bb8be107e3b9d6b7226b1c8bd16ca1bab8f51b8e1de08aa8b",
|
||||
"4ca13aaa161c79025b5cd6c9a8ac33554f5ceb479fe293d9a342c865cd9c9948",
|
||||
"333afbe82e2a3df38bd1ef998f39c5feef2554697aa21b5410c0e95ef9156249",
|
||||
"587c4fcabd18ff890064171fce3d5be0c4aa1bba46893fb6a827a85ab54d20f3",
|
||||
"964328e4d51d67c4e2f1fd102a66b861d98199f81d18d660b1b4b52504cd772a",
|
||||
"196aad5594651efd679d30b9feb0f0d172cf977b4f89aa670ec741a8bf21e669",
|
||||
"9137bfd66bbf47bfa0bfcbb9f6e71b6eb3fd9776530e9fd30d3dab19e182f35d",
|
||||
"8217392c4ed2313188f295d94148a027a7f43824a5f5fba33a0b8c1045d509b4",
|
||||
"be9e12761519a4836e73015544163254877e1c4912fcea67a10e7026421dde75",
|
||||
"7b5220421a520b876cc6cdba0d3895104d7fac914dca5b93f9fe8b226566b71e",
|
||||
"5c83fccfeb4bf0eb8a94d43ebc84a81639a32f26c7ef77d0a2b626b7de7befdb",
|
||||
"132fd6c92cf176f975efdb5ded53470b462a48a2815c6f54a93ce4f935784cc7",
|
||||
"46a3dba364022d11aa616a2bc20e3be5c4390f38b9446edfa464d90d9af5d48f",
|
||||
"34b3f3fd8a83905a37762060f51d0b116377b4820b031b8e668e16f46c5b0285",
|
||||
"f0e397e033dabec859a4b9a9043c5f1fb0dba504764d6bcf2fe9bf2ffd318474",
|
||||
"85ecf59c7dd3b24ad17f591bc4737f32f1384c370a7a6f2add06a811dc824b6c",
|
||||
"4d03cdb1e6ad8e066a83654626d8c221433e8d4fd901c671300af37e000177f2",
|
||||
"61cb9c651893e6401b25f2bdf79c9f3ddc9ffe69cf6c791c420462bd73e347e1",
|
||||
"85f2686a42158cd5ad327781ecccd1bdcd346941dd4b4edc45f717de6a011800",
|
||||
"92de2ab82cac528e6d4ccd61e5b7c79591dcad9909c8ad3c8276ece6d48c0f08",
|
||||
"23a878a06bb94bff33083349149f3c860f2b00bc3fb28f04cbaf717c08af19a3",
|
||||
"1b1cce18ff0323566b192885d7ced30f9a9531a2580240f2c593a7d5b8580974",
|
||||
"08fcdec7ea1376d84f3b13a47a4b73c7781c9c7890bb28f712b58af4fd3f24fe",
|
||||
"03cc08fc4ece807c6495272c412be23b045622cc6b786ed8d5c94156ae678a0e",
|
||||
"c4d8a61dc3f5dcf4b83f27a90cbc37e816cf4754e12309626ec5679c99087c46",
|
||||
"b29d00681e29001cdd63c4bc50e5e25715faef692aeebb678c8050e1c095e888",
|
||||
"ac154617e93f2bb1afa232675f2135437a9cc9700c14c51c40084946596ba11a",
|
||||
"ce9549de8e68ae89f424dd9e1cde8a4eea2069da667cfcfbe837691d37366668",
|
||||
"426c45a98e2af35cc9708149f6c086ff5a3972e77d62c627d5e20de5d731cad8",
|
||||
"7e21bfe240a3d9b77a129c734a1d428dbc890379fbaf862853f48b2f7470b2b0",
|
||||
"fa090a71f77223a7210de6db18d9aa809e89fb15253aea28131df6c5a7639140",
|
||||
"7094ad044c5ab025e088b43aa0b947601fabe58ed700a412fd96e4b917ced0c8",
|
||||
"936d5cdc4f081b6fe36c356af4378d472cd7990303f2ea44da645afd7d5d7f9c",
|
||||
"05342037d3b69349dce7b95529d4b2a63ceb9d9393217a68f7cc8c958a96c3ea",
|
||||
"ff9e1c414ef27b1178b1de296526f50520b7ddb06286bf9c47792bfb449e40b6",
|
||||
"2f2b7bedb34d2854b17ccb702cddd8bc0157e39721d58be0b2ad54ee291fc9f1",
|
||||
"0d8db1f34140bbf7eb809137018a74af08cb3345b8a3e368cdda8521dab45791",
|
||||
"b109e4bfabcfe4a1c38be1156d9ca851c75e6aa2e57c0869e40cd9056f571e07",
|
||||
"5cb363547ca077c806fc69bc8c2006831ab89e72fd778ac1a48fa810934e350e",
|
||||
"85ee928bb110fd64eae54a91fc8548883e7fc4c60a3c61b505c31cea2d295c86",
|
||||
"1ec3df7d10ee6fd5f0532ad4fe771e6befc28b0bed0250bf523695d6d49a8246",
|
||||
"de9db2fc07c866bd7b885fb41522b63d550d0ce2e8ac5e14464a41733c2319e6",
|
||||
"9a27136422a8f56768db29ba172a7ba26c3c7aa910324e78e5ab3a3268ac3674",
|
||||
"60213c315119bf9005cb533d1a5b403b4a13c59982fe7773d30fdd8f519f4205",
|
||||
"40eb61ef1812eb8a4d389599bf449fc86653b2c4986061b952f46fc049de53f4",
|
||||
"658ef0d8140162b5f04591be13b47456245f531208bbca3260b857ca09b803c5",
|
||||
"02270fa66255048d724894e2206b4e773cc6a7b6d17ca090cdc25f317d5f53b9",
|
||||
"2ec6a0147f419161f7198d05be5f93152d9ccc10672db0ea47ff1687c0f0dd15",
|
||||
"4be1d8ceb96eb80ef7ce30079ded31163272aeccff5c18fe3aaa32ea2f5bed9d",
|
||||
"04ecaf48f44de87243b17b4c71ebff00020738639336010fa57435a54b623798",
|
||||
"e313a9feb7cfd1d56ec87b1f1062ff9a80da498f7b761af4bef0cecd1b4c385b",
|
||||
"ede3748f971f22341f7f5844dc60fc03cdb30c7cc720ebe13ae588c17a78aa94",
|
||||
"d90c0faa70e39b7c0a8c55457ed6e6478a4e4bf3707b08104326a1ee8377c3ab",
|
||||
"c79ffd0bbc8d004cc542e212990df6498abddd3deb50fd00ed00a2ff690974d6",
|
||||
"35c37d88cf73a89c4124b0ee537347c37fdb47156c8b0ecc509efc58236ed3f0",
|
||||
"a99182f343ccf05e557ffa6df71f03688b2afcf314c59daa774fe78db6f47add",
|
||||
"01115397a78af8a4ae2727ca7a01843235b626bd3db80888d3dfd0020d4135e2",
|
||||
"4a55aced578470d2f7280096d7fe8095f294095fba4778d1977d6db9270472f0",
|
||||
"4624adf8a5633f65b213b8ca46b55cb0ee36c41495f39b1ae70cbd545779b1a0",
|
||||
"d72bcd5b57a9c47e7bd5e9a1103657d10beb7b6c6d41f2b2985bc3bd3cc74860",
|
||||
"48baadb9a46293c92f29e7617846171356a42c3b5d18d49a05a7e173993785f7",
|
||||
"3da927737af8cb0e1c77097e35c54158d18aabfb3051c45bcc7ddfe00b157b1f",
|
||||
"b4a24bfdb2cb802c8d48a3a18fbfe18622a767fe7eddfca57d4555550ccd1643",
|
||||
"c58f82ac7c49dcba1721a88358f07636c9df60d3fd383e5789b808dc57a1dc9d",
|
||||
"5e1f756eff5155df073d30f4452bdafc4adaf4f35960771bf2c1e30137fd7a79",
|
||||
"be4a332f289338d67bd4834eae3128c488a61d255e972da484b6252b67a46b89",
|
||||
"d496e4a36238d03a83d8b45cf33d9388aa7568a279b034d1cdd87b457356cc5b",
|
||||
"a1c5212730ccda34de393210e276bbd44720dda777bcfd602315a3eee582f7dc",
|
||||
"08914ec63f6ef7fe1d678937dc0f6178883440b26b4aca29fce79068947e8397",
|
||||
"49e2cd2bd9b974074d9814f93eed371620bd4ea5fbf97a625065704e8fb382d7",
|
||||
"047c194111818b48ce93a4b006e4a09b9a2650757a87357111796e11e847bf23",
|
||||
"5955b0baa8265341f35a6f24fdc79066ba3ca9c5354c69b6b37a9ef3a26be556",
|
||||
"d7c962f3ea1938c5267cca4072548acf3afcce4d438ed62027caa211a5f98e8b",
|
||||
"c8cfba67cb4ce7e291b35154a50476d9a5c6bbb5d6cbaaa5d2408547fea7b02b",
|
||||
"de8a940d8a69a64ce264d2ab7320662aef2e391c587cb2aae22a86718d5dffbb",
|
||||
"94176f1310b26e54d4de48f87b74aa0b60532f184a2268508dece86dd7f85d36",
|
||||
"9ce6ee3fca56c9256a69df404782301300a6e5e7f5a25a1f6d68c0e9e42584c9",
|
||||
"7c423c4a220c6ff43ab6432f92b166323c58ee77f8c096ba0b00d52d7bd507e8",
|
||||
"0b62b9c1ae4d4988720e8d41d980b334458189de0a3dd01699338d7b07c3894e",
|
||||
"64f45f6f75110624506c53716f2fc1d5fe5f88f82a5bc6a7459ce70eae56dbb3",
|
||||
"12ffbeb8e52fed161af4d8a015d1a5c45dcb8240e5c8933ce3a88ba2c58f97e8",
|
||||
"2ee6b7b96043c8ded9fb52f87cdd0d0580ca6f8cef183c8a656394a11c0aa393",
|
||||
"aaef26b1f5726258bf9ce305a3e54bca65cf68779f90f9d24287245c27362e27",
|
||||
"ef59588dce57c35d010bea4d209f44c62f0b7c7e65bc0226c0e4971934da9435",
|
||||
"0e606c2f6f8dcd579faf4739312bd7327ac7796fa44a81780fe0d66fc7761fb9",
|
||||
"2f307198afdbde5f95989a17e06ce1bb9ff36c441cf3b2248431534fe13bb9fe",
|
||||
"51418e6df23d450aaacc74ef2df53a6b1693727b70bda9ebc43acfc23d8fb5ea",
|
||||
"6e9e3ac46705ed80520695b924435b00d2b3079598bf7faca7fd1524be777e5e",
|
||||
"1e96241e2876aad29ce64f5d7e7fbb8db7265449df816c0d30a96633778c5cb6",
|
||||
"81788f00eb72696d811f946e65d2c96528c45590874a1defdd46651e9b79a3a1",
|
||||
"d9aa5a9f1df50e933d7105a5d72b5fe96bfbb9fd4b5b0eaa5e80af12e72d497a",
|
||||
"e1b6976a732d27fc5d6a96b6d3d0d1d5eaa6ec46bae4665f17e7a43aefc75280",
|
||||
"9151c75edcec1cc90aa2d2c240ff657b0eef3f5f1ec37418c8854b2493114f1d",
|
||||
"3e7c12d0132421f08ea0a390cfa325e422a6b35120fb2eb650f108a165237934",
|
||||
"1ee0e85c7d8a91089c03f37318cdc9127026bf789e3ce4b75046eaa3eebd3458",
|
||||
"4ae64a3ef66cad847409ce175bd5365c9097fd21647a05730ac6b45841add3c8",
|
||||
"f0ea0f334cf1d64678a6dab08c07e2f94f339e8389bd17ebc882b5c8b736cbf2",
|
||||
"da904db96060546ff69e28993ce8183766da9402ac10fae9fc1f1d67ebd83c90",
|
||||
"db11820615f7b5e47778c45d2e083e77f49b608b587dc09ec26f077aba07a242",
|
||||
"ff5c726a83bd785484de75bb03b421f9e8e382bf2740120a2fcf72326aa01c75",
|
||||
"f8643a7efd6304980db323303ab73a6fd4f4ee1047520d39d571580395b97f21",
|
||||
"8facf9737d07838aedf6030593bfb247d8c29fe8d9b18b2913408627a4424d7e",
|
||||
"f0672964aa6e4c7dd4768e18827023787386927f4db89fd661444979afb43c18",
|
||||
"6fd3649c8401f2704ed2be18518b870eb6bf2b9a6689d1b336f05bd8b49017f6",
|
||||
"ed172dac7de827493e0c0fdd8d3299333acb678e72ed499e0224b389cc1e0fba",
|
||||
"7f9a8a8cc8e34add11934a1a5882be5978a6d28405cb0a053ec5699a502b1cef",
|
||||
"6ca829ebd2a0a40994f68c1db7978ec274b45c46e9b351df869a2bfe0630bbd4",
|
||||
"0bbb017c437573a55db88258a9d9a01188bdd23bb6b26903b137814871661f47",
|
||||
"9a6358d2541f46b6d05b80fe25a2cb025fbe9e4b227a6275908d5ee31c948569",
|
||||
"a75d26c6d4ce944024f10e6d23e8b5b888d680120e15dc0e4fee8d8833ee0c6a",
|
||||
"1d43d33556699b42c124b46e41243abf48727fe488428056fdd174a3861c1e3c",
|
||||
"7b5bd3fecbaa093f005c4f806ea67846c0df6b04df7729925cb14724f6a8b582",
|
||||
"6bdf2b54f2f5ab90191261d33dee80fede75896994016422b28db8ba62327d82",
|
||||
"1a16181b250085a91ccecc118473fa2ab98515e894a7b63b347c24b5be560c7a",
|
||||
"22d24891755910b48ad632358c26245bdcc375abc41f7e2c9fb3c7773dbf4e22",
|
||||
"5b70c5d4a373d541619c944fcc3b61259550b0e9fba3eca16f0879e5845b43b9",
|
||||
"b78f9098c9d76987b7409e63426a8d49972bb4e75289576c680cf96513d44b6d",
|
||||
"916b53b8e85eb7e0a2a76d6fc8d2163430e7183ccb103d6705f54af4bb070907",
|
||||
"dc3d78f43110d2aa9df83c5485ec33663ad5452b8cdeb1aeeac9d6b1487fb781",
|
||||
"3975539ed5402cb9f5ab503584524dd141cc4296b666ec66d807f94f62b1c026",
|
||||
"bd1f97fd89183643423073f22733880616456ca41960699f18e868cb9ac35508",
|
||||
"90b468ff0f83460c3dd8cfe778c39d32c6bb1eeff9ac5de7804a4050d3b8073e",
|
||||
"0e886d49d88b82c9f8dbdd2f38a535992f35ab16629724d746394db3898235fa",
|
||||
"76c22e965242d1ca5614e829d9028dcad9c4b09393bcbdd318b0365557335fb9",
|
||||
"59b168488ec8629f820a1efd8fc5a0c2adec4253e61d6a2945a68a9a43be9035",
|
||||
"ff172b42854eaf2865caa985d2fb6283c5ab19574126623ffd615a761a5bce72",
|
||||
"cb46ac9ccc024ee74c96e3cf1c13a6949a432e855dfa881b6a307c0e6daac59e",
|
||||
"9971574924c0f413bf4c0f96bb9c2fbdfea8f475e33a8fb6f15fa40903b63444",
|
||||
"1a95567deb0f45a8941e2248f33286485984a5e9d86d16c37d42169ad864dc36",
|
||||
"205fc7f7ec7a83f0bc22d5269c91762cd00adc7428456d799be5a0cd76f08b0f",
|
||||
"849dd41ef59a722901b7a0deb2c1fd3c110a91a726120a0a119cb7a15cf98438",
|
||||
"a32880917c714612101af95e5c8d8eb5fb046fdcc68bae76c05b829b3fa73c2e",
|
||||
"70b38d6d510d13b359dffa910329952c620a4bce4ee7a8552b9bb3a14572394d",
|
||||
"ef257ab2f4226faa6ba288a6793f026609068effb866c18496a847e8b60b102d",
|
||||
"e5196ab42ff53c8352288bde6b6b7312cd6f39f7d21b556b0db178d8470d5790",
|
||||
"ca98f128bf085f2b718f2b3c12da7c4d98887cc94251a2b1705b637611bd83bb",
|
||||
"79508f0b93a49ec19c5cb05906ca1ba3d3db8ed4f9c6884873d0d7e3e985ea51",
|
||||
"9088be3f47f9debc63e928739f7163182b49eab044518b151f0b89f6b6aefdd0",
|
||||
"46b2782fd669b6288a4d7348cf6671360277ba4864cc69bce3497369ac2ec31e",
|
||||
"0fa5131557db67b430d516530be939ff25882adf68a076602f3dfad8c77c963a",
|
||||
"3404302cc097d5457244453a4c9990804201ee8161188df811bcb32404998c71",
|
||||
"856939710dbb90a8eeda875a31f9a52af759bd932b88e7b08df35414c54d4721",
|
||||
"72569573b9b41d0ac5ce17764a139c6b8b36ef3ca6d92cec625dbcdae758ba22",
|
||||
"9746da344e435a008d6acb4847211bb676376ecc76c825b5d44a28b89ceeb40e",
|
||||
"3eafded1595516f032e33ec975f4c9c3a1055d13aa5575cf8a801d6103fdbeb4",
|
||||
"e88a6d2daa863c0787cc523a2cab45c546fad788951b10d75e2b0954db24cca7",
|
||||
"38f531e67f88f66de44d3357c8e8f2db456160ca31dd2024c9562f6afd260278",
|
||||
};
|
||||
// block 685498 (13 key images in one transaction)
|
||||
static const char * const key_images_685498[] =
|
||||
{
|
||||
"749b7277aa21c70c417f255fb181c3a30b44277edf657eaaebf28a2709dd2a90",
|
||||
"5a9b3e1a87332d735cedaa2b5623a6a5e99d99f5a2887c8fc84293577e8bf25c",
|
||||
"bea438768445eb3650cf619bf6758e94035abfe0ccda91d4a58c582df143d835",
|
||||
"376e237ff4da5e5cbd6e1bba4b01412fa751f2959c0c57006589f382413df429",
|
||||
"14ac2f2e044f8635a3a42ecb46c575424073c1f6e5ed5e905f516d57f63184b5",
|
||||
"2d1d2ecb77b69a2901de00897d0509c1b7855a3b2f8eb1afe419008fc03cd15a",
|
||||
"ea01658f0972b77ae9112d525ec073e3ec5c3b98d5ad912d95ab2636354b70b6",
|
||||
"d3934864a46101d8c242415282e7fc9ee73ad16cd40355535d226ab45ecdb61a",
|
||||
"ee379b05c5d02432330ebd4ea9c4f1c87d14c388568d526a0f8a22649a14e453",
|
||||
"aeb7b842b410b13ca4af7a5ffd5ae6caddc8bfec653df1b945e478839a2e0057",
|
||||
"451806929d9f5c3a7f365472703871abadc25b2a5a2d75472a45e86cd76c610b",
|
||||
"272d9b9fcc9e253c08da9caf8233471150019582eaefef461c1f9ceff7e2c337",
|
||||
"633cdedeb3b96ec4f234c670254c6f721e0b368d00b48c6b26759db7d62cf52d",
|
||||
};
|
||||
|
||||
if (height() > 202612)
|
||||
{
|
||||
for (const auto &kis: key_images_202612)
|
||||
{
|
||||
crypto::key_image ki;
|
||||
epee::string_tools::hex_to_pod(kis, ki);
|
||||
if (!has_key_image(ki))
|
||||
{
|
||||
LOG_PRINT_L1("Fixup: adding missing spent key " << ki);
|
||||
add_spent_key(ki);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (height() > 685498)
|
||||
{
|
||||
for (const auto &kis: key_images_685498)
|
||||
{
|
||||
crypto::key_image ki;
|
||||
epee::string_tools::hex_to_pod(kis, ki);
|
||||
if (!has_key_image(ki))
|
||||
{
|
||||
LOG_PRINT_L1("Fixup: adding missing spent key " << ki);
|
||||
add_spent_key(ki);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
batch_stop();
|
||||
}
|
||||
|
||||
bool BlockchainDB::txpool_tx_matches_category(const crypto::hash& tx_hash, relay_category category)
|
||||
|
|
|
@ -820,7 +820,7 @@ void BlockchainLMDB::add_block(const block& blk, size_t block_weight, uint64_t l
|
|||
bi.bi_diff_lo = (cumulative_difficulty & 0xffffffffffffffff).convert_to<uint64_t>();
|
||||
bi.bi_hash = blk_hash;
|
||||
bi.bi_cum_rct = num_rct_outs;
|
||||
if (blk.major_version >= 4)
|
||||
if (m_height > 0 && blk.major_version >= 4)
|
||||
{
|
||||
uint64_t last_height = m_height-1;
|
||||
MDB_val_set(h, last_height);
|
||||
|
@ -1351,7 +1351,7 @@ void BlockchainLMDB::open(const std::string& filename, const int db_flags)
|
|||
if (is_hdd_result)
|
||||
{
|
||||
if (is_hdd_result.value())
|
||||
MCLOG_RED(el::Level::Warning, "global", "The blockchain is on a rotating drive: this will be very slow, use an SSD if possible");
|
||||
MCLOG_RED(el::Level::Debug, "global", "The blockchain is on a rotating drive: this will be very slow, use an SSD if possible");
|
||||
}
|
||||
|
||||
m_folder = filename;
|
||||
|
@ -1504,7 +1504,7 @@ void BlockchainLMDB::open(const std::string& filename, const int db_flags)
|
|||
mdb_env_close(m_env);
|
||||
m_open = false;
|
||||
MFATAL("Existing lmdb database needs to be converted, which cannot be done on a read-only database.");
|
||||
MFATAL("Please run monerod once to convert the database.");
|
||||
MFATAL("Please run wownerod once to convert the database.");
|
||||
return;
|
||||
}
|
||||
// Note that there was a schema change within version 0 as well.
|
||||
|
|
|
@ -157,7 +157,7 @@ endif()
|
|||
|
||||
set_property(TARGET blockchain_import
|
||||
PROPERTY
|
||||
OUTPUT_NAME "monero-blockchain-import")
|
||||
OUTPUT_NAME "wownero-blockchain-import")
|
||||
install(TARGETS blockchain_import DESTINATION bin)
|
||||
|
||||
monero_add_executable(blockchain_export
|
||||
|
@ -178,7 +178,7 @@ target_link_libraries(blockchain_export
|
|||
|
||||
set_property(TARGET blockchain_export
|
||||
PROPERTY
|
||||
OUTPUT_NAME "monero-blockchain-export")
|
||||
OUTPUT_NAME "wownero-blockchain-export")
|
||||
install(TARGETS blockchain_export DESTINATION bin)
|
||||
|
||||
monero_add_executable(blockchain_blackball
|
||||
|
@ -200,7 +200,7 @@ target_link_libraries(blockchain_blackball
|
|||
|
||||
set_property(TARGET blockchain_blackball
|
||||
PROPERTY
|
||||
OUTPUT_NAME "monero-blockchain-mark-spent-outputs")
|
||||
OUTPUT_NAME "wownero-blockchain-mark-spent-outputs")
|
||||
install(TARGETS blockchain_blackball DESTINATION bin)
|
||||
|
||||
|
||||
|
@ -222,7 +222,7 @@ target_link_libraries(blockchain_usage
|
|||
|
||||
set_property(TARGET blockchain_usage
|
||||
PROPERTY
|
||||
OUTPUT_NAME "monero-blockchain-usage")
|
||||
OUTPUT_NAME "wownero-blockchain-usage")
|
||||
install(TARGETS blockchain_usage DESTINATION bin)
|
||||
|
||||
monero_add_executable(blockchain_ancestry
|
||||
|
@ -243,7 +243,7 @@ target_link_libraries(blockchain_ancestry
|
|||
|
||||
set_property(TARGET blockchain_ancestry
|
||||
PROPERTY
|
||||
OUTPUT_NAME "monero-blockchain-ancestry")
|
||||
OUTPUT_NAME "wownero-blockchain-ancestry")
|
||||
install(TARGETS blockchain_ancestry DESTINATION bin)
|
||||
|
||||
monero_add_executable(blockchain_depth
|
||||
|
@ -264,7 +264,7 @@ target_link_libraries(blockchain_depth
|
|||
|
||||
set_property(TARGET blockchain_depth
|
||||
PROPERTY
|
||||
OUTPUT_NAME "monero-blockchain-depth")
|
||||
OUTPUT_NAME "wownero-blockchain-depth")
|
||||
install(TARGETS blockchain_depth DESTINATION bin)
|
||||
|
||||
monero_add_executable(blockchain_stats
|
||||
|
@ -285,7 +285,7 @@ target_link_libraries(blockchain_stats
|
|||
|
||||
set_property(TARGET blockchain_stats
|
||||
PROPERTY
|
||||
OUTPUT_NAME "monero-blockchain-stats")
|
||||
OUTPUT_NAME "wownero-blockchain-stats")
|
||||
install(TARGETS blockchain_stats DESTINATION bin)
|
||||
|
||||
monero_add_executable(blockchain_prune_known_spent_data
|
||||
|
@ -307,7 +307,7 @@ target_link_libraries(blockchain_prune_known_spent_data
|
|||
|
||||
set_property(TARGET blockchain_prune_known_spent_data
|
||||
PROPERTY
|
||||
OUTPUT_NAME "monero-blockchain-prune-known-spent-data")
|
||||
OUTPUT_NAME "wownero-blockchain-prune-known-spent-data")
|
||||
install(TARGETS blockchain_prune_known_spent_data DESTINATION bin)
|
||||
|
||||
monero_add_executable(blockchain_prune
|
||||
|
@ -316,7 +316,7 @@ monero_add_executable(blockchain_prune
|
|||
|
||||
set_property(TARGET blockchain_prune
|
||||
PROPERTY
|
||||
OUTPUT_NAME "monero-blockchain-prune")
|
||||
OUTPUT_NAME "wownero-blockchain-prune")
|
||||
install(TARGETS blockchain_prune DESTINATION bin)
|
||||
|
||||
target_link_libraries(blockchain_prune
|
||||
|
|
|
@ -386,12 +386,12 @@ int main(int argc, char* argv[])
|
|||
|
||||
if (command_line::get_arg(vm, command_line::arg_help))
|
||||
{
|
||||
std::cout << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL;
|
||||
std::cout << "Wownero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL;
|
||||
std::cout << desc_options << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
mlog_configure(mlog_get_default_log_path("monero-blockchain-ancestry.log"), true);
|
||||
mlog_configure(mlog_get_default_log_path("wownero-blockchain-ancestry.log"), true);
|
||||
if (!command_line::is_arg_defaulted(vm, arg_log_level))
|
||||
mlog_set_log(command_line::get_arg(vm, arg_log_level).c_str());
|
||||
else
|
||||
|
|
|
@ -132,7 +132,7 @@ static std::string get_default_db_path()
|
|||
boost::filesystem::path dir = tools::get_default_data_dir();
|
||||
// remove .bitmonero, replace with .shared-ringdb
|
||||
dir = dir.remove_filename();
|
||||
dir /= ".shared-ringdb";
|
||||
dir /= ".wow-shared-ringdb";
|
||||
return dir.string();
|
||||
}
|
||||
|
||||
|
@ -1176,7 +1176,7 @@ int main(int argc, char* argv[])
|
|||
const command_line::arg_descriptor<bool> arg_rct_only = {"rct-only", "Only work on ringCT outputs", false};
|
||||
const command_line::arg_descriptor<bool> arg_check_subsets = {"check-subsets", "Check ring subsets (very expensive)", false};
|
||||
const command_line::arg_descriptor<bool> arg_verbose = {"verbose", "Verbose output)", false};
|
||||
const command_line::arg_descriptor<std::vector<std::string> > arg_inputs = {"inputs", "Path to Monero DB, and path to any fork DBs"};
|
||||
const command_line::arg_descriptor<std::vector<std::string> > arg_inputs = {"inputs", "Path to Wownero DB, and path to any fork DBs"};
|
||||
const command_line::arg_descriptor<std::string> arg_db_sync_mode = {
|
||||
"db-sync-mode"
|
||||
, "Specify sync option, using format [safe|fast|fastest]:[nrecords_per_sync]."
|
||||
|
@ -1219,12 +1219,12 @@ int main(int argc, char* argv[])
|
|||
|
||||
if (command_line::get_arg(vm, command_line::arg_help))
|
||||
{
|
||||
std::cout << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL;
|
||||
std::cout << "Wownero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL;
|
||||
std::cout << desc_options << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
mlog_configure(mlog_get_default_log_path("monero-blockchain-mark-spent-outputs.log"), true);
|
||||
mlog_configure(mlog_get_default_log_path("wownero-blockchain-mark-spent-outputs.log"), true);
|
||||
if (!command_line::is_arg_defaulted(vm, arg_log_level))
|
||||
mlog_set_log(command_line::get_arg(vm, arg_log_level).c_str());
|
||||
else
|
||||
|
|
|
@ -88,12 +88,12 @@ int main(int argc, char* argv[])
|
|||
|
||||
if (command_line::get_arg(vm, command_line::arg_help))
|
||||
{
|
||||
std::cout << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL;
|
||||
std::cout << "Wownero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL;
|
||||
std::cout << desc_options << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
mlog_configure(mlog_get_default_log_path("monero-blockchain-depth.log"), true);
|
||||
mlog_configure(mlog_get_default_log_path("wownero-blockchain-depth.log"), true);
|
||||
if (!command_line::is_arg_defaulted(vm, arg_log_level))
|
||||
mlog_set_log(command_line::get_arg(vm, arg_log_level).c_str());
|
||||
else
|
||||
|
|
|
@ -90,12 +90,12 @@ int main(int argc, char* argv[])
|
|||
|
||||
if (command_line::get_arg(vm, command_line::arg_help))
|
||||
{
|
||||
std::cout << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL;
|
||||
std::cout << "Wownero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL;
|
||||
std::cout << desc_options << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
mlog_configure(mlog_get_default_log_path("monero-blockchain-export.log"), true);
|
||||
mlog_configure(mlog_get_default_log_path("wownero-blockchain-export.log"), true);
|
||||
if (!command_line::is_arg_defaulted(vm, arg_log_level))
|
||||
mlog_set_log(command_line::get_arg(vm, arg_log_level).c_str());
|
||||
else
|
||||
|
|
|
@ -637,7 +637,7 @@ int main(int argc, char* argv[])
|
|||
|
||||
if (command_line::get_arg(vm, command_line::arg_help))
|
||||
{
|
||||
std::cout << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL;
|
||||
std::cout << "Wownero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL;
|
||||
std::cout << desc_options << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
@ -674,7 +674,7 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
m_config_folder = command_line::get_arg(vm, cryptonote::arg_data_dir);
|
||||
|
||||
mlog_configure(mlog_get_default_log_path("monero-blockchain-import.log"), true);
|
||||
mlog_configure(mlog_get_default_log_path("wownero-blockchain-import.log"), true);
|
||||
if (!command_line::is_arg_defaulted(vm, arg_log_level))
|
||||
mlog_set_log(command_line::get_arg(vm, arg_log_level).c_str());
|
||||
else
|
||||
|
|
|
@ -483,12 +483,12 @@ int main(int argc, char* argv[])
|
|||
|
||||
if (command_line::get_arg(vm, command_line::arg_help))
|
||||
{
|
||||
std::cout << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL;
|
||||
std::cout << "Wownero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL;
|
||||
std::cout << desc_options << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
mlog_configure(mlog_get_default_log_path("monero-blockchain-prune.log"), true);
|
||||
mlog_configure(mlog_get_default_log_path("wownero-blockchain-prune.log"), true);
|
||||
if (!command_line::is_arg_defaulted(vm, arg_log_level))
|
||||
mlog_set_log(command_line::get_arg(vm, arg_log_level).c_str());
|
||||
else
|
||||
|
|
|
@ -137,12 +137,12 @@ int main(int argc, char* argv[])
|
|||
|
||||
if (command_line::get_arg(vm, command_line::arg_help))
|
||||
{
|
||||
std::cout << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL;
|
||||
std::cout << "Wownero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL;
|
||||
std::cout << desc_options << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
mlog_configure(mlog_get_default_log_path("monero-blockchain-prune-known-spent-data.log"), true);
|
||||
mlog_configure(mlog_get_default_log_path("wownero-blockchain-prune-known-spent-data.log"), true);
|
||||
if (!command_line::is_arg_defaulted(vm, arg_log_level))
|
||||
mlog_set_log(command_line::get_arg(vm, arg_log_level).c_str());
|
||||
else
|
||||
|
|
|
@ -175,12 +175,12 @@ int main(int argc, char* argv[])
|
|||
|
||||
if (command_line::get_arg(vm, command_line::arg_help))
|
||||
{
|
||||
std::cout << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL;
|
||||
std::cout << "Wownero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL;
|
||||
std::cout << desc_options << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
mlog_configure(mlog_get_default_log_path("monero-blockchain-stats.log"), true);
|
||||
mlog_configure(mlog_get_default_log_path("wownero-blockchain-stats.log"), true);
|
||||
if (!command_line::is_arg_defaulted(vm, arg_log_level))
|
||||
mlog_set_log(command_line::get_arg(vm, arg_log_level).c_str());
|
||||
else
|
||||
|
|
|
@ -120,12 +120,12 @@ int main(int argc, char* argv[])
|
|||
|
||||
if (command_line::get_arg(vm, command_line::arg_help))
|
||||
{
|
||||
std::cout << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL;
|
||||
std::cout << "Wownero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL;
|
||||
std::cout << desc_options << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
mlog_configure(mlog_get_default_log_path("monero-blockchain-usage.log"), true);
|
||||
mlog_configure(mlog_get_default_log_path("wownero-blockchain-usage.log"), true);
|
||||
if (!command_line::is_arg_defaulted(vm, arg_log_level))
|
||||
mlog_set_log(command_line::get_arg(vm, arg_log_level).c_str());
|
||||
else
|
||||
|
|
|
@ -41,7 +41,7 @@ const size_t ${BLOB_NAME}_len = sizeof(${BLOB_NAME});
|
|||
"
|
||||
)
|
||||
]=])
|
||||
foreach(BLOB_NAME checkpoints testnet_blocks stagenet_blocks)
|
||||
foreach(BLOB_NAME checkpoints)
|
||||
set(OUTPUT_C_SOURCE "generated_${BLOB_NAME}.c")
|
||||
list(APPEND GENERATED_SOURCES ${OUTPUT_C_SOURCE})
|
||||
set(INPUT_DAT_FILE "${BLOB_NAME}.dat")
|
||||
|
|
|
@ -4,18 +4,12 @@
|
|||
|
||||
extern const unsigned char checkpoints[];
|
||||
extern const size_t checkpoints_len;
|
||||
extern const unsigned char stagenet_blocks[];
|
||||
extern const size_t stagenet_blocks_len;
|
||||
extern const unsigned char testnet_blocks[];
|
||||
extern const size_t testnet_blocks_len;
|
||||
|
||||
namespace blocks
|
||||
{
|
||||
|
||||
const std::unordered_map<cryptonote::network_type, const epee::span<const unsigned char>, std::hash<size_t>> CheckpointsByNetwork = {
|
||||
{cryptonote::network_type::MAINNET, {checkpoints, checkpoints_len}},
|
||||
{cryptonote::network_type::STAGENET, {stagenet_blocks, stagenet_blocks_len}},
|
||||
{cryptonote::network_type::TESTNET, {testnet_blocks, testnet_blocks_len}}
|
||||
{cryptonote::network_type::MAINNET, {checkpoints, checkpoints_len}}
|
||||
};
|
||||
|
||||
const epee::span<const unsigned char> GetCheckpointsData(cryptonote::network_type network)
|
||||
|
|
Binary file not shown.
|
@ -197,53 +197,50 @@ namespace cryptonote
|
|||
ADD_CHECKPOINT2(550000, "409f68cddd8e74b37469b41c1e61250d81c5776b42264f416d5d27c4626383ed", "0x5f3d4d03e");
|
||||
return true;
|
||||
}
|
||||
ADD_CHECKPOINT2(1, "771fbcd656ec1464d3a02ead5e18644030007a0fc664c0a964d30922821a8148", "0x2");
|
||||
ADD_CHECKPOINT2(10, "c0e3b387e47042f72d8ccdca88071ff96bff1ac7cde09ae113dbb7ad3fe92381", "0x2a974");
|
||||
ADD_CHECKPOINT2(100, "ac3e11ca545e57c49fca2b4e8c48c03c23be047c43e471e1394528b1f9f80b2d", "0x35d14b");
|
||||
ADD_CHECKPOINT2(1000, "5acfc45acffd2b2e7345caf42fa02308c5793f15ec33946e969e829f40b03876", "0x36a0373");
|
||||
ADD_CHECKPOINT2(10000, "c758b7c81f928be3295d45e230646de8b852ec96a821eac3fea4daf3fcac0ca2", "0x60a91390");
|
||||
ADD_CHECKPOINT2(22231, "7cb10e29d67e1c069e6e11b17d30b809724255fee2f6868dc14cfc6ed44dfb25", "0x1e288793d");
|
||||
ADD_CHECKPOINT2(29556, "53c484a8ed91e4da621bb2fa88106dbde426fe90d7ef07b9c1e5127fb6f3a7f6", "0x71f64cce8");
|
||||
ADD_CHECKPOINT2(50000, "0fe8758ab06a8b9cb35b7328fd4f757af530a5d37759f9d3e421023231f7b31c", "0x893044b400");
|
||||
ADD_CHECKPOINT2(80000, "a62dcd7b536f22e003ebae8726e9e7276f63d594e264b6f0cd7aab27b66e75e3", "0x5cc113f1076");
|
||||
ADD_CHECKPOINT2(202612, "bbd604d2ba11ba27935e006ed39c9bfdd99b76bf4a50654bc1e1e61217962698", "0x73310a259eb2");
|
||||
ADD_CHECKPOINT2(202613, "e2aa337e78df1f98f462b3b1e560c6b914dec47b610698b7b7d1e3e86b6197c2", "0x733154039b97");
|
||||
ADD_CHECKPOINT2(202614, "c29e3dc37d8da3e72e506e31a213a58771b24450144305bcba9e70fa4d6ea6fb", "0x73319dc90cb6");
|
||||
ADD_CHECKPOINT2(205000, "5d3d7a26e6dc7535e34f03def711daa8c263785f73ec1fadef8a45880fde8063", "0x75fcc3d85123");
|
||||
ADD_CHECKPOINT2(220000, "9613f455933c00e3e33ac315cc6b455ee8aa0c567163836858c2d9caff111553", "0x89cfed0cae3c");
|
||||
ADD_CHECKPOINT2(230300, "bae7a80c46859db355556e3a9204a337ae8f24309926a1312323fdecf1920e61", "0x967d13e5baa9");
|
||||
ADD_CHECKPOINT2(230700, "93e631240ceac831da1aebfc5dac8f722c430463024763ebafa888796ceaeedf", "0x96fb9663ebe7");
|
||||
ADD_CHECKPOINT2(231350, "b5add137199b820e1ea26640e5c3e121fd85faa86a1e39cf7e6cc097bdeb1131", "0x97b9919177bf");
|
||||
ADD_CHECKPOINT2(232150, "955de8e6b6508af2c24f7334f97beeea651d78e9ade3ab18fec3763be3201aa8", "0x98a038b612e8");
|
||||
ADD_CHECKPOINT2(249380, "654fb0a81ce3e5caf7e3264a70f447d4bd07586c08fa50f6638cc54da0a52b2d", "0xac9739634e6d");
|
||||
ADD_CHECKPOINT2(460000, "75037a7aed3e765db96c75bcf908f59d690a5f3390baebb9edeafd336a1c4831", "0x167799549bdda");
|
||||
ADD_CHECKPOINT2(500000, "2428f0dbe49796be05ed81b347f53e1f7f44aed0abf641446ec2b94cae066b02", "0x188ce145e4ba9");
|
||||
ADD_CHECKPOINT2(600000, "f5828ebf7d7d1cb61762c4dfe3ccf4ecab2e1aad23e8113668d981713b7a54c5", "0x1d9f3759e1554");
|
||||
ADD_CHECKPOINT2(700000, "12be9b3d210b93f574d2526abb9c1ab2a881b479131fd0d4f7dac93875f503cd", "0x2201e4ee39c2c");
|
||||
ADD_CHECKPOINT2(825000, "56503f9ad766774b575be3aff73245e9d159be88132c93d1754764f28da2ff60", "0x27565a442d5df");
|
||||
ADD_CHECKPOINT2(900000, "d9958d0e7dcf91a5a7b11de225927bf7efc6eb26240315ce12372be902cc1337", "0x2a6334031546e");
|
||||
ADD_CHECKPOINT2(913193, "5292d5d56f6ba4de33a58d9a34d263e2cb3c6fee0aed2286fd4ac7f36d53c85f", "0x2aefe7f40f5ea");
|
||||
ADD_CHECKPOINT2(1000000, "a886ef5149902d8342475fee9bb296341b891ac67c4842f47a833f23c00ed721", "0x2edd71370f0e5");
|
||||
ADD_CHECKPOINT2(1100000, "3fd720c5c8b3072fc1ccda922dec1ef25f9ed88a1e6ad4103d0fe00b180a5903", "0x390eb0035c53a");
|
||||
ADD_CHECKPOINT2(1150000, "1dd16f626d18e1e988490dfd06de5920e22629c972c58b4d8daddea0038627b2", "0x422d5662e9e37");
|
||||
ADD_CHECKPOINT2(1200000, "fa7d13a90850882060479d100141ff84286599ae39c3277c8ea784393f882d1f", "0x4c73503fc4aa3");
|
||||
ADD_CHECKPOINT2(1300000, "31b34272343a44a9f4ac7de7a8fcf3b7d8a3124d7d6870affd510d2f37e74cd0", "0x723f49bc249d5");
|
||||
ADD_CHECKPOINT2(1390000, "a8f5649dd4ded60eedab475f2bec8c934681c07e3cf640e9be0617554f13ff6c", "0xb4bba65e2841b");
|
||||
ADD_CHECKPOINT2(1450000, "ac94e8860093bc7c83e4e91215cba1d663421ecf4067a0ae609c3a8b52bcfac2", "0x11a4aabdca9511");
|
||||
ADD_CHECKPOINT2(1530000, "01759bce497ec38e63c78b1038892169203bb78f87e488172f6b854fcd63ba7e", "0x2819ce9f9e91e5");
|
||||
ADD_CHECKPOINT2(1579000, "7d0d7a2346373afd41ed1e744a939fc5d474a7dbaa257be5c6fff4009e789241", "0x357a590e7dda83");
|
||||
ADD_CHECKPOINT2(1668900, "ac2dcaf3d2f58ffcf8391639f0f1ebafcb8eac43c49479c7c37f611868d07568", "0x474226e475cc3b");
|
||||
ADD_CHECKPOINT2(1775600, "1c6e01c661dc22cab939e79ec6a5272190624ce8356d2f7b958e4f9a57fdb05e", "0x5e3b9d206a27c6");
|
||||
ADD_CHECKPOINT2(1856000, "9b57f17f29c71a3acd8a7904b93c41fa6eb8d2b7c73936ce4f1702d14880ba29", "0x6bde5e1caccee1");
|
||||
ADD_CHECKPOINT2(1958000, "98a5d6e51afdf3146e0eefb10a66e8648d8d4d5c2742be8835e976ba217c9bb2", "0x79dd46d2a0971a");
|
||||
ADD_CHECKPOINT2(2046000, "5e867f0b8baefed9244a681df97fc885d8ab36c3dfcd24c7a3abf3b8ac8b8314", "0x9cb8b6ff2978c6");
|
||||
ADD_CHECKPOINT2(2092500, "c4e00820c9c7989b49153d5e90ae095a18a11d990e82fcc3be54e6ed785472b5", "0xb4e585a31369cb");
|
||||
ADD_CHECKPOINT2(2182500, "0d22b5f81982eff21d094af9e821dc2007e6342069e3b1a37b15d97646353124", "0xead4a874083492");
|
||||
ADD_CHECKPOINT2(2661600, "41c9060e8426012238e8a26da26fcb90797436896cc70886a894c2c560bcccf2", "0x2e0d87526ff161f");
|
||||
ADD_CHECKPOINT2(2677000, "1b9fee6246eeb176bd17d637bf252e9af54a4218675f01b4449cc0901867f9eb", "0x2f165bc1a5163ba");
|
||||
ADD_CHECKPOINT2(2706000, "d8eb144c5e1fe6b329ecc900ec95e7792fccff84175fb23a25ed59d7299a511c", "0x310f7d89372f705");
|
||||
ADD_CHECKPOINT2(2720000, "b19fb41dff15bd1016afbee9f8469f05aab715c9e5d1b974466a11fd58ecbb86", "0x3216b5851ddbb61");
|
||||
ADD_CHECKPOINT2(2817000, "39726d19ccaac01d150bec827b877ffae710b516bd633503662036ef4422e577", "0x3900669561954c1");
|
||||
ADD_CHECKPOINT2(1, "97f4ce4d7879b3bea54dcec738cd2ebb7952b4e9bb9743262310cd5fec749340", "0x2");
|
||||
ADD_CHECKPOINT2(6969, "aa7b66e8c461065139b55c29538a39c33ceda93e587f84d490ed573d80511c87", "0x118eef693fd"); //Hard fork to v8
|
||||
ADD_CHECKPOINT2(53666, "3f43f56f66ef0c43cf2fd14d0d28fa2aae0ef8f40716773511345750770f1255", "0xb677d6405ae"); //Hard fork to v9
|
||||
ADD_CHECKPOINT2(63469, "4e33a9343fc5b86661ec0affaeb5b5a065290602c02d817337e4a979fe5747d8", "0xe7cd9819062"); //Hard fork to v10
|
||||
ADD_CHECKPOINT2(81769, "41db9fef8d0ccfa78b570ee9525d4f55de77b510c3ae4b08a1d51b9aec9ade1d", "0x150066455b88"); //Hard fork to v11
|
||||
ADD_CHECKPOINT2(82069, "fdea800d23d0b2eea19dec8af31e453e883e8315c97e25c8bb3e88ca164f8369", "0x15079b5fdaa8"); //Hard fork to v12
|
||||
ADD_CHECKPOINT2(114969, "b48245956b87f243048fd61021f4b3e5443e57eee7ff8ba4762d18926e80b80c", "0x1ca552b3ec68"); //Hard fork to v13
|
||||
ADD_CHECKPOINT2(115257, "338e056551087fe23d6c4b4280244bc5362b004716d85ec799a775f190f9fea9", "0x1cb25f5d4628"); //Hard fork to v14
|
||||
ADD_CHECKPOINT2(160777, "9496690579af21f38f00e67e11c2e85a15912fe4f412aad33d1162be1579e755", "0x5376eaa196a8"); //Hard fork to v15
|
||||
ADD_CHECKPOINT2(253999, "755a289fe8a68e96a0f69069ba4007b676ec87dce2e47dfb9647fe5691f49883", "0x172d026ef7fe8"); //Hard fork to v16
|
||||
ADD_CHECKPOINT2(254287, "b37cb55abe73965b424f8028bf71bef98d069645077ffa52f0c134907b7734e3", "0x1746622f56668"); //Hard fork to v17
|
||||
ADD_CHECKPOINT2(256700, "389a8ab95a80e84ec74639c1078bc67b33af208ef00f53bd9609cfc40efa7059", "0x185ace3c1bd68");
|
||||
ADD_CHECKPOINT2(271600, "9597cdbdc52ca57d7dbd8f9c0a23a73194ef2ebbcfdc75c21992672706108d43", "0x1e2d2d6a2a9e8");
|
||||
ADD_CHECKPOINT2(278300, "b10dcdf7a51651f60fbcc0447409773eef1458d2c706d9a61daf467571ac19c9", "0x20a83a16d3968");
|
||||
ADD_CHECKPOINT2(282700, "79c06cafd7cb5f76bcebbf8f1ae16203bb41fd75b284bcd0eb0b457991ab7d4a", "0x22e3baf142de8");
|
||||
ADD_CHECKPOINT2(307686, "dfd056b2739c132a07629409a59a028cb7414fac23e3419e79d2f49d66fc3af5", "0x305ba542e3ea8"); // "difficulty": 25800000
|
||||
ADD_CHECKPOINT2(307692, "d822cd72037f62824ec87c9dc11768b45dc2632f697fa372e1885789c90f37fc", "0x305e124633878"); // "difficulty": 1890000
|
||||
ADD_CHECKPOINT2(307735, "60970378aecdc0a78ccf5154edcc56f23aad8554b49e4716f820461a7588bfdc", "0x3070771b9ba58"); // "difficulty": 17900000
|
||||
ADD_CHECKPOINT2(307742, "0ed835bc9fcd949b5a184cf607dcc62ac4268c9e4cf220f8b09bcce58f10916b", "0x30732f1248978"); // "difficulty": 21300000
|
||||
ADD_CHECKPOINT2(307750, "7bcafbc757237125b70f569b181eb1b66c530b10d817d7b940f7a73dc827211c", "0x30766666b3d98"); // "difficulty": 10900000
|
||||
ADD_CHECKPOINT2(307766, "02fd6c7d6bae710cfa3efb08f50e4bc9a590f6ab61eabd87e5e951338c0c36f6", "0x307d2d47a7918"); // "difficulty": 2960000
|
||||
ADD_CHECKPOINT2(307800, "3594894b4231cfdfe911afed6552f9fb4cfe6048bacd0973a3a98623ec8548ce", "0x308b305ca7618");
|
||||
ADD_CHECKPOINT2(307880, "659274b698f680c6cae2716cbd4e15ad5def23b5de98e53734c4af2c2e74bb7a", "0x30af6e91e8018");
|
||||
ADD_CHECKPOINT2(307883, "9a8c35cd10963a14bba8a9628d1776df92fee5e3153b7249f5d15726efafaaea", "0x30b0965ba5a18");
|
||||
ADD_CHECKPOINT2(312130, "e0da085bd273fff9f5f8e604fce0e91908bc62b6b004731a93e16e89cb9b1f54", "0x3cfe7148f2e18");
|
||||
ADD_CHECKPOINT2(324600, "b24cd1ed7c192bbcf3d5b15729f2b032566687f96bda6f8cb73a5b16df4c6e6b", "0x69caecbe78718");
|
||||
ADD_CHECKPOINT2(327700, "f113c8cbe077aab9296ecbfb41780c147aeb54edfece7e4b9946b8abd0f06de7", "0x732431429c818");
|
||||
ADD_CHECKPOINT2(331170, "05243fba853fe375c671a6783eecac28777bca51f5977d5285c235424e52bb69", "0x7c3469310d218"); //Hard fork to v18
|
||||
ADD_CHECKPOINT2(331458, "f79a664a5e4bc11fa7d804be2c3c72db50c87a27f1f540f337564cbb6314e4cd", "0x7c34d47adf218"); //Hard fork to v19
|
||||
ADD_CHECKPOINT2(331891, "faceea4b4ab33fc962c24dfa2f98c2aeda4788f67c1e0044c62419912c1a64fe", "0x7c359086aeb58"); // restart DIFFICULTY_WINDOW
|
||||
ADD_CHECKPOINT2(332100, "d32c409058c1eceb9a105190c7a5f480b2d6f49f318b18652b49ae971c710124", "0x7c538441cca36");
|
||||
ADD_CHECKPOINT2(334000, "17d3b15f8e1a73e1c61335ee7979e9e3d211b9055e8a7fb2481e5f49a51b1c22", "0x7ddd5a79d69c4");
|
||||
ADD_CHECKPOINT2(348500, "2d43a157f369e2aa26a329b56456142ecd1361f5808c688d97112a2e3bbd23f4", "0x90889ed877ada");
|
||||
ADD_CHECKPOINT2(489400, "b14f49eae77398117ea93435676100d8b655a804689f73a5a4d0d5e71160d603", "0x1123c39bb52f7e");
|
||||
ADD_CHECKPOINT2(491200, "cedba73ad35ce7f51aaca2beb36dc32d79ecc716d146eb8211e6a815f3666c4a", "0x11334734abbd17");
|
||||
ADD_CHECKPOINT2(497100, "2c4c70ac1ada94151f19d67ccf1aa4e846e6067f49f67c85cc03f78e768ea42b", "0x116906bc97a751");
|
||||
ADD_CHECKPOINT2(500000, "f4f771261b8c13cd83a9d8fa22e3cfe988564ad4b57dd90e79d5c0e77d61cf6a", "0x1185e7f2357a03");
|
||||
ADD_CHECKPOINT2(503500, "776f36a17056c3e22bbfb51d5aeabb58000731e9ad549f0f2f8ad1e1bcedf312", "0x11a4884467f53d");
|
||||
ADD_CHECKPOINT2(509900, "59520faa272fc68e0426c827a38b21cdc1df8f5a37c5fdcbbe00350fece5f3ae", "0x11dc780bd1b580");
|
||||
ADD_CHECKPOINT2(514000, "1569e712750f19e57aee3f73cc3091a0eea392740bd396ad3570bc96e0e6ffb5", "0x11fff58abe0a82"); //Hard fork to v20
|
||||
ADD_CHECKPOINT2(516700, "0443c47c5a4e344c3f68a491a3b2f6b78a769cdf9076249c93f187ececf9cc7c", "0x12128a532a59a6");
|
||||
ADD_CHECKPOINT2(522000, "8c15ae514063bf05e7662ab33b86a4131aa89df0784ce3da7876c5339bc1de3d", "0x123d9c604a7be6");
|
||||
ADD_CHECKPOINT2(566000, "136e37f5f130dd2dc2d8d30e46e16d74377cb834b7c5be32cd09ee6ad402556c", "0x1318d703b1bff7");
|
||||
ADD_CHECKPOINT2(611300, "34fd2ff914ad34edc2dabb0fe38f15b2ac6a301dc501bdfec15d2108b304a455", "0x13b61f061add9d");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -288,22 +285,13 @@ namespace cryptonote
|
|||
std::vector<std::string> records;
|
||||
|
||||
// All four MoneroPulse domains have DNSSEC on and valid
|
||||
static const std::vector<std::string> dns_urls = { "checkpoints.moneropulse.se"
|
||||
, "checkpoints.moneropulse.org"
|
||||
, "checkpoints.moneropulse.net"
|
||||
, "checkpoints.moneropulse.co"
|
||||
static const std::vector<std::string> dns_urls = {
|
||||
};
|
||||
|
||||
static const std::vector<std::string> testnet_dns_urls = { "testpoints.moneropulse.se"
|
||||
, "testpoints.moneropulse.org"
|
||||
, "testpoints.moneropulse.net"
|
||||
, "testpoints.moneropulse.co"
|
||||
static const std::vector<std::string> testnet_dns_urls = {
|
||||
};
|
||||
|
||||
static const std::vector<std::string> stagenet_dns_urls = { "stagenetpoints.moneropulse.se"
|
||||
, "stagenetpoints.moneropulse.org"
|
||||
, "stagenetpoints.moneropulse.net"
|
||||
, "stagenetpoints.moneropulse.co"
|
||||
static const std::vector<std::string> stagenet_dns_urls = {
|
||||
};
|
||||
|
||||
if (!tools::dns_utils::load_txt_records_from_dns(records, nettype == TESTNET ? testnet_dns_urls : nettype == STAGENET ? stagenet_dns_urls : dns_urls))
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
#include <cstdint>
|
||||
|
||||
namespace tools {
|
||||
|
||||
|
|
|
@ -295,7 +295,7 @@ DNSResolver::DNSResolver() : m_data(new DNSResolverData())
|
|||
// should be a valid DNSSEC record, and switch to known good
|
||||
// DNSSEC resolvers if verification fails
|
||||
bool available, valid;
|
||||
static const char *probe_hostname = "updates.moneropulse.org";
|
||||
static const char *probe_hostname = "";
|
||||
auto records = get_txt_record(probe_hostname, available, valid);
|
||||
if (!valid)
|
||||
{
|
||||
|
@ -419,7 +419,7 @@ namespace dns_utils
|
|||
std::string address_from_txt_record(const std::string& s)
|
||||
{
|
||||
// make sure the txt record has "oa1:xmr" and find it
|
||||
auto pos = s.find("oa1:xmr");
|
||||
auto pos = s.find("oa1:wow");
|
||||
if (pos == std::string::npos)
|
||||
return {};
|
||||
// search from there to find "recipient_address="
|
||||
|
@ -432,13 +432,13 @@ std::string address_from_txt_record(const std::string& s)
|
|||
if (pos2 != std::string::npos)
|
||||
{
|
||||
// length of address == 95, we can at least validate that much here
|
||||
if (pos2 - pos == 95)
|
||||
if (pos2 - pos == 97)
|
||||
{
|
||||
return s.substr(pos, 95);
|
||||
return s.substr(pos, 97);
|
||||
}
|
||||
else if (pos2 - pos == 106) // length of address == 106 --> integrated address
|
||||
else if (pos2 - pos == 108) // length of address == 106 --> integrated address
|
||||
{
|
||||
return s.substr(pos, 106);
|
||||
return s.substr(pos, 108);
|
||||
}
|
||||
}
|
||||
return {};
|
||||
|
@ -554,7 +554,7 @@ bool load_txt_records_from_dns(std::vector<std::string> &good_records, const std
|
|||
|
||||
if (num_valid_records < 2)
|
||||
{
|
||||
LOG_PRINT_L0("WARNING: no two valid DNS TXT records were received");
|
||||
LOG_PRINT_L2("WARNING: no two valid DNS TXT records were received");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ namespace tools
|
|||
while (1)
|
||||
{
|
||||
t1 = epee::misc_utils::get_ns_count();
|
||||
if (t1 - t0 > 1*1000000000) break; // work one second
|
||||
if (t1 - t0 > 1*100000000) break; // work 0.1 seconds
|
||||
}
|
||||
|
||||
uint64_t r1 = get_tick_count();
|
||||
|
|
|
@ -46,13 +46,6 @@ namespace tools
|
|||
|
||||
// All four MoneroPulse domains have DNSSEC on and valid
|
||||
static const std::vector<std::string> dns_urls = {
|
||||
"updates.moneropulse.org",
|
||||
"updates.moneropulse.net",
|
||||
"updates.moneropulse.fr",
|
||||
"updates.moneropulse.de",
|
||||
"updates.moneropulse.no",
|
||||
"updates.moneropulse.ch",
|
||||
"updates.moneropulse.se"
|
||||
};
|
||||
|
||||
if (!tools::dns_utils::load_txt_records_from_dns(records, dns_urls))
|
||||
|
@ -102,11 +95,11 @@ namespace tools
|
|||
|
||||
std::string get_update_url(const std::string &software, const std::string &subdir, const std::string &buildtag, const std::string &version, bool user)
|
||||
{
|
||||
const char *base = user ? "https://downloads.getmonero.org/" : "https://updates.getmonero.org/";
|
||||
const char *base = user ? "" : "";
|
||||
#ifdef _WIN32
|
||||
static const char *extension = strncmp(buildtag.c_str(), "source", 6) ? (strncmp(buildtag.c_str(), "install-", 8) ? ".zip" : ".exe") : ".tar.bz2";
|
||||
#elif defined(__APPLE__)
|
||||
static const char *extension = strncmp(software.c_str(), "monero-gui", 10) ? ".tar.bz2" : ".dmg";
|
||||
static const char *extension = strncmp(software.c_str(), "wownero-gui", 10) ? ".tar.bz2" : ".dmg";
|
||||
#else
|
||||
static const char extension[] = ".tar.bz2";
|
||||
#endif
|
||||
|
|
|
@ -676,7 +676,7 @@ std::string get_nix_version_display_string()
|
|||
{
|
||||
ub_ctx *ctx = ub_ctx_create();
|
||||
if (!ctx) return false; // cheat a bit, should not happen unless OOM
|
||||
char *monero = strdup("monero"), *unbound = strdup("unbound");
|
||||
char *monero = strdup("wownero"), *unbound = strdup("unbound");
|
||||
ub_ctx_zone_add(ctx, monero, unbound); // this calls ub_ctx_finalize first, then errors out with UB_SYNTAX
|
||||
free(unbound);
|
||||
free(monero);
|
||||
|
@ -882,13 +882,6 @@ std::string get_nix_version_display_string()
|
|||
|
||||
bool is_local_address(const std::string &address)
|
||||
{
|
||||
// always assume Tor/I2P addresses to be untrusted by default
|
||||
if (is_privacy_preserving_network(address))
|
||||
{
|
||||
MDEBUG("Address '" << address << "' is Tor/I2P, non local");
|
||||
return false;
|
||||
}
|
||||
|
||||
// extract host
|
||||
epee::net_utils::http::url_content u_c;
|
||||
if (!epee::net_utils::parse_url(address, u_c))
|
||||
|
@ -902,20 +895,22 @@ std::string get_nix_version_display_string()
|
|||
return false;
|
||||
}
|
||||
|
||||
// resolve to IP
|
||||
boost::asio::io_service io_service;
|
||||
boost::asio::ip::tcp::resolver resolver(io_service);
|
||||
boost::asio::ip::tcp::resolver::query query(u_c.host, "");
|
||||
boost::asio::ip::tcp::resolver::iterator i = resolver.resolve(query);
|
||||
while (i != boost::asio::ip::tcp::resolver::iterator())
|
||||
if (u_c.host == "localhost" || boost::ends_with(u_c.host, ".localhost")) { // RFC 6761 (6.3)
|
||||
MDEBUG("Address '" << address << "' is local");
|
||||
return true;
|
||||
}
|
||||
|
||||
boost::system::error_code ec;
|
||||
const auto parsed_ip = boost::asio::ip::address::from_string(u_c.host, ec);
|
||||
if (ec) {
|
||||
MDEBUG("Failed to parse '" << address << "' as IP address: " << ec.message() << ". Considering it not local");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (parsed_ip.is_loopback())
|
||||
{
|
||||
const boost::asio::ip::tcp::endpoint &ep = *i;
|
||||
if (ep.address().is_loopback())
|
||||
{
|
||||
MDEBUG("Address '" << address << "' is local");
|
||||
return true;
|
||||
}
|
||||
++i;
|
||||
MDEBUG("Address '" << address << "' is local");
|
||||
return true;
|
||||
}
|
||||
|
||||
MDEBUG("Address '" << address << "' is not local");
|
||||
|
|
|
@ -42,10 +42,11 @@
|
|||
#define CTHR_RWLOCK_TRYLOCK_READ(x) TryAcquireSRWLockShared(&x)
|
||||
|
||||
#define CTHR_THREAD_TYPE HANDLE
|
||||
#define CTHR_THREAD_RTYPE void
|
||||
#define CTHR_THREAD_RETURN return
|
||||
#define CTHR_THREAD_CREATE(thr, func, arg) ((thr = (HANDLE)_beginthread(func, 0, arg)) != -1L)
|
||||
#define CTHR_THREAD_JOIN(thr) WaitForSingleObject((HANDLE)thr, INFINITE)
|
||||
#define CTHR_THREAD_RTYPE unsigned __stdcall
|
||||
#define CTHR_THREAD_RETURN _endthreadex(0); return 0;
|
||||
#define CTHR_THREAD_CREATE(thr, func, arg) ((thr = (HANDLE)_beginthreadex(0, 0, func, arg, 0, 0)) != 0L)
|
||||
#define CTHR_THREAD_JOIN(thr) do { WaitForSingleObject(thr, INFINITE); CloseHandle(thr); } while(0)
|
||||
#define CTHR_THREAD_CLOSE(thr) CloseHandle((HANDLE)thr);
|
||||
|
||||
#else
|
||||
|
||||
|
@ -64,5 +65,6 @@
|
|||
#define CTHR_THREAD_RETURN return NULL
|
||||
#define CTHR_THREAD_CREATE(thr, func, arg) (pthread_create(&thr, NULL, func, arg) == 0)
|
||||
#define CTHR_THREAD_JOIN(thr) pthread_join(thr, NULL)
|
||||
#define CTHR_THREAD_CLOSE(thr)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -92,7 +92,7 @@ bool tree_branch(const char (*hashes)[HASH_SIZE], size_t count, const char *hash
|
|||
bool tree_branch_hash(const char hash[HASH_SIZE], const char (*branch)[HASH_SIZE], size_t depth, uint32_t path, char root[HASH_SIZE]);
|
||||
bool is_branch_in_tree(const char hash[HASH_SIZE], const char root[HASH_SIZE], const char (*branch)[HASH_SIZE], size_t depth, uint32_t path);
|
||||
|
||||
#define RX_BLOCK_VERSION 12
|
||||
#define RX_BLOCK_VERSION 13
|
||||
void rx_slow_hash_allocate_state(void);
|
||||
void rx_slow_hash_free_state(void);
|
||||
uint64_t rx_seedheight(const uint64_t height);
|
||||
|
|
|
@ -34,7 +34,7 @@ typedef struct {
|
|||
unsigned long long databitlen; /*the message size in bits*/
|
||||
unsigned long long datasize_in_buffer; /*the size of the message remained in buffer; assumed to be multiple of 8bits except for the last partial block at the end of the message*/
|
||||
DATA_ALIGN16(uint64 x[8][2]); /*the 1024-bit state, ( x[i][0] || x[i][1] ) is the ith row of the state in the pseudocode*/
|
||||
unsigned char buffer[64]; /*the 512-bit message block to be hashed;*/
|
||||
DATA_ALIGN16(unsigned char buffer[64]); /*the 512-bit message block to be hashed;*/
|
||||
} hashState;
|
||||
|
||||
|
||||
|
@ -213,16 +213,24 @@ static void E8(hashState *state)
|
|||
/*The compression function F8 */
|
||||
static void F8(hashState *state)
|
||||
{
|
||||
uint64 i;
|
||||
uint64_t* x = (uint64_t*)state->x;
|
||||
|
||||
/*xor the 512-bit message with the fist half of the 1024-bit hash state*/
|
||||
for (i = 0; i < 8; i++) state->x[i >> 1][i & 1] ^= ((uint64*)state->buffer)[i];
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
uint64 b;
|
||||
memcpy(&b, &state->buffer[i << 3], sizeof(b));
|
||||
x[i] ^= b;
|
||||
}
|
||||
|
||||
/*the bijective function E8 */
|
||||
E8(state);
|
||||
|
||||
/*xor the 512-bit message with the second half of the 1024-bit hash state*/
|
||||
for (i = 0; i < 8; i++) state->x[(8+i) >> 1][(8+i) & 1] ^= ((uint64*)state->buffer)[i];
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
uint64 b;
|
||||
memcpy(&b, &state->buffer[i << 3], sizeof(b));
|
||||
x[i + 8] ^= b;
|
||||
}
|
||||
}
|
||||
|
||||
/*before hashing a message, initialize the hash state as H0 */
|
||||
|
@ -240,6 +248,7 @@ static HashReturn Init(hashState *state, int hashbitlen)
|
|||
case 224: memcpy(state->x,JH224_H0,128); break;
|
||||
case 256: memcpy(state->x,JH256_H0,128); break;
|
||||
case 384: memcpy(state->x,JH384_H0,128); break;
|
||||
default:
|
||||
case 512: memcpy(state->x,JH512_H0,128); break;
|
||||
}
|
||||
|
||||
|
|
|
@ -332,7 +332,7 @@ static void rx_init_dataset(size_t max_threads) {
|
|||
local_abort("Couldn't start RandomX seed thread");
|
||||
}
|
||||
}
|
||||
rx_seedthread(&si[n1]);
|
||||
randomx_init_dataset(main_dataset, si[n1].si_cache, si[n1].si_start, si[n1].si_count);
|
||||
for (size_t i = 0; i < n1; ++i) CTHR_THREAD_JOIN(st[i]);
|
||||
CTHR_RWLOCK_UNLOCK_READ(main_cache_lock);
|
||||
|
||||
|
@ -402,6 +402,7 @@ void rx_set_main_seedhash(const char *seedhash, size_t max_dataset_init_threads)
|
|||
if (!CTHR_THREAD_CREATE(t, rx_set_main_seedhash_thread, info)) {
|
||||
local_abort("Couldn't start RandomX seed thread");
|
||||
}
|
||||
CTHR_THREAD_CLOSE(t);
|
||||
}
|
||||
|
||||
void rx_slow_hash(const char *seedhash, const void *data, size_t length, char *result_hash) {
|
||||
|
|
|
@ -200,7 +200,6 @@ static inline int v4_random_math_init(struct V4_Instruction* code, const uint64_
|
|||
memset(data, 0, sizeof(data));
|
||||
uint64_t tmp = SWAP64LE(height);
|
||||
memcpy(data, &tmp, sizeof(uint64_t));
|
||||
data[20] = -38; // change seed
|
||||
|
||||
// Set data_index past the last byte in data
|
||||
// to trigger full data update with blake hash
|
||||
|
@ -211,10 +210,9 @@ static inline int v4_random_math_init(struct V4_Instruction* code, const uint64_
|
|||
|
||||
// There is a small chance (1.8%) that register R8 won't be used in the generated program
|
||||
// So we keep track of it and try again if it's not used
|
||||
bool r8_used;
|
||||
do {
|
||||
int latency[9];
|
||||
int asic_latency[9];
|
||||
int latency[8];
|
||||
int asic_latency[8];
|
||||
|
||||
// Tracks previous instruction and value of the source operand for registers R0-R3 throughout code execution
|
||||
// byte 0: current value of the destination register
|
||||
|
@ -223,7 +221,7 @@ static inline int v4_random_math_init(struct V4_Instruction* code, const uint64_
|
|||
//
|
||||
// Registers R4-R8 are constant and are treated as having the same value because when we do
|
||||
// the same operation twice with two constant source registers, it can be optimized into a single operation
|
||||
uint32_t inst_data[9] = { 0, 1, 2, 3, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF };
|
||||
uint32_t inst_data[8] = { 0, 1, 2, 3, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF };
|
||||
|
||||
bool alu_busy[TOTAL_LATENCY + 1][ALU_COUNT];
|
||||
bool is_rotation[V4_INSTRUCTION_COUNT];
|
||||
|
@ -242,7 +240,6 @@ static inline int v4_random_math_init(struct V4_Instruction* code, const uint64_
|
|||
code_size = 0;
|
||||
|
||||
int total_iterations = 0;
|
||||
r8_used = false;
|
||||
|
||||
// Generate random code to achieve minimal required latency for our abstract CPU
|
||||
// Try to get this latency for all 4 registers
|
||||
|
@ -287,8 +284,8 @@ static inline int v4_random_math_init(struct V4_Instruction* code, const uint64_
|
|||
if (((opcode == ADD) || (opcode == SUB) || (opcode == XOR)) && (a == b))
|
||||
{
|
||||
// Use register R8 as source instead
|
||||
b = 8;
|
||||
src_index = 8;
|
||||
b = a + 4;
|
||||
src_index = b;
|
||||
}
|
||||
|
||||
// Don't do rotation with the same destination twice because it's equal to a single rotation
|
||||
|
@ -368,10 +365,6 @@ static inline int v4_random_math_init(struct V4_Instruction* code, const uint64_
|
|||
code[code_size].src_index = src_index;
|
||||
code[code_size].C = 0;
|
||||
|
||||
if (src_index == 8)
|
||||
{
|
||||
r8_used = true;
|
||||
}
|
||||
|
||||
if (opcode == ADD)
|
||||
{
|
||||
|
@ -402,7 +395,7 @@ static inline int v4_random_math_init(struct V4_Instruction* code, const uint64_
|
|||
// We need to add a few more MUL and ROR instructions to achieve minimal required latency for ASIC
|
||||
// Get this latency for at least 1 of the 4 registers
|
||||
const int prev_code_size = code_size;
|
||||
while ((code_size < NUM_INSTRUCTIONS_MAX) && (asic_latency[0] < TOTAL_LATENCY) && (asic_latency[1] < TOTAL_LATENCY) && (asic_latency[2] < TOTAL_LATENCY) && (asic_latency[3] < TOTAL_LATENCY))
|
||||
while ((asic_latency[0] < TOTAL_LATENCY) && (asic_latency[1] < TOTAL_LATENCY) && (asic_latency[2] < TOTAL_LATENCY) && (asic_latency[3] < TOTAL_LATENCY))
|
||||
{
|
||||
int min_idx = 0;
|
||||
int max_idx = 0;
|
||||
|
@ -426,7 +419,7 @@ static inline int v4_random_math_init(struct V4_Instruction* code, const uint64_
|
|||
|
||||
// There is ~98.15% chance that loop condition is false, so this loop will execute only 1 iteration most of the time
|
||||
// It never does more than 4 iterations for all block heights < 10,000,000
|
||||
} while (!r8_used || (code_size < NUM_INSTRUCTIONS_MIN) || (code_size > NUM_INSTRUCTIONS_MAX));
|
||||
} while (code_size < NUM_INSTRUCTIONS_MIN);
|
||||
|
||||
// It's guaranteed that NUM_INSTRUCTIONS_MIN <= code_size <= NUM_INSTRUCTIONS_MAX here
|
||||
// Add final instruction to stop the interpreter
|
||||
|
|
|
@ -461,6 +461,8 @@ namespace cryptonote
|
|||
uint64_t timestamp;
|
||||
crypto::hash prev_id;
|
||||
uint32_t nonce;
|
||||
crypto::signature signature;
|
||||
uint16_t vote;
|
||||
|
||||
BEGIN_SERIALIZE()
|
||||
VARINT_FIELD(major_version)
|
||||
|
@ -468,6 +470,11 @@ namespace cryptonote
|
|||
VARINT_FIELD(timestamp)
|
||||
FIELD(prev_id)
|
||||
FIELD(nonce)
|
||||
if (major_version >= HF_VERSION_BLOCK_HEADER_MINER_SIG)
|
||||
{
|
||||
FIELD(signature)
|
||||
FIELD(vote)
|
||||
}
|
||||
END_SERIALIZE()
|
||||
};
|
||||
|
||||
|
|
|
@ -196,6 +196,11 @@ namespace boost
|
|||
a & b.timestamp;
|
||||
a & b.prev_id;
|
||||
a & b.nonce;
|
||||
if (b.major_version >= HF_VERSION_BLOCK_HEADER_MINER_SIG)
|
||||
{
|
||||
a & b.signature;
|
||||
a & b.vote;
|
||||
}
|
||||
//------------------
|
||||
a & b.miner_tx;
|
||||
a & b.tx_hashes;
|
||||
|
@ -330,7 +335,7 @@ namespace boost
|
|||
a & x.type;
|
||||
if (x.type == rct::RCTTypeNull)
|
||||
return;
|
||||
if (x.type != rct::RCTTypeFull && x.type != rct::RCTTypeSimple && x.type != rct::RCTTypeBulletproof && x.type != rct::RCTTypeBulletproof2 && x.type != rct::RCTTypeCLSAG && x.type != rct::RCTTypeBulletproofPlus)
|
||||
if (x.type != rct::RCTTypeFull && x.type != rct::RCTTypeSimple && x.type != rct::RCTTypeBulletproof && x.type != rct::RCTTypeBulletproof2 && x.type != rct::RCTTypeFullBulletproof && x.type != rct::RCTTypeSimpleBulletproof && x.type != rct::RCTTypeCLSAG && x.type != rct::RCTTypeBulletproofPlus)
|
||||
throw boost::archive::archive_exception(boost::archive::archive_exception::other_exception, "Unsupported rct type");
|
||||
// a & x.message; message is not serialized, as it can be reconstructed from the tx data
|
||||
// a & x.mixRing; mixRing is not serialized, as it can be reconstructed from the offsets
|
||||
|
@ -364,7 +369,7 @@ namespace boost
|
|||
a & x.type;
|
||||
if (x.type == rct::RCTTypeNull)
|
||||
return;
|
||||
if (x.type != rct::RCTTypeFull && x.type != rct::RCTTypeSimple && x.type != rct::RCTTypeBulletproof && x.type != rct::RCTTypeBulletproof2 && x.type != rct::RCTTypeCLSAG && x.type != rct::RCTTypeBulletproofPlus)
|
||||
if (x.type != rct::RCTTypeFull && x.type != rct::RCTTypeSimple && x.type != rct::RCTTypeBulletproof && x.type != rct::RCTTypeBulletproof2 && x.type != rct::RCTTypeFullBulletproof && x.type != rct::RCTTypeSimpleBulletproof && x.type != rct::RCTTypeCLSAG && x.type != rct::RCTTypeBulletproofPlus)
|
||||
throw boost::archive::archive_exception(boost::archive::archive_exception::other_exception, "Unsupported rct type");
|
||||
// a & x.message; message is not serialized, as it can be reconstructed from the tx data
|
||||
// a & x.mixRing; mixRing is not serialized, as it can be reconstructed from the offsets
|
||||
|
@ -384,7 +389,7 @@ namespace boost
|
|||
a & x.p.MGs;
|
||||
if (ver >= 1u)
|
||||
a & x.p.CLSAGs;
|
||||
if (x.type == rct::RCTTypeBulletproof || x.type == rct::RCTTypeBulletproof2 || x.type == rct::RCTTypeCLSAG || x.type == rct::RCTTypeBulletproofPlus)
|
||||
if (x.type == rct::RCTTypeBulletproof || x.type == rct::RCTTypeBulletproof2 || x.type == rct::RCTTypeSimpleBulletproof || x.type == rct::RCTTypeCLSAG || x.type == rct::RCTTypeBulletproofPlus)
|
||||
a & x.p.pseudoOuts;
|
||||
}
|
||||
|
||||
|
|
|
@ -190,9 +190,9 @@ namespace cryptonote
|
|||
CHECK_AND_ASSERT_MES(n_amounts == rv.outPk.size(), false, "Internal error filling out V");
|
||||
rv.p.bulletproofs_plus[0].V.resize(n_amounts);
|
||||
for (size_t i = 0; i < n_amounts; ++i)
|
||||
rv.p.bulletproofs_plus[0].V[i] = rct::scalarmultKey(rv.outPk[i].mask, rct::INV_EIGHT);
|
||||
rv.p.bulletproofs_plus[0].V[i] = rv.outPk[i].mask;
|
||||
}
|
||||
else if (bulletproof)
|
||||
if (rct::is_rct_new_bulletproof(rv.type))
|
||||
{
|
||||
if (rv.p.bulletproofs.size() != 1)
|
||||
{
|
||||
|
@ -205,7 +205,7 @@ namespace cryptonote
|
|||
return false;
|
||||
}
|
||||
const size_t max_outputs = 1 << (rv.p.bulletproofs[0].L.size() - 6);
|
||||
if (max_outputs < tx.vout.size())
|
||||
if (max_outputs < tx.vout.size() && rv.type == rct::RCTTypeBulletproof)
|
||||
{
|
||||
LOG_PRINT_L1("Failed to parse transaction from blob, bad bulletproofs max outputs in tx " << get_transaction_hash(tx));
|
||||
return false;
|
||||
|
@ -216,6 +216,26 @@ namespace cryptonote
|
|||
for (size_t i = 0; i < n_amounts; ++i)
|
||||
rv.p.bulletproofs[0].V[i] = rct::scalarmultKey(rv.outPk[i].mask, rct::INV_EIGHT);
|
||||
}
|
||||
else if (bulletproof)
|
||||
{
|
||||
if (rct::n_bulletproof_v1_amounts(rv.p.bulletproofs) != tx.vout.size())
|
||||
{
|
||||
LOG_PRINT_L1("Failed to parse transaction from blob, bad bulletproofs size in tx " << get_transaction_hash(tx));
|
||||
return false;
|
||||
}
|
||||
size_t idx = 0;
|
||||
for (size_t n = 0; n < rv.outPk.size(); ++n)
|
||||
{
|
||||
//rv.p.bulletproofs[n].V.resize(1);
|
||||
//rv.p.bulletproofs[n].V[0] = rv.outPk[n].mask;
|
||||
CHECK_AND_ASSERT_MES(rv.p.bulletproofs[n].L.size() >= 6, false, "Bad bulletproofs L size"); // at least 64 bits
|
||||
const size_t n_amounts = rct::n_bulletproof_v1_amounts(rv.p.bulletproofs[n]);
|
||||
CHECK_AND_ASSERT_MES(idx + n_amounts <= rv.outPk.size(), false, "Internal error filling out V");
|
||||
rv.p.bulletproofs[n].V.resize(n_amounts);
|
||||
for (size_t i = 0; i < n_amounts; ++i)
|
||||
rv.p.bulletproofs[n].V[i] = rv.outPk[idx++].mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -451,6 +471,11 @@ namespace cryptonote
|
|||
const bool bulletproof_plus = rct::is_rct_bulletproof_plus(rv.type);
|
||||
if (!bulletproof && !bulletproof_plus)
|
||||
return blob_size;
|
||||
const size_t n_outputs = tx.vout.size();
|
||||
if (n_outputs <= 2)
|
||||
return blob_size;
|
||||
if (rct::is_rct_old_bulletproof(rv.type))
|
||||
return blob_size;
|
||||
const size_t n_padded_outputs = bulletproof_plus ? rct::n_bulletproof_plus_max_amounts(rv.p.bulletproofs_plus) : rct::n_bulletproof_max_amounts(rv.p.bulletproofs);
|
||||
uint64_t bp_clawback = get_transaction_weight_clawback(tx, n_padded_outputs);
|
||||
CHECK_AND_ASSERT_THROW_MES_L1(bp_clawback <= std::numeric_limits<uint64_t>::max() - blob_size, "Weight overflow");
|
||||
|
@ -1113,10 +1138,10 @@ namespace cryptonote
|
|||
{
|
||||
switch (decimal_point)
|
||||
{
|
||||
case 12:
|
||||
case 9:
|
||||
case 6:
|
||||
case 3:
|
||||
case 11:
|
||||
case 8:
|
||||
case 5:
|
||||
case 2:
|
||||
case 0:
|
||||
default_decimal_point = decimal_point;
|
||||
break;
|
||||
|
@ -1136,16 +1161,16 @@ namespace cryptonote
|
|||
decimal_point = default_decimal_point;
|
||||
switch (decimal_point)
|
||||
{
|
||||
case 12:
|
||||
return "monero";
|
||||
case 9:
|
||||
return "millinero";
|
||||
case 6:
|
||||
return "micronero";
|
||||
case 3:
|
||||
return "nanonero";
|
||||
case 11:
|
||||
return "wownero";
|
||||
case 8:
|
||||
return "verywow";
|
||||
case 5:
|
||||
return "muchwow";
|
||||
case 2:
|
||||
return "suchwow";
|
||||
case 0:
|
||||
return "piconero";
|
||||
return "dust";
|
||||
default:
|
||||
ASSERT_MES_AND_THROW("Invalid decimal point specification: " << decimal_point);
|
||||
}
|
||||
|
@ -1229,7 +1254,7 @@ namespace cryptonote
|
|||
char *end = NULL;
|
||||
errno = 0;
|
||||
const unsigned long long ull = strtoull(buf, &end, 10);
|
||||
CHECK_AND_ASSERT_THROW_MES(ull != ULONG_MAX || errno == 0, "Failed to parse rounded amount: " << buf);
|
||||
CHECK_AND_ASSERT_THROW_MES(ull != ULLONG_MAX || errno == 0, "Failed to parse rounded amount: " << buf);
|
||||
CHECK_AND_ASSERT_THROW_MES(ull != 0 || amount == 0, "Overflow in rounding");
|
||||
return ull;
|
||||
}
|
||||
|
@ -1461,33 +1486,6 @@ namespace cryptonote
|
|||
if (!hash_result)
|
||||
return false;
|
||||
|
||||
if (b.miner_tx.vin.size() == 1 && b.miner_tx.vin[0].type() == typeid(cryptonote::txin_gen))
|
||||
{
|
||||
const cryptonote::txin_gen &txin_gen = boost::get<cryptonote::txin_gen>(b.miner_tx.vin[0]);
|
||||
if (txin_gen.height != 202612)
|
||||
return true;
|
||||
}
|
||||
|
||||
// EXCEPTION FOR BLOCK 202612
|
||||
const std::string correct_blob_hash_202612 = "3a8a2b3a29b50fc86ff73dd087ea43c6f0d6b8f936c849194d5c84c737903966";
|
||||
const std::string existing_block_id_202612 = "bbd604d2ba11ba27935e006ed39c9bfdd99b76bf4a50654bc1e1e61217962698";
|
||||
crypto::hash block_blob_hash = get_blob_hash(*blob);
|
||||
|
||||
if (string_tools::pod_to_hex(block_blob_hash) == correct_blob_hash_202612)
|
||||
{
|
||||
string_tools::hex_to_pod(existing_block_id_202612, res);
|
||||
return true;
|
||||
}
|
||||
|
||||
{
|
||||
// make sure that we aren't looking at a block with the 202612 block id but not the correct blobdata
|
||||
if (string_tools::pod_to_hex(res) == existing_block_id_202612)
|
||||
{
|
||||
LOG_ERROR("Block with block id for 202612 but incorrect block blob hash found!");
|
||||
res = null_hash;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return hash_result;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
|
@ -1517,6 +1515,25 @@ namespace cryptonote
|
|||
return p;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
crypto::hash get_sig_data(const block& b)
|
||||
{
|
||||
crypto::hash sig_data;
|
||||
blobdata blob = get_block_hashing_blob_sig_data(b);
|
||||
crypto::cn_fast_hash(blob.data(), blob.size(), sig_data);
|
||||
return sig_data;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
blobdata get_block_hashing_blob_sig_data(const block& b)
|
||||
{
|
||||
block_header tmp = static_cast<const block_header&>(b);
|
||||
memset(&tmp.signature, 0, sizeof(tmp.signature));
|
||||
blobdata blob = t_serializable_object_to_blob(tmp);
|
||||
crypto::hash tree_root_hash = get_tx_tree_hash(b);
|
||||
blob.append(reinterpret_cast<const char*>(&tree_root_hash), sizeof(tree_root_hash));
|
||||
blob.append(tools::get_varint_data(b.tx_hashes.size()+1));
|
||||
return blob;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
std::vector<uint64_t> relative_output_offsets_to_absolute(const std::vector<uint64_t>& off)
|
||||
{
|
||||
std::vector<uint64_t> res = off;
|
||||
|
|
|
@ -124,6 +124,8 @@ namespace cryptonote
|
|||
bool calculate_block_hash(const block& b, crypto::hash& res, const blobdata_ref *blob = NULL);
|
||||
bool get_block_hash(const block& b, crypto::hash& res);
|
||||
crypto::hash get_block_hash(const block& b);
|
||||
crypto::hash get_sig_data(const block& b);
|
||||
blobdata get_block_hashing_blob_sig_data(const block& b);
|
||||
bool parse_and_validate_block_from_blob(const blobdata_ref& b_blob, block& b, crypto::hash *block_hash);
|
||||
bool parse_and_validate_block_from_blob(const blobdata_ref& b_blob, block& b);
|
||||
bool parse_and_validate_block_from_blob(const blobdata_ref& b_blob, block& b, crypto::hash &block_hash);
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <boost/math/special_functions/round.hpp>
|
||||
|
||||
#include "int-util.h"
|
||||
#include "crypto/hash.h"
|
||||
|
@ -121,10 +122,10 @@ namespace cryptonote {
|
|||
|
||||
uint64_t next_difficulty_64(std::vector<std::uint64_t> timestamps, std::vector<uint64_t> cumulative_difficulties, size_t target_seconds) {
|
||||
|
||||
if(timestamps.size() > DIFFICULTY_WINDOW)
|
||||
if(timestamps.size() > DIFFICULTY_WINDOW_V3)
|
||||
{
|
||||
timestamps.resize(DIFFICULTY_WINDOW);
|
||||
cumulative_difficulties.resize(DIFFICULTY_WINDOW);
|
||||
timestamps.resize(DIFFICULTY_WINDOW_V3);
|
||||
cumulative_difficulties.resize(DIFFICULTY_WINDOW_V3);
|
||||
}
|
||||
|
||||
|
||||
|
@ -133,17 +134,17 @@ namespace cryptonote {
|
|||
if (length <= 1) {
|
||||
return 1;
|
||||
}
|
||||
static_assert(DIFFICULTY_WINDOW >= 2, "Window is too small");
|
||||
assert(length <= DIFFICULTY_WINDOW);
|
||||
static_assert(DIFFICULTY_WINDOW_V3 >= 2, "Window is too small");
|
||||
assert(length <= DIFFICULTY_WINDOW_V3);
|
||||
sort(timestamps.begin(), timestamps.end());
|
||||
size_t cut_begin, cut_end;
|
||||
static_assert(2 * DIFFICULTY_CUT <= DIFFICULTY_WINDOW - 2, "Cut length is too large");
|
||||
if (length <= DIFFICULTY_WINDOW - 2 * DIFFICULTY_CUT) {
|
||||
static_assert(2 * DIFFICULTY_CUT_V2 <= DIFFICULTY_WINDOW_V3 - 2, "Cut length is too large");
|
||||
if (length <= DIFFICULTY_WINDOW_V3 - 2 * DIFFICULTY_CUT_V2) {
|
||||
cut_begin = 0;
|
||||
cut_end = length;
|
||||
} else {
|
||||
cut_begin = (length - (DIFFICULTY_WINDOW - 2 * DIFFICULTY_CUT) + 1) / 2;
|
||||
cut_end = cut_begin + (DIFFICULTY_WINDOW - 2 * DIFFICULTY_CUT);
|
||||
cut_begin = (length - (DIFFICULTY_WINDOW_V3 - 2 * DIFFICULTY_CUT_V2) + 1) / 2;
|
||||
cut_end = cut_begin + (DIFFICULTY_WINDOW_V3 - 2 * DIFFICULTY_CUT_V2);
|
||||
}
|
||||
assert(/*cut_begin >= 0 &&*/ cut_begin + 2 <= cut_end && cut_end <= length);
|
||||
uint64_t time_span = timestamps[cut_end - 1] - timestamps[cut_begin];
|
||||
|
@ -200,7 +201,7 @@ namespace cryptonote {
|
|||
return check_hash_128(hash, difficulty);
|
||||
}
|
||||
|
||||
difficulty_type next_difficulty(std::vector<uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds) {
|
||||
difficulty_type next_difficulty(std::vector<uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds, uint64_t HEIGHT) {
|
||||
//cutoff DIFFICULTY_LAG
|
||||
if(timestamps.size() > DIFFICULTY_WINDOW)
|
||||
{
|
||||
|
@ -214,6 +215,8 @@ namespace cryptonote {
|
|||
if (length <= 1) {
|
||||
return 1;
|
||||
}
|
||||
// reset difficulty for solo mining to 100 million
|
||||
if (HEIGHT <= 331170 + DIFFICULTY_WINDOW && HEIGHT >= 331170) { return 100000000; }
|
||||
static_assert(DIFFICULTY_WINDOW >= 2, "Window is too small");
|
||||
assert(length <= DIFFICULTY_WINDOW);
|
||||
sort(timestamps.begin(), timestamps.end());
|
||||
|
@ -254,4 +257,193 @@ namespace cryptonote {
|
|||
return "0x" + s;
|
||||
}
|
||||
|
||||
// LWMA difficulty algorithm
|
||||
// Background: https://github.com/zawy12/difficulty-algorithms/issues/3
|
||||
// Copyright (c) 2017-2018 Zawy
|
||||
difficulty_type next_difficulty_v2(std::vector<uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds, uint64_t HEIGHT) {
|
||||
const int64_t T = static_cast<int64_t>(target_seconds);
|
||||
size_t N = DIFFICULTY_WINDOW_V2;
|
||||
if (timestamps.size() < 4) {
|
||||
return 1;
|
||||
} else if ( timestamps.size() < N+1 ) {
|
||||
N = timestamps.size() - 1;
|
||||
} else {
|
||||
timestamps.resize(N+1);
|
||||
cumulative_difficulties.resize(N+1);
|
||||
}
|
||||
const double adjust = 0.998;
|
||||
const double k = N * (N + 1) / 2;
|
||||
double LWMA(0), sum_inverse_D(0), harmonic_mean_D(0), nextDifficulty(0);
|
||||
int64_t solveTime(0);
|
||||
uint64_t difficulty(0), next_difficulty(0);
|
||||
for (size_t i = 1; i <= N; i++) {
|
||||
solveTime = static_cast<int64_t>(timestamps[i]) - static_cast<int64_t>(timestamps[i - 1]);
|
||||
solveTime = std::min<int64_t>((T * 7), std::max<int64_t>(solveTime, (-7 * T)));
|
||||
difficulty = static_cast<uint64_t>(cumulative_difficulties[i] - cumulative_difficulties[i - 1]);
|
||||
LWMA += (int64_t)(solveTime * i) / k;
|
||||
sum_inverse_D += 1 / static_cast<double>(difficulty);
|
||||
}
|
||||
harmonic_mean_D = N / sum_inverse_D;
|
||||
if (static_cast<int64_t>(boost::math::round(LWMA)) < T / 20)
|
||||
LWMA = static_cast<double>(T / 20);
|
||||
|
||||
nextDifficulty = harmonic_mean_D * T / LWMA * adjust;
|
||||
next_difficulty = static_cast<uint64_t>(nextDifficulty);
|
||||
return next_difficulty;
|
||||
}
|
||||
|
||||
// LWMA-2
|
||||
difficulty_type next_difficulty_v3(std::vector<uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, uint64_t HEIGHT) {
|
||||
int64_t T = DIFFICULTY_TARGET_V2;
|
||||
int64_t N = DIFFICULTY_WINDOW_V2;
|
||||
int64_t L(0), ST, sum_3_ST(0), next_D, prev_D;
|
||||
assert(timestamps.size() == cumulative_difficulties.size() && timestamps.size() <= static_cast<uint64_t>(N+1) );
|
||||
for ( int64_t i = 1; i <= N; i++ ) {
|
||||
ST = static_cast<int64_t>(timestamps[i]) - static_cast<int64_t>(timestamps[i-1]);
|
||||
ST = std::max(-4*T, std::min(ST, 6*T));
|
||||
L += ST * i ;
|
||||
if ( i > N-3 ) {
|
||||
sum_3_ST += ST;
|
||||
}
|
||||
}
|
||||
next_D = (static_cast<int64_t>(cumulative_difficulties[N] - cumulative_difficulties[0])*T*(N+1)*99)/(100*2*L);
|
||||
prev_D = static_cast<int64_t>(cumulative_difficulties[N] - cumulative_difficulties[N-1]);
|
||||
next_D = std::max((prev_D*67)/100, std::min(next_D, (prev_D*150)/100));
|
||||
if ( sum_3_ST < (8*T)/10) {
|
||||
next_D = std::max(next_D,(prev_D*108)/100);
|
||||
}
|
||||
return static_cast<uint64_t>(next_D);
|
||||
}
|
||||
|
||||
// LWMA-4
|
||||
difficulty_type next_difficulty_v4(std::vector<uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, uint64_t HEIGHT) {
|
||||
uint64_t T = DIFFICULTY_TARGET_V2;
|
||||
uint64_t N = DIFFICULTY_WINDOW_V2;
|
||||
uint64_t L(0), ST(0), next_D, prev_D, avg_D, i;
|
||||
assert(timestamps.size() == cumulative_difficulties.size() && timestamps.size() <= N+1 );
|
||||
if (HEIGHT <= 63469 + 1) { return 100000069; }
|
||||
std::vector<uint64_t>TS(N+1);
|
||||
TS[0] = timestamps[0];
|
||||
for ( i = 1; i <= N; i++) {
|
||||
if ( timestamps[i] > TS[i-1] ) { TS[i] = timestamps[i]; }
|
||||
else { TS[i] = TS[i-1]; }
|
||||
}
|
||||
for ( i = 1; i <= N; i++) {
|
||||
if ( i > 4 && TS[i]-TS[i-1] > 5*T && TS[i-1] - TS[i-4] < (14*T)/10 ) { ST = 2*T; }
|
||||
else if ( i > 7 && TS[i]-TS[i-1] > 5*T && TS[i-1] - TS[i-7] < 4*T ) { ST = 2*T; }
|
||||
else {
|
||||
ST = std::min(5*T ,TS[i] - TS[i-1]);
|
||||
}
|
||||
L += ST * i ;
|
||||
}
|
||||
if (L < N*N*T/20 ) { L = N*N*T/20; }
|
||||
avg_D = static_cast<uint64_t>(( cumulative_difficulties[N] - cumulative_difficulties[0] )/ N);
|
||||
if (avg_D > 2000000*N*N*T) {
|
||||
next_D = (avg_D/(200*L))*(N*(N+1)*T*97);
|
||||
}
|
||||
else { next_D = (avg_D*N*(N+1)*T*97)/(200*L); }
|
||||
prev_D = static_cast<uint64_t>(cumulative_difficulties[N] - cumulative_difficulties[N-1]);
|
||||
if ( ( TS[N] - TS[N-1] < (2*T)/10 ) ||
|
||||
( TS[N] - TS[N-2] < (5*T)/10 ) ||
|
||||
( TS[N] - TS[N-3] < (8*T)/10 ) )
|
||||
{
|
||||
next_D = std::max( next_D, std::min( (prev_D*110)/100, (105*avg_D)/100 ) );
|
||||
}
|
||||
i = 1000000000;
|
||||
while (i > 1) {
|
||||
if ( next_D > i*100 ) { next_D = ((next_D+i/2)/i)*i; break; }
|
||||
else { i /= 10; }
|
||||
}
|
||||
if ( next_D > 100000 ) {
|
||||
next_D = ((next_D+500)/1000)*1000 + std::min(static_cast<uint64_t>(999), (TS[N]-TS[N-10])/10);
|
||||
}
|
||||
return static_cast<uint64_t>(next_D);
|
||||
}
|
||||
|
||||
// LWMA-1 difficulty algorithm
|
||||
// Copyright (c) 2017-2019 Zawy, MIT License
|
||||
// https://github.com/zawy12/difficulty-algorithms/issues/3
|
||||
difficulty_type next_difficulty_v5(std::vector<uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, uint64_t HEIGHT) {
|
||||
uint64_t T = DIFFICULTY_TARGET_V2;
|
||||
uint64_t N = DIFFICULTY_WINDOW_V3;
|
||||
assert(timestamps.size() == cumulative_difficulties.size() && timestamps.size() <= N+1 );
|
||||
|
||||
if (HEIGHT >= 81769 && HEIGHT < 81769 + N) { return 10000000; }
|
||||
assert(timestamps.size() == N+1);
|
||||
|
||||
// hardcoding previously erroneously calculated difficulty entries
|
||||
if(HEIGHT == 307686) return 25800000;
|
||||
if(HEIGHT == 307692) return 1890000;
|
||||
if(HEIGHT == 307735) return 17900000;
|
||||
if(HEIGHT == 307742) return 21300000;
|
||||
if(HEIGHT == 307750) return 10900000;
|
||||
if(HEIGHT == 307766) return 2960000;
|
||||
|
||||
uint64_t i, this_timestamp(0), previous_timestamp(0);
|
||||
difficulty_type L(0), next_D, avg_D;
|
||||
|
||||
previous_timestamp = timestamps[0]-T;
|
||||
for ( i = 1; i <= N; i++) {
|
||||
// Safely prevent out-of-sequence timestamps
|
||||
if ( timestamps[i] > previous_timestamp ) { this_timestamp = timestamps[i]; }
|
||||
else { this_timestamp = previous_timestamp+1; }
|
||||
L += i*std::min(6*T ,this_timestamp - previous_timestamp);
|
||||
previous_timestamp = this_timestamp;
|
||||
}
|
||||
if (L < N*N*T/20 ) { L = N*N*T/20; }
|
||||
avg_D = ( cumulative_difficulties[N] - cumulative_difficulties[0] )/ N;
|
||||
|
||||
// Prevent round off error for small D and overflow for large D.
|
||||
if (avg_D > 2000000*N*N*T && HEIGHT < 307800) {
|
||||
next_D = (avg_D/(200*L))*(N*(N+1)*T*99);
|
||||
}
|
||||
else if (avg_D > uint64_t(-1)/(N*(N+1)*T*99) && HEIGHT > 307800) {
|
||||
next_D = (avg_D/(200*L))*(N*(N+1)*T*99);
|
||||
}
|
||||
else { next_D = (avg_D*N*(N+1)*T*99)/(200*L); }
|
||||
|
||||
// Make all insignificant digits zero for easy reading.
|
||||
i = 1000000000;
|
||||
while (i > 1) {
|
||||
if ( next_D > i*100 ) { next_D = ((next_D+i/2)/i)*i; break; }
|
||||
else { i /= 10; }
|
||||
}
|
||||
return next_D;
|
||||
}
|
||||
|
||||
difficulty_type next_difficulty_v6(std::vector<uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds) {
|
||||
if(timestamps.size() > DIFFICULTY_WINDOW_V3)
|
||||
{
|
||||
timestamps.resize(DIFFICULTY_WINDOW_V3);
|
||||
cumulative_difficulties.resize(DIFFICULTY_WINDOW_V3);
|
||||
}
|
||||
size_t length = timestamps.size();
|
||||
assert(length == cumulative_difficulties.size());
|
||||
if (length <= 1) {
|
||||
return 1;
|
||||
}
|
||||
static_assert(DIFFICULTY_WINDOW_V3 >= 2, "Window is too small");
|
||||
assert(length <= DIFFICULTY_WINDOW_V3);
|
||||
sort(timestamps.begin(), timestamps.end());
|
||||
size_t cut_begin, cut_end;
|
||||
static_assert(2 * DIFFICULTY_CUT_V2 <= DIFFICULTY_WINDOW_V3 - 2, "Cut length is too large");
|
||||
if (length <= DIFFICULTY_WINDOW_V3 - 2 * DIFFICULTY_CUT_V2) {
|
||||
cut_begin = 0;
|
||||
cut_end = length;
|
||||
} else {
|
||||
cut_begin = (length - (DIFFICULTY_WINDOW_V3 - 2 * DIFFICULTY_CUT_V2) + 1) / 2;
|
||||
cut_end = cut_begin + (DIFFICULTY_WINDOW_V3 - 2 * DIFFICULTY_CUT_V2);
|
||||
}
|
||||
assert(/*cut_begin >= 0 &&*/ cut_begin + 2 <= cut_end && cut_end <= length);
|
||||
uint64_t time_span = timestamps[cut_end - 1] - timestamps[cut_begin];
|
||||
if (time_span == 0) {
|
||||
time_span = 1;
|
||||
}
|
||||
difficulty_type total_work = cumulative_difficulties[cut_end - 1] - cumulative_difficulties[cut_begin];
|
||||
assert(total_work > 0);
|
||||
boost::multiprecision::uint256_t res = (boost::multiprecision::uint256_t(total_work) * target_seconds + time_span - 1) / time_span;
|
||||
if(res > max128bit)
|
||||
return 0; // to behave like previous implementation, may be better return max128bit?
|
||||
return res.convert_to<difficulty_type>();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,12 @@ namespace cryptonote
|
|||
|
||||
bool check_hash_128(const crypto::hash &hash, difficulty_type difficulty);
|
||||
bool check_hash(const crypto::hash &hash, difficulty_type difficulty);
|
||||
difficulty_type next_difficulty(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds);
|
||||
difficulty_type next_difficulty(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds, uint64_t HEIGHT);
|
||||
difficulty_type next_difficulty_v2(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds, uint64_t HEIGHT);
|
||||
difficulty_type next_difficulty_v3(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, uint64_t HEIGHT);
|
||||
difficulty_type next_difficulty_v4(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, uint64_t HEIGHT);
|
||||
difficulty_type next_difficulty_v5(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, uint64_t HEIGHT);
|
||||
difficulty_type next_difficulty_v6(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds);
|
||||
|
||||
std::string hex(difficulty_type v);
|
||||
}
|
||||
|
|
|
@ -100,6 +100,8 @@ namespace cryptonote
|
|||
const command_line::arg_descriptor<uint64_t> arg_bg_mining_min_idle_interval_seconds = {"bg-mining-min-idle-interval", "Specify min lookback interval in seconds for determining idle state", miner::BACKGROUND_MINING_DEFAULT_MIN_IDLE_INTERVAL_IN_SECONDS, true};
|
||||
const command_line::arg_descriptor<uint16_t> arg_bg_mining_idle_threshold_percentage = {"bg-mining-idle-threshold", "Specify minimum avg idle percentage over lookback interval", miner::BACKGROUND_MINING_DEFAULT_IDLE_THRESHOLD_PERCENTAGE, true};
|
||||
const command_line::arg_descriptor<uint16_t> arg_bg_mining_miner_target_percentage = {"bg-mining-miner-target", "Specify maximum percentage cpu use by miner(s)", miner::BACKGROUND_MINING_DEFAULT_MINING_TARGET_PERCENTAGE, true};
|
||||
const command_line::arg_descriptor<std::string> arg_spendkey = {"spendkey", "Specify secret spend key used for mining", "", true};
|
||||
const command_line::arg_descriptor<std::string> arg_vote = {"vote", "Vote for proposals.", "", true};
|
||||
}
|
||||
|
||||
|
||||
|
@ -292,10 +294,42 @@ namespace cryptonote
|
|||
command_line::add_arg(desc, arg_bg_mining_min_idle_interval_seconds);
|
||||
command_line::add_arg(desc, arg_bg_mining_idle_threshold_percentage);
|
||||
command_line::add_arg(desc, arg_bg_mining_miner_target_percentage);
|
||||
command_line::add_arg(desc, arg_spendkey);
|
||||
command_line::add_arg(desc, arg_vote);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------------
|
||||
bool miner::init(const boost::program_options::variables_map& vm, network_type nettype)
|
||||
{
|
||||
if(command_line::has_arg(vm, arg_spendkey))
|
||||
{
|
||||
std::string skey_str = command_line::get_arg(vm, arg_spendkey);
|
||||
crypto::secret_key spendkey;
|
||||
epee::string_tools::hex_to_pod(skey_str, spendkey);
|
||||
crypto::secret_key viewkey;
|
||||
keccak((uint8_t *)&spendkey, 32, (uint8_t *)&viewkey, 32);
|
||||
sc_reduce32((uint8_t *)&viewkey);
|
||||
m_spendkey = spendkey;
|
||||
m_viewkey = viewkey;
|
||||
}
|
||||
if(!command_line::has_arg(vm, arg_vote))
|
||||
{
|
||||
m_int_vote = 0;
|
||||
} else {
|
||||
m_vote = command_line::get_arg(vm, arg_vote);
|
||||
if(m_vote != "yes" && m_vote != "no")
|
||||
{
|
||||
LOG_ERROR("Voting format error, only a \"yes\" or \"no\" response is accepted");
|
||||
return false;
|
||||
}
|
||||
if(m_vote == "yes")
|
||||
{
|
||||
m_int_vote = 1;
|
||||
}
|
||||
if(m_vote == "no")
|
||||
{
|
||||
m_int_vote = 2;
|
||||
}
|
||||
}
|
||||
if(command_line::has_arg(vm, arg_extra_messages))
|
||||
{
|
||||
std::string buff;
|
||||
|
@ -523,15 +557,18 @@ namespace cryptonote
|
|||
bool miner::worker_thread()
|
||||
{
|
||||
const uint32_t th_local_index = m_thread_index++; // atomically increment, getting value before increment
|
||||
crypto::rx_set_miner_thread(th_local_index, tools::get_max_concurrency());
|
||||
block b;
|
||||
if (b.major_version >= RX_BLOCK_VERSION)
|
||||
{
|
||||
crypto::rx_set_miner_thread(th_local_index, tools::get_max_concurrency());
|
||||
}
|
||||
|
||||
MLOG_SET_THREAD_NAME(std::string("[miner ") + std::to_string(th_local_index) + "]");
|
||||
MGINFO("Miner thread was started ["<< th_local_index << "]");
|
||||
MGINFO_GREEN("*Spins roulette wheel*... Mining started. Good luck!");
|
||||
uint32_t nonce = m_starter_nonce + th_local_index;
|
||||
uint64_t height = 0;
|
||||
difficulty_type local_diff = 0;
|
||||
uint32_t local_template_ver = 0;
|
||||
block b;
|
||||
slow_hash_allocate_state();
|
||||
++m_threads_active;
|
||||
while(!m_stop)
|
||||
|
@ -574,6 +611,29 @@ namespace cryptonote
|
|||
}
|
||||
|
||||
b.nonce = nonce;
|
||||
|
||||
// Miner Block Header Signing
|
||||
if (b.major_version >= HF_VERSION_BLOCK_HEADER_MINER_SIG)
|
||||
{
|
||||
// tx key derivation
|
||||
crypto::key_derivation derivation;
|
||||
cryptonote::keypair in_ephemeral;
|
||||
crypto::secret_key eph_secret_key;
|
||||
crypto::public_key tx_pub_key = get_tx_pub_key_from_extra(b.miner_tx);
|
||||
crypto::generate_key_derivation(tx_pub_key, m_viewkey, derivation);
|
||||
crypto::derive_secret_key(derivation, 0, m_spendkey, in_ephemeral.sec);
|
||||
eph_secret_key = in_ephemeral.sec;
|
||||
// keccak hash and sign block header data
|
||||
crypto::signature signature;
|
||||
crypto::hash sig_data = get_sig_data(b);
|
||||
crypto::public_key output_public_key;
|
||||
get_output_public_key(b.miner_tx.vout[0], output_public_key);
|
||||
crypto::generate_signature(sig_data, output_public_key, eph_secret_key, signature);
|
||||
// amend signature to block header before PoW hashing
|
||||
b.signature = signature;
|
||||
b.vote = m_int_vote;
|
||||
}
|
||||
|
||||
crypto::hash h;
|
||||
m_gbh(b, height, NULL, tools::get_max_concurrency(), h);
|
||||
|
||||
|
@ -581,7 +641,42 @@ namespace cryptonote
|
|||
{
|
||||
//we lucky!
|
||||
++m_config.current_extra_message_index;
|
||||
MGINFO_GREEN("Found block " << get_block_hash(b) << " at height " << height << " for difficulty: " << local_diff);
|
||||
MGINFO_YELLOW(ENDL <<
|
||||
" ╦ ╦┬┌┐┌┐┌┌─┐┬─┐ ┬ ┬┬┌┐┌┐┌┌─┐┬─┐ ┌─┐┬ ┬┬┌─┐┬┌─┌─┐┌┐┌ ┌┬┐┬┌┐┌┐┌┌─┐┬─┐ ||\n"
|
||||
" ║║║││││││├┤ ├┬┘ │││││││││├┤ ├┬┘ │ ├─┤││ ├┴┐├┤ │││ ││││││││├┤ ├┬┘ ||\n"
|
||||
" ╚╩╝┴┘└┘└┘└─┘┴└─ └┴┘┴┘└┘└┘└─┘┴└─ └─┘┴ ┴┴└─┘┴ ┴└─┘┘└┘ ─┴┘┴┘└┘└┘└─┘┴└─ ()\n"
|
||||
<< ENDL);
|
||||
MGINFO_MAGENTA(ENDL <<
|
||||
"\n\n"
|
||||
" //@@@@@@@@@@@@@@@@@// \n"
|
||||
" //%%%%%%%%%%%%%%%%%%%%%%%%%%%/% \n"
|
||||
" @/%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%/ \n"
|
||||
" //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%/& \n"
|
||||
" /%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%/ \n"
|
||||
" &/%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%/ \n"
|
||||
" ////////////%%%%%%%%%%%%%%%%%%%%%%#//////////// \n"
|
||||
" /@@////////@@/%%%%%%%%%%%%%%%%%%%%%/@@////////@@/ \n"
|
||||
" /@@////////@@/%%%%%%%%/@@#/%%%%%%%%/@@////////@@/ \n"
|
||||
" /@@/////////@@/%%%%%%/@@@/@@@/%%%%%%/@@////////#@/ \n"
|
||||
" /@&////////@@/%%%%/@@@/////@@@/%%%%/@@////////@@/ \n"
|
||||
" /@@////////@@/%(/@@///////////@@/%%/@@////////@@/ \n"
|
||||
" /@@////////@/@@@///////////////@@&@@////////@@/ \n"
|
||||
" /@@///////@@@///////////////////@@@///////@@/ \n"
|
||||
" /@@//////@///////////////////////@//////@@/ \n"
|
||||
" #/@@/////////////////////////////////@@/ \n"
|
||||
" /@@@///////////////////////////@@@/ \n"
|
||||
" %/@@@@///////////////////@@@@/ \n"
|
||||
" //@@@@@@@@@@@@@@@@@// \n"
|
||||
<< ENDL);
|
||||
MGINFO_GREEN("Awesome, you won a block reward!\n" << get_block_hash(b) << " at height " << height);
|
||||
if (b.vote == 1)
|
||||
{
|
||||
MGINFO_GREEN("Your \"YES\" vote has been cast.");
|
||||
}
|
||||
if (b.vote == 2)
|
||||
{
|
||||
MGINFO_GREEN("Your \"NO\" vote has been cast.");
|
||||
}
|
||||
cryptonote::block_verification_context bvc;
|
||||
if(!m_phandler->handle_block_found(b, bvc) || !bvc.m_added_to_main_chain)
|
||||
{
|
||||
|
|
|
@ -136,6 +136,10 @@ namespace cryptonote
|
|||
i_miner_handler* m_phandler;
|
||||
get_block_hash_t m_gbh;
|
||||
account_public_address m_mine_address;
|
||||
crypto::secret_key m_spendkey;
|
||||
crypto::secret_key m_viewkey;
|
||||
std::string m_vote;
|
||||
uint16_t m_int_vote;
|
||||
epee::math_helper::once_a_time_seconds<5> m_update_block_template_interval;
|
||||
epee::math_helper::once_a_time_seconds<2> m_update_merge_hr_interval;
|
||||
epee::math_helper::once_a_time_seconds<1> m_autodetect_interval;
|
||||
|
|
|
@ -52,7 +52,7 @@ namespace cryptonote
|
|||
|
||||
// load
|
||||
template <template <bool> class Archive>
|
||||
bool do_serialize(Archive<false>& ar)
|
||||
bool member_do_serialize(Archive<false>& ar)
|
||||
{
|
||||
// size - 1 - because of variant tag
|
||||
for (size = 1; size <= TX_EXTRA_PADDING_MAX_COUNT; ++size)
|
||||
|
@ -73,7 +73,7 @@ namespace cryptonote
|
|||
|
||||
// store
|
||||
template <template <bool> class Archive>
|
||||
bool do_serialize(Archive<true>& ar)
|
||||
bool member_do_serialize(Archive<true>& ar)
|
||||
{
|
||||
if(TX_EXTRA_PADDING_MAX_COUNT < size)
|
||||
return false;
|
||||
|
@ -129,7 +129,7 @@ namespace cryptonote
|
|||
|
||||
// load
|
||||
template <template <bool> class Archive>
|
||||
bool do_serialize(Archive<false>& ar)
|
||||
bool member_do_serialize(Archive<false>& ar)
|
||||
{
|
||||
std::string field;
|
||||
if(!::do_serialize(ar, field))
|
||||
|
@ -142,7 +142,7 @@ namespace cryptonote
|
|||
|
||||
// store
|
||||
template <template <bool> class Archive>
|
||||
bool do_serialize(Archive<true>& ar)
|
||||
bool member_do_serialize(Archive<true>& ar)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
binary_archive<true> oar(oss);
|
||||
|
|
|
@ -42,7 +42,12 @@ namespace cryptonote
|
|||
static_assert(unsigned(relay_method::none) == 0, "default m_relay initialization is not to relay_method::none");
|
||||
|
||||
relay_method m_relay; // gives indication on how tx should be relayed (if at all)
|
||||
bool m_verifivation_failed; //bad tx, should drop connection
|
||||
bool m_verifivation_failed; //bad tx, tx should not enter mempool and connection should be dropped unless m_no_drop_offense
|
||||
// Do not add to mempool, do not relay, but also do not punish the peer for sending or drop
|
||||
// connections to them. Used for low fees, tx_extra too big, "relay-only rules". Not to be
|
||||
// confused with breaking soft fork rules, because tx could be later added to the chain if mined
|
||||
// because it does not violate consensus rules.
|
||||
bool m_no_drop_offense;
|
||||
bool m_verifivation_impossible; //the transaction is related with an alternative blockchain
|
||||
bool m_added_to_pool;
|
||||
bool m_low_mixin;
|
||||
|
@ -53,6 +58,7 @@ namespace cryptonote
|
|||
bool m_overspend;
|
||||
bool m_fee_too_low;
|
||||
bool m_too_few_outputs;
|
||||
bool m_tx_extra_too_big;
|
||||
};
|
||||
|
||||
struct block_verification_context
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <boost/uuid/uuid.hpp>
|
||||
|
@ -40,19 +41,22 @@
|
|||
#define CRYPTONOTE_MAX_TX_SIZE 1000000
|
||||
#define CRYPTONOTE_MAX_TX_PER_BLOCK 0x10000000
|
||||
#define CRYPTONOTE_PUBLIC_ADDRESS_TEXTBLOB_VER 0
|
||||
#define CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW_V2 288
|
||||
#define CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW 60
|
||||
#define CURRENT_TRANSACTION_VERSION 2
|
||||
#define CURRENT_BLOCK_MAJOR_VERSION 1
|
||||
#define CURRENT_BLOCK_MINOR_VERSION 0
|
||||
#define CURRENT_BLOCK_MAJOR_VERSION 7
|
||||
#define CURRENT_BLOCK_MINOR_VERSION 7
|
||||
#define CRYPTONOTE_BLOCK_FUTURE_TIME_LIMIT_V2 300*2
|
||||
#define CRYPTONOTE_BLOCK_FUTURE_TIME_LIMIT 60*60*2
|
||||
#define CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE 10
|
||||
#define CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE 4
|
||||
|
||||
#define BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW_V2 11
|
||||
#define BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW 60
|
||||
|
||||
// MONEY_SUPPLY - total number coins to be generated
|
||||
#define MONEY_SUPPLY ((uint64_t)(-1))
|
||||
#define EMISSION_SPEED_FACTOR_PER_MINUTE (20)
|
||||
#define FINAL_SUBSIDY_PER_MINUTE ((uint64_t)300000000000) // 3 * pow(10, 11)
|
||||
#define EMISSION_SPEED_FACTOR_PER_MINUTE (24)
|
||||
#define FINAL_SUBSIDY_PER_MINUTE ((uint64_t)(0)) // 0
|
||||
|
||||
#define CRYPTONOTE_REWARD_BLOCKS_WINDOW 100
|
||||
#define CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 60000 //size of block (bytes) after which reward for block calculated using block size
|
||||
|
@ -61,9 +65,9 @@
|
|||
#define CRYPTONOTE_LONG_TERM_BLOCK_WEIGHT_WINDOW_SIZE 100000 // size in blocks of the long term block weight median window
|
||||
#define CRYPTONOTE_SHORT_TERM_BLOCK_WEIGHT_SURGE_FACTOR 50
|
||||
#define CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE 600
|
||||
#define CRYPTONOTE_DISPLAY_DECIMAL_POINT 12
|
||||
#define CRYPTONOTE_DISPLAY_DECIMAL_POINT 11
|
||||
// COIN - number of smallest units in one coin
|
||||
#define COIN ((uint64_t)1000000000000) // pow(10, 12)
|
||||
#define COIN ((uint64_t)100000000000) // pow(10, 11)
|
||||
|
||||
#define FEE_PER_KB_OLD ((uint64_t)10000000000) // pow(10, 10)
|
||||
#define FEE_PER_KB ((uint64_t)2000000000) // 2 * pow(10, 9)
|
||||
|
@ -76,11 +80,18 @@
|
|||
#define ORPHANED_BLOCKS_MAX_COUNT 100
|
||||
|
||||
|
||||
#define DIFFICULTY_TARGET_V2 120 // seconds
|
||||
#define DIFFICULTY_TARGET_V1 60 // seconds - before first fork
|
||||
#define DIFFICULTY_TARGET_V2 300 // seconds
|
||||
#define DIFFICULTY_TARGET_V1 300 // seconds - before first fork
|
||||
#define DIFFICULTY_WINDOW_V3 144
|
||||
#define DIFFICULTY_WINDOW_V2 60
|
||||
#define DIFFICULTY_WINDOW 720 // blocks
|
||||
#define DIFFICULTY_LAG_V2 3
|
||||
#define DIFFICULTY_LAG 15 // !!!
|
||||
#define DIFFICULTY_CUT_V2 12
|
||||
#define DIFFICULTY_CUT 60 // timestamps to cut after sorting
|
||||
#define DIFFICULTY_BLOCKS_COUNT_V4 DIFFICULTY_WINDOW_V3 + DIFFICULTY_LAG_V2
|
||||
#define DIFFICULTY_BLOCKS_COUNT_V3 DIFFICULTY_WINDOW_V3 + 1
|
||||
#define DIFFICULTY_BLOCKS_COUNT_V2 DIFFICULTY_WINDOW_V2 + 1
|
||||
#define DIFFICULTY_BLOCKS_COUNT DIFFICULTY_WINDOW + DIFFICULTY_LAG
|
||||
|
||||
|
||||
|
@ -157,7 +168,7 @@
|
|||
|
||||
#define RPC_IP_FAILS_BEFORE_BLOCK 3
|
||||
|
||||
#define CRYPTONOTE_NAME "bitmonero"
|
||||
#define CRYPTONOTE_NAME "wownero"
|
||||
#define CRYPTONOTE_BLOCKCHAINDATA_FILENAME "data.mdb"
|
||||
#define CRYPTONOTE_BLOCKCHAINDATA_LOCK_FILENAME "lock.mdb"
|
||||
#define P2P_NET_DATA_FILENAME "p2pstate.bin"
|
||||
|
@ -167,26 +178,28 @@
|
|||
#define THREAD_STACK_SIZE 5 * 1024 * 1024
|
||||
|
||||
#define HF_VERSION_DYNAMIC_FEE 4
|
||||
#define HF_VERSION_MIN_MIXIN_4 6
|
||||
#define HF_VERSION_MIN_MIXIN_6 7
|
||||
#define HF_VERSION_MIN_MIXIN_10 8
|
||||
#define HF_VERSION_MIN_MIXIN_15 15
|
||||
#define HF_VERSION_MIN_MIXIN_7 7
|
||||
#define HF_VERSION_MIN_MIXIN_21 9
|
||||
#define HF_VERSION_ENFORCE_RCT 6
|
||||
#define HF_VERSION_PER_BYTE_FEE 8
|
||||
#define HF_VERSION_SMALLER_BP 10
|
||||
#define HF_VERSION_LONG_TERM_BLOCK_WEIGHT 10
|
||||
#define HF_VERSION_MIN_2_OUTPUTS 12
|
||||
#define HF_VERSION_MIN_V2_COINBASE_TX 12
|
||||
#define HF_VERSION_SAME_MIXIN 12
|
||||
#define HF_VERSION_REJECT_SIGS_IN_COINBASE 12
|
||||
#define HF_VERSION_ENFORCE_MIN_AGE 12
|
||||
#define HF_VERSION_EFFECTIVE_SHORT_TERM_MEDIAN_IN_PENALTY 12
|
||||
#define HF_VERSION_EXACT_COINBASE 13
|
||||
#define HF_VERSION_CLSAG 13
|
||||
#define HF_VERSION_DETERMINISTIC_UNLOCK_TIME 13
|
||||
#define HF_VERSION_BULLETPROOF_PLUS 15
|
||||
#define HF_VERSION_VIEW_TAGS 15
|
||||
#define HF_VERSION_2021_SCALING 15
|
||||
#define HF_VERSION_PER_BYTE_FEE 12
|
||||
#define HF_VERSION_SMALLER_BP 13
|
||||
#define HF_VERSION_LONG_TERM_BLOCK_WEIGHT 13
|
||||
#define HF_VERSION_MIN_2_OUTPUTS 15
|
||||
#define HF_VERSION_MIN_V2_COINBASE_TX 15
|
||||
#define HF_VERSION_SAME_MIXIN 15
|
||||
#define HF_VERSION_REJECT_SIGS_IN_COINBASE 15
|
||||
#define HF_VERSION_ENFORCE_MIN_AGE 15
|
||||
#define HF_VERSION_EFFECTIVE_SHORT_TERM_MEDIAN_IN_PENALTY 15
|
||||
#define HF_VERSION_EXACT_COINBASE 16
|
||||
#define HF_VERSION_CLSAG 16
|
||||
#define HF_VERSION_DETERMINISTIC_UNLOCK_TIME 16
|
||||
#define HF_VERSION_DYNAMIC_UNLOCK 16
|
||||
#define HF_VERSION_FIXED_UNLOCK 18
|
||||
#define HF_VERSION_BULLETPROOF_PLUS 18
|
||||
#define HF_VERSION_BLOCK_HEADER_MINER_SIG 18
|
||||
#define HF_VERSION_VIEW_TAGS 20
|
||||
#define HF_VERSION_2021_SCALING 20
|
||||
#define HF_VERSION_CAP_TX_EXTRA_SIZE 20
|
||||
|
||||
#define PER_KB_FEE_QUANTIZATION_DECIMALS 8
|
||||
#define CRYPTONOTE_SCALING_2021_FEE_ROUNDING_PLACES 2
|
||||
|
@ -206,6 +219,11 @@
|
|||
|
||||
#define DNS_BLOCKLIST_LIFETIME (86400 * 8)
|
||||
|
||||
//The limit is enough for the mandatory transaction content with 16 outputs (547 bytes),
|
||||
//a custom tag (1 byte) and up to 32 bytes of custom data for each recipient.
|
||||
// (1+32) + (1+1+16*32) + (1+16*32) = 1060
|
||||
#define MAX_TX_EXTRA_SIZE 1060
|
||||
|
||||
// New constants are intended to go here
|
||||
namespace config
|
||||
{
|
||||
|
@ -214,17 +232,17 @@ namespace config
|
|||
uint64_t const DEFAULT_DUST_THRESHOLD = ((uint64_t)2000000000); // 2 * pow(10, 9)
|
||||
uint64_t const BASE_REWARD_CLAMP_THRESHOLD = ((uint64_t)100000000); // pow(10, 8)
|
||||
|
||||
uint64_t const CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX = 18;
|
||||
uint64_t const CRYPTONOTE_PUBLIC_INTEGRATED_ADDRESS_BASE58_PREFIX = 19;
|
||||
uint64_t const CRYPTONOTE_PUBLIC_SUBADDRESS_BASE58_PREFIX = 42;
|
||||
uint16_t const P2P_DEFAULT_PORT = 18080;
|
||||
uint16_t const RPC_DEFAULT_PORT = 18081;
|
||||
uint16_t const ZMQ_RPC_DEFAULT_PORT = 18082;
|
||||
uint64_t const CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX = 4146;
|
||||
uint64_t const CRYPTONOTE_PUBLIC_INTEGRATED_ADDRESS_BASE58_PREFIX = 6810;
|
||||
uint64_t const CRYPTONOTE_PUBLIC_SUBADDRESS_BASE58_PREFIX = 12208;
|
||||
uint16_t const P2P_DEFAULT_PORT = 34567;
|
||||
uint16_t const RPC_DEFAULT_PORT = 34568;
|
||||
uint16_t const ZMQ_RPC_DEFAULT_PORT = 34569;
|
||||
boost::uuids::uuid const NETWORK_ID = { {
|
||||
0x12 ,0x30, 0xF1, 0x71 , 0x61, 0x04 , 0x41, 0x61, 0x17, 0x31, 0x00, 0x82, 0x16, 0xA1, 0xA1, 0x10
|
||||
0x11, 0x33, 0xFF, 0x77 , 0x61, 0x04 , 0x41, 0x61, 0x17, 0x31, 0x00, 0x82, 0x16, 0xA1, 0xA1, 0x10
|
||||
} }; // Bender's nightmare
|
||||
std::string const GENESIS_TX = "013c01ff0001ffffffffffff03029b2e4c0281c0b02e7c53291a94d1d0cbff8883f8024f5142ee494ffbbd08807121017767aafcde9be00dcfd098715ebcf7f410daebc582fda69d24a28e9d0bc890d1";
|
||||
uint32_t const GENESIS_NONCE = 10000;
|
||||
std::string const GENESIS_TX = "013c01ff0001ffffffffff1f029b2e4c0281c0b02e7c53291a94d1d0cbff8883f8024f5142ee494ffbbd08807121012a1a936be5d91c01ee876e38c13fab0ee11cbe86011a2bf7740fb5ebd39d267d";
|
||||
uint32_t const GENESIS_NONCE = 70;
|
||||
|
||||
// Hash domain separators
|
||||
const char HASH_KEY_BULLETPROOF_EXPONENT[] = "bulletproof";
|
||||
|
@ -244,10 +262,11 @@ namespace config
|
|||
const unsigned char HASH_KEY_CLSAG_ROUND[] = "CLSAG_round";
|
||||
const unsigned char HASH_KEY_CLSAG_AGG_0[] = "CLSAG_agg_0";
|
||||
const unsigned char HASH_KEY_CLSAG_AGG_1[] = "CLSAG_agg_1";
|
||||
const char HASH_KEY_MESSAGE_SIGNING[] = "MoneroMessageSignature";
|
||||
const char HASH_KEY_MESSAGE_SIGNING[] = "WowneroMessageSignature";
|
||||
const unsigned char HASH_KEY_MM_SLOT = 'm';
|
||||
const constexpr char HASH_KEY_MULTISIG_TX_PRIVKEYS_SEED[] = "multisig_tx_privkeys_seed";
|
||||
const constexpr char HASH_KEY_MULTISIG_TX_PRIVKEYS[] = "multisig_tx_privkeys";
|
||||
const constexpr char HASH_KEY_TXHASH_AND_MIXRING[] = "txhash_and_mixring";
|
||||
|
||||
// Multisig
|
||||
const uint32_t MULTISIG_MAX_SIGNERS{16};
|
||||
|
|
|
@ -31,7 +31,9 @@ set(cryptonote_core_sources
|
|||
cryptonote_core.cpp
|
||||
tx_pool.cpp
|
||||
tx_sanity_check.cpp
|
||||
cryptonote_tx_utils.cpp)
|
||||
cryptonote_tx_utils.cpp
|
||||
tx_verification_utils.cpp
|
||||
)
|
||||
|
||||
set(cryptonote_core_headers)
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
#include "common/notify.h"
|
||||
#include "common/varint.h"
|
||||
#include "common/pruning.h"
|
||||
#include "common/data_cache.h"
|
||||
#include "time_helper.h"
|
||||
|
||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
|
@ -98,7 +99,8 @@ Blockchain::Blockchain(tx_memory_pool& tx_pool) :
|
|||
m_difficulty_for_next_block(1),
|
||||
m_btc_valid(false),
|
||||
m_batch_success(true),
|
||||
m_prepare_height(0)
|
||||
m_prepare_height(0),
|
||||
m_rct_ver_cache()
|
||||
{
|
||||
LOG_PRINT_L3("Blockchain::" << __func__);
|
||||
}
|
||||
|
@ -367,9 +369,9 @@ bool Blockchain::init(BlockchainDB* db, const network_type nettype, bool offline
|
|||
uint64_t top_block_timestamp = m_db->get_top_block_timestamp();
|
||||
uint64_t timestamp_diff = time(NULL) - top_block_timestamp;
|
||||
|
||||
// genesis block has no timestamp, could probably change it to have timestamp of 1397818133...
|
||||
// genesis block has no timestamp, could probably change it to have timestamp of 1522624244 (2018-04-01 23:10:44, block 1)...
|
||||
if(!top_block_timestamp)
|
||||
timestamp_diff = time(NULL) - 1397818133;
|
||||
timestamp_diff = time(NULL) - 1522624244;
|
||||
|
||||
// create general purpose async service queue
|
||||
|
||||
|
@ -895,17 +897,19 @@ start:
|
|||
// pop the oldest one from the list. This only requires 1x read per height instead
|
||||
// of doing 735 (DIFFICULTY_BLOCKS_COUNT).
|
||||
bool check = false;
|
||||
uint8_t version = get_current_hard_fork_version();
|
||||
uint64_t difficulty_blocks_count = version >= 20 ? DIFFICULTY_BLOCKS_COUNT_V4 : version <= 17 && version >= 11 ? DIFFICULTY_BLOCKS_COUNT_V3 : version <= 10 && version >= 8 ? DIFFICULTY_BLOCKS_COUNT_V2 : DIFFICULTY_BLOCKS_COUNT;
|
||||
if (m_reset_timestamps_and_difficulties_height)
|
||||
m_timestamps_and_difficulties_height = 0;
|
||||
if (m_timestamps_and_difficulties_height != 0 && ((height - m_timestamps_and_difficulties_height) == 1) && m_timestamps.size() >= DIFFICULTY_BLOCKS_COUNT)
|
||||
if (m_timestamps_and_difficulties_height != 0 && ((height - m_timestamps_and_difficulties_height) == 1) && m_timestamps.size() >= difficulty_blocks_count)
|
||||
{
|
||||
uint64_t index = height - 1;
|
||||
m_timestamps.push_back(m_db->get_block_timestamp(index));
|
||||
m_difficulties.push_back(m_db->get_block_cumulative_difficulty(index));
|
||||
|
||||
while (m_timestamps.size() > DIFFICULTY_BLOCKS_COUNT)
|
||||
while (m_timestamps.size() > difficulty_blocks_count)
|
||||
m_timestamps.erase(m_timestamps.begin());
|
||||
while (m_difficulties.size() > DIFFICULTY_BLOCKS_COUNT)
|
||||
while (m_difficulties.size() > difficulty_blocks_count)
|
||||
m_difficulties.erase(m_difficulties.begin());
|
||||
|
||||
m_timestamps_and_difficulties_height = height;
|
||||
|
@ -918,7 +922,7 @@ start:
|
|||
std::vector<difficulty_type> difficulties_from_cache = difficulties;
|
||||
|
||||
{
|
||||
uint64_t offset = height - std::min <uint64_t> (height, static_cast<uint64_t>(DIFFICULTY_BLOCKS_COUNT));
|
||||
uint64_t offset = height - std::min <uint64_t> (height, static_cast<uint64_t>(difficulty_blocks_count));
|
||||
if (offset == 0)
|
||||
++offset;
|
||||
|
||||
|
@ -964,7 +968,21 @@ start:
|
|||
}
|
||||
|
||||
size_t target = get_difficulty_target();
|
||||
difficulty_type diff = next_difficulty(timestamps, difficulties, target);
|
||||
uint64_t HEIGHT = m_db->height();
|
||||
difficulty_type diff;
|
||||
if (version >= 20) {
|
||||
diff = next_difficulty_v6(timestamps, difficulties, target);
|
||||
} else if (version <= 17 && version >= 11) {
|
||||
diff = next_difficulty_v5(timestamps, difficulties, HEIGHT);
|
||||
} else if (version == 10) {
|
||||
diff = next_difficulty_v4(timestamps, difficulties, HEIGHT);
|
||||
} else if (version == 9) {
|
||||
diff = next_difficulty_v3(timestamps, difficulties, HEIGHT);
|
||||
} else if (version == 8) {
|
||||
diff = next_difficulty_v2(timestamps, difficulties, target, HEIGHT);
|
||||
} else {
|
||||
diff = next_difficulty(timestamps, difficulties, target, HEIGHT);
|
||||
}
|
||||
|
||||
CRITICAL_REGION_LOCAL1(m_difficulty_lock);
|
||||
m_difficulty_for_next_block_top_hash = top_hash;
|
||||
|
@ -989,7 +1007,7 @@ start:
|
|||
MGINFO("START DUMP");
|
||||
MGINFO(ss.str());
|
||||
MGINFO("END DUMP");
|
||||
MGINFO("Please send moneromooo on Libera.Chat the contents of this log, from a couple dozen lines before START DUMP to END DUMP");
|
||||
MGINFO("Please send wowario on IRC OTFC #wownero-dev the contents of this log, from a couple dozen lines before START DUMP to END DUMP");
|
||||
}
|
||||
return diff;
|
||||
}
|
||||
|
@ -1023,11 +1041,13 @@ size_t Blockchain::recalculate_difficulties(boost::optional<uint64_t> start_heig
|
|||
|
||||
std::vector<uint64_t> timestamps;
|
||||
std::vector<difficulty_type> difficulties;
|
||||
timestamps.reserve(DIFFICULTY_BLOCKS_COUNT + 1);
|
||||
difficulties.reserve(DIFFICULTY_BLOCKS_COUNT + 1);
|
||||
uint8_t version = get_current_hard_fork_version();
|
||||
uint64_t difficulty_blocks_count = version >= 20 ? DIFFICULTY_BLOCKS_COUNT_V4 : version <= 17 && version >= 11 ? DIFFICULTY_BLOCKS_COUNT_V3 : version <= 10 && version >= 8 ? DIFFICULTY_BLOCKS_COUNT_V2 : DIFFICULTY_BLOCKS_COUNT;
|
||||
timestamps.reserve(difficulty_blocks_count + 1);
|
||||
difficulties.reserve(difficulty_blocks_count + 1);
|
||||
if (start_height > 1)
|
||||
{
|
||||
for (uint64_t i = 0; i < DIFFICULTY_BLOCKS_COUNT; ++i)
|
||||
for (uint64_t i = 0; i < difficulty_blocks_count; ++i)
|
||||
{
|
||||
uint64_t height = start_height - 1 - i;
|
||||
if (height == 0)
|
||||
|
@ -1042,7 +1062,21 @@ size_t Blockchain::recalculate_difficulties(boost::optional<uint64_t> start_heig
|
|||
for (uint64_t height = start_height; height <= top_height; ++height)
|
||||
{
|
||||
size_t target = get_ideal_hard_fork_version(height) < 2 ? DIFFICULTY_TARGET_V1 : DIFFICULTY_TARGET_V2;
|
||||
difficulty_type recalculated_diff = next_difficulty(timestamps, difficulties, target);
|
||||
uint64_t HEIGHT = m_db->height();
|
||||
difficulty_type recalculated_diff;
|
||||
if (version >= 20) {
|
||||
recalculated_diff = next_difficulty_v6(timestamps, difficulties, target);
|
||||
} else if (version <= 17 && version >= 11) {
|
||||
recalculated_diff = next_difficulty_v5(timestamps, difficulties, HEIGHT);
|
||||
} else if (version == 10) {
|
||||
recalculated_diff = next_difficulty_v4(timestamps, difficulties, HEIGHT);
|
||||
} else if (version == 9) {
|
||||
recalculated_diff = next_difficulty_v3(timestamps, difficulties, HEIGHT);
|
||||
} else if (version == 8) {
|
||||
recalculated_diff = next_difficulty_v2(timestamps, difficulties, target, HEIGHT);
|
||||
} else {
|
||||
recalculated_diff = next_difficulty(timestamps, difficulties, target, HEIGHT);
|
||||
}
|
||||
|
||||
boost::multiprecision::uint256_t recalculated_cum_diff_256 = boost::multiprecision::uint256_t(recalculated_diff) + last_cum_diff;
|
||||
CHECK_AND_ASSERT_THROW_MES(recalculated_cum_diff_256 <= std::numeric_limits<difficulty_type>::max(), "Difficulty overflow!");
|
||||
|
@ -1070,9 +1104,9 @@ size_t Blockchain::recalculate_difficulties(boost::optional<uint64_t> start_heig
|
|||
timestamps.push_back(m_db->get_block_timestamp(height));
|
||||
difficulties.push_back(recalculated_cum_diff);
|
||||
}
|
||||
if (timestamps.size() > DIFFICULTY_BLOCKS_COUNT)
|
||||
if (timestamps.size() > difficulty_blocks_count)
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(timestamps.size() == DIFFICULTY_BLOCKS_COUNT + 1, "Wrong timestamps size: " << timestamps.size());
|
||||
CHECK_AND_ASSERT_THROW_MES(timestamps.size() == difficulty_blocks_count + 1, "Wrong timestamps size: " << timestamps.size());
|
||||
timestamps.erase(timestamps.begin());
|
||||
difficulties.erase(difficulties.begin());
|
||||
}
|
||||
|
@ -1297,16 +1331,18 @@ difficulty_type Blockchain::get_next_difficulty_for_alternative_chain(const std:
|
|||
LOG_PRINT_L3("Blockchain::" << __func__);
|
||||
std::vector<uint64_t> timestamps;
|
||||
std::vector<difficulty_type> cumulative_difficulties;
|
||||
uint8_t version = get_current_hard_fork_version();
|
||||
uint64_t difficulty_blocks_count = version >= 20 ? DIFFICULTY_BLOCKS_COUNT_V4 : version <= 17 && version >= 11 ? DIFFICULTY_BLOCKS_COUNT_V3 : version <= 10 && version >= 8 ? DIFFICULTY_BLOCKS_COUNT_V2 : DIFFICULTY_BLOCKS_COUNT;
|
||||
|
||||
// if the alt chain isn't long enough to calculate the difficulty target
|
||||
// based on its blocks alone, need to get more blocks from the main chain
|
||||
if(alt_chain.size()< DIFFICULTY_BLOCKS_COUNT)
|
||||
if(alt_chain.size()< difficulty_blocks_count)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_blockchain_lock);
|
||||
|
||||
// Figure out start and stop offsets for main chain blocks
|
||||
size_t main_chain_stop_offset = alt_chain.size() ? alt_chain.front().height : bei.height;
|
||||
size_t main_chain_count = DIFFICULTY_BLOCKS_COUNT - std::min(static_cast<size_t>(DIFFICULTY_BLOCKS_COUNT), alt_chain.size());
|
||||
size_t main_chain_count = difficulty_blocks_count - std::min(static_cast<size_t>(difficulty_blocks_count), alt_chain.size());
|
||||
main_chain_count = std::min(main_chain_count, main_chain_stop_offset);
|
||||
size_t main_chain_start_offset = main_chain_stop_offset - main_chain_count;
|
||||
|
||||
|
@ -1321,7 +1357,7 @@ difficulty_type Blockchain::get_next_difficulty_for_alternative_chain(const std:
|
|||
}
|
||||
|
||||
// make sure we haven't accidentally grabbed too many blocks...maybe don't need this check?
|
||||
CHECK_AND_ASSERT_MES((alt_chain.size() + timestamps.size()) <= DIFFICULTY_BLOCKS_COUNT, false, "Internal error, alt_chain.size()[" << alt_chain.size() << "] + vtimestampsec.size()[" << timestamps.size() << "] NOT <= DIFFICULTY_WINDOW[]" << DIFFICULTY_BLOCKS_COUNT);
|
||||
CHECK_AND_ASSERT_MES((alt_chain.size() + timestamps.size()) <= difficulty_blocks_count, false, "Internal error, alt_chain.size()[" << alt_chain.size() << "] + vtimestampsec.size()[" << timestamps.size() << "] NOT <= DIFFICULTY_WINDOW[]" << difficulty_blocks_count);
|
||||
|
||||
for (const auto &bei : alt_chain)
|
||||
{
|
||||
|
@ -1333,8 +1369,8 @@ difficulty_type Blockchain::get_next_difficulty_for_alternative_chain(const std:
|
|||
// and timestamps from it alone
|
||||
else
|
||||
{
|
||||
timestamps.resize(static_cast<size_t>(DIFFICULTY_BLOCKS_COUNT));
|
||||
cumulative_difficulties.resize(static_cast<size_t>(DIFFICULTY_BLOCKS_COUNT));
|
||||
timestamps.resize(static_cast<size_t>(difficulty_blocks_count));
|
||||
cumulative_difficulties.resize(static_cast<size_t>(difficulty_blocks_count));
|
||||
size_t count = 0;
|
||||
size_t max_i = timestamps.size()-1;
|
||||
// get difficulties and timestamps from most recent blocks in alt chain
|
||||
|
@ -1343,7 +1379,7 @@ difficulty_type Blockchain::get_next_difficulty_for_alternative_chain(const std:
|
|||
timestamps[max_i - count] = bei.bl.timestamp;
|
||||
cumulative_difficulties[max_i - count] = bei.cumulative_difficulty;
|
||||
count++;
|
||||
if(count >= DIFFICULTY_BLOCKS_COUNT)
|
||||
if(count >= difficulty_blocks_count)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1352,7 +1388,22 @@ difficulty_type Blockchain::get_next_difficulty_for_alternative_chain(const std:
|
|||
size_t target = get_ideal_hard_fork_version(bei.height) < 2 ? DIFFICULTY_TARGET_V1 : DIFFICULTY_TARGET_V2;
|
||||
|
||||
// calculate the difficulty target for the block and return it
|
||||
return next_difficulty(timestamps, cumulative_difficulties, target);
|
||||
uint64_t HEIGHT = m_db->height();
|
||||
difficulty_type next_diff;
|
||||
if (version >= 20) {
|
||||
next_diff = next_difficulty_v6(timestamps, cumulative_difficulties, target);
|
||||
} else if (version <= 17 && version >= 11) {
|
||||
next_diff = next_difficulty_v5(timestamps, cumulative_difficulties, HEIGHT);
|
||||
} else if (version == 10) {
|
||||
next_diff = next_difficulty_v4(timestamps, cumulative_difficulties, HEIGHT);
|
||||
} else if (version == 9) {
|
||||
next_diff = next_difficulty_v3(timestamps, cumulative_difficulties, HEIGHT);
|
||||
} else if (version == 8) {
|
||||
next_diff = next_difficulty_v2(timestamps, cumulative_difficulties, target, HEIGHT);
|
||||
} else {
|
||||
next_diff = next_difficulty(timestamps, cumulative_difficulties, target, HEIGHT);
|
||||
}
|
||||
return next_diff;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
// This function does a sanity check on basic things that all miner
|
||||
|
@ -1363,6 +1414,46 @@ difficulty_type Blockchain::get_next_difficulty_for_alternative_chain(const std:
|
|||
// valid output types
|
||||
bool Blockchain::prevalidate_miner_transaction(const block& b, uint64_t height, uint8_t hf_version)
|
||||
{
|
||||
// Miner Block Header Signing
|
||||
if (hf_version >= HF_VERSION_BLOCK_HEADER_MINER_SIG)
|
||||
{
|
||||
// sanity checks
|
||||
if (b.miner_tx.vout.size() != 1)
|
||||
{
|
||||
MWARNING("Only 1 output in miner transaction allowed");
|
||||
return false;
|
||||
}
|
||||
if (!check_output_types(b.miner_tx, hf_version))
|
||||
{
|
||||
MWARNING("Wrong txout type");
|
||||
return false;
|
||||
}
|
||||
if (b.vote > 2)
|
||||
{
|
||||
MWARNING("Vote integer must be either 0, 1, or 2");
|
||||
return false;
|
||||
}
|
||||
// keccak hash block header data and check miner signature
|
||||
// if signature is invalid, reject block
|
||||
crypto::hash sig_data = get_sig_data(b);
|
||||
crypto::signature signature = b.signature;
|
||||
crypto::public_key output_public_key;
|
||||
get_output_public_key(b.miner_tx.vout[0], output_public_key);
|
||||
if (!crypto::check_signature(sig_data, output_public_key, signature))
|
||||
{
|
||||
MWARNING("Miner signature is invalid");
|
||||
return false;
|
||||
} else {
|
||||
LOG_PRINT_L1("Miner signature is good");
|
||||
LOG_PRINT_L1("Vote: " << b.vote);
|
||||
}
|
||||
}
|
||||
|
||||
if (hf_version >= HF_VERSION_CAP_TX_EXTRA_SIZE && b.miner_tx.extra.size() > MAX_TX_EXTRA_SIZE)
|
||||
{
|
||||
MWARNING("coinbase transaction tx-extra is too big: " << b.miner_tx.extra.size() << " bytes, the limit is: " << MAX_TX_EXTRA_SIZE);
|
||||
return false;
|
||||
}
|
||||
LOG_PRINT_L3("Blockchain::" << __func__);
|
||||
CHECK_AND_ASSERT_MES(b.miner_tx.vin.size() == 1, false, "coinbase transaction in the block has no inputs");
|
||||
CHECK_AND_ASSERT_MES(b.miner_tx.vin[0].type() == typeid(txin_gen), false, "coinbase transaction in the block has the wrong type");
|
||||
|
@ -1380,7 +1471,18 @@ bool Blockchain::prevalidate_miner_transaction(const block& b, uint64_t height,
|
|||
return false;
|
||||
}
|
||||
MDEBUG("Miner tx hash: " << get_transaction_hash(b.miner_tx));
|
||||
CHECK_AND_ASSERT_MES(b.miner_tx.unlock_time == height + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW, false, "coinbase transaction transaction has the wrong unlock time=" << b.miner_tx.unlock_time << ", expected " << height + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW);
|
||||
if (hf_version >= HF_VERSION_FIXED_UNLOCK) {
|
||||
CHECK_AND_ASSERT_MES(b.miner_tx.unlock_time == height + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW_V2, false, "coinbase transaction transaction has the wrong unlock time=" << b.miner_tx.unlock_time << ", expected " << height + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW_V2);
|
||||
} else if (hf_version < HF_VERSION_FIXED_UNLOCK && hf_version >= HF_VERSION_DYNAMIC_UNLOCK) {
|
||||
uint64_t N = m_nettype == MAINNET ? 1337 : 5;
|
||||
crypto::hash blk_id = get_block_id_by_height(height-N);
|
||||
std::string hex_str = epee::string_tools::pod_to_hex(blk_id).substr(0, 3);
|
||||
uint64_t blk_num = std::stol(hex_str,nullptr,16)*2;
|
||||
uint64_t unlock_window = blk_num + 288;
|
||||
CHECK_AND_ASSERT_MES(b.miner_tx.unlock_time == height + unlock_window, false, "coinbase transaction transaction has the wrong unlock time=" << b.miner_tx.unlock_time << ", expected " << height + unlock_window);
|
||||
} else {
|
||||
CHECK_AND_ASSERT_MES(b.miner_tx.unlock_time == height + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW, false, "coinbase transaction transaction has the wrong unlock time=" << b.miner_tx.unlock_time << ", expected " << height + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW);
|
||||
}
|
||||
|
||||
//check outs overflow
|
||||
if(!check_outs_overflow(b.miner_tx))
|
||||
|
@ -1751,7 +1853,7 @@ bool Blockchain::create_block_template(block& b, const crypto::hash *from_block,
|
|||
//make blocks coin-base tx looks close to real coinbase tx to get truthful blob weight
|
||||
uint8_t hf_version = b.major_version;
|
||||
size_t max_outs = hf_version >= 4 ? 1 : 11;
|
||||
bool r = construct_miner_tx(height, median_weight, already_generated_coins, txs_weight, fee, miner_address, b.miner_tx, ex_nonce, max_outs, hf_version);
|
||||
bool r = construct_miner_tx(this, m_nettype, height, median_weight, already_generated_coins, txs_weight, fee, miner_address, b.miner_tx, ex_nonce, max_outs, hf_version);
|
||||
CHECK_AND_ASSERT_MES(r, false, "Failed to construct miner tx, first chance");
|
||||
size_t cumulative_weight = txs_weight + get_transaction_weight(b.miner_tx);
|
||||
#if defined(DEBUG_CREATE_BLOCK_TEMPLATE)
|
||||
|
@ -1760,7 +1862,7 @@ bool Blockchain::create_block_template(block& b, const crypto::hash *from_block,
|
|||
#endif
|
||||
for (size_t try_count = 0; try_count != 10; ++try_count)
|
||||
{
|
||||
r = construct_miner_tx(height, median_weight, already_generated_coins, cumulative_weight, fee, miner_address, b.miner_tx, ex_nonce, max_outs, hf_version);
|
||||
r = construct_miner_tx(this, m_nettype, height, median_weight, already_generated_coins, cumulative_weight, fee, miner_address, b.miner_tx, ex_nonce, max_outs, hf_version);
|
||||
|
||||
CHECK_AND_ASSERT_MES(r, false, "Failed to construct miner tx, second chance");
|
||||
size_t coinbase_weight = get_transaction_weight(b.miner_tx);
|
||||
|
@ -1846,12 +1948,14 @@ bool Blockchain::get_miner_data(uint8_t& major_version, uint64_t& height, crypto
|
|||
bool Blockchain::complete_timestamps_vector(uint64_t start_top_height, std::vector<uint64_t>& timestamps) const
|
||||
{
|
||||
LOG_PRINT_L3("Blockchain::" << __func__);
|
||||
uint8_t version = get_current_hard_fork_version();
|
||||
size_t blockchain_timestamp_check_window = version >= 10 ? BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW_V2 : BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW;
|
||||
|
||||
if(timestamps.size() >= BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW)
|
||||
if(timestamps.size() >= blockchain_timestamp_check_window)
|
||||
return true;
|
||||
|
||||
CRITICAL_REGION_LOCAL(m_blockchain_lock);
|
||||
size_t need_elements = BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW - timestamps.size();
|
||||
size_t need_elements = blockchain_timestamp_check_window - timestamps.size();
|
||||
CHECK_AND_ASSERT_MES(start_top_height < m_db->height(), false, "internal error: passed start_height not < " << " m_db->height() -- " << start_top_height << " >= " << m_db->height());
|
||||
size_t stop_offset = start_top_height > need_elements ? start_top_height - need_elements : 0;
|
||||
timestamps.reserve(timestamps.size() + start_top_height - stop_offset);
|
||||
|
@ -2063,7 +2167,7 @@ bool Blockchain::handle_alternative_block(const block& b, const crypto::hash& id
|
|||
cryptonote::blobdata blob;
|
||||
if (m_tx_pool.have_tx(txid, relay_category::legacy))
|
||||
{
|
||||
if (m_tx_pool.get_transaction_info(txid, td))
|
||||
if (m_tx_pool.get_transaction_info(txid, td, true/*include_sensitive_data*/))
|
||||
{
|
||||
bei.block_cumulative_weight += td.weight;
|
||||
}
|
||||
|
@ -3104,7 +3208,7 @@ bool Blockchain::check_tx_outputs(const transaction& tx, tx_verification_context
|
|||
}
|
||||
}
|
||||
|
||||
// from v10, allow bulletproofs v2
|
||||
// from v13, allow bulletproofs v2
|
||||
if (hf_version < HF_VERSION_SMALLER_BP) {
|
||||
if (tx.version >= 2) {
|
||||
if (tx.rct_signatures.type == rct::RCTTypeBulletproof2)
|
||||
|
@ -3116,7 +3220,7 @@ bool Blockchain::check_tx_outputs(const transaction& tx, tx_verification_context
|
|||
}
|
||||
}
|
||||
|
||||
// from v11, allow only bulletproofs v2
|
||||
// from v14, allow only bulletproofs v2
|
||||
if (hf_version > HF_VERSION_SMALLER_BP) {
|
||||
if (tx.version >= 2) {
|
||||
if (tx.rct_signatures.type == rct::RCTTypeBulletproof)
|
||||
|
@ -3128,7 +3232,7 @@ bool Blockchain::check_tx_outputs(const transaction& tx, tx_verification_context
|
|||
}
|
||||
}
|
||||
|
||||
// from v13, allow CLSAGs
|
||||
// from v16, allow CLSAGs
|
||||
if (hf_version < HF_VERSION_CLSAG) {
|
||||
if (tx.version >= 2) {
|
||||
if (tx.rct_signatures.type == rct::RCTTypeCLSAG)
|
||||
|
@ -3140,31 +3244,33 @@ bool Blockchain::check_tx_outputs(const transaction& tx, tx_verification_context
|
|||
}
|
||||
}
|
||||
|
||||
// from v14, allow only CLSAGs
|
||||
// from v17, allow only CLSAGs
|
||||
if (hf_version > HF_VERSION_CLSAG) {
|
||||
if (tx.version >= 2) {
|
||||
if (tx.rct_signatures.type <= rct::RCTTypeBulletproof2)
|
||||
{
|
||||
// two MLSAG txes went in due to a bug with txes that went into the txpool before the fork, grandfather them in
|
||||
static const char * grandfathered[2] = { "c5151944f0583097ba0c88cd0f43e7fabb3881278aa2f73b3b0a007c5d34e910", "6f2f117cde6fbcf8d4a6ef8974fcac744726574ac38cf25d3322c996b21edd4c" };
|
||||
crypto::hash h0, h1;
|
||||
epee::string_tools::hex_to_pod(grandfathered[0], h0);
|
||||
epee::string_tools::hex_to_pod(grandfathered[1], h1);
|
||||
if (cryptonote::get_transaction_hash(tx) == h0 || cryptonote::get_transaction_hash(tx) == h1)
|
||||
{
|
||||
MDEBUG("Grandfathering cryptonote::get_transaction_hash(tx) in");
|
||||
}
|
||||
else
|
||||
{
|
||||
MERROR_VER("Ringct type " << (unsigned)tx.rct_signatures.type << " is not allowed from v" << (HF_VERSION_CLSAG + 1));
|
||||
tvc.m_invalid_output = true;
|
||||
return false;
|
||||
}
|
||||
MERROR_VER("Ringct type " << (unsigned)tx.rct_signatures.type << " is not allowed from v" << (HF_VERSION_CLSAG + 1));
|
||||
tvc.m_invalid_output = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// from v15, allow bulletproofs plus
|
||||
|
||||
// from v12, forbid old bulletproofs
|
||||
if (hf_version > 11) {
|
||||
if (tx.version >= 2) {
|
||||
const bool old_bulletproof = rct::is_rct_old_bulletproof(tx.rct_signatures.type);
|
||||
if (old_bulletproof)
|
||||
{
|
||||
MERROR_VER("Old Bulletproofs are not allowed after v11");
|
||||
tvc.m_invalid_output = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// from v18, allow bulletproofs plus
|
||||
if (hf_version < HF_VERSION_BULLETPROOF_PLUS) {
|
||||
if (tx.version >= 2) {
|
||||
const bool bulletproof_plus = rct::is_rct_bulletproof_plus(tx.rct_signatures.type);
|
||||
|
@ -3177,7 +3283,7 @@ bool Blockchain::check_tx_outputs(const transaction& tx, tx_verification_context
|
|||
}
|
||||
}
|
||||
|
||||
// from v16, forbid bulletproofs
|
||||
// from v19, forbid bulletproofs
|
||||
if (hf_version > HF_VERSION_BULLETPROOF_PLUS) {
|
||||
if (tx.version >= 2) {
|
||||
const bool bulletproof = rct::is_rct_bulletproof(tx.rct_signatures.type);
|
||||
|
@ -3190,13 +3296,20 @@ bool Blockchain::check_tx_outputs(const transaction& tx, tx_verification_context
|
|||
}
|
||||
}
|
||||
|
||||
// from v15, require view tags on outputs
|
||||
// from v20, require view tags on outputs
|
||||
if (!check_output_types(tx, hf_version))
|
||||
{
|
||||
tvc.m_invalid_output = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// from v20, limit tx extra size
|
||||
if (hf_version >= HF_VERSION_CAP_TX_EXTRA_SIZE && tx.extra.size() > MAX_TX_EXTRA_SIZE)
|
||||
{
|
||||
MERROR_VER("transaction tx-extra is too big: " << tx.extra.size() << " bytes, the limit is: " << MAX_TX_EXTRA_SIZE);
|
||||
tvc.m_tx_extra_too_big = true;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
|
@ -3211,7 +3324,7 @@ bool Blockchain::have_tx_keyimges_as_spent(const transaction &tx) const
|
|||
}
|
||||
return false;
|
||||
}
|
||||
bool Blockchain::expand_transaction_2(transaction &tx, const crypto::hash &tx_prefix_hash, const std::vector<std::vector<rct::ctkey>> &pubkeys) const
|
||||
bool Blockchain::expand_transaction_2(transaction &tx, const crypto::hash &tx_prefix_hash, const std::vector<std::vector<rct::ctkey>> &pubkeys)
|
||||
{
|
||||
PERF_TIMER(expand_transaction_2);
|
||||
CHECK_AND_ASSERT_MES(tx.version == 2, false, "Transaction version is not 2");
|
||||
|
@ -3222,7 +3335,7 @@ bool Blockchain::expand_transaction_2(transaction &tx, const crypto::hash &tx_pr
|
|||
rv.message = rct::hash2rct(tx_prefix_hash);
|
||||
|
||||
// mixRing - full and simple store it in opposite ways
|
||||
if (rv.type == rct::RCTTypeFull)
|
||||
if (rv.type == rct::RCTTypeFull || rv.type == rct::RCTTypeFullBulletproof)
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(!pubkeys.empty() && !pubkeys[0].empty(), false, "empty pubkeys");
|
||||
rv.mixRing.resize(pubkeys[0].size());
|
||||
|
@ -3237,7 +3350,7 @@ bool Blockchain::expand_transaction_2(transaction &tx, const crypto::hash &tx_pr
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (rv.type == rct::RCTTypeSimple || rv.type == rct::RCTTypeBulletproof || rv.type == rct::RCTTypeBulletproof2 || rv.type == rct::RCTTypeCLSAG || rv.type == rct::RCTTypeBulletproofPlus)
|
||||
else if (rv.type == rct::RCTTypeSimple || rv.type == rct::RCTTypeBulletproof || rv.type == rct::RCTTypeBulletproof2 || rv.type == rct::RCTTypeSimpleBulletproof || rv.type == rct::RCTTypeCLSAG || rv.type == rct::RCTTypeBulletproofPlus)
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(!pubkeys.empty() && !pubkeys[0].empty(), false, "empty pubkeys");
|
||||
rv.mixRing.resize(pubkeys.size());
|
||||
|
@ -3256,7 +3369,7 @@ bool Blockchain::expand_transaction_2(transaction &tx, const crypto::hash &tx_pr
|
|||
}
|
||||
|
||||
// II
|
||||
if (rv.type == rct::RCTTypeFull)
|
||||
if (rv.type == rct::RCTTypeFull || rv.type == rct::RCTTypeFullBulletproof)
|
||||
{
|
||||
if (!tx.pruned)
|
||||
{
|
||||
|
@ -3266,7 +3379,7 @@ bool Blockchain::expand_transaction_2(transaction &tx, const crypto::hash &tx_pr
|
|||
rv.p.MGs[0].II[n] = rct::ki2rct(boost::get<txin_to_key>(tx.vin[n]).k_image);
|
||||
}
|
||||
}
|
||||
else if (rv.type == rct::RCTTypeSimple || rv.type == rct::RCTTypeBulletproof || rv.type == rct::RCTTypeBulletproof2)
|
||||
else if (rv.type == rct::RCTTypeSimple || rv.type == rct::RCTTypeBulletproof || rv.type == rct::RCTTypeBulletproof2 || rv.type == rct::RCTTypeSimpleBulletproof)
|
||||
{
|
||||
if (!tx.pruned)
|
||||
{
|
||||
|
@ -3340,7 +3453,7 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
|
|||
size_t n_unmixable = 0, n_mixable = 0;
|
||||
size_t min_actual_mixin = std::numeric_limits<size_t>::max();
|
||||
size_t max_actual_mixin = 0;
|
||||
const size_t min_mixin = hf_version >= HF_VERSION_MIN_MIXIN_15 ? 15 : hf_version >= HF_VERSION_MIN_MIXIN_10 ? 10 : hf_version >= HF_VERSION_MIN_MIXIN_6 ? 6 : hf_version >= HF_VERSION_MIN_MIXIN_4 ? 4 : 2;
|
||||
const size_t min_mixin = hf_version >= HF_VERSION_MIN_MIXIN_21 ? 21 : 7;
|
||||
for (const auto& txin : tx.vin)
|
||||
{
|
||||
// non txin_to_key inputs will be rejected below
|
||||
|
@ -3387,7 +3500,7 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
|
|||
// allowed is when spending unmixable non-RCT outputs in the chain.
|
||||
// Caveat: at HF_VERSION_MIN_MIXIN_15, temporarily allow ring sizes
|
||||
// of 11 to allow a grace period in the transition to larger ring size.
|
||||
if (min_actual_mixin < min_mixin && !(hf_version == HF_VERSION_MIN_MIXIN_15 && min_actual_mixin == 10))
|
||||
if (min_actual_mixin < min_mixin && !(hf_version == HF_VERSION_MIN_MIXIN_21 && min_actual_mixin == 7))
|
||||
{
|
||||
if (n_unmixable == 0)
|
||||
{
|
||||
|
@ -3401,10 +3514,10 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
|
|||
tvc.m_low_mixin = true;
|
||||
return false;
|
||||
}
|
||||
} else if ((hf_version > HF_VERSION_MIN_MIXIN_15 && min_actual_mixin > 15)
|
||||
|| (hf_version == HF_VERSION_MIN_MIXIN_15 && min_actual_mixin != 15 && min_actual_mixin != 10) // grace period to allow either 15 or 10
|
||||
|| (hf_version < HF_VERSION_MIN_MIXIN_15 && hf_version >= HF_VERSION_MIN_MIXIN_10+2 && min_actual_mixin > 10)
|
||||
|| ((hf_version == HF_VERSION_MIN_MIXIN_10 || hf_version == HF_VERSION_MIN_MIXIN_10+1) && min_actual_mixin != 10)
|
||||
} else if ((hf_version > HF_VERSION_MIN_MIXIN_21 && min_actual_mixin > 21)
|
||||
|| (hf_version == HF_VERSION_MIN_MIXIN_21 && min_actual_mixin != 21 && min_actual_mixin != 7) // grace period to allow either 15 or 10
|
||||
|| (hf_version < HF_VERSION_MIN_MIXIN_21 && hf_version >= HF_VERSION_MIN_MIXIN_7+2 && min_actual_mixin > 7)
|
||||
|| ((hf_version == HF_VERSION_MIN_MIXIN_7 || hf_version == HF_VERSION_MIN_MIXIN_7+1) && min_actual_mixin != 7)
|
||||
)
|
||||
{
|
||||
MERROR_VER("Tx " << get_transaction_hash(tx) << " has invalid ring size (" << (min_actual_mixin + 1) << "), it should be " << (min_mixin + 1));
|
||||
|
@ -3534,6 +3647,13 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
|
|||
false, "Transaction spends at least one output which is too young");
|
||||
}
|
||||
|
||||
// Warn that new RCT types are present, and thus the cache is not being used effectively
|
||||
static constexpr const std::uint8_t RCT_CACHE_TYPE = rct::RCTTypeBulletproofPlus;
|
||||
if (tx.rct_signatures.type > RCT_CACHE_TYPE)
|
||||
{
|
||||
MWARNING("RCT cache is not caching new verification results. Please update RCT_CACHE_TYPE!");
|
||||
}
|
||||
|
||||
if (tx.version == 1)
|
||||
{
|
||||
if (threads > 1)
|
||||
|
@ -3555,12 +3675,6 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!expand_transaction_2(tx, tx_prefix_hash, pubkeys))
|
||||
{
|
||||
MERROR_VER("Failed to expand rct signatures!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// from version 2, check ringct signatures
|
||||
// obviously, the original and simple rct APIs use a mixRing that's indexes
|
||||
// in opposite orders, because it'd be too simple otherwise...
|
||||
|
@ -3573,66 +3687,13 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
|
|||
return false;
|
||||
}
|
||||
case rct::RCTTypeSimple:
|
||||
case rct::RCTTypeSimpleBulletproof:
|
||||
case rct::RCTTypeBulletproof:
|
||||
case rct::RCTTypeBulletproof2:
|
||||
case rct::RCTTypeCLSAG:
|
||||
case rct::RCTTypeBulletproofPlus:
|
||||
{
|
||||
// check all this, either reconstructed (so should really pass), or not
|
||||
{
|
||||
if (pubkeys.size() != rv.mixRing.size())
|
||||
{
|
||||
MERROR_VER("Failed to check ringct signatures: mismatched pubkeys/mixRing size");
|
||||
return false;
|
||||
}
|
||||
for (size_t i = 0; i < pubkeys.size(); ++i)
|
||||
{
|
||||
if (pubkeys[i].size() != rv.mixRing[i].size())
|
||||
{
|
||||
MERROR_VER("Failed to check ringct signatures: mismatched pubkeys/mixRing size");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t n = 0; n < pubkeys.size(); ++n)
|
||||
{
|
||||
for (size_t m = 0; m < pubkeys[n].size(); ++m)
|
||||
{
|
||||
if (pubkeys[n][m].dest != rct::rct2pk(rv.mixRing[n][m].dest))
|
||||
{
|
||||
MERROR_VER("Failed to check ringct signatures: mismatched pubkey at vin " << n << ", index " << m);
|
||||
return false;
|
||||
}
|
||||
if (pubkeys[n][m].mask != rct::rct2pk(rv.mixRing[n][m].mask))
|
||||
{
|
||||
MERROR_VER("Failed to check ringct signatures: mismatched commitment at vin " << n << ", index " << m);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const size_t n_sigs = rct::is_rct_clsag(rv.type) ? rv.p.CLSAGs.size() : rv.p.MGs.size();
|
||||
if (n_sigs != tx.vin.size())
|
||||
{
|
||||
MERROR_VER("Failed to check ringct signatures: mismatched MGs/vin sizes");
|
||||
return false;
|
||||
}
|
||||
for (size_t n = 0; n < tx.vin.size(); ++n)
|
||||
{
|
||||
bool error;
|
||||
if (rct::is_rct_clsag(rv.type))
|
||||
error = memcmp(&boost::get<txin_to_key>(tx.vin[n]).k_image, &rv.p.CLSAGs[n].I, 32);
|
||||
else
|
||||
error = rv.p.MGs[n].II.empty() || memcmp(&boost::get<txin_to_key>(tx.vin[n]).k_image, &rv.p.MGs[n].II[0], 32);
|
||||
if (error)
|
||||
{
|
||||
MERROR_VER("Failed to check ringct signatures: mismatched key image");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!rct::verRctNonSemanticsSimpleCached(rv))
|
||||
if (!ver_rct_non_semantics_simple_cached(tx, pubkeys, m_rct_ver_cache, RCT_CACHE_TYPE))
|
||||
{
|
||||
MERROR_VER("Failed to check ringct signatures!");
|
||||
return false;
|
||||
|
@ -3640,7 +3701,14 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
|
|||
break;
|
||||
}
|
||||
case rct::RCTTypeFull:
|
||||
case rct::RCTTypeFullBulletproof:
|
||||
{
|
||||
if (!expand_transaction_2(tx, tx_prefix_hash, pubkeys))
|
||||
{
|
||||
MERROR_VER("Failed to expand rct signatures!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// check all this, either reconstructed (so should really pass), or not
|
||||
{
|
||||
bool size_matches = true;
|
||||
|
@ -3755,7 +3823,7 @@ uint64_t Blockchain::get_dynamic_base_fee(uint64_t block_reward, size_t median_b
|
|||
div128_64(hi, lo, median_block_weight, &hi, &lo, NULL, NULL);
|
||||
assert(hi == 0);
|
||||
lo -= lo / 20;
|
||||
return lo;
|
||||
return lo == 0 ? 1 : lo;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3877,6 +3945,8 @@ void Blockchain::get_dynamic_base_fee_estimate_2021_scaling(uint64_t grace_block
|
|||
const uint8_t version = get_current_hard_fork_version();
|
||||
const uint64_t db_height = m_db->height();
|
||||
|
||||
CHECK_AND_ASSERT_THROW_MES(grace_blocks <= CRYPTONOTE_REWARD_BLOCKS_WINDOW, "Grace blocks invalid In 2021 fee scaling estimate.");
|
||||
|
||||
// we want Mlw = median of max((min(Mbw, 1.7 * Ml), Zm), Ml / 1.7)
|
||||
// Mbw: block weight for the last 99990 blocks, 0 for the next 10
|
||||
// Ml: penalty free zone (dynamic), aka long_term_median, aka median of max((min(Mb, 1.7 * Ml), Zm), Ml / 1.7)
|
||||
|
@ -3890,7 +3960,6 @@ void Blockchain::get_dynamic_base_fee_estimate_2021_scaling(uint64_t grace_block
|
|||
const uint64_t Mlw_penalty_free_zone_for_wallet = std::max<uint64_t>(rm.median(), CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5);
|
||||
|
||||
// Msw: median over [100 - grace blocks] past + [grace blocks] future blocks
|
||||
CHECK_AND_ASSERT_THROW_MES(grace_blocks <= 100, "Grace blocks invalid In 2021 fee scaling estimate.");
|
||||
std::vector<uint64_t> weights;
|
||||
get_last_n_blocks_weights(weights, 100 - grace_blocks);
|
||||
weights.reserve(100);
|
||||
|
@ -4053,14 +4122,16 @@ uint64_t Blockchain::get_adjusted_time(uint64_t height) const
|
|||
LOG_PRINT_L3("Blockchain::" << __func__);
|
||||
|
||||
// if not enough blocks, no proper median yet, return current time
|
||||
if(height < BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW)
|
||||
uint8_t version = get_current_hard_fork_version();
|
||||
size_t blockchain_timestamp_check_window = version >= 10 ? BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW_V2 : BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW;
|
||||
if(height < blockchain_timestamp_check_window)
|
||||
{
|
||||
return static_cast<uint64_t>(time(NULL));
|
||||
}
|
||||
std::vector<uint64_t> timestamps;
|
||||
|
||||
// need most recent 60 blocks, get index of first of those
|
||||
size_t offset = height - BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW;
|
||||
size_t offset = height - blockchain_timestamp_check_window;
|
||||
timestamps.reserve(height - offset);
|
||||
for(;offset < height; ++offset)
|
||||
{
|
||||
|
@ -4070,7 +4141,7 @@ uint64_t Blockchain::get_adjusted_time(uint64_t height) const
|
|||
|
||||
// project the median to match approximately when the block being validated will appear
|
||||
// the median is calculated from a chunk of past blocks, so we use +1 to offset onto the current block
|
||||
median_ts += (BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW + 1) * DIFFICULTY_TARGET_V2 / 2;
|
||||
median_ts += (blockchain_timestamp_check_window + 1) * DIFFICULTY_TARGET_V2 / 2;
|
||||
|
||||
// project the current block's time based on the previous block's time
|
||||
// we don't use the current block's time directly to mitigate timestamp manipulation
|
||||
|
@ -4089,7 +4160,9 @@ bool Blockchain::check_block_timestamp(std::vector<uint64_t>& timestamps, const
|
|||
|
||||
if(b.timestamp < median_ts)
|
||||
{
|
||||
MERROR_VER("Timestamp of block with id: " << get_block_hash(b) << ", " << b.timestamp << ", less than median of last " << BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW << " blocks, " << median_ts);
|
||||
uint8_t version = get_current_hard_fork_version();
|
||||
size_t blockchain_timestamp_check_window = version >= 10 ? BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW_V2 : BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW;
|
||||
MERROR_VER("Timestamp of block with id: " << get_block_hash(b) << ", " << b.timestamp << ", less than median of last " << blockchain_timestamp_check_window << " blocks, " << median_ts);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -4106,16 +4179,19 @@ bool Blockchain::check_block_timestamp(std::vector<uint64_t>& timestamps, const
|
|||
bool Blockchain::check_block_timestamp(const block& b, uint64_t& median_ts) const
|
||||
{
|
||||
LOG_PRINT_L3("Blockchain::" << __func__);
|
||||
if(b.timestamp > (uint64_t)time(NULL) + CRYPTONOTE_BLOCK_FUTURE_TIME_LIMIT)
|
||||
uint8_t version = get_current_hard_fork_version();
|
||||
uint64_t cryptonote_block_future_time_limit = version >= 8 ? CRYPTONOTE_BLOCK_FUTURE_TIME_LIMIT_V2 : CRYPTONOTE_BLOCK_FUTURE_TIME_LIMIT;
|
||||
size_t blockchain_timestamp_check_window = version >= 10 ? BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW_V2 : BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW;
|
||||
if(b.timestamp > (uint64_t)time(NULL) + cryptonote_block_future_time_limit)
|
||||
{
|
||||
MERROR_VER("Timestamp of block with id: " << get_block_hash(b) << ", " << b.timestamp << ", bigger than local time + 2 hours");
|
||||
MERROR_VER("Timestamp of block with id: " << get_block_hash(b) << ", " << b.timestamp << ", bigger than local time + 10 minutes");
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto h = m_db->height();
|
||||
|
||||
// if not enough blocks, no proper median yet, return true
|
||||
if(h < BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW)
|
||||
if(h < blockchain_timestamp_check_window)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -4123,7 +4199,7 @@ bool Blockchain::check_block_timestamp(const block& b, uint64_t& median_ts) cons
|
|||
std::vector<uint64_t> timestamps;
|
||||
|
||||
// need most recent 60 blocks, get index of first of those
|
||||
size_t offset = h - BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW;
|
||||
size_t offset = h - blockchain_timestamp_check_window;
|
||||
timestamps.reserve(h - offset);
|
||||
for(;offset < h; ++offset)
|
||||
{
|
||||
|
@ -4661,40 +4737,9 @@ bool Blockchain::update_next_cumulative_weight_limit(uint64_t *long_term_effecti
|
|||
}
|
||||
else
|
||||
{
|
||||
const uint64_t block_weight = m_db->get_block_weight(db_height - 1);
|
||||
const uint64_t nblocks = std::min<uint64_t>(m_long_term_block_weights_window, db_height);
|
||||
const uint64_t long_term_median = get_long_term_block_weight_median(db_height - nblocks, nblocks);
|
||||
|
||||
uint64_t long_term_median;
|
||||
if (db_height == 1)
|
||||
{
|
||||
long_term_median = CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint64_t nblocks = std::min<uint64_t>(m_long_term_block_weights_window, db_height);
|
||||
if (nblocks == db_height)
|
||||
--nblocks;
|
||||
long_term_median = get_long_term_block_weight_median(db_height - nblocks - 1, nblocks);
|
||||
}
|
||||
|
||||
m_long_term_effective_median_block_weight = std::max<uint64_t>(CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5, long_term_median);
|
||||
|
||||
uint64_t short_term_constraint = m_long_term_effective_median_block_weight;
|
||||
if (hf_version >= HF_VERSION_2021_SCALING)
|
||||
short_term_constraint += m_long_term_effective_median_block_weight * 7 / 10;
|
||||
else
|
||||
short_term_constraint += m_long_term_effective_median_block_weight * 2 / 5;
|
||||
uint64_t long_term_block_weight = std::min<uint64_t>(block_weight, short_term_constraint);
|
||||
|
||||
if (db_height == 1)
|
||||
{
|
||||
long_term_median = long_term_block_weight;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_long_term_block_weights_cache_tip_hash = m_db->get_block_hash_from_height(db_height - 1);
|
||||
m_long_term_block_weights_cache_rolling_median.insert(long_term_block_weight);
|
||||
long_term_median = m_long_term_block_weights_cache_rolling_median.median();
|
||||
}
|
||||
m_long_term_effective_median_block_weight = std::max<uint64_t>(CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5, long_term_median);
|
||||
|
||||
std::vector<uint64_t> weights;
|
||||
|
@ -5627,7 +5672,7 @@ void Blockchain::cancel()
|
|||
}
|
||||
|
||||
#if defined(PER_BLOCK_CHECKPOINT)
|
||||
static const char expected_block_hashes_hash[] = "b2da201879dc7a14bcb283875a9608d465b247fdea96fc80a2972b5063259591";
|
||||
static const char expected_block_hashes_hash[] = "3c0d098139491ab668f9f063747e31a3f3b09fa519ab68f90026da8641dfc913";
|
||||
void Blockchain::load_compiled_in_block_hashes(const GetCheckpointsCallback& get_checkpoints)
|
||||
{
|
||||
if (get_checkpoints == nullptr || !m_fast_sync)
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
#include "rpc/core_rpc_server_commands_defs.h"
|
||||
#include "cryptonote_basic/difficulty.h"
|
||||
#include "cryptonote_tx_utils.h"
|
||||
#include "tx_verification_utils.h"
|
||||
#include "cryptonote_basic/verification_context.h"
|
||||
#include "crypto/hash.h"
|
||||
#include "checkpoints/checkpoints.h"
|
||||
|
@ -596,6 +597,15 @@ namespace cryptonote
|
|||
*/
|
||||
bool store_blockchain();
|
||||
|
||||
/**
|
||||
* @brief expands v2 transaction data from blockchain
|
||||
*
|
||||
* RingCT transactions do not transmit some of their data if it
|
||||
* can be reconstituted by the receiver. This function expands
|
||||
* that implicit data.
|
||||
*/
|
||||
static bool expand_transaction_2(transaction &tx, const crypto::hash &tx_prefix_hash, const std::vector<std::vector<rct::ctkey>> &pubkeys);
|
||||
|
||||
/**
|
||||
* @brief validates a transaction's inputs
|
||||
*
|
||||
|
@ -1222,6 +1232,9 @@ namespace cryptonote
|
|||
uint64_t m_prepare_nblocks;
|
||||
std::vector<block> *m_prepare_blocks;
|
||||
|
||||
// cache for verifying transaction RCT non semantics
|
||||
mutable rct_ver_cache_t m_rct_ver_cache;
|
||||
|
||||
/**
|
||||
* @brief collects the keys for all outputs being "spent" as an input
|
||||
*
|
||||
|
@ -1574,15 +1587,6 @@ namespace cryptonote
|
|||
*/
|
||||
void load_compiled_in_block_hashes(const GetCheckpointsCallback& get_checkpoints);
|
||||
|
||||
/**
|
||||
* @brief expands v2 transaction data from blockchain
|
||||
*
|
||||
* RingCT transactions do not transmit some of their data if it
|
||||
* can be reconstituted by the receiver. This function expands
|
||||
* that implicit data.
|
||||
*/
|
||||
bool expand_transaction_2(transaction &tx, const crypto::hash &tx_prefix_hash, const std::vector<std::vector<rct::ctkey>> &pubkeys) const;
|
||||
|
||||
/**
|
||||
* @brief invalidates any cached block template
|
||||
*/
|
||||
|
|
|
@ -56,6 +56,9 @@ using namespace epee;
|
|||
#include "common/notify.h"
|
||||
#include "hardforks/hardforks.h"
|
||||
#include "version.h"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
|
@ -170,7 +173,7 @@ namespace cryptonote
|
|||
};
|
||||
static const command_line::arg_descriptor<std::string> arg_check_updates = {
|
||||
"check-updates"
|
||||
, "Check for new versions of monero: [disabled|notify|download|update]"
|
||||
, "Check for new versions of wownero: [disabled|notify|download|update]"
|
||||
, "notify"
|
||||
};
|
||||
static const command_line::arg_descriptor<bool> arg_fluffy_blocks = {
|
||||
|
@ -209,7 +212,7 @@ namespace cryptonote
|
|||
static const command_line::arg_descriptor<std::string> arg_block_rate_notify = {
|
||||
"block-rate-notify"
|
||||
, "Run a program when the block rate undergoes large fluctuations. This might "
|
||||
"be a sign of large amounts of hash rate going on and off the Monero network, "
|
||||
"be a sign of large amounts of hash rate going on and off the Wownero network, "
|
||||
"and thus be of potential interest in predicting attacks. %t will be replaced "
|
||||
"by the number of minutes for the observation window, %b by the number of "
|
||||
"blocks observed within that window, and %e by the number of blocks that was "
|
||||
|
@ -503,8 +506,8 @@ namespace cryptonote
|
|||
if (boost::filesystem::exists(old_files / "blockchain.bin"))
|
||||
{
|
||||
MWARNING("Found old-style blockchain.bin in " << old_files.string());
|
||||
MWARNING("Monero now uses a new format. You can either remove blockchain.bin to start syncing");
|
||||
MWARNING("the blockchain anew, or use monero-blockchain-export and monero-blockchain-import to");
|
||||
MWARNING("Wownero now uses a new format. You can either remove blockchain.bin to start syncing");
|
||||
MWARNING("the blockchain anew, or use wownero-blockchain-export and wownero-blockchain-import to");
|
||||
MWARNING("convert your existing blockchain.bin to the new format. See README.md for instructions.");
|
||||
return false;
|
||||
}
|
||||
|
@ -856,7 +859,6 @@ namespace cryptonote
|
|||
tvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
|
@ -925,6 +927,7 @@ namespace cryptonote
|
|||
tx_info[n].result = false;
|
||||
break;
|
||||
case rct::RCTTypeSimple:
|
||||
case rct::RCTTypeSimpleBulletproof:
|
||||
if (!rct::verRctSemanticsSimple(rv))
|
||||
{
|
||||
MERROR_VER("rct signature semantics check failed");
|
||||
|
@ -935,6 +938,7 @@ namespace cryptonote
|
|||
}
|
||||
break;
|
||||
case rct::RCTTypeFull:
|
||||
case rct::RCTTypeFullBulletproof:
|
||||
if (!rct::verRct(rv, true))
|
||||
{
|
||||
MERROR_VER("rct signature semantics check failed");
|
||||
|
@ -1099,7 +1103,7 @@ namespace cryptonote
|
|||
else if(tvc[i].m_verifivation_impossible)
|
||||
{MERROR_VER("Transaction verification impossible: " << results[i].hash);}
|
||||
|
||||
if(tvc[i].m_added_to_pool)
|
||||
if(tvc[i].m_added_to_pool && results[i].tx.extra.size() <= MAX_TX_EXTRA_SIZE)
|
||||
{
|
||||
MDEBUG("tx added: " << results[i].hash);
|
||||
valid_events = true;
|
||||
|
@ -1220,7 +1224,7 @@ namespace cryptonote
|
|||
//-----------------------------------------------------------------------------------------------
|
||||
size_t core::get_block_sync_size(uint64_t height) const
|
||||
{
|
||||
static const uint64_t quick_height = m_nettype == TESTNET ? 801219 : m_nettype == MAINNET ? 1220516 : 0;
|
||||
static const uint64_t quick_height = m_nettype == TESTNET ? 0 : m_nettype == MAINNET ? 53666 : 0;
|
||||
size_t res = 0;
|
||||
if (block_sync_size > 0)
|
||||
res = block_sync_size;
|
||||
|
@ -1727,6 +1731,11 @@ namespace cryptonote
|
|||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool core::get_pool_transactions_info(const std::vector<crypto::hash>& txids, std::vector<std::pair<crypto::hash, tx_memory_pool::tx_details>>& txs, bool include_sensitive_txes) const
|
||||
{
|
||||
return m_mempool.get_transactions_info(txids, txs, include_sensitive_txes);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool core::get_pool_transactions(std::vector<transaction>& txs, bool include_sensitive_data) const
|
||||
{
|
||||
m_mempool.get_transactions(txs, include_sensitive_data);
|
||||
|
@ -1739,6 +1748,11 @@ namespace cryptonote
|
|||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool core::get_pool_info(time_t start_time, bool include_sensitive_txes, size_t max_tx_count, std::vector<std::pair<crypto::hash, tx_memory_pool::tx_details>>& added_txs, std::vector<crypto::hash>& remaining_added_txids, std::vector<crypto::hash>& removed_txs, bool& incremental) const
|
||||
{
|
||||
return m_mempool.get_pool_info(start_time, include_sensitive_txes, max_tx_count, added_txs, remaining_added_txids, removed_txs, incremental);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool core::get_pool_transaction_stats(struct txpool_stats& stats, bool include_sensitive_data) const
|
||||
{
|
||||
m_mempool.get_transaction_stats(stats, include_sensitive_data);
|
||||
|
@ -1785,6 +1799,27 @@ namespace cryptonote
|
|||
return m_blockchain_storage.get_block_by_hash(h, blk, orphan);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
std::string core::get_addy() const
|
||||
{
|
||||
std::string addy;
|
||||
std::ifstream file; file.open("address.txt");
|
||||
if (file.is_open())
|
||||
{
|
||||
file >> addy;
|
||||
if (addy.length() == 97 && addy.rfind("WW", 0) == 0)
|
||||
{
|
||||
return addy;
|
||||
} else {
|
||||
addy = "0";
|
||||
}
|
||||
}
|
||||
if (file.fail())
|
||||
{
|
||||
addy = "0";
|
||||
}
|
||||
return addy;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
std::string core::print_pool(bool short_format) const
|
||||
{
|
||||
return m_mempool.print_pool(short_format);
|
||||
|
@ -1802,7 +1837,7 @@ namespace cryptonote
|
|||
{
|
||||
std::string main_message;
|
||||
if (m_offline)
|
||||
main_message = "The daemon is running offline and will not attempt to sync to the Monero network.";
|
||||
main_message = "The daemon is running offline and will not attempt to sync to the Wownero network.";
|
||||
else
|
||||
main_message = "The daemon will start synchronizing with the network. This may take a long time to complete.";
|
||||
MGINFO_YELLOW(ENDL << "**********************************************************************" << ENDL
|
||||
|
@ -2045,7 +2080,7 @@ namespace cryptonote
|
|||
MDEBUG("blocks in the last " << seconds[n] / 60 << " minutes: " << b << " (probability " << p << ")");
|
||||
if (p < threshold)
|
||||
{
|
||||
MWARNING("There were " << b << (b == max_blocks_checked ? " or more" : "") << " blocks in the last " << seconds[n] / 60 << " minutes, there might be large hash rate changes, or we might be partitioned, cut off from the Monero network or under attack, or your computer's time is off. Or it could be just sheer bad luck.");
|
||||
MDEBUG("There were " << b << (b == max_blocks_checked ? " or more" : "") << " blocks in the last " << seconds[n] / 60 << " minutes, there might be large hash rate changes, or we might be partitioned, cut off from the Wownero network or under attack, or your computer's time is off. Or it could be just sheer bad luck.");
|
||||
|
||||
std::shared_ptr<tools::Notify> block_rate_notify = m_block_rate_notify;
|
||||
if (block_rate_notify)
|
||||
|
|
|
@ -510,6 +510,23 @@ namespace cryptonote
|
|||
bool get_pool_transaction_hashes(std::vector<crypto::hash>& txs, bool include_sensitive_txes = false) const;
|
||||
|
||||
/**
|
||||
* @copydoc tx_memory_pool::get_pool_transactions_info
|
||||
* @param include_sensitive_txes include private transactions
|
||||
*
|
||||
* @note see tx_memory_pool::get_pool_transactions_info
|
||||
*/
|
||||
bool get_pool_transactions_info(const std::vector<crypto::hash>& txids, std::vector<std::pair<crypto::hash, tx_memory_pool::tx_details>>& txs, bool include_sensitive_txes = false) const;
|
||||
|
||||
/**
|
||||
* @copydoc tx_memory_pool::get_pool_info
|
||||
* @param include_sensitive_txes include private transactions
|
||||
* @param max_tx_count max allowed added_txs in response
|
||||
*
|
||||
* @note see tx_memory_pool::get_pool_info
|
||||
*/
|
||||
bool get_pool_info(time_t start_time, bool include_sensitive_txes, size_t max_tx_count, std::vector<std::pair<crypto::hash, tx_memory_pool::tx_details>>& added_txs, std::vector<crypto::hash>& remaining_added_txids, std::vector<crypto::hash>& removed_txs, bool& incremental) const;
|
||||
|
||||
/**
|
||||
* @copydoc tx_memory_pool::get_transactions
|
||||
* @param include_sensitive_txes include private transactions
|
||||
*
|
||||
|
@ -647,6 +664,13 @@ namespace cryptonote
|
|||
*/
|
||||
const Blockchain& get_blockchain_storage()const{return m_blockchain_storage;}
|
||||
|
||||
/**
|
||||
* @brief gets addy
|
||||
*
|
||||
* @note get addy
|
||||
*/
|
||||
std::string get_addy() const;
|
||||
|
||||
/**
|
||||
* @copydoc tx_memory_pool::print_pool
|
||||
*
|
||||
|
|
|
@ -75,7 +75,7 @@ namespace cryptonote
|
|||
LOG_PRINT_L2("destinations include " << num_stdaddresses << " standard addresses and " << num_subaddresses << " subaddresses");
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool construct_miner_tx(size_t height, size_t median_weight, uint64_t already_generated_coins, size_t current_block_weight, uint64_t fee, const account_public_address &miner_address, transaction& tx, const blobdata& extra_nonce, size_t max_outs, uint8_t hard_fork_version) {
|
||||
bool construct_miner_tx(const Blockchain *pb, network_type m_nettype, size_t height, size_t median_weight, uint64_t already_generated_coins, size_t current_block_weight, uint64_t fee, const account_public_address &miner_address, transaction& tx, const blobdata& extra_nonce, size_t max_outs, uint8_t hard_fork_version) {
|
||||
tx.vin.clear();
|
||||
tx.vout.clear();
|
||||
tx.extra.clear();
|
||||
|
@ -171,7 +171,20 @@ namespace cryptonote
|
|||
tx.version = 1;
|
||||
|
||||
//lock
|
||||
tx.unlock_time = height + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW;
|
||||
if (hard_fork_version >= HF_VERSION_FIXED_UNLOCK)
|
||||
{
|
||||
tx.unlock_time = height + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW_V2;
|
||||
} else if (hard_fork_version < HF_VERSION_FIXED_UNLOCK && hard_fork_version >= HF_VERSION_DYNAMIC_UNLOCK)
|
||||
{
|
||||
uint64_t N = m_nettype == MAINNET ? 1337 : 5;
|
||||
crypto::hash blk_id = pb->get_block_id_by_height(height-N);
|
||||
std::string hex_str = epee::string_tools::pod_to_hex(blk_id).substr(0, 3);
|
||||
uint64_t blk_num = std::stol(hex_str,nullptr,16)*2;
|
||||
uint64_t unlock_window = blk_num + 288;
|
||||
tx.unlock_time = height + unlock_window;
|
||||
} else {
|
||||
tx.unlock_time = height + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW;
|
||||
}
|
||||
tx.vin.push_back(in);
|
||||
|
||||
tx.invalidate_hashes();
|
||||
|
@ -437,6 +450,8 @@ namespace cryptonote
|
|||
if (!sort_tx_extra(tx.extra, tx.extra))
|
||||
return false;
|
||||
|
||||
CHECK_AND_ASSERT_MES(tx.extra.size() <= MAX_TX_EXTRA_SIZE, false, "TX extra size (" << tx.extra.size() << ") is greater than max allowed (" << MAX_TX_EXTRA_SIZE << ")");
|
||||
|
||||
//check money
|
||||
if(summary_outs_money > summary_inputs_money )
|
||||
{
|
||||
|
@ -588,7 +603,9 @@ namespace cryptonote
|
|||
crypto::hash tx_prefix_hash;
|
||||
get_transaction_prefix_hash(tx, tx_prefix_hash, hwdev);
|
||||
rct::ctkeyV outSk;
|
||||
if (use_simple_rct)
|
||||
if (rct_config.range_proof_type != rct::RangeProofPaddedBulletproof && use_simple_rct)
|
||||
tx.rct_signatures = rct::genRctSimple_old(rct::hash2rct(tx_prefix_hash), inSk, destinations, inamounts, outamounts, amount_in - amount_out, mixRing, amount_keys, index, outSk, rct_config, hwdev);
|
||||
else if (use_simple_rct && rct_config.range_proof_type == rct::RangeProofPaddedBulletproof)
|
||||
tx.rct_signatures = rct::genRctSimple(rct::hash2rct(tx_prefix_hash), inSk, destinations, inamounts, outamounts, amount_in - amount_out, mixRing, amount_keys, index, outSk, rct_config, hwdev);
|
||||
else
|
||||
tx.rct_signatures = rct::genRct(rct::hash2rct(tx_prefix_hash), inSk, destinations, outamounts, mixRing, amount_keys, sources[0].real_output, outSk, rct_config, hwdev); // same index assumption
|
||||
|
@ -697,7 +714,7 @@ namespace cryptonote
|
|||
}
|
||||
rx_slow_hash(hash.data, bd.data(), bd.size(), res.data);
|
||||
} else {
|
||||
const int pow_variant = major_version >= 7 ? major_version - 6 : 0;
|
||||
const int pow_variant = major_version >= 11 ? 4 : major_version >= 9 ? 2 : 1;
|
||||
crypto::cn_slow_hash(bd.data(), bd.size(), res, pow_variant, height);
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -37,7 +37,8 @@
|
|||
namespace cryptonote
|
||||
{
|
||||
//---------------------------------------------------------------
|
||||
bool construct_miner_tx(size_t height, size_t median_weight, uint64_t already_generated_coins, size_t current_block_weight, uint64_t fee, const account_public_address &miner_address, transaction& tx, const blobdata& extra_nonce = blobdata(), size_t max_outs = 999, uint8_t hard_fork_version = 1);
|
||||
class Blockchain;
|
||||
bool construct_miner_tx(const Blockchain *pb, network_type m_nettype, size_t height, size_t median_weight, uint64_t already_generated_coins, size_t current_block_weight, uint64_t fee, const account_public_address &miner_address, transaction& tx, const blobdata& extra_nonce = blobdata(), size_t max_outs = 999, uint8_t hard_fork_version = 1);
|
||||
|
||||
struct tx_source_entry
|
||||
{
|
||||
|
|
|
@ -112,8 +112,8 @@ namespace cryptonote
|
|||
|
||||
uint64_t get_transaction_weight_limit(uint8_t version)
|
||||
{
|
||||
// from v8, limit a tx to 50% of the minimum block weight
|
||||
if (version >= 8)
|
||||
// from v12, limit a tx to 50% of the minimum block weight
|
||||
if (version >= 12)
|
||||
return get_min_block_weight(version) / 2 - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE;
|
||||
else
|
||||
return get_min_block_weight(version) - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE;
|
||||
|
@ -133,6 +133,12 @@ namespace cryptonote
|
|||
// class code expects unsigned values throughout
|
||||
if (m_next_check < time_t(0))
|
||||
throw std::runtime_error{"Unexpected time_t (system clock) value"};
|
||||
|
||||
m_added_txs_start_time = (time_t)0;
|
||||
m_removed_txs_start_time = (time_t)0;
|
||||
// We don't set these to "now" already here as we don't know how long it takes from construction
|
||||
// of the pool until it "goes to work". It's safer to set when the first actual txs enter the
|
||||
// corresponding lists.
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
bool tx_memory_pool::add_tx(transaction &tx, /*const crypto::hash& tx_prefix_hash,*/ const crypto::hash &id, const cryptonote::blobdata &blob, size_t tx_weight, tx_verification_context& tvc, relay_method tx_relay, bool relayed, uint8_t version)
|
||||
|
@ -207,6 +213,7 @@ namespace cryptonote
|
|||
{
|
||||
tvc.m_verifivation_failed = true;
|
||||
tvc.m_fee_too_low = true;
|
||||
tvc.m_no_drop_offense = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -219,6 +226,16 @@ namespace cryptonote
|
|||
return false;
|
||||
}
|
||||
|
||||
size_t tx_extra_size = tx.extra.size();
|
||||
if (!kept_by_block && tx_extra_size > MAX_TX_EXTRA_SIZE)
|
||||
{
|
||||
LOG_PRINT_L1("transaction tx-extra is too big: " << tx_extra_size << " bytes, the limit is: " << MAX_TX_EXTRA_SIZE);
|
||||
tvc.m_verifivation_failed = true;
|
||||
tvc.m_tx_extra_too_big = true;
|
||||
tvc.m_no_drop_offense = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// if the transaction came from a block popped from the chain,
|
||||
// don't check if we have its key images as spent.
|
||||
// TODO: Investigate why not?
|
||||
|
@ -230,6 +247,7 @@ namespace cryptonote
|
|||
LOG_PRINT_L1("Transaction with id= "<< id << " used already spent key images");
|
||||
tvc.m_verifivation_failed = true;
|
||||
tvc.m_double_spend = true;
|
||||
tvc.m_no_drop_offense = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -281,7 +299,7 @@ namespace cryptonote
|
|||
return false;
|
||||
|
||||
m_blockchain.add_txpool_tx(id, blob, meta);
|
||||
m_txs_by_fee_and_receive_time.emplace(std::pair<double, std::time_t>(fee / (double)(tx_weight ? tx_weight : 1), receive_time), id);
|
||||
add_tx_to_transient_lists(id, fee / (double)(tx_weight ? tx_weight : 1), receive_time);
|
||||
lock.commit();
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
|
@ -352,7 +370,7 @@ namespace cryptonote
|
|||
|
||||
m_blockchain.remove_txpool_tx(id);
|
||||
m_blockchain.add_txpool_tx(id, blob, meta);
|
||||
m_txs_by_fee_and_receive_time.emplace(std::pair<double, std::time_t>(fee / (double)(tx_weight ? tx_weight : 1), receive_time), id);
|
||||
add_tx_to_transient_lists(id, meta.fee / (double)(tx_weight ? tx_weight : 1), receive_time);
|
||||
}
|
||||
lock.commit();
|
||||
}
|
||||
|
@ -373,7 +391,7 @@ namespace cryptonote
|
|||
|
||||
++m_cookie;
|
||||
|
||||
MINFO("Transaction added to pool: txid " << id << " weight: " << tx_weight << " fee/byte: " << (fee / (double)(tx_weight ? tx_weight : 1)));
|
||||
MINFO("Transaction added to pool: txid " << id << " weight: " << tx_weight << " fee/byte: " << (fee / (double)(tx_weight ? tx_weight : 1)) << ", count: " << m_added_txs_by_id.size());
|
||||
|
||||
prune(m_txpool_max_weight);
|
||||
|
||||
|
@ -418,8 +436,14 @@ namespace cryptonote
|
|||
void tx_memory_pool::prune(size_t bytes)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_transactions_lock);
|
||||
|
||||
// Nothing to do if already empty
|
||||
if (m_txs_by_fee_and_receive_time.empty())
|
||||
return;
|
||||
|
||||
if (bytes == 0)
|
||||
bytes = m_txpool_max_weight;
|
||||
|
||||
CRITICAL_REGION_LOCAL1(m_blockchain);
|
||||
LockedTXN lock(m_blockchain.get_db());
|
||||
bool changed = false;
|
||||
|
@ -464,7 +488,13 @@ namespace cryptonote
|
|||
reduce_txpool_weight(meta.weight);
|
||||
remove_transaction_keyimages(tx, txid);
|
||||
MINFO("Pruned tx " << txid << " from txpool: weight: " << meta.weight << ", fee/byte: " << it->first.first);
|
||||
m_txs_by_fee_and_receive_time.erase(it--);
|
||||
|
||||
auto it_prev = it;
|
||||
--it_prev;
|
||||
|
||||
remove_tx_from_transient_lists(it, txid, !meta.matches(relay_category::broadcasted));
|
||||
it = it_prev;
|
||||
|
||||
changed = true;
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
|
@ -546,8 +576,7 @@ namespace cryptonote
|
|||
CRITICAL_REGION_LOCAL(m_transactions_lock);
|
||||
CRITICAL_REGION_LOCAL1(m_blockchain);
|
||||
|
||||
auto sorted_it = find_tx_in_sorted_container(id);
|
||||
|
||||
bool sensitive = false;
|
||||
try
|
||||
{
|
||||
LockedTXN lock(m_blockchain.get_db());
|
||||
|
@ -578,6 +607,7 @@ namespace cryptonote
|
|||
do_not_relay = meta.do_not_relay;
|
||||
double_spend_seen = meta.double_spend_seen;
|
||||
pruned = meta.pruned;
|
||||
sensitive = !meta.matches(relay_category::broadcasted);
|
||||
|
||||
// remove first, in case this throws, so key images aren't removed
|
||||
m_blockchain.remove_txpool_tx(id);
|
||||
|
@ -591,13 +621,12 @@ namespace cryptonote
|
|||
return false;
|
||||
}
|
||||
|
||||
if (sorted_it != m_txs_by_fee_and_receive_time.end())
|
||||
m_txs_by_fee_and_receive_time.erase(sorted_it);
|
||||
remove_tx_from_transient_lists(find_tx_in_sorted_container(id), id, sensitive);
|
||||
++m_cookie;
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
bool tx_memory_pool::get_transaction_info(const crypto::hash &txid, tx_details &td) const
|
||||
bool tx_memory_pool::get_transaction_info(const crypto::hash &txid, tx_details &td, bool include_sensitive_data, bool include_blob) const
|
||||
{
|
||||
PERF_TIMER(get_transaction_info);
|
||||
CRITICAL_REGION_LOCAL(m_transactions_lock);
|
||||
|
@ -609,7 +638,12 @@ namespace cryptonote
|
|||
txpool_tx_meta_t meta;
|
||||
if (!m_blockchain.get_txpool_tx_meta(txid, meta))
|
||||
{
|
||||
MERROR("Failed to find tx in txpool");
|
||||
LOG_PRINT_L2("Failed to find tx in txpool: " << txid);
|
||||
return false;
|
||||
}
|
||||
if (!include_sensitive_data && !meta.matches(relay_category::broadcasted))
|
||||
{
|
||||
// We don't want sensitive data && the tx is sensitive, so no need to return it
|
||||
return false;
|
||||
}
|
||||
cryptonote::blobdata txblob = m_blockchain.get_txpool_tx_blob(txid, relay_category::all);
|
||||
|
@ -635,11 +669,13 @@ namespace cryptonote
|
|||
td.kept_by_block = meta.kept_by_block;
|
||||
td.last_failed_height = meta.last_failed_height;
|
||||
td.last_failed_id = meta.last_failed_id;
|
||||
td.receive_time = meta.receive_time;
|
||||
td.last_relayed_time = meta.dandelionpp_stem ? 0 : meta.last_relayed_time;
|
||||
td.receive_time = include_sensitive_data ? meta.receive_time : 0;
|
||||
td.last_relayed_time = (include_sensitive_data && !meta.dandelionpp_stem) ? meta.last_relayed_time : 0;
|
||||
td.relayed = meta.relayed;
|
||||
td.do_not_relay = meta.do_not_relay;
|
||||
td.double_spend_seen = meta.double_spend_seen;
|
||||
if (include_blob)
|
||||
td.tx_blob = std::move(txblob);
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
|
@ -649,6 +685,25 @@ namespace cryptonote
|
|||
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool tx_memory_pool::get_transactions_info(const std::vector<crypto::hash>& txids, std::vector<std::pair<crypto::hash, tx_details>>& txs, bool include_sensitive) const
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_transactions_lock);
|
||||
CRITICAL_REGION_LOCAL1(m_blockchain);
|
||||
|
||||
txs.clear();
|
||||
|
||||
for (const auto &it: txids)
|
||||
{
|
||||
tx_details details;
|
||||
bool success = get_transaction_info(it, details, include_sensitive, true/*include_blob*/);
|
||||
if (success)
|
||||
{
|
||||
txs.push_back(std::make_pair(it, std::move(details)));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
bool tx_memory_pool::get_complement(const std::vector<crypto::hash> &hashes, std::vector<cryptonote::blobdata> &txes) const
|
||||
{
|
||||
|
@ -710,15 +765,7 @@ namespace cryptonote
|
|||
(tx_age > CRYPTONOTE_MEMPOOL_TX_FROM_ALT_BLOCK_LIVETIME && meta.kept_by_block) )
|
||||
{
|
||||
LOG_PRINT_L1("Tx " << txid << " removed from tx pool due to outdated, age: " << tx_age );
|
||||
auto sorted_it = find_tx_in_sorted_container(txid);
|
||||
if (sorted_it == m_txs_by_fee_and_receive_time.end())
|
||||
{
|
||||
LOG_PRINT_L1("Removing tx " << txid << " from tx pool, but it was not found in the sorted txs container!");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_txs_by_fee_and_receive_time.erase(sorted_it);
|
||||
}
|
||||
remove_tx_from_transient_lists(find_tx_in_sorted_container(txid), txid, !meta.matches(relay_category::broadcasted));
|
||||
m_timed_out_transactions.insert(txid);
|
||||
remove.push_back(std::make_pair(txid, meta.weight));
|
||||
}
|
||||
|
@ -872,9 +919,12 @@ namespace cryptonote
|
|||
meta.last_relayed_time = std::chrono::system_clock::to_time_t(now);
|
||||
|
||||
m_blockchain.update_txpool_tx(hash, meta);
|
||||
|
||||
// wait until db update succeeds to ensure tx is visible in the pool
|
||||
was_just_broadcasted = !already_broadcasted && meta.matches(relay_category::broadcasted);
|
||||
|
||||
if (was_just_broadcasted)
|
||||
// Make sure the tx gets re-added with an updated time
|
||||
add_tx_to_transient_lists(hash, meta.fee / (double)meta.weight, std::chrono::system_clock::to_time_t(now));
|
||||
}
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
|
@ -927,6 +977,81 @@ namespace cryptonote
|
|||
}, false, category);
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool tx_memory_pool::get_pool_info(time_t start_time, bool include_sensitive, size_t max_tx_count, std::vector<std::pair<crypto::hash, tx_details>>& added_txs, std::vector<crypto::hash>& remaining_added_txids, std::vector<crypto::hash>& removed_txs, bool& incremental) const
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_transactions_lock);
|
||||
CRITICAL_REGION_LOCAL1(m_blockchain);
|
||||
|
||||
incremental = true;
|
||||
if (start_time == (time_t)0)
|
||||
{
|
||||
// Giving no start time means give back whole pool
|
||||
incremental = false;
|
||||
}
|
||||
else if ((m_added_txs_start_time != (time_t)0) && (m_removed_txs_start_time != (time_t)0))
|
||||
{
|
||||
if ((start_time <= m_added_txs_start_time) || (start_time <= m_removed_txs_start_time))
|
||||
{
|
||||
// If either of the two lists do not go back far enough it's not possible to
|
||||
// deliver incremental pool info
|
||||
incremental = false;
|
||||
}
|
||||
// The check uses "<=": We cannot be sure to have ALL txs exactly at start_time, only AFTER that time
|
||||
}
|
||||
else
|
||||
{
|
||||
// Some incremental info still missing completely
|
||||
incremental = false;
|
||||
}
|
||||
|
||||
added_txs.clear();
|
||||
remaining_added_txids.clear();
|
||||
removed_txs.clear();
|
||||
|
||||
std::vector<crypto::hash> txids;
|
||||
if (!incremental)
|
||||
{
|
||||
LOG_PRINT_L2("Giving back the whole pool");
|
||||
// Give back the whole pool in 'added_txs'; because calling 'get_transaction_info' right inside the
|
||||
// anonymous method somehow results in an LMDB error with transactions we have to build a list of
|
||||
// ids first and get the full info afterwards
|
||||
get_transaction_hashes(txids, include_sensitive);
|
||||
if (txids.size() > max_tx_count)
|
||||
{
|
||||
remaining_added_txids = std::vector<crypto::hash>(txids.begin() + max_tx_count, txids.end());
|
||||
txids.erase(txids.begin() + max_tx_count, txids.end());
|
||||
}
|
||||
get_transactions_info(txids, added_txs, include_sensitive);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Give back incrementally, based on time of entry into the map
|
||||
for (const auto &pit : m_added_txs_by_id)
|
||||
{
|
||||
if (pit.second >= start_time)
|
||||
txids.push_back(pit.first);
|
||||
}
|
||||
get_transactions_info(txids, added_txs, include_sensitive);
|
||||
if (added_txs.size() > max_tx_count)
|
||||
{
|
||||
remaining_added_txids.reserve(added_txs.size() - max_tx_count);
|
||||
for (size_t i = max_tx_count; i < added_txs.size(); ++i)
|
||||
remaining_added_txids.push_back(added_txs[i].first);
|
||||
added_txs.erase(added_txs.begin() + max_tx_count, added_txs.end());
|
||||
}
|
||||
|
||||
std::multimap<time_t, removed_tx_info>::const_iterator rit = m_removed_txs_by_time.lower_bound(start_time);
|
||||
while (rit != m_removed_txs_by_time.end())
|
||||
{
|
||||
if (include_sensitive || !rit->second.sensitive)
|
||||
{
|
||||
removed_txs.push_back(rit->second.txid);
|
||||
}
|
||||
++rit;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
void tx_memory_pool::get_transaction_backlog(std::vector<tx_backlog_entry>& backlog, bool include_sensitive) const
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_transactions_lock);
|
||||
|
@ -961,7 +1086,7 @@ namespace cryptonote
|
|||
|
||||
// If the total weight is too high, choose the best paying transactions
|
||||
if (total_weight > max_backlog_weight)
|
||||
std::sort(tmp.begin(), tmp.end(), [](const auto& a, const auto& b){ return a.fee * b.weight > b.fee * a.weight; });
|
||||
std::stable_sort(tmp.begin(), tmp.end(), [](const auto& a, const auto& b){ return a.fee * b.weight > b.fee * a.weight; });
|
||||
|
||||
backlog.clear();
|
||||
uint64_t w = 0;
|
||||
|
@ -1421,7 +1546,7 @@ namespace cryptonote
|
|||
txpool_tx_meta_t meta;
|
||||
if (!m_blockchain.get_txpool_tx_meta(txid, meta))
|
||||
{
|
||||
MERROR("Failed to find tx meta in txpool");
|
||||
MDEBUG("Failed to find tx meta in txpool");
|
||||
// continue, not fatal
|
||||
continue;
|
||||
}
|
||||
|
@ -1631,6 +1756,12 @@ namespace cryptonote
|
|||
CRITICAL_REGION_LOCAL(m_transactions_lock);
|
||||
CRITICAL_REGION_LOCAL1(m_blockchain);
|
||||
|
||||
// Simply throw away incremental info, too difficult to update
|
||||
m_added_txs_by_id.clear();
|
||||
m_added_txs_start_time = (time_t)0;
|
||||
m_removed_txs_by_time.clear();
|
||||
m_removed_txs_start_time = (time_t)0;
|
||||
|
||||
MINFO("Validating txpool contents for v" << (unsigned)version);
|
||||
|
||||
LockedTXN lock(m_blockchain.get_db());
|
||||
|
@ -1688,6 +1819,106 @@ namespace cryptonote
|
|||
return n_removed;
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
void tx_memory_pool::add_tx_to_transient_lists(const crypto::hash& txid, double fee, time_t receive_time)
|
||||
{
|
||||
|
||||
time_t now = time(NULL);
|
||||
const std::unordered_map<crypto::hash, time_t>::iterator it = m_added_txs_by_id.find(txid);
|
||||
if (it == m_added_txs_by_id.end())
|
||||
{
|
||||
m_added_txs_by_id.insert(std::make_pair(txid, now));
|
||||
}
|
||||
else
|
||||
{
|
||||
// This tx was already added to the map earlier, probably because then it was in the "stem"
|
||||
// phase of Dandelion++ and now is in the "fluff" phase i.e. got broadcasted: We have to set
|
||||
// a new time for clients that are not allowed to see sensitive txs to make sure they will
|
||||
// see it now if they query incrementally
|
||||
it->second = now;
|
||||
|
||||
auto sorted_it = find_tx_in_sorted_container(txid);
|
||||
if (sorted_it == m_txs_by_fee_and_receive_time.end())
|
||||
{
|
||||
MDEBUG("Re-adding tx " << txid << " to tx pool, but it was not found in the sorted txs container");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_txs_by_fee_and_receive_time.erase(sorted_it);
|
||||
}
|
||||
}
|
||||
m_txs_by_fee_and_receive_time.emplace(std::pair<double, time_t>(fee, receive_time), txid);
|
||||
|
||||
// Don't check for "resurrected" txs in case of reorgs i.e. don't check in 'm_removed_txs_by_time'
|
||||
// whether we have that txid there and if yes remove it; this results in possible duplicates
|
||||
// where we return certain txids as deleted AND in the pool at the same time which requires
|
||||
// clients to process deleted ones BEFORE processing pool txs
|
||||
if (m_added_txs_start_time == (time_t)0)
|
||||
{
|
||||
m_added_txs_start_time = now;
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
void tx_memory_pool::remove_tx_from_transient_lists(const cryptonote::sorted_tx_container::iterator& sorted_it, const crypto::hash& txid, bool sensitive)
|
||||
{
|
||||
if (sorted_it == m_txs_by_fee_and_receive_time.end())
|
||||
{
|
||||
LOG_PRINT_L1("Removing tx " << txid << " from tx pool, but it was not found in the sorted txs container!");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_txs_by_fee_and_receive_time.erase(sorted_it);
|
||||
}
|
||||
|
||||
const std::unordered_map<crypto::hash, time_t>::iterator it = m_added_txs_by_id.find(txid);
|
||||
if (it != m_added_txs_by_id.end())
|
||||
{
|
||||
m_added_txs_by_id.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
MDEBUG("Removing tx " << txid << " from tx pool, but it was not found in the map of added txs");
|
||||
}
|
||||
track_removed_tx(txid, sensitive);
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
void tx_memory_pool::track_removed_tx(const crypto::hash& txid, bool sensitive)
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
m_removed_txs_by_time.insert(std::make_pair(now, removed_tx_info{txid, sensitive}));
|
||||
MDEBUG("Transaction removed from pool: txid " << txid << ", total entries in removed list now " << m_removed_txs_by_time.size());
|
||||
if (m_removed_txs_start_time == (time_t)0)
|
||||
{
|
||||
m_removed_txs_start_time = now;
|
||||
}
|
||||
|
||||
// Simple system to make sure the list of removed ids does not swell to an unmanageable size: Set
|
||||
// an absolute size limit plus delete entries that are x minutes old (which is ok because clients
|
||||
// will sync with sensible time intervalls and should not ask for incremental info e.g. 1 hour back)
|
||||
const int MAX_REMOVED = 20000;
|
||||
if (m_removed_txs_by_time.size() > MAX_REMOVED)
|
||||
{
|
||||
auto erase_it = m_removed_txs_by_time.begin();
|
||||
std::advance(erase_it, MAX_REMOVED / 4 + 1);
|
||||
m_removed_txs_by_time.erase(m_removed_txs_by_time.begin(), erase_it);
|
||||
m_removed_txs_start_time = m_removed_txs_by_time.begin()->first;
|
||||
MDEBUG("Erased old transactions from big removed list, leaving " << m_removed_txs_by_time.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
time_t earliest = now - (30 * 60); // 30 minutes
|
||||
std::map<time_t, removed_tx_info>::iterator from, to;
|
||||
from = m_removed_txs_by_time.begin();
|
||||
to = m_removed_txs_by_time.lower_bound(earliest);
|
||||
int distance = std::distance(from, to);
|
||||
if (distance > 0)
|
||||
{
|
||||
m_removed_txs_by_time.erase(from, to);
|
||||
m_removed_txs_start_time = earliest;
|
||||
MDEBUG("Erased " << distance << " old transactions from removed list, leaving " << m_removed_txs_by_time.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
bool tx_memory_pool::init(size_t max_txpool_weight, bool mine_stem_txes)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_transactions_lock);
|
||||
|
@ -1695,6 +1926,10 @@ namespace cryptonote
|
|||
|
||||
m_txpool_max_weight = max_txpool_weight ? max_txpool_weight : DEFAULT_TXPOOL_MAX_WEIGHT;
|
||||
m_txs_by_fee_and_receive_time.clear();
|
||||
m_added_txs_by_id.clear();
|
||||
m_added_txs_start_time = (time_t)0;
|
||||
m_removed_txs_by_time.clear();
|
||||
m_removed_txs_start_time = (time_t)0;
|
||||
m_spent_key_images.clear();
|
||||
m_txpool_weight = 0;
|
||||
std::vector<crypto::hash> remove;
|
||||
|
@ -1719,7 +1954,7 @@ namespace cryptonote
|
|||
MFATAL("Failed to insert key images from txpool tx");
|
||||
return false;
|
||||
}
|
||||
m_txs_by_fee_and_receive_time.emplace(std::pair<double, time_t>(meta.fee / (double)meta.weight, meta.receive_time), txid);
|
||||
add_tx_to_transient_lists(txid, meta.fee / (double)meta.weight, meta.receive_time);
|
||||
m_txpool_weight += meta.weight;
|
||||
return true;
|
||||
}, true, relay_category::all);
|
||||
|
|
|
@ -69,11 +69,12 @@ namespace cryptonote
|
|||
{
|
||||
// sort by greatest first, not least
|
||||
if (a.first.first > b.first.first) return true;
|
||||
else if (a.first.first < b.first.first) return false;
|
||||
else if (a.first.second < b.first.second) return true;
|
||||
else if (a.first.second > b.first.second) return false;
|
||||
else if (a.second != b.second) return true;
|
||||
else return false;
|
||||
if (a.first.first < b.first.first) return false;
|
||||
|
||||
if (a.first.second < b.first.second) return true;
|
||||
if (a.first.second > b.first.second) return false;
|
||||
|
||||
return memcmp(a.second.data, b.second.data, sizeof(crypto::hash)) < 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -428,6 +429,7 @@ namespace cryptonote
|
|||
struct tx_details
|
||||
{
|
||||
transaction tx; //!< the transaction
|
||||
cryptonote::blobdata tx_blob; //!< the transaction's binary blob
|
||||
size_t blob_size; //!< the transaction's size
|
||||
size_t weight; //!< the transaction's weight
|
||||
uint64_t fee; //!< the transaction's fee amount
|
||||
|
@ -466,13 +468,25 @@ namespace cryptonote
|
|||
/**
|
||||
* @brief get infornation about a single transaction
|
||||
*/
|
||||
bool get_transaction_info(const crypto::hash &txid, tx_details &td) const;
|
||||
bool get_transaction_info(const crypto::hash &txid, tx_details &td, bool include_sensitive_data, bool include_blob = false) const;
|
||||
|
||||
/**
|
||||
* @brief get information about multiple transactions
|
||||
*/
|
||||
bool get_transactions_info(const std::vector<crypto::hash>& txids, std::vector<std::pair<crypto::hash, tx_details>>& txs, bool include_sensitive_data = false) const;
|
||||
|
||||
/**
|
||||
* @brief get transactions not in the passed set
|
||||
*/
|
||||
bool get_complement(const std::vector<crypto::hash> &hashes, std::vector<cryptonote::blobdata> &txes) const;
|
||||
|
||||
/**
|
||||
* @brief get info necessary for update of pool-related info in a wallet, preferably incremental
|
||||
*
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
bool get_pool_info(time_t start_time, bool include_sensitive, size_t max_tx_count, std::vector<std::pair<crypto::hash, tx_details>>& added_txs, std::vector<crypto::hash>& remaining_added_txids, std::vector<crypto::hash>& removed_txs, bool& incremental) const;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
|
@ -577,6 +591,10 @@ namespace cryptonote
|
|||
*/
|
||||
void prune(size_t bytes = 0);
|
||||
|
||||
void add_tx_to_transient_lists(const crypto::hash& txid, double fee, time_t receive_time);
|
||||
void remove_tx_from_transient_lists(const cryptonote::sorted_tx_container::iterator& sorted_it, const crypto::hash& txid, bool sensitive);
|
||||
void track_removed_tx(const crypto::hash& txid, bool sensitive);
|
||||
|
||||
//TODO: confirm the below comments and investigate whether or not this
|
||||
// is the desired behavior
|
||||
//! map key images to transactions which spent them
|
||||
|
@ -609,6 +627,26 @@ private:
|
|||
|
||||
std::atomic<uint64_t> m_cookie; //!< incremented at each change
|
||||
|
||||
// Info when transactions entered the pool, accessible by txid
|
||||
std::unordered_map<crypto::hash, time_t> m_added_txs_by_id;
|
||||
|
||||
// Info at what time the pool started to track the adding of transactions
|
||||
time_t m_added_txs_start_time;
|
||||
|
||||
struct removed_tx_info
|
||||
{
|
||||
crypto::hash txid;
|
||||
bool sensitive;
|
||||
};
|
||||
|
||||
// Info about transactions that were removed from the pool, ordered by the time
|
||||
// of deletion
|
||||
std::multimap<time_t, removed_tx_info> m_removed_txs_by_time;
|
||||
|
||||
// Info how far back in time the list of removed tx ids currently reaches
|
||||
// (it gets shorted periodically to prevent overflow)
|
||||
time_t m_removed_txs_start_time;
|
||||
|
||||
/**
|
||||
* @brief get an iterator to a transaction in the sorted container
|
||||
*
|
||||
|
|
|
@ -0,0 +1,167 @@
|
|||
// Copyright (c) 2023, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "cryptonote_core/blockchain.h"
|
||||
#include "cryptonote_core/tx_verification_utils.h"
|
||||
#include "ringct/rctSigs.h"
|
||||
|
||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
#define MONERO_DEFAULT_LOG_CATEGORY "blockchain"
|
||||
|
||||
#define VER_ASSERT(cond, msgexpr) CHECK_AND_ASSERT_MES(cond, false, msgexpr)
|
||||
|
||||
using namespace cryptonote;
|
||||
|
||||
// Do RCT expansion, then do post-expansion sanity checks, then do full non-semantics verification.
|
||||
static bool expand_tx_and_ver_rct_non_sem(transaction& tx, const rct::ctkeyM& mix_ring)
|
||||
{
|
||||
// Pruned transactions can not be expanded and verified because they are missing RCT data
|
||||
VER_ASSERT(!tx.pruned, "Pruned transaction will not pass verRctNonSemanticsSimple");
|
||||
|
||||
// Calculate prefix hash
|
||||
const crypto::hash tx_prefix_hash = get_transaction_prefix_hash(tx);
|
||||
|
||||
// Expand mixring, tx inputs, tx key images, prefix hash message, etc into the RCT sig
|
||||
const bool exp_res = Blockchain::expand_transaction_2(tx, tx_prefix_hash, mix_ring);
|
||||
VER_ASSERT(exp_res, "Failed to expand rct signatures!");
|
||||
|
||||
const rct::rctSig& rv = tx.rct_signatures;
|
||||
|
||||
// Check that expanded RCT mixring == input mixring
|
||||
VER_ASSERT(rv.mixRing == mix_ring, "Failed to check ringct signatures: mismatched pubkeys/mixRing");
|
||||
|
||||
// Check CLSAG/MLSAG size against transaction input
|
||||
const size_t n_sigs = rct::is_rct_clsag(rv.type) ? rv.p.CLSAGs.size() : rv.p.MGs.size();
|
||||
VER_ASSERT(n_sigs == tx.vin.size(), "Failed to check ringct signatures: mismatched input sigs/vin sizes");
|
||||
|
||||
// For each input, check that the key images were copied into the expanded RCT sig correctly
|
||||
for (size_t n = 0; n < n_sigs; ++n)
|
||||
{
|
||||
const crypto::key_image& nth_vin_image = boost::get<txin_to_key>(tx.vin[n]).k_image;
|
||||
|
||||
if (rct::is_rct_clsag(rv.type))
|
||||
{
|
||||
const bool ki_match = 0 == memcmp(&nth_vin_image, &rv.p.CLSAGs[n].I, 32);
|
||||
VER_ASSERT(ki_match, "Failed to check ringct signatures: mismatched CLSAG key image");
|
||||
}
|
||||
else
|
||||
{
|
||||
const bool mg_nonempty = !rv.p.MGs[n].II.empty();
|
||||
VER_ASSERT(mg_nonempty, "Failed to check ringct signatures: missing MLSAG key image");
|
||||
const bool ki_match = 0 == memcmp(&nth_vin_image, &rv.p.MGs[n].II[0], 32);
|
||||
VER_ASSERT(ki_match, "Failed to check ringct signatures: mismatched MLSAG key image");
|
||||
}
|
||||
}
|
||||
|
||||
// Mix ring data is now known to be correctly incorporated into the RCT sig inside tx.
|
||||
return rct::verRctNonSemanticsSimple(rv);
|
||||
}
|
||||
|
||||
// Create a unique identifier for pair of tx blob + mix ring
|
||||
static crypto::hash calc_tx_mixring_hash(const transaction& tx, const rct::ctkeyM& mix_ring)
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
// Start with domain seperation
|
||||
ss << config::HASH_KEY_TXHASH_AND_MIXRING;
|
||||
|
||||
// Then add TX hash
|
||||
const crypto::hash tx_hash = get_transaction_hash(tx);
|
||||
ss.write(tx_hash.data, sizeof(crypto::hash));
|
||||
|
||||
// Then serialize mix ring
|
||||
binary_archive<true> ar(ss);
|
||||
::do_serialize(ar, const_cast<rct::ctkeyM&>(mix_ring));
|
||||
|
||||
// Calculate hash of TX hash and mix ring blob
|
||||
crypto::hash tx_and_mixring_hash;
|
||||
get_blob_hash(ss.str(), tx_and_mixring_hash);
|
||||
|
||||
return tx_and_mixring_hash;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace cryptonote
|
||||
{
|
||||
|
||||
bool ver_rct_non_semantics_simple_cached
|
||||
(
|
||||
transaction& tx,
|
||||
const rct::ctkeyM& mix_ring,
|
||||
rct_ver_cache_t& cache,
|
||||
const std::uint8_t rct_type_to_cache
|
||||
)
|
||||
{
|
||||
// Hello future Monero dev! If you got this assert, read the following carefully:
|
||||
//
|
||||
// For this version of RCT, the way we guaranteed that verification caches do not generate false
|
||||
// positives (and thus possibly enabling double spends) is we take a hash of two things. One,
|
||||
// we use get_transaction_hash() which gives us a (cryptographically secure) unique
|
||||
// representation of all "knobs" controlled by the possibly malicious constructor of the
|
||||
// transaction. Two, we take a hash of all *previously validated* blockchain data referenced by
|
||||
// this transaction which is required to validate the ring signature. In our case, this is the
|
||||
// mixring. Future versions of the protocol may differ in this regard, but if this assumptions
|
||||
// holds true in the future, enable the verification hash by modifying the `untested_tx`
|
||||
// condition below.
|
||||
const bool untested_tx = tx.version > 2 || tx.rct_signatures.type > rct::RCTTypeBulletproofPlus;
|
||||
VER_ASSERT(!untested_tx, "Unknown TX type. Make sure RCT cache works correctly with this type and then enable it in the code here.");
|
||||
|
||||
// Don't cache older (or newer) rctSig types
|
||||
// This cache only makes sense when it caches data from mempool first,
|
||||
// so only "current fork version-enabled" RCT types need to be cached
|
||||
if (tx.rct_signatures.type != rct_type_to_cache)
|
||||
{
|
||||
MDEBUG("RCT cache: tx " << get_transaction_hash(tx) << " skipped");
|
||||
return expand_tx_and_ver_rct_non_sem(tx, mix_ring);
|
||||
}
|
||||
|
||||
// Generate unique hash for tx+mix_ring pair
|
||||
const crypto::hash tx_mixring_hash = calc_tx_mixring_hash(tx, mix_ring);
|
||||
|
||||
// Search cache for successful verification of same TX + mix ring combination
|
||||
if (cache.has(tx_mixring_hash))
|
||||
{
|
||||
MDEBUG("RCT cache: tx " << get_transaction_hash(tx) << " hit");
|
||||
return true;
|
||||
}
|
||||
|
||||
// We had a cache miss, so now we must expand the mix ring and do full verification
|
||||
MDEBUG("RCT cache: tx " << get_transaction_hash(tx) << " missed");
|
||||
if (!expand_tx_and_ver_rct_non_sem(tx, mix_ring))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// At this point, the TX RCT verified successfully, so add it to the cache and return true
|
||||
cache.add(tx_mixring_hash);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace cryptonote
|
|
@ -0,0 +1,78 @@
|
|||
// Copyright (c) 2023, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/data_cache.h"
|
||||
#include "cryptonote_basic/cryptonote_basic.h"
|
||||
|
||||
namespace cryptonote
|
||||
{
|
||||
|
||||
// Modifying this value should not affect consensus. You can adjust it for performance needs
|
||||
static constexpr const size_t RCT_VER_CACHE_SIZE = 8192;
|
||||
|
||||
using rct_ver_cache_t = ::tools::data_cache<::crypto::hash, RCT_VER_CACHE_SIZE>;
|
||||
|
||||
/**
|
||||
* @brief Cached version of rct::verRctNonSemanticsSimple
|
||||
*
|
||||
* This function will not affect how the transaction is serialized and it will never modify the
|
||||
* transaction prefix.
|
||||
*
|
||||
* The reference to tx is mutable since the transaction's ring signatures may be expanded by
|
||||
* Blockchain::expand_transaction_2. However, on cache hits, the transaction will not be
|
||||
* expanded. This means that the caller does not need to call expand_transaction_2 on this
|
||||
* transaction before passing it; the transaction will not successfully verify with "old" RCT data
|
||||
* if the transaction has been otherwise modified since the last verification.
|
||||
*
|
||||
* But, if cryptonote::get_transaction_hash(tx) returns a "stale" hash, this function is not
|
||||
* guaranteed to work. So make sure that the cryptonote::transaction passed has not had
|
||||
* modifications to it since the last time its hash was fetched without properly invalidating the
|
||||
* hashes.
|
||||
*
|
||||
* rct_type_to_cache can be any RCT version value as long as rct::verRctNonSemanticsSimple works for
|
||||
* this RCT version, but for most applications, it doesn't make sense to not make this version
|
||||
* the "current" RCT version (i.e. the version that transactions in the mempool are).
|
||||
*
|
||||
* @param tx transaction which contains RCT signature to verify
|
||||
* @param mix_ring mixring referenced by this tx. THIS DATA MUST BE PREVIOUSLY VALIDATED
|
||||
* @param cache saves tx+mixring hashes used to cache calls
|
||||
* @param rct_type_to_cache Only RCT sigs with version (e.g. RCTTypeBulletproofPlus) will be cached
|
||||
* @return true when verRctNonSemanticsSimple() w/ expanded tx.rct_signatures would return true
|
||||
* @return false when verRctNonSemanticsSimple() w/ expanded tx.rct_signatures would return false
|
||||
*/
|
||||
bool ver_rct_non_semantics_simple_cached
|
||||
(
|
||||
transaction& tx,
|
||||
const rct::ctkeyM& mix_ring,
|
||||
rct_ver_cache_t& cache,
|
||||
std::uint8_t rct_type_to_cache
|
||||
);
|
||||
|
||||
} // namespace cryptonote
|
|
@ -401,7 +401,7 @@ namespace cryptonote
|
|||
int64_t diff = static_cast<int64_t>(hshd.current_height) - static_cast<int64_t>(m_core.get_current_blockchain_height());
|
||||
uint64_t abs_diff = std::abs(diff);
|
||||
uint64_t max_block_height = std::max(hshd.current_height,m_core.get_current_blockchain_height());
|
||||
uint64_t last_block_v1 = m_core.get_nettype() == TESTNET ? 624633 : m_core.get_nettype() == MAINNET ? 1009826 : (uint64_t)-1;
|
||||
uint64_t last_block_v1 = (uint64_t)-1;
|
||||
uint64_t diff_v2 = max_block_height > last_block_v1 ? std::min(abs_diff, max_block_height - last_block_v1) : 0;
|
||||
MCLOG(is_inital ? el::Level::Info : el::Level::Debug, "global", el::Color::Yellow, context << "Sync data returned a new top block candidate: " << m_core.get_current_blockchain_height() << " -> " << hshd.current_height
|
||||
<< " [Your node is " << abs_diff << " blocks (" << tools::get_human_readable_timespan((abs_diff - diff_v2) * DIFFICULTY_TARGET_V1 + diff_v2 * DIFFICULTY_TARGET_V2) << ") "
|
||||
|
@ -979,8 +979,18 @@ namespace cryptonote
|
|||
int t_cryptonote_protocol_handler<t_core>::handle_notify_new_transactions(int command, NOTIFY_NEW_TRANSACTIONS::request& arg, cryptonote_connection_context& context)
|
||||
{
|
||||
MLOG_P2P_MESSAGE("Received NOTIFY_NEW_TRANSACTIONS (" << arg.txs.size() << " txes)");
|
||||
std::unordered_set<blobdata> seen;
|
||||
for (const auto &blob: arg.txs)
|
||||
{
|
||||
MLOGIF_P2P_MESSAGE(cryptonote::transaction tx; crypto::hash hash; bool ret = cryptonote::parse_and_validate_tx_from_blob(blob, tx, hash);, ret, "Including transaction " << hash);
|
||||
if (seen.find(blob) != seen.end())
|
||||
{
|
||||
LOG_PRINT_CCONTEXT_L1("Duplicate transaction in notification, dropping connection");
|
||||
drop_connection(context, false, false);
|
||||
return 1;
|
||||
}
|
||||
seen.insert(blob);
|
||||
}
|
||||
|
||||
if(context.m_state != cryptonote_connection_context::state_normal)
|
||||
return 1;
|
||||
|
@ -1020,7 +1030,7 @@ namespace cryptonote
|
|||
for (auto& tx : arg.txs)
|
||||
{
|
||||
tx_verification_context tvc{};
|
||||
if (!m_core.handle_incoming_tx({tx, crypto::null_hash}, tvc, tx_relay, true))
|
||||
if (!m_core.handle_incoming_tx({tx, crypto::null_hash}, tvc, tx_relay, true) && !tvc.m_no_drop_offense)
|
||||
{
|
||||
LOG_PRINT_CCONTEXT_L1("Tx verification failed, dropping connection");
|
||||
drop_connection(context, false, false);
|
||||
|
@ -2262,7 +2272,7 @@ skip:
|
|||
}
|
||||
|
||||
const uint64_t first_block_height = context.m_last_response_height - context.m_needed_objects.size() + 1;
|
||||
static const uint64_t bp_fork_height = m_core.get_earliest_ideal_height_for_version(8);
|
||||
static const uint64_t bp_fork_height = m_core.get_earliest_ideal_height_for_version(HF_VERSION_SMALLER_BP +1);
|
||||
bool sync_pruned_blocks = m_sync_pruned_blocks && first_block_height >= bp_fork_height && m_core.get_blockchain_pruning_seed();
|
||||
span = m_block_queue.reserve_span(first_block_height, context.m_last_response_height, count_limit, context.m_connection_id, context.m_remote_address, sync_pruned_blocks, m_core.get_blockchain_pruning_seed(), context.m_pruning_seed, context.m_remote_blockchain_height, context.m_needed_objects);
|
||||
MDEBUG(context << " span from " << first_block_height << ": " << span.first << "/" << span.second);
|
||||
|
@ -2484,7 +2494,7 @@ skip:
|
|||
}
|
||||
}
|
||||
MGINFO_YELLOW(ENDL << "**********************************************************************" << ENDL
|
||||
<< "You are now synchronized with the network. You may now start monero-wallet-cli." << ENDL
|
||||
<< "You are now synchronized with the network. You may now start wownero-wallet-cli." << ENDL
|
||||
<< ENDL
|
||||
<< "Use the \"help\" command to see the list of available commands." << ENDL
|
||||
<< "**********************************************************************");
|
||||
|
@ -2936,7 +2946,7 @@ skip:
|
|||
m_core.set_target_blockchain_height(target);
|
||||
if (target == 0 && context.m_state > cryptonote_connection_context::state_before_handshake && !m_stopping)
|
||||
{
|
||||
MCWARNING("global", "monerod is now disconnected from the network");
|
||||
MCWARNING("global", "wownerod is now disconnected from the network");
|
||||
m_ask_for_txpool_complement = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,5 +71,5 @@ target_link_libraries(daemon
|
|||
${Blocks})
|
||||
set_property(TARGET daemon
|
||||
PROPERTY
|
||||
OUTPUT_NAME "monerod")
|
||||
OUTPUT_NAME "wownerod")
|
||||
install(TARGETS daemon DESTINATION bin)
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
|
||||
namespace daemon_args
|
||||
{
|
||||
std::string const WINDOWS_SERVICE_NAME = "Monero Daemon";
|
||||
std::string const WINDOWS_SERVICE_NAME = "Wownero Daemon";
|
||||
|
||||
const command_line::arg_descriptor<std::string, false, true, 2> arg_config_file = {
|
||||
"config-file"
|
||||
|
|
|
@ -417,7 +417,7 @@ bool t_command_parser_executor::start_mining(const std::vector<std::string>& arg
|
|||
}
|
||||
if (info.is_subaddress)
|
||||
{
|
||||
tools::fail_msg_writer() << "subaddress for mining reward is not yet supported!" << std::endl;
|
||||
tools::fail_msg_writer() << "You can't use a subaddress to mine. You need to use your wallet's main address, which starts with \"Wo\"." << std::endl;
|
||||
return true;
|
||||
}
|
||||
if(nettype != cryptonote::MAINNET)
|
||||
|
@ -969,10 +969,10 @@ bool t_command_parser_executor::prune_blockchain(const std::vector<std::string>&
|
|||
|
||||
if (args.empty() || args[0] != "confirm")
|
||||
{
|
||||
std::cout << "Warning: pruning from within monerod will not shrink the database file size." << std::endl;
|
||||
std::cout << "Warning: pruning from within wownerod will not shrink the database file size." << std::endl;
|
||||
std::cout << "Instead, parts of the file will be marked as free, so the file will not grow" << std::endl;
|
||||
std::cout << "until that newly free space is used up. If you want a smaller file size now," << std::endl;
|
||||
std::cout << "exit monerod and run monero-blockchain-prune (you will temporarily need more" << std::endl;
|
||||
std::cout << "exit wownerod and run wownero-blockchain-prune (you will temporarily need more" << std::endl;
|
||||
std::cout << "disk space for the database conversion though). If you are OK with the database" << std::endl;
|
||||
std::cout << "file keeping the same size, re-run this command with the \"confirm\" parameter." << std::endl;
|
||||
return true;
|
||||
|
|
|
@ -412,7 +412,7 @@ bool t_command_server::apropos(const std::vector<std::string>& args)
|
|||
std::string t_command_server::get_commands_str()
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << std::endl;
|
||||
ss << "Wownero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << std::endl;
|
||||
ss << "Commands: " << std::endl;
|
||||
std::string usage = m_command_lookup.get_usage();
|
||||
boost::replace_all(usage, "\n", "\n ");
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
namespace daemonize
|
||||
{
|
||||
std::string const t_executor::NAME = "Monero Daemon";
|
||||
std::string const t_executor::NAME = "Wownero Daemon";
|
||||
|
||||
void t_executor::init_options(
|
||||
boost::program_options::options_description & configurable_options
|
||||
|
@ -58,7 +58,7 @@ namespace daemonize
|
|||
boost::program_options::variables_map const & vm
|
||||
)
|
||||
{
|
||||
LOG_PRINT_L0("Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ") Daemonised");
|
||||
LOG_PRINT_L0("Wownero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ") Daemonised");
|
||||
return t_daemon{vm, public_rpc_port};
|
||||
}
|
||||
|
||||
|
|
|
@ -190,7 +190,7 @@ int main(int argc, char const * argv[])
|
|||
|
||||
if (command_line::get_arg(vm, command_line::arg_help))
|
||||
{
|
||||
std::cout << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL;
|
||||
std::cout << "Wownero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL;
|
||||
std::cout << "Usage: " + std::string{argv[0]} + " [options|settings] [daemon_command...]" << std::endl << std::endl;
|
||||
std::cout << visible_options << std::endl;
|
||||
return 0;
|
||||
|
@ -199,7 +199,7 @@ int main(int argc, char const * argv[])
|
|||
// Monero Version
|
||||
if (command_line::get_arg(vm, command_line::arg_version))
|
||||
{
|
||||
std::cout << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL;
|
||||
std::cout << "Wownero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -219,6 +219,19 @@ int main(int argc, char const * argv[])
|
|||
{
|
||||
po::store(po::parse_config_file<char>(config_path.string<std::string>().c_str(), core_settings), vm);
|
||||
}
|
||||
catch (const po::unknown_option &e)
|
||||
{
|
||||
std::string unrecognized_option = e.get_option_name();
|
||||
if (all_options.find_nothrow(unrecognized_option, false))
|
||||
{
|
||||
std::cerr << "Option '" << unrecognized_option << "' is not allowed in the config file, please use it as a command line flag." << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Unrecognized option '" << unrecognized_option << "' in config file." << std::endl;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
// log system isn't initialized yet
|
||||
|
@ -293,7 +306,7 @@ int main(int argc, char const * argv[])
|
|||
tools::set_max_concurrency(command_line::get_arg(vm, daemon_args::arg_max_concurrency));
|
||||
|
||||
// logging is now set up
|
||||
MGINFO("Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")");
|
||||
MGINFO("Wownero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")");
|
||||
|
||||
// If there are positional options, we're running a daemon command
|
||||
{
|
||||
|
|
|
@ -94,6 +94,7 @@ namespace {
|
|||
void print_block_header(cryptonote::block_header_response const & header)
|
||||
{
|
||||
tools::success_msg_writer()
|
||||
<< "vote: " << header.vote << std::endl
|
||||
<< "timestamp: " << boost::lexical_cast<std::string>(header.timestamp) << " (" << tools::get_human_readable_timestamp(header.timestamp) << ")" << std::endl
|
||||
<< "previous hash: " << header.prev_hash << std::endl
|
||||
<< "nonce: " << boost::lexical_cast<std::string>(header.nonce) << std::endl
|
||||
|
@ -590,13 +591,13 @@ bool t_rpc_command_executor::mining_status() {
|
|||
}
|
||||
else
|
||||
{
|
||||
tools::msg_writer() << "Mining at " << get_mining_speed(mres.speed) << " with " << mres.threads_count << " threads";
|
||||
tools::msg_writer() << "\nMining at " << get_mining_speed(mres.speed) << " with " << mres.threads_count << " threads";
|
||||
}
|
||||
|
||||
tools::msg_writer() << "PoW algorithm: " << mres.pow_algorithm;
|
||||
if (mres.active || mres.is_background_mining_enabled)
|
||||
{
|
||||
tools::msg_writer() << "Mining address: " << mres.address;
|
||||
tools::msg_writer() << "Mining address:\n" << mres.address;
|
||||
}
|
||||
|
||||
if (mres.is_background_mining_enabled)
|
||||
|
@ -614,8 +615,8 @@ bool t_rpc_command_executor::mining_status() {
|
|||
uint64_t daily = 86400ull / mres.block_target * mres.block_reward * ratio;
|
||||
uint64_t monthly = 86400ull / mres.block_target * 30.5 * mres.block_reward * ratio;
|
||||
uint64_t yearly = 86400ull / mres.block_target * 356 * mres.block_reward * ratio;
|
||||
tools::msg_writer() << "Expected: " << cryptonote::print_money(daily) << " monero daily, "
|
||||
<< cryptonote::print_money(monthly) << " monero monthly, " << cryptonote::print_money(yearly) << " yearly";
|
||||
tools::msg_writer() << "Expected: " << cryptonote::print_money(daily) << " WOW daily, "
|
||||
<< cryptonote::print_money(monthly) << " WOW monthly, " << cryptonote::print_money(yearly) << " yearly";
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -1459,10 +1460,10 @@ bool t_rpc_command_executor::print_status()
|
|||
bool daemon_is_alive = m_rpc_client->check_connection();
|
||||
|
||||
if(daemon_is_alive) {
|
||||
tools::success_msg_writer() << "monerod is running";
|
||||
tools::success_msg_writer() << "wownerod is running";
|
||||
}
|
||||
else {
|
||||
tools::fail_msg_writer() << "monerod is NOT running";
|
||||
tools::fail_msg_writer() << "wownerod is NOT running";
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -2533,7 +2534,7 @@ bool t_rpc_command_executor::version()
|
|||
}
|
||||
}
|
||||
|
||||
if (res.version.empty() || !cryptonote::rpc::is_version_string_valid(res.version))
|
||||
if (res.version.empty())
|
||||
{
|
||||
tools::fail_msg_writer() << "The daemon software version is not available.";
|
||||
}
|
||||
|
|
|
@ -120,7 +120,7 @@ void fork(const std::string & pidfile)
|
|||
if (!tmpdir)
|
||||
tmpdir = TMPDIR;
|
||||
std::string output = tmpdir;
|
||||
output += "/bitmonero.daemon.stdout.stderr";
|
||||
output += "/wownero.daemon.stdout.stderr";
|
||||
const int flags = O_WRONLY | O_CREAT | O_APPEND;
|
||||
const mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
|
||||
if (open(output.c_str(), flags, mode) < 0)
|
||||
|
|
|
@ -46,7 +46,7 @@ target_link_libraries(cn_deserialize
|
|||
|
||||
set_property(TARGET cn_deserialize
|
||||
PROPERTY
|
||||
OUTPUT_NAME "monero-utils-deserialize")
|
||||
OUTPUT_NAME "wownero-utils-deserialize")
|
||||
|
||||
|
||||
set(object_sizes_sources
|
||||
|
@ -67,7 +67,7 @@ target_link_libraries(object_sizes
|
|||
|
||||
set_property(TARGET object_sizes
|
||||
PROPERTY
|
||||
OUTPUT_NAME "monero-utils-object-sizes")
|
||||
OUTPUT_NAME "wownero-utils-object-sizes")
|
||||
|
||||
|
||||
set(dns_checks_sources
|
||||
|
@ -89,5 +89,5 @@ target_link_libraries(dns_checks
|
|||
|
||||
set_property(TARGET dns_checks
|
||||
PROPERTY
|
||||
OUTPUT_NAME "monero-utils-dns-checks")
|
||||
OUTPUT_NAME "wownero-utils-dns-checks")
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ int main(int argc, char* argv[])
|
|||
|
||||
if (command_line::get_arg(vm, command_line::arg_help))
|
||||
{
|
||||
std::cout << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL;
|
||||
std::cout << "Wownero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL;
|
||||
std::cout << desc_options << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -121,7 +121,7 @@ int main(int argc, char* argv[])
|
|||
|
||||
if (command_line::get_arg(vm, command_line::arg_help))
|
||||
{
|
||||
std::cout << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL;
|
||||
std::cout << "Wownero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL;
|
||||
std::cout << desc_options << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
@ -129,20 +129,20 @@ int main(int argc, char* argv[])
|
|||
mlog_configure("", true);
|
||||
mlog_set_categories("+" MONERO_DEFAULT_LOG_CATEGORY ":INFO");
|
||||
|
||||
lookup(LOOKUP_A, {"seeds.moneroseeds.se", "seeds.moneroseeds.ae.org", "seeds.moneroseeds.ch", "seeds.moneroseeds.li"});
|
||||
lookup(LOOKUP_A, {""});
|
||||
|
||||
lookup(LOOKUP_TXT, {"updates.moneropulse.org", "updates.moneropulse.net", "updates.moneropulse.co", "updates.moneropulse.se", "updates.moneropulse.fr", "updates.moneropulse.de", "updates.moneropulse.no", "updates.moneropulse.ch"});
|
||||
lookup(LOOKUP_TXT, {""});
|
||||
|
||||
lookup(LOOKUP_TXT, {"checkpoints.moneropulse.org", "checkpoints.moneropulse.net", "checkpoints.moneropulse.co", "checkpoints.moneropulse.se"});
|
||||
lookup(LOOKUP_TXT, {""});
|
||||
|
||||
// those are in the code, but don't seem to actually exist
|
||||
#if 0
|
||||
lookup(LOOKUP_TXT, {"testpoints.moneropulse.org", "testpoints.moneropulse.net", "testpoints.moneropulse.co", "testpoints.moneropulse.se");
|
||||
lookup(LOOKUP_TXT, {"");
|
||||
|
||||
lookup(LOOKUP_TXT, {"stagenetpoints.moneropulse.org", "stagenetpoints.moneropulse.net", "stagenetpoints.moneropulse.co", "stagenetpoints.moneropulse.se"});
|
||||
lookup(LOOKUP_TXT, {""});
|
||||
#endif
|
||||
|
||||
lookup(LOOKUP_TXT, {"segheights.moneropulse.org", "segheights.moneropulse.net", "segheights.moneropulse.co", "segheights.moneropulse.se"});
|
||||
lookup(LOOKUP_TXT, {""});
|
||||
|
||||
return 0;
|
||||
CATCH_ENTRY_L0("main", 1);
|
||||
|
|
|
@ -465,7 +465,7 @@ namespace hw {
|
|||
this->sw = (this->buffer_recv[length_recv]<<8) | this->buffer_recv[length_recv+1];
|
||||
logRESP();
|
||||
MDEBUG("Device "<< this->id << " exchange: sw: " << this->sw << " expected: " << ok);
|
||||
ASSERT_X(sw != SW_CLIENT_NOT_SUPPORTED, "Monero Ledger App doesn't support current monero version. Try to update the Monero Ledger App, at least " << MINIMAL_APP_VERSION_MAJOR<< "." << MINIMAL_APP_VERSION_MINOR << "." << MINIMAL_APP_VERSION_MICRO << " is required.");
|
||||
ASSERT_X(sw != SW_CLIENT_NOT_SUPPORTED, "Wownero Ledger App doesn't support current monero version. Try to update the Wownero Ledger App, at least " << MINIMAL_APP_VERSION_MAJOR<< "." << MINIMAL_APP_VERSION_MINOR << "." << MINIMAL_APP_VERSION_MICRO << " is required.");
|
||||
ASSERT_X(sw != SW_PROTOCOL_NOT_SUPPORTED, "Make sure no other program is communicating with the Ledger.");
|
||||
ASSERT_SW(this->sw,ok,mask);
|
||||
|
||||
|
@ -526,6 +526,7 @@ namespace hw {
|
|||
{0x2c97, 0x0001, 0, 0xffa0},
|
||||
{0x2c97, 0x0004, 0, 0xffa0},
|
||||
{0x2c97, 0x0005, 0, 0xffa0},
|
||||
{0x2c97, 0x0006, 0, 0xffa0},
|
||||
};
|
||||
|
||||
bool device_ledger::connect(void) {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue