diff --git a/.gitignore b/.gitignore index fcb6da493..a38e4865c 100644 --- a/.gitignore +++ b/.gitignore @@ -136,3 +136,5 @@ make # CLion .idea cmake-build-debug +# vscode +.vscode diff --git a/README.md b/README.md index 874877da6..eafc587ee 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ![ZeroOne](doc/splash.png) -01coin Community v0.12.3.5 +01coin Community v0.12.3.6 ================================== [Bitcointalk ANN thread](https://bitcointalk.org/index.php?topic=3457534.0) diff --git a/configure.ac b/configure.ac index 709bfaeef..b368a9e92 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 0) define(_CLIENT_VERSION_MINOR, 12) define(_CLIENT_VERSION_REVISION, 3) -define(_CLIENT_VERSION_BUILD, 5) +define(_CLIENT_VERSION_BUILD, 6) define(_CLIENT_VERSION_IS_RELEASE, true) define(_COPYRIGHT_YEAR, 2019) define(_COPYRIGHT_HOLDERS,[The %s developers]) diff --git a/contrib/seeds/makeseeds.py b/contrib/seeds/makeseeds.py index 0c4eabf9c..68c903a9a 100755 --- a/contrib/seeds/makeseeds.py +++ b/contrib/seeds/makeseeds.py @@ -11,7 +11,7 @@ MAX_SEEDS_PER_ASN=4 -MIN_PROTOCOL_VERSION = 70210 +MIN_PROTOCOL_VERSION = 70211 MAX_LAST_SEEN_DIFF = 60 * 60 * 24 * 1 # 1 day MAX_LAST_PAID_DIFF = 60 * 60 * 24 * 30 # 1 month diff --git a/doc/Doxyfile b/doc/Doxyfile index c08f5b870..367071f60 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -41,7 +41,7 @@ PROJECT_NAME = "ZeroOne Core" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 0.12.3.3 +PROJECT_NUMBER = 0.12.3.6 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/doc/README_windows.txt b/doc/README_windows.txt index 1c52302f2..fcf833c81 100644 --- a/doc/README_windows.txt +++ b/doc/README_windows.txt @@ -1,4 +1,4 @@ -ZeroOne Core 0.12.1 +ZeroOne Core 0.12.3 ===================== Intro @@ -18,6 +18,6 @@ However, it downloads and stores the entire history of ZeroOne transactions; depending on the speed of your computer and network connection, the synchronization process can take anywhere from a few hours to a day or more. -See the zeroone wiki at: - https://zeroonecoin.atlassian.net/wiki/ +See the zeroone kb at: + http://kb.01coin.io/ for more help and information. diff --git a/doc/release-notes.md b/doc/release-notes.md index acec82e13..c756c74f7 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -1,4 +1,4 @@ -# 01coin version 0.12.3.4 +# 01coin version 0.12.3.6 Release is now available from: @@ -19,19 +19,23 @@ If you are running an older version, shut it down. Wait until it has completely ### Downgrade warning -Downgrade to a version < 0.12.3.4 +Downgrade to a version < 0.12.3.6 -Because release 0.12.3.4 is a mandatory upgrade release, downgrading to an earlier version is not supported. +Because release 0.12.3.6 is a mandatory upgrade release, downgrading to an earlier version is not supported. ## Notable changes -- Enforces Spork 8 as of block 159551 (approx. Nov. 24) -- All masternode owners and miners should upgrade as soon as possible +- Node sw supports only protocol 70211 +- ZOC SLIP44 CoinType 399, HD(m/44'/399'/0'/0/0) +- Sharky-miner-blocks are burnt, block reward not shared w/MN and w/no tx processed will become unmatured/unpsent/burned +- Several cleanups and optimizations to speedup and unfreeze mnsync asset stages +- All users, exchanges, masternode owners and miners should upgrade as soon as possible -### 0.12.3.4 Change log -See detailed [set of changes](https://github.com/zocteam/zeroonecoin/compare/v0.12.3.3...zocteam:v0.12.3.4). +### 0.12.3.6 Change log + +See detailed [set of changes](https://github.com/zocteam/zeroonecoin/compare/v0.12.3.5...zocteam:v0.12.3.6). ## Credits diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index 45986c858..e0c4664cc 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -48,7 +48,7 @@ MAX_INV_SZ = 50000 MAX_BLOCK_SIZE = 1000000 -COIN = 100000000 # 1 btc in satoshis +COIN = 100000000 # 1 zoc in zuffs NODE_NETWORK = (1 << 0) NODE_GETUTXO = (1 << 1) diff --git a/src/chainparamsseeds.h b/src/chainparamsseeds.h index 25e3215b9..d64aa1b32 100644 --- a/src/chainparamsseeds.h +++ b/src/chainparamsseeds.h @@ -8,106 +8,325 @@ * IPv4 as well as onion addresses are wrapped inside a IPv6 address accordingly. */ static SeedSpec6 pnSeed6_main[] = { - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x97,0x50,0xb8,0x69}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x33,0x26,0x4e,0x17}, 10000}, - {{0x26,0x07,0x53,0x00,0x00,0x61,0x09,0xbb,0x00,0x00,0x00,0x00,0x0d,0x03,0x40,0x39}, 10000}, - {{0x20,0x01,0x41,0xd0,0x08,0x00,0x1a,0x45,0x00,0x00,0x00,0x00,0x10,0xac,0xb9,0x22}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x97,0x50,0x03,0xed}, 10000}, - {{0x20,0x01,0x41,0xd0,0x10,0x00,0x29,0x95,0x00,0x00,0x00,0x00,0x01,0x63,0x1c,0x0d}, 10000}, - {{0x20,0x01,0x41,0xd0,0x10,0x00,0x29,0x95,0x00,0x00,0x00,0x00,0x09,0x25,0x49,0x71}, 10000}, - {{0x20,0x01,0x41,0xd0,0x10,0x00,0x29,0x95,0x00,0x00,0x00,0x00,0x09,0x36,0x8e,0xce}, 10000}, - {{0x20,0x01,0x41,0xd0,0x10,0x00,0x29,0x95,0x00,0x00,0x00,0x00,0x09,0xc5,0xaa,0x05}, 10000}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x01,0xf1,0xf9,0xa6}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x01,0xf1,0xf9,0xa7}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xbd,0x94,0xe2}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0x94,0x63,0x4d}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x22,0x49,0xe0,0x84}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x22,0x4a,0x2c,0x33}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x23,0xe3,0x25,0x63}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x23,0xf5,0x7e,0xae}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x73,0xe8,0x95}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x20,0xdb,0xd0}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x21,0x1b,0x92}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x52,0x7f,0xe5}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x65,0xdf,0xb8}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x6b,0xab,0x4a}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xad,0xda,0xb2}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xf9,0xc7,0xb7}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x33,0x26,0x4e,0x3f}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x33,0x26,0x69,0xe2}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x4d,0x9b,0xb8}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x71,0xf1,0x33}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xd2,0x18,0xca}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xd2,0x1f,0x43}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x87,0xd0,0x3d}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xbd,0xa4,0xeb}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x65,0x4b,0x87}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x28,0x73,0x24,0x98}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x20,0x95,0xb3}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x20,0xb8,0xe7}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x43,0xe4,0xcc}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x43,0xe7,0x39}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x56,0x46,0x57}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xad,0xd5,0xe4}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xad,0xd6,0xb5}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xad,0xda,0x98}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xad,0xda,0xd6}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x33,0x0f,0x25,0xa6}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x33,0x44,0xd1,0x8d}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x33,0x9e,0x6c,0x47}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x34,0x88,0xe8,0x1f}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x34,0xa6,0xb8,0x15}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3d,0x08,0x00,0x08}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3d,0x08,0x00,0x0e}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3d,0x08,0x00,0x17}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3d,0x08,0x00,0x19}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x6e,0x81,0xf9}, 10000}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xce,0x1d,0x98}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x37,0xd8,0xa3}, 10000}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0x6f,0x0e,0x92}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0x57,0xc8,0x0c}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xd3,0x46,0xf1}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xd3,0x98,0xd2}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xd3,0xd6,0x6e}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xd3,0x2d,0x54}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xd3,0x38,0xdb}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xd3,0x4e,0x75}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xd3,0xde,0x9e}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xd3,0xed,0x13}, 10000}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xd3,0xf3,0xcc}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x02,0xfa,0xbe}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xf1,0xd4,0xb2}, 10000}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xa9,0x98,0xd4}, 10000}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xa9,0xcb,0x97}, 10000}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xa9,0xd3,0xbf}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x79,0xc4,0xb9}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x79,0xc4,0xc4}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x79,0xc4,0xc9}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x79,0xc4,0xcc}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x79,0xc4,0xbf}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x79,0xc5,0x1d}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x79,0xc5,0x26}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x79,0xc5,0x3d}, 10000}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xd6,0xf5,0xfb}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xff,0x09,0xbd}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x28,0x7e,0x67}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xff,0x0e,0x86}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x56,0x69,0x34,0x14}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x56,0x69,0x36,0x0c}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x28,0x71,0xee}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xa9,0x02,0x04}, 10000}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5a,0xff,0xe1,0xb3}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xb1,0xa3,0x63}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x7d,0x3f,0xe0}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xb1,0xed,0x5b}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xb1,0xed,0xa8}, 10000}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xb1,0xfe,0x30}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xfa,0xfc,0xd4}, 10000}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xa5,0x91,0x6f}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0xad,0x06,0xec}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x70,0xa5,0xa5,0x44}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x86,0xd1,0x10,0x41}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x86,0xd1,0x67,0xdb}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x86,0xff,0x59,0xdc}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8b,0xb4,0x86,0xb4}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8b,0xb4,0xd7,0x33}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8e,0xea,0x9d,0xf3}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x4c,0xcb,0x49}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0xd9,0x70,0x8a}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0xd9,0x70,0x8b}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x92,0x42,0xb3,0x7b}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xd8,0x30,0x29}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xd8,0x30,0x2d}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0xad,0x66,0x9b}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x3d,0x7b,0xe1}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0xc5,0x9e,0xdd}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x71,0x1c,0x43,0x29}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x71,0x1c,0x43,0x2a}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x71,0x1c,0x43,0x35}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x71,0x1c,0x43,0x38}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x74,0xcb,0x12,0x65}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0xd9,0x70,0x80}, 10000}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x95,0x5a,0x3b,0xf7}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa3,0xac,0xc8,0x02}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa5,0xe3,0x01,0xa4}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa7,0x56,0x47,0xa4}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xef,0xe1,0xf6}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xef,0xe1,0xf9}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xef,0xee,0x06}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xef,0xee,0x07}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xf9,0xf2,0x28}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x21,0x91,0xef}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x3f,0xbf,0xf1}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0xcb,0x75,0xc1}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x97,0x50,0x03,0xeb}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9b,0x8a,0x97,0x4d}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa4,0x44,0x63,0x6f}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa7,0x56,0x65,0x94}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xac,0x6e,0x0a,0xef}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xac,0x6e,0x0a,0xf0}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xac,0x6e,0x12,0x3f}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xd0,0x84,0xa2}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x7a,0xdf,0xc8}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0xaa,0x70,0x14}, 10000}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0xdd,0x98,0xb2}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0xe6,0xa2,0x7e}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0xf0,0xf2,0x89}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x86,0x09,0x58}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0xdd,0x99,0xb2}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0xf0,0xf2,0x9b}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0xf0,0xf2,0x9d}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0xf0,0xf3,0xb2}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0xf0,0xf3,0xb3}, 10000}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xbf,0xe8,0x2c}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0xbb,0xac,0xf2}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0xbb,0xae,0x5b}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcf,0xb4,0xd9,0x3a}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcf,0xb4,0xd9,0x3b}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcf,0xf6,0x72,0xa1}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xd6,0x5d,0x96}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0xb6,0x45,0x31}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0xb6,0x46,0xef}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0xc9,0xec,0x9a}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcb,0xc6,0x92,0xe8}, 10000}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x08,0xf7,0xdc}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x53,0xa5,0xe5}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0xed,0x0c,0x31}, 10000}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0xed,0xd3,0x5c}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0xed,0xd3,0x6b}, 10000}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x8d,0x86,0xcd}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xbd,0x91,0xc0}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xbd,0x91,0xc2}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xbd,0x91,0xdd}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xbd,0x91,0xde}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xdf,0xab,0x20,0x9b}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xdf,0xab,0x2d,0xe3}, 10000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xdf,0xab,0x2e,0x43}, 10000} + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x3d,0x02,0x75}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x3d,0x05,0x26}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x3d,0x12,0x6c}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x3d,0x15,0x06}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x3d,0x3d,0x42}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x3d,0x61,0xac}, 10000}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xdf,0xab,0x2e,0x43}, 10000}, + {{0x20,0x01,0x15,0xe8,0x01,0x10,0x61,0xb7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 10000}, + {{0x20,0x01,0x19,0xf0,0x70,0x01,0x41,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02}, 10000}, + {{0x20,0x01,0x19,0xf0,0x70,0x01,0x41,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x04}, 10000}, + {{0x20,0x01,0x19,0xf0,0x70,0x01,0x41,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x05}, 10000}, + {{0x20,0x01,0x19,0xf0,0x70,0x01,0x41,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x07}, 10000}, + {{0x20,0x01,0x19,0xf0,0x70,0x01,0x41,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x08}, 10000}, + {{0x20,0x01,0x19,0xf0,0x70,0x01,0x41,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x09}, 10000}, + {{0x20,0x01,0x19,0xf0,0x70,0x01,0x41,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10}, 10000}, + {{0x20,0x01,0x19,0xf0,0x70,0x01,0x41,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x11}, 10000}, + {{0x20,0x01,0x19,0xf0,0x70,0x01,0x41,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x12}, 10000}, + {{0x20,0x01,0x19,0xf0,0x70,0x01,0x41,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x13}, 10000}, + {{0x20,0x01,0x19,0xf0,0x70,0x01,0x41,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x14}, 10000}, + {{0x20,0x01,0x19,0xf0,0x70,0x01,0x41,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x15}, 10000}, + {{0x20,0x01,0x19,0xf0,0x70,0x01,0x41,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x16}, 10000}, + {{0x20,0x01,0x19,0xf0,0x70,0x01,0x41,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x17}, 10000}, + {{0x20,0x01,0x41,0xd0,0x10,0x00,0x29,0x95,0x04,0x57,0x03,0x2e,0xdc,0x0e,0x00,0x04}, 10000}, + {{0x20,0x01,0x41,0xd0,0x10,0x00,0x29,0x95,0x04,0x57,0x03,0x2e,0xdc,0x0e,0x00,0x05}, 10000}, + {{0x20,0x01,0x41,0xd0,0x10,0x00,0x29,0x95,0x04,0x57,0x03,0x2e,0xdc,0x0e,0x00,0x06}, 10000}, + {{0x20,0x01,0x41,0xd0,0x10,0x00,0x29,0x95,0x04,0x57,0x03,0x2e,0xdc,0x0e,0x00,0x09}, 10000}, + {{0x20,0x01,0x41,0xd0,0x10,0x00,0x29,0x95,0x04,0x57,0x03,0x2e,0xdc,0x0e,0x00,0x0c}, 10000}, + {{0x20,0x01,0x41,0xd0,0x10,0x00,0x29,0x95,0x04,0x57,0x03,0x2e,0xdc,0x0e,0x00,0x0d}, 10000}, + {{0x20,0x01,0x41,0xd0,0x10,0x00,0x29,0x95,0x04,0x57,0x03,0x2e,0xdc,0x0e,0x00,0x0e}, 10000}, + {{0x20,0x01,0x41,0xd0,0x10,0x00,0x29,0x95,0x00,0x00,0x00,0x00,0x02,0x42,0x20,0x76}, 10000}, + {{0x20,0x01,0x41,0xd0,0x06,0x02,0x24,0xb8,0x00,0x00,0x00,0x00,0x03,0x6e,0x77,0x39}, 10000}, + {{0x20,0x01,0x41,0xd0,0x06,0x02,0x24,0xb8,0x00,0x00,0x00,0x00,0x03,0x8c,0xb8,0x3c}, 10000}, + {{0x20,0x01,0x41,0xd0,0x06,0x02,0x24,0xb8,0x00,0x00,0x00,0x00,0x03,0xf9,0x2f,0x8e}, 10000}, + {{0x20,0x01,0x41,0xd0,0x07,0x00,0x22,0x7f,0x01,0x18,0xd7,0xc2,0x9e,0x7c,0x00,0x01}, 10000}, + {{0x20,0x01,0x41,0xd0,0x07,0x00,0x22,0x7f,0x00,0x00,0x00,0x00,0x11,0x5a,0x1b,0xa4}, 10000}, + {{0x20,0x01,0x41,0xd0,0x07,0x00,0x22,0x7f,0x00,0x00,0x00,0x00,0x11,0x9d,0x92,0x2d}, 10000}, + {{0x20,0x01,0x41,0xd0,0x07,0x00,0x22,0x7f,0x00,0x00,0x00,0x00,0x12,0xad,0x54,0xb3}, 10000}, + {{0x20,0x01,0x41,0xd0,0x07,0x00,0x22,0x7f,0x00,0x00,0x00,0x00,0x13,0x06,0x52,0xb6}, 10000}, + {{0x20,0x01,0x41,0xd0,0x07,0x00,0x22,0x7f,0x00,0x00,0x00,0x00,0x14,0x79,0xd7,0xf8}, 10000}, + {{0x20,0x01,0x41,0xd0,0x07,0x00,0x22,0x7f,0x00,0x00,0x00,0x00,0x19,0x57,0x1a,0xd2}, 10000}, + {{0x20,0x01,0x41,0xd0,0x07,0x00,0x22,0x7f,0x00,0x00,0x00,0x00,0x1a,0x4a,0x38,0x89}, 10000}, + {{0x20,0x01,0x41,0xd0,0x07,0x00,0x22,0x7f,0x00,0x00,0x00,0x00,0x0c,0x6b,0x43,0x7c}, 10000}, + {{0x20,0x01,0x41,0xd0,0x07,0x00,0x22,0x7f,0x00,0x00,0x00,0x00,0x0e,0xf2,0x0d,0x9e}, 10000}, + {{0x20,0x01,0x41,0xd0,0x07,0x00,0x22,0x7f,0x00,0x00,0x00,0x00,0x0f,0x8d,0x30,0xe8}, 10000}, + {{0x20,0x01,0x41,0xd0,0x07,0x00,0x22,0x7f,0x00,0x00,0x00,0x00,0x0f,0x9d,0xfa,0x65}, 10000}, + {{0x20,0x01,0x41,0xd0,0x07,0x00,0x22,0x7f,0x00,0x00,0x00,0x00,0x0f,0xdf,0x6c,0x77}, 10000}, + {{0x26,0x07,0x53,0x00,0x00,0x61,0x09,0xbb,0x00,0x00,0x00,0x00,0x13,0xfd,0x5a,0x46}, 10000}, + {{0x2a,0x01,0x04,0xf8,0x1c,0x1c,0x73,0xa4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x04}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x05}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x07}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x08}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x09}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x11}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x12}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x13}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x14}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x15}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x16}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x17}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x18}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x19}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x21}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x22}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x23}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x24}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x25}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x26}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x27}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x28}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x29}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x13}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x30}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x31}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x32}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x33}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x34}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x35}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x36}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x37}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x38}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x39}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x41}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x42}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x43}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x44}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x45}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x47}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x48}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x49}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x15}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x50}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x51}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x52}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x53}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x54}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x55}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x56}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x57}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x58}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x59}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x16}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x60}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x61}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x62}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x63}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x64}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x65}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x66}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x67}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x68}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x69}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x17}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x70}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x71}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x72}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x73}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x74}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x75}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x76}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x77}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x78}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x79}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x19}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x21}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x22}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x23}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x24}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x25}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x26}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x27}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x29}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x31}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x32}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x34}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x35}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x36}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x37}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x39}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x42}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x43}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x45}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x46}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x47}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x49}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x51}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x52}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x53}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x54}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x55}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x56}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x57}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x58}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x59}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x62}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x64}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x65}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x67}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x68}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x69}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x71}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x72}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x73}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x74}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x75}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x76}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x77}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x79}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x82}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x83}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x84}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x85}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x86}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x87}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x89}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x91}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x92}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x93}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x94}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x95}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x96}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x97}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98}, 10000}, + {{0x2a,0x02,0xc2,0x07,0x20,0x28,0x36,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x99}, 10000}, + {{0x2a,0x05,0x82,0x80,0x00,0x0f,0x42,0xa0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 10000}, + {{0x2a,0x0c,0xb9,0xc0,0x00,0x0f,0x42,0xb1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 10000} }; static SeedSpec6 pnSeed6_test[] = { diff --git a/src/clientversion.cpp b/src/clientversion.cpp index 25e978e70..f7fe77e45 100644 --- a/src/clientversion.cpp +++ b/src/clientversion.cpp @@ -1,4 +1,6 @@ // Copyright (c) 2012-2014 The Bitcoin Core developers +// Copyright (c) 2014-2019 The Dash Core developers +// Copyright (c) 2018-2019 The ZeroOne Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -18,9 +20,9 @@ const std::string CLIENT_NAME("ZeroOne Core"); /** * Client version number */ -#define CLIENT_VERSION_SUFFIX "w27" -// Date:"190702" = 0x2E8EE -#define BUILD_SUFFIX 2E8EE +#define CLIENT_VERSION_SUFFIX "w32" +// Date:"190914" = 0x2E9C2 +#define BUILD_SUFFIX 2E9C2 diff --git a/src/clientversion.h b/src/clientversion.h index d0932c25b..219bf9629 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -19,7 +19,7 @@ #define CLIENT_VERSION_MAJOR 0 #define CLIENT_VERSION_MINOR 12 #define CLIENT_VERSION_REVISION 3 -#define CLIENT_VERSION_BUILD 5 +#define CLIENT_VERSION_BUILD 6 //! Set to true for release, false for prerelease or test build #define CLIENT_VERSION_IS_RELEASE true diff --git a/src/governance-object.h b/src/governance-object.h index 3d3c0de00..fdbb6499a 100644 --- a/src/governance-object.h +++ b/src/governance-object.h @@ -26,8 +26,8 @@ class CGovernanceObject; class CGovernanceVote; static const int MAX_GOVERNANCE_OBJECT_DATA_SIZE = 16 * 1024; -static const int MIN_GOVERNANCE_PEER_PROTO_VERSION = 70208; -static const int GOVERNANCE_FILTER_PROTO_VERSION = 70208; +static const int MIN_GOVERNANCE_PEER_PROTO_VERSION = 70211; +static const int GOVERNANCE_FILTER_PROTO_VERSION = 70211; static const double GOVERNANCE_FILTER_FP_RATE = 0.001; @@ -306,40 +306,13 @@ class CGovernanceObject inline void SerializationOp(Stream& s, Operation ser_action) { // SERIALIZE DATA FOR SAVING/LOADING OR NETWORK FUNCTIONS - int nVersion = s.GetVersion(); READWRITE(nHashParent); READWRITE(nRevision); READWRITE(nTime); READWRITE(nCollateralHash); - if (nVersion == 70208 && (s.GetType() & SER_NETWORK)) { - // converting from/to old format - std::string strDataHex; - if (ser_action.ForRead()) { - READWRITE(LIMITED_STRING(strDataHex, MAX_GOVERNANCE_OBJECT_DATA_SIZE)); - vchData = ParseHex(strDataHex); - } else { - strDataHex = HexStr(vchData); - READWRITE(LIMITED_STRING(strDataHex, MAX_GOVERNANCE_OBJECT_DATA_SIZE)); - } - } else { - // using new format directly - READWRITE(vchData); - } + READWRITE(vchData); READWRITE(nObjectType); - if (nVersion == 70208 && (s.GetType() & SER_NETWORK)) { - // converting from/to old format - CTxIn txin; - if (ser_action.ForRead()) { - READWRITE(txin); - masternodeOutpoint = txin.prevout; - } else { - txin = CTxIn(masternodeOutpoint); - READWRITE(txin); - } - } else { - // using new format directly - READWRITE(masternodeOutpoint); - } + READWRITE(masternodeOutpoint); if (!(s.GetType() & SER_GETHASH)) { READWRITE(vchSig); } diff --git a/src/governance-vote.h b/src/governance-vote.h index d28af0d7d..c7671321c 100644 --- a/src/governance-vote.h +++ b/src/governance-vote.h @@ -120,20 +120,7 @@ class CGovernanceVote template inline void SerializationOp(Stream& s, Operation ser_action) { int nVersion = s.GetVersion(); - if (nVersion == 70208 && (s.GetType() & SER_NETWORK)) { - // converting from/to old format - CTxIn txin{}; - if (ser_action.ForRead()) { - READWRITE(txin); - masternodeOutpoint = txin.prevout; - } else { - txin = CTxIn(masternodeOutpoint); - READWRITE(txin); - } - } else { - // using new format directly - READWRITE(masternodeOutpoint); - } + READWRITE(masternodeOutpoint); READWRITE(nParentHash); READWRITE(nVoteOutcome); READWRITE(nVoteSignal); diff --git a/src/governance.cpp b/src/governance.cpp index fcd4b4f46..f160b756e 100644 --- a/src/governance.cpp +++ b/src/governance.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2014-2017 The Dash Core developers -// Copyright (c) 2017-2018 The ZeroOne Core developers +// Copyright (c) 2018-2019 The ZeroOne Core developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -95,8 +95,6 @@ void CGovernanceManager::ProcessMessage(CNode* pfrom, const std::string& strComm if(pfrom->nVersion < MIN_GOVERNANCE_PEER_PROTO_VERSION) { LogPrint("gobject", "MNGOVERNANCESYNC -- peer=%d using obsolete version %i\n", pfrom->id, pfrom->nVersion); - connman.PushMessage(pfrom, CNetMsgMaker(pfrom->GetSendVersion()).Make(NetMsgType::REJECT, strCommand, REJECT_OBSOLETE, - strprintf("Version must be %d or greater", MIN_GOVERNANCE_PEER_PROTO_VERSION))); return; } @@ -140,8 +138,6 @@ void CGovernanceManager::ProcessMessage(CNode* pfrom, const std::string& strComm if(pfrom->nVersion < MIN_GOVERNANCE_PEER_PROTO_VERSION) { LogPrint("gobject", "MNGOVERNANCEOBJECT -- peer=%d using obsolete version %i\n", pfrom->id, pfrom->nVersion); - connman.PushMessage(pfrom, CNetMsgMaker(pfrom->GetSendVersion()).Make(NetMsgType::REJECT, strCommand, REJECT_OBSOLETE, - strprintf("Version must be %d or greater", MIN_GOVERNANCE_PEER_PROTO_VERSION))); return; } @@ -231,8 +227,7 @@ void CGovernanceManager::ProcessMessage(CNode* pfrom, const std::string& strComm if(pfrom->nVersion < MIN_GOVERNANCE_PEER_PROTO_VERSION) { LogPrint("gobject", "MNGOVERNANCEOBJECTVOTE -- peer=%d using obsolete version %i\n", pfrom->id, pfrom->nVersion); - connman.PushMessage(pfrom, CNetMsgMaker(pfrom->GetSendVersion()).Make(NetMsgType::REJECT, strCommand, REJECT_OBSOLETE, - strprintf("Version must be %d or greater", MIN_GOVERNANCE_PEER_PROTO_VERSION))); + return; } // Ignore such messages until masternode list is synced @@ -1024,7 +1019,8 @@ void CGovernanceManager::RequestGovernanceObject(CNode* pfrom, const uint256& nH CNetMsgMaker msgMaker(pfrom->GetSendVersion()); if(pfrom->nVersion < GOVERNANCE_FILTER_PROTO_VERSION) { - connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::MNGOVERNANCESYNC, nHash)); + // dont waste time with old nodes + //connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::MNGOVERNANCESYNC, nHash)); return; } diff --git a/src/instantx.cpp b/src/instantx.cpp index 3e21253ad..362855188 100644 --- a/src/instantx.cpp +++ b/src/instantx.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2014-2017 The Dash Core developers -// Copyright (c) 2017-2018 The ZeroOne Core developers +// Copyright (c) 2018-2019 The ZeroOne Core developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -61,8 +61,6 @@ void CInstantSend::ProcessMessage(CNode* pfrom, const std::string& strCommand, C { if(pfrom->nVersion < MIN_INSTANTSEND_PROTO_VERSION) { LogPrint("instantsend", "TXLOCKVOTE -- peer=%d using obsolete version %i\n", pfrom->id, pfrom->nVersion); - connman.PushMessage(pfrom, CNetMsgMaker(pfrom->GetSendVersion()).Make(NetMsgType::REJECT, strCommand, REJECT_OBSOLETE, - strprintf("Version must be %d or greater", MIN_INSTANTSEND_PROTO_VERSION))); return; } diff --git a/src/instantx.h b/src/instantx.h index fb847d07a..eb9e840ee 100644 --- a/src/instantx.h +++ b/src/instantx.h @@ -36,7 +36,7 @@ static const int MAX_INSTANTSEND_DEPTH = 60; /// Default number of "pseudo-confirmations" for an InstantSend tx static const int DEFAULT_INSTANTSEND_DEPTH = 5; -static const int MIN_INSTANTSEND_PROTO_VERSION = 70210; +static const int MIN_INSTANTSEND_PROTO_VERSION = 70211; /// For how long we are going to accept votes/locks /// after we saw the first one for a specific transaction diff --git a/src/masternode-payments.cpp b/src/masternode-payments.cpp index cc6ea2fdd..18f621915 100644 --- a/src/masternode-payments.cpp +++ b/src/masternode-payments.cpp @@ -230,11 +230,17 @@ bool CMasternodePayments::UpdateLastVote(const CMasternodePaymentVote& vote) { LOCK(cs_mapMasternodePaymentVotes); - const auto it = mapMasternodesLastVote.find(vote.masternodeOutpoint); - if (it != mapMasternodesLastVote.end()) { - if (it->second == vote.nBlockHeight) + const auto it1 = mapMasternodesDidNotVote.find(vote.masternodeOutpoint); + if (it1 != mapMasternodesDidNotVote.end()) { + mapMasternodesDidNotVote.erase(vote.masternodeOutpoint); + mnodeman.DecreasePoSeBanScore(vote.masternodeOutpoint); + } + + const auto it2 = mapMasternodesLastVote.find(vote.masternodeOutpoint); + if (it2 != mapMasternodesLastVote.end()) { + if (it2->second == vote.nBlockHeight) return false; - it->second = vote.nBlockHeight; + it2->second = vote.nBlockHeight; return true; } @@ -299,8 +305,6 @@ void CMasternodePayments::ProcessMessage(CNode* pfrom, const std::string& strCom if(pfrom->nVersion < GetMinMasternodePaymentsProto()) { LogPrint("mnpayments", "MASTERNODEPAYMENTSYNC -- peer=%d using obsolete version %i\n", pfrom->id, pfrom->nVersion); - connman.PushMessage(pfrom, CNetMsgMaker(pfrom->GetSendVersion()).Make(NetMsgType::REJECT, strCommand, REJECT_OBSOLETE, - strprintf("Version must be %d or greater", GetMinMasternodePaymentsProto()))); return; } @@ -309,12 +313,6 @@ void CMasternodePayments::ProcessMessage(CNode* pfrom, const std::string& strCom // but this is a heavy one so it's better to finish sync first. if (!masternodeSync.IsSynced()) return; - // DEPRECATED, should be removed on next protocol bump - if(pfrom->nVersion == 70208) { - int nCountNeeded; - vRecv >> nCountNeeded; - } - if(netfulfilledman.HasFulfilledRequest(pfrom->addr, NetMsgType::MASTERNODEPAYMENTSYNC)) { LOCK(cs_main); // Asking for the payments list multiple times in a short period of time is no good @@ -334,8 +332,6 @@ void CMasternodePayments::ProcessMessage(CNode* pfrom, const std::string& strCom if(pfrom->nVersion < GetMinMasternodePaymentsProto()) { LogPrint("mnpayments", "MASTERNODEPAYMENTVOTE -- peer=%d using obsolete version %i\n", pfrom->id, pfrom->nVersion); - connman.PushMessage(pfrom, CNetMsgMaker(pfrom->GetSendVersion()).Make(NetMsgType::REJECT, strCommand, REJECT_OBSOLETE, - strprintf("Version must be %d or greater", GetMinMasternodePaymentsProto()))); return; } @@ -573,13 +569,16 @@ bool CMasternodeBlockPayees::HasPayeeWithVotes(const CScript& payeeIn, int nVote { LOCK(cs_vecPayees); + int i = (int)vecPayees.size(); for (const auto& payee : vecPayees) { - if (payee.GetVoteCount() >= nVotesReq && payee.GetPayee() == payeeIn) { + int v = payee.GetVoteCount(); + if (v >= nVotesReq && payee.GetPayee() == payeeIn) { + LogPrint("mnpayments", "CMasternodeBlockPayees::HasPayeeWithVotes -- found payee with %d votes of %d+ required from %d\n", v, nVotesReq, i); return true; } } - - LogPrint("mnpayments", "CMasternodeBlockPayees::HasPayeeWithVotes -- ERROR: couldn't find any payee with %d+ votes\n", nVotesReq); + // This is a loop called function, dont spam debug log so much for now... + // LogPrint("mnpayments", "CMasternodeBlockPayees::HasPayeeWithVotes -- ERROR: couldn't find any payee with %d+ votes in %d\n", nVotesReq, vecPayees.size()); return false; } @@ -890,6 +889,45 @@ void CMasternodePayments::CheckBlockVotes(int nBlockHeight) LogPrint("mnpayments", "%s", debugStr); } +void CMasternodePayments::CheckMissingVotes() +{ + // Do not check until fully synced + if(!masternodeSync.IsSynced()) { + LogPrintf("CMasternodePayments::CheckMissingVotes -- won't check until fully synced\n"); + return; + } + + LOCK(cs_mapMasternodePaymentVotes); + + std::string debugStr; + int n = (int)mapMasternodesDidNotVote.size(); + debugStr += strprintf("CMasternodePayments::CheckMissingVotes -- nBlockHeight=%d, total missing votes was:%d\n", nCachedBlockHeight, n); + if (mapMasternodesDidNotVote.empty()) { + LogPrint("mnpayments", "%s", debugStr); + return; + } + + std::map mMdnv; + mMdnv = mapMasternodesDidNotVote; + debugStr += " Masternodes which missed a vote:\n"; + for (const auto& item : mMdnv) { + debugStr += strprintf(" - %s: %d\n", item.first.ToStringShort(), item.second); + if(item.second <= 0) { + // didn't change stats since last call, clean entry + mapMasternodesDidNotVote.erase(item.first); + } + // MN is not doing its dutty + if(item.second >= 1) { + mnodeman.IncreasePoSeBanScore(item.first); + int i = item.second-1; + mapMasternodesDidNotVote.emplace(item.first, 0).first->second = i; + } + + } + LogPrintf("%s", debugStr); + +} + void CMasternodePaymentVote::Relay(CConnman& connman) const { // Do not relay until fully synced @@ -924,7 +962,7 @@ bool CMasternodePaymentVote::CheckSignature(const CPubKey& pubKeyMasternode, int if(masternodeSync.IsMasternodeListSynced() && nBlockHeight > nValidationHeight) { nDos = 20; } - return error("CMasternodePaymentVote::CheckSignature -- Got bad Masternode payment signature, masternode=%s, error: %s", + return error("CMasternodePaymentVote::CheckSignature -- Got bad Masternode payment signature, masternode=%s, spk6, error: %s", masternodeOutpoint.ToStringShort(), strError); } } @@ -940,8 +978,10 @@ bool CMasternodePaymentVote::CheckSignature(const CPubKey& pubKeyMasternode, int if(masternodeSync.IsMasternodeListSynced() && nBlockHeight > nValidationHeight) { nDos = 20; } - return error("CMasternodePaymentVote::CheckSignature -- Got bad Masternode payment signature, masternode=%s, error: %s", + // error message is spamming debug.log , make log only during debug + LogPrint("mnpayments", "ERROR: CMasternodePaymentVote::CheckSignature -- Got bad Masternode payment signature, masternode=%s, error: %s", masternodeOutpoint.ToStringShort(), strError); + return false; } } diff --git a/src/masternode-payments.h b/src/masternode-payments.h index 30ffea381..914c41ea3 100644 --- a/src/masternode-payments.h +++ b/src/masternode-payments.h @@ -25,7 +25,7 @@ class CMasternodeBlockPayees; // vote for masternode and be elected as a payment winner // V1 - Last protocol version before update // V2 - Newest protocol version -static const int MIN_MASTERNODE_PAYMENT_PROTO_VERSION_1 = 70210; +static const int MIN_MASTERNODE_PAYMENT_PROTO_VERSION_1 = 70211; static const int MIN_MASTERNODE_PAYMENT_PROTO_VERSION_2 = 70211; extern CCriticalSection cs_vecPayees; @@ -135,21 +135,7 @@ class CMasternodePaymentVote template inline void SerializationOp(Stream& s, Operation ser_action) { - int nVersion = s.GetVersion(); - if (nVersion == 70208 && (s.GetType() & SER_NETWORK)) { - // converting from/to old format - CTxIn txin{}; - if (ser_action.ForRead()) { - READWRITE(txin); - masternodeOutpoint = txin.prevout; - } else { - txin = CTxIn(masternodeOutpoint); - READWRITE(txin); - } - } else { - // using new format directly - READWRITE(masternodeOutpoint); - } + READWRITE(masternodeOutpoint); READWRITE(nBlockHeight); READWRITE(*(CScriptBase*)(&payee)); if (!(s.GetType() & SER_GETHASH)) { @@ -210,6 +196,7 @@ class CMasternodePayments bool HasVerifiedPaymentVote(const uint256& hashIn) const; bool ProcessBlock(int nBlockHeight, CConnman& connman); void CheckBlockVotes(int nBlockHeight); + void CheckMissingVotes(); void Sync(CNode* node, CConnman& connman) const; void RequestLowDataPaymentBlocks(CNode* pnode, CConnman& connman) const; diff --git a/src/masternode-sync.cpp b/src/masternode-sync.cpp index 5822f7936..e7d3cb2e6 100644 --- a/src/masternode-sync.cpp +++ b/src/masternode-sync.cpp @@ -136,9 +136,9 @@ void CMasternodeSync::ProcessTick(CConnman& connman) static int nTick = 0; if(nTick++ % MASTERNODE_SYNC_TICK_SECONDS != 0) return; - // reset the sync process if the last call to this function was more than 60 minutes ago (client was in sleep mode) + // reset the sync process if the last call to this function was more than 10 minutes ago (client was in sleep mode) static int64_t nTimeLastProcess = GetTime(); - if(GetTime() - nTimeLastProcess > 60*60) { + if(GetTime() - nTimeLastProcess > 10*60) { LogPrintf("CMasternodeSync::ProcessTick -- WARNING: no actions for too long, restarting sync...\n"); Reset(); SwitchToNextAsset(connman); @@ -166,7 +166,7 @@ void CMasternodeSync::ProcessTick(CConnman& connman) } // Calculate "progress" for LOG reporting / GUI notification - double nSyncProgress = double(nRequestedMasternodeAttempt + (nRequestedMasternodeAssets - 1) * 8) / (8*4); + double nSyncProgress = (double(nRequestedMasternodeAttempt)/(8*6))+(double((nRequestedMasternodeAssets-1)*8)/(8*4)); LogPrintf("CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d nRequestedMasternodeAttempt %d nSyncProgress %f\n", nTick, nRequestedMasternodeAssets, nRequestedMasternodeAttempt, nSyncProgress); uiInterface.NotifyAdditionalDataSyncProgressChanged(nSyncProgress); @@ -191,11 +191,7 @@ void CMasternodeSync::ProcessTick(CConnman& connman) mnodeman.DsegUpdate(pnode, connman); } else if(nRequestedMasternodeAttempt < 6) { //sync payment votes - if(pnode->nVersion == 70208) { - connman.PushMessage(pnode, msgMaker.Make(NetMsgType::MASTERNODEPAYMENTSYNC, mnpayments.GetStorageLimit())); //sync payment votes - } else { - connman.PushMessage(pnode, msgMaker.Make(NetMsgType::MASTERNODEPAYMENTSYNC)); //sync payment votes - } + connman.PushMessage(pnode, msgMaker.Make(NetMsgType::MASTERNODEPAYMENTSYNC)); //sync payment votes SendGovernanceSyncRequest(pnode, connman); } else { nRequestedMasternodeAssets = MASTERNODE_SYNC_FINISHED; @@ -206,7 +202,9 @@ void CMasternodeSync::ProcessTick(CConnman& connman) } // NORMAL NETWORK MODE - TESTNET/MAINNET - { + // search for relevant nodes only + if (pnode->nVersion >= mnpayments.GetMinMasternodePaymentsProto()) { + if(netfulfilledman.HasFulfilledRequest(pnode->addr, "full-sync")) { // We already fully synced from this node recently, // disconnect to free this connection slot for another peer. @@ -260,8 +258,10 @@ void CMasternodeSync::ProcessTick(CConnman& connman) return; } - // request from three peers max - if (nRequestedMasternodeAttempt > 2) { + // request up to six peers max (in 30seconds timeout) + if (nRequestedMasternodeAttempt > 5) { + // so all six requests done, no need to wait timeout to move + SwitchToNextAsset(connman); connman.ReleaseNodeVector(vNodesCopy); return; } @@ -270,7 +270,8 @@ void CMasternodeSync::ProcessTick(CConnman& connman) if(netfulfilledman.HasFulfilledRequest(pnode->addr, "masternode-list-sync")) continue; netfulfilledman.AddFulfilledRequest(pnode->addr, "masternode-list-sync"); - if (pnode->nVersion < mnpayments.GetMinMasternodePaymentsProto()) continue; + // TODO : cleanup after testing sync is better + // if (pnode->nVersion < mnpayments.GetMinMasternodePaymentsProto()) continue; nRequestedMasternodeAttempt++; mnodeman.DsegUpdate(pnode, connman); @@ -310,8 +311,10 @@ void CMasternodeSync::ProcessTick(CConnman& connman) return; } - // request from three peers max - if (nRequestedMasternodeAttempt > 2) { + // request up to six peers max (in 30 seconds timeout) + if (nRequestedMasternodeAttempt > 5) { + // so all six requests done, no need to wait timeout to move + SwitchToNextAsset(connman); connman.ReleaseNodeVector(vNodesCopy); return; } @@ -320,16 +323,13 @@ void CMasternodeSync::ProcessTick(CConnman& connman) if(netfulfilledman.HasFulfilledRequest(pnode->addr, "masternode-payment-sync")) continue; netfulfilledman.AddFulfilledRequest(pnode->addr, "masternode-payment-sync"); - if(pnode->nVersion < mnpayments.GetMinMasternodePaymentsProto()) continue; + // TODO : cleanup after testing sync is better + // if(pnode->nVersion < mnpayments.GetMinMasternodePaymentsProto()) continue; nRequestedMasternodeAttempt++; // ask node for all payment votes it has (new nodes will only return votes for future payments) //sync payment votes - if(pnode->nVersion == 70208) { - connman.PushMessage(pnode, msgMaker.Make(NetMsgType::MASTERNODEPAYMENTSYNC, mnpayments.GetStorageLimit())); - } else { - connman.PushMessage(pnode, msgMaker.Make(NetMsgType::MASTERNODEPAYMENTSYNC)); - } + connman.PushMessage(pnode, msgMaker.Make(NetMsgType::MASTERNODEPAYMENTSYNC)); // ask node for missing pieces only (old nodes will not be asked) mnpayments.RequestLowDataPaymentBlocks(pnode, connman); diff --git a/src/masternode.cpp b/src/masternode.cpp index 9a3e9355b..d70d0bd77 100644 --- a/src/masternode.cpp +++ b/src/masternode.cpp @@ -456,6 +456,9 @@ bool CMasternodeBroadcast::SimpleCheck(int& nDos) if(nProtocolVersion < mnpayments.GetMinMasternodePaymentsProto()) { LogPrintf("CMasternodeBroadcast::SimpleCheck -- outdated Masternode: masternode=%s nProtocolVersion=%d\n", outpoint.ToStringShort(), nProtocolVersion); nActiveState = MASTERNODE_UPDATE_REQUIRED; + // dont waste time, disconnect + nDos = 100; + return false; } CScript pubkeyScript; @@ -599,6 +602,46 @@ bool CMasternodeBroadcast::CheckOutpoint(int& nDos) return true; } +bool CMasternodeBroadcast::CheckAddr(int& nDos) +{ + // we are a masternode with the same outpoint (i.e. already activated) and this mnb is ours (matches our Masternode privkey) + // so nothing to do here for us + if(fMasternodeMode && outpoint == activeMasternode.outpoint && pubKeyMasternode == activeMasternode.pubKeyMasternode) { + return false; + } + + // do not ban the node we get this message from + nDos = 0; + + // make sure addr is valid + if(!IsValidNetAddr()) { + LogPrintf("CMasternodeBroadcast::CheckAddr -- Invalid addr, rejected: masternode=%s addr=%s\n", + outpoint.ToStringShort(), addr.ToString()); + //nDos += 33; + return false; + } + + int mainnetDefaultPort = Params(CBaseChainParams::MAIN).GetDefaultPort(); + if(Params().NetworkIDString() == CBaseChainParams::MAIN) { + if(addr.GetPort() != mainnetDefaultPort) { + LogPrintf("CMasternodeBroadcast::CheckAddr -- Invalid addr port, rejected: masternode=%s addr=%s\n", + outpoint.ToStringShort(), addr.ToString()); + //nDos += 33; + return false; + } + } else if(addr.GetPort() == mainnetDefaultPort) return false; + + + if (mnodeman.HasAddr(addr)) { + LogPrintf("CMasternodeBroadcast::CheckAddr -- Addr already in use, rejected: masternode=%s addr=%s\n", + outpoint.ToStringShort(), addr.ToString()); + //nDos += 33; + return false; + } + + return true; +} + uint256 CMasternodeBroadcast::GetHash() const { // Note: doesn't match serialization @@ -857,6 +900,8 @@ bool CMasternodePing::CheckAndUpdate(CMasternode* pmn, bool fFromNewBroadcast, i if(!fFromNewBroadcast) { if (pmn->IsUpdateRequired()) { LogPrint("masternode", "CMasternodePing::CheckAndUpdate -- masternode protocol is outdated, masternode=%s\n", masternodeOutpoint.ToStringShort()); + // old node, disconnect + nDos = 100; return false; } @@ -868,9 +913,10 @@ bool CMasternodePing::CheckAndUpdate(CMasternode* pmn, bool fFromNewBroadcast, i { BlockMap::iterator mi = mapBlockIndex.find(blockHash); - if ((*mi).second && (*mi).second->nHeight < chainActive.Height() - 24) { - LogPrintf("CMasternodePing::CheckAndUpdate -- Masternode ping is invalid, block hash is too old: masternode=%s blockHash=%s\n", masternodeOutpoint.ToStringShort(), blockHash.ToString()); - // nDos = 1; + if ((*mi).second && (*mi).second->nHeight < chainActive.Height() - 24) { // 24 blocks ago was about 1h ago + LogPrint("masternode", "CMasternodePing::CheckAndUpdate -- Masternode ping is invalid, block hash is too old: masternode=%s blockHash=%s\n", masternodeOutpoint.ToStringShort(), blockHash.ToString()); + // invalid ping data should cause damage to reputation but this is used in the sync loop and is causing real peers to get banned + //nDos = 1; //disable, this is happening frequently and causing banned peers return false; } } diff --git a/src/masternode.h b/src/masternode.h index 979c2f991..a3fd80e74 100644 --- a/src/masternode.h +++ b/src/masternode.h @@ -52,43 +52,15 @@ class CMasternodePing template inline void SerializationOp(Stream& s, Operation ser_action) { - int nVersion = s.GetVersion(); - if (nVersion == 70208 && (s.GetType() & SER_NETWORK)) { - // converting from/to old format - CTxIn txin{}; - if (ser_action.ForRead()) { - READWRITE(txin); - masternodeOutpoint = txin.prevout; - } else { - txin = CTxIn(masternodeOutpoint); - READWRITE(txin); - } - } else { - // using new format directly - READWRITE(masternodeOutpoint); - } + READWRITE(masternodeOutpoint); READWRITE(blockHash); READWRITE(sigTime); if (!(s.GetType() & SER_GETHASH)) { READWRITE(vchSig); } - if(ser_action.ForRead() && s.size() == 0) { - // TODO: drop this after migration to 70209 - fSentinelIsCurrent = false; - nSentinelVersion = DEFAULT_SENTINEL_VERSION; - nDaemonVersion = DEFAULT_DAEMON_VERSION; - return; - } READWRITE(fSentinelIsCurrent); READWRITE(nSentinelVersion); - if(ser_action.ForRead() && s.size() == 0) { - // TODO: drop this after migration to 70209 - nDaemonVersion = DEFAULT_DAEMON_VERSION; - return; - } - if (!(nVersion == 70208 && (s.GetType() & SER_NETWORK))) { - READWRITE(nDaemonVersion); - } + READWRITE(nDaemonVersion); } uint256 GetHash() const; @@ -204,21 +176,7 @@ class CMasternode : public masternode_info_t template inline void SerializationOp(Stream& s, Operation ser_action) { LOCK(cs); - int nVersion = s.GetVersion(); - if (nVersion == 70208 && (s.GetType() & SER_NETWORK)) { - // converting from/to old format - CTxIn txin{}; - if (ser_action.ForRead()) { - READWRITE(txin); - outpoint = txin.prevout; - } else { - txin = CTxIn(outpoint); - READWRITE(txin); - } - } else { - // using new format directly - READWRITE(outpoint); - } + READWRITE(outpoint); READWRITE(addr); READWRITE(pubKeyCollateralAddress); READWRITE(pubKeyMasternode); @@ -361,21 +319,7 @@ class CMasternodeBroadcast : public CMasternode template inline void SerializationOp(Stream& s, Operation ser_action) { - int nVersion = s.GetVersion(); - if (nVersion == 70208 && (s.GetType() & SER_NETWORK)) { - // converting from/to old format - CTxIn txin{}; - if (ser_action.ForRead()) { - READWRITE(txin); - outpoint = txin.prevout; - } else { - txin = CTxIn(outpoint); - READWRITE(txin); - } - } else { - // using new format directly - READWRITE(outpoint); - } + READWRITE(outpoint); READWRITE(addr); READWRITE(pubKeyCollateralAddress); READWRITE(pubKeyMasternode); @@ -399,6 +343,7 @@ class CMasternodeBroadcast : public CMasternode bool SimpleCheck(int& nDos); bool Update(CMasternode* pmn, int& nDos, CConnman& connman); bool CheckOutpoint(int& nDos); + bool CheckAddr(int& nDos); bool Sign(const CKey& keyCollateralAddress); bool CheckSignature(int& nDos) const; @@ -428,27 +373,8 @@ class CMasternodeVerification template inline void SerializationOp(Stream& s, Operation ser_action) { - int nVersion = s.GetVersion(); - if (nVersion == 70208 && (s.GetType() & SER_NETWORK)) { - // converting from/to old format - CTxIn txin1{}; - CTxIn txin2{}; - if (ser_action.ForRead()) { - READWRITE(txin1); - READWRITE(txin2); - masternodeOutpoint1 = txin1.prevout; - masternodeOutpoint2 = txin2.prevout; - } else { - txin1 = CTxIn(masternodeOutpoint1); - txin2 = CTxIn(masternodeOutpoint2); - READWRITE(txin1); - READWRITE(txin2); - } - } else { - // using new format directly - READWRITE(masternodeOutpoint1); - READWRITE(masternodeOutpoint2); - } + READWRITE(masternodeOutpoint1); + READWRITE(masternodeOutpoint2); READWRITE(addr); READWRITE(nonce); READWRITE(nBlockHeight); diff --git a/src/masternodeman.cpp b/src/masternodeman.cpp index 00906f13d..f44c58403 100644 --- a/src/masternodeman.cpp +++ b/src/masternodeman.cpp @@ -13,7 +13,9 @@ #include "messagesigner.h" #include "netfulfilledman.h" #include "netmessagemaker.h" -#include "validation.cpp" +#include "net.h" +#include "netbase.h" +#include "validation.h" #ifdef ENABLE_WALLET #include "privatesend-client.h" #endif // ENABLE_WALLET @@ -47,7 +49,6 @@ struct CompareScoreMN }; struct CompareByAddr - { bool operator()(const CMasternode* t1, const CMasternode* t2) const @@ -56,6 +57,38 @@ struct CompareByAddr } }; +struct CompareByPoSeBanScore +{ + bool operator()(const CMasternode* t1, + const CMasternode* t2) const + { + return t1->nPoSeBanScore < t2->nPoSeBanScore; + } +}; + +template < typename T> +std::pair findInVector(const std::vector & vecOfElements, const T & element) +{ + std::pair result; + + // Find given element in vector + auto it = std::find(vecOfElements.begin(), vecOfElements.end(), element); + + if (it != vecOfElements.end()) + { + result.second = distance(vecOfElements.begin(), it); + result.first = true; + } + else + { + result.first = false; + result.second = -1; + } + + return result; +} + + CMasternodeMan::CMasternodeMan(): cs(), mapMasternodes(), @@ -80,6 +113,7 @@ bool CMasternodeMan::Add(CMasternode &mn) LOCK(cs); if (Has(mn.outpoint)) return false; + if (HasAddr(mn.addr)) return false; LogPrint("masternode", "CMasternodeMan::Add -- Adding new Masternode: addr=%s, %i now\n", mn.addr.ToString(), size() + 1); mapMasternodes[mn.outpoint] = mn; @@ -114,12 +148,26 @@ void CMasternodeMan::AskForMN(CNode* pnode, const COutPoint& outpoint, CConnman& LogPrintf("CMasternodeMan::AskForMN -- Asking peer %s for missing masternode entry for the first time: %s\n", addrSquashed.ToString(), outpoint.ToStringShort()); } mWeAskedForMasternodeListEntry[outpoint][addrSquashed] = GetTime() + DSEG_UPDATE_SECONDS; + connman.PushMessage(pnode, msgMaker.Make(NetMsgType::DSEG, outpoint)); +} - if (pnode->GetSendVersion() == 70208) { - connman.PushMessage(pnode, msgMaker.Make(NetMsgType::DSEG, CTxIn(outpoint))); - } else { - connman.PushMessage(pnode, msgMaker.Make(NetMsgType::DSEG, outpoint)); +void CMasternodeMan::AskForMnv(const CService& addr, const COutPoint& outpoint) +{ + if(activeMasternode.outpoint.IsNull()) return; + if(!masternodeSync.IsSynced()) return; + + CAddress caddr = CAddress(addr, NODE_NETWORK); + + netfulfilledman.HasFulfilledRequest(addr, strprintf("%s", NetMsgType::MNVERIFY)+"-request"); + g_connman->AddPendingMasternode(addr); + + // use random nonce, store it and require node to reply with correct one later + CMasternodeVerification mnv(addr, GetRandInt(999999), nCachedBlockHeight - 1); + { + LOCK(cs_mapPendingMNV); + mapPendingMNV.insert(std::make_pair(addr, std::make_pair(GetTime(), mnv))); } + LogPrintf("CMasternodeMan::AskForMnv -- verifying node using nonce %d addr=%s\n", mnv.nonce, addr.ToString()); } bool CMasternodeMan::AllowMixing(const COutPoint &outpoint) @@ -148,8 +196,38 @@ bool CMasternodeMan::DisallowMixing(const COutPoint &outpoint) return true; } +bool CMasternodeMan::IncreasePoSeBanScore(const COutPoint &outpoint) +{ + // this function is not for ourselves + if(outpoint == activeMasternode.outpoint) return false; + LOCK(cs); + CMasternode* pmn = Find(outpoint); + if (!pmn) { + return false; + } + pmn->IncreasePoSeBanScore(); + + return true; +} + +bool CMasternodeMan::DecreasePoSeBanScore(const COutPoint &outpoint) +{ + // this function is not for ourselves + if(outpoint == activeMasternode.outpoint) return false; + LOCK(cs); + CMasternode* pmn = Find(outpoint); + if (!pmn) { + return false; + } + pmn->DecreasePoSeBanScore(); + + return true; +} + bool CMasternodeMan::PoSeBan(const COutPoint &outpoint) { + // this function is not for ourselves + if(outpoint == activeMasternode.outpoint) return false; LOCK(cs); CMasternode* pmn = Find(outpoint); if (!pmn) { @@ -160,6 +238,45 @@ bool CMasternodeMan::PoSeBan(const COutPoint &outpoint) return true; } +bool CMasternodeMan::IncreasePoSeBanScore(const CService& addr) +{ + // this function is not for ourselves + if(addr == activeMasternode.service) return false; + LOCK(cs); + for (const auto& mnpair : mapMasternodes) { + if (addr == mnpair.second.addr) { + return IncreasePoSeBanScore(mnpair.second.outpoint); + } + } + return false; +} + +bool CMasternodeMan::DecreasePoSeBanScore(const CService& addr) +{ + // this function is not for ourselves + if(addr == activeMasternode.service) return false; + LOCK(cs); + for (const auto& mnpair : mapMasternodes) { + if (addr == mnpair.second.addr) { + return DecreasePoSeBanScore(mnpair.second.outpoint); + } + } + return false; +} + +bool CMasternodeMan::PoSeBan(const CService& addr) +{ + // this function is not for ourselves + if(addr == activeMasternode.service) return false; + LOCK(cs); + for (const auto& mnpair : mapMasternodes) { + if (addr == mnpair.second.addr) { + return PoSeBan(mnpair.second.outpoint); + } + } + return false; +} + void CMasternodeMan::Check() { LOCK2(cs_main, cs); @@ -428,12 +545,7 @@ void CMasternodeMan::DsegUpdate(CNode* pnode, CConnman& connman) } } } - - if (pnode->GetSendVersion() == 70208) { - connman.PushMessage(pnode, msgMaker.Make(NetMsgType::DSEG, CTxIn())); - } else { - connman.PushMessage(pnode, msgMaker.Make(NetMsgType::DSEG, COutPoint())); - } + connman.PushMessage(pnode, msgMaker.Make(NetMsgType::DSEG, COutPoint())); int64_t askAgain = GetTime() + DSEG_UPDATE_SECONDS; mWeAskedForMasternodeList[addrSquashed] = askAgain; @@ -502,6 +614,17 @@ bool CMasternodeMan::Has(const COutPoint& outpoint) return mapMasternodes.find(outpoint) != mapMasternodes.end(); } +bool CMasternodeMan::HasAddr(const CService& addr) +{ + LOCK(cs); + for (const auto& mnpair : mapMasternodes) { + if (addr == mnpair.second.addr) { + return true; + } + } + return false; +} + // // Deterministically select the oldest/best masternode to pay on the network // @@ -789,17 +912,22 @@ void CMasternodeMan::ProcessPendingMnbRequests(CConnman& connman) int64_t nTimeAdded = itPendingMNB->second.first; if (fDone || (GetTime() - nTimeAdded > 15)) { - if (!fDone) { - LogPrint("masternode", "CMasternodeMan::%s -- failed to connect to %s\n", __func__, itPendingMNB->first.ToString()); - //Punish not reachable MN , required cs_main - //PunishNode(itPendingMNB->first,connman); + if (!fDone && (fOkDual || (fOkIPv4 && itPendingMNB->first.IsIPv4()) || (fOkIPv6 && itPendingMNB->first.IsIPv6())) ) + { + // failed to connect to address + LogPrintf("CMasternodeMan::ProcessPendingMnbRequests -- Punish not reachable addr %s\n", itPendingMNB->first.ToString()); + //Punish not reachable MN , requires cs, requires cs_main + PunishNode(itPendingMNB->first, 20, connman); } mapPendingMNB.erase(itPendingMNB++); } else { ++itPendingMNB; } } - LogPrint("masternode", "%s -- mapPendingMNB size: %d\n", __func__, mapPendingMNB.size()); + + int sz = mapPendingMNB.size(); + if (sz>0) LogPrintf("CMasternodeMan::ProcessPendingMnbRequests -- mapPendingMNB size: %d\n", sz); + else LogPrint("masternode", "CMasternodeMan::ProcessPendingMnbRequests -- mapPendingMNB size: %d\n", sz); } void CMasternodeMan::ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman) @@ -882,14 +1010,7 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, const std::string& strCommand, if (!masternodeSync.IsSynced()) return; COutPoint masternodeOutpoint; - - if (pfrom->nVersion == 70208) { - CTxIn vin; - vRecv >> vin; - masternodeOutpoint = vin.prevout; - } else { - vRecv >> masternodeOutpoint; - } + vRecv >> masternodeOutpoint; LogPrint("masternode", "DSEG -- Masternode list, masternode=%s\n", masternodeOutpoint.ToStringShort()); @@ -994,21 +1115,49 @@ void CMasternodeMan::PushDsegInvs(CNode* pnode, const CMasternode& mn) mapSeenMasternodePing.insert(std::make_pair(hashMNP, mnp)); } - -void CMasternodeMan::PunishNode(const CService& addr, CConnman& connman) +// Requires cs_main. +void CMasternodeMan::PunishNode(const CService& addr, int howmuch, CConnman& connman) { - CNode* found = connman.FindNode(addr); - LogPrint("masternode","CMasternodeMan::%s -- searching bad node-id at addr=%s\n", __func__, addr.ToString()); - if(found){ - LogPrintf("CMasternodeMan::PunishNode -- found Misbehaving node-id=%d at addr=%s\n", found->id, addr.ToString()); - LOCK(cs_main); - Misbehaving(found->id, 20); + if(!masternodeSync.IsSynced()) return; + // do not auto-punish + if(addr == activeMasternode.service) return; + if(fOkDual || (fOkIPv4 && addr.IsIPv4()) || (fOkIPv6 && addr.IsIPv6())) + { + // Requires cs. Punish not reachable MN. + IncreasePoSeBanScore(addr); + + LogPrint("masternode","CMasternodeMan::%s -- searching bad node-id at addr=%s\n", __func__, addr.ToString()); + CNode* found = connman.FindNode(addr); + if(found){ + LogPrint("masternode","CMasternodeMan::PunishNode -- found Misbehaving node-id=%d at addr=%s\n", found->id, addr.ToString()); + LOCK(cs_main); + Misbehaving(found->id, howmuch); + } } } +// check socket connect +bool CMasternodeMan::MnCheckConnect(CMasternode* pmn) +{ + bool docheck = fOkDual || (fOkIPv4 && pmn->addr.IsIPv4()) || (fOkIPv6 && pmn->addr.IsIPv6()); + if (!docheck) { + LogPrintf("CMasternodeMan::MnCheckConnect -- Cannot check connection to '%s'\n", pmn->addr.ToString()); + return docheck; + } + + // Check socket connectivity + LogPrintf("CMasternodeMan::MnCheckConnect -- Check connection to '%s'\n", pmn->addr.ToString()); + SOCKET hSocket; + bool fConnected = ConnectSocket(pmn->addr, hSocket, nConnectTimeout) && IsSelectableSocket(hSocket); + CloseSocket(hSocket); -// Verification of masternodes via unique direct requests. + if (!fConnected) { + LogPrintf("CMasternodeMan::MnCheckConnect -- %s: Could not connect to %s\n", pmn->outpoint.ToStringShort(), pmn->addr.ToString()); + } + return fConnected; +} +// Verification of masternodes via unique direct requests void CMasternodeMan::DoFullVerificationStep(CConnman& connman) { if(activeMasternode.outpoint.IsNull()) return; @@ -1028,35 +1177,31 @@ void CMasternodeMan::DoFullVerificationStep(CConnman& connman) // send verify requests only if we are in top MAX_POSE_RANK rank_pair_vec_t::iterator it = vecMasternodeRanks.begin(); while(it != vecMasternodeRanks.end()) { - if(it->first > MAX_POSE_RANK) { - LogPrint("masternode", "CMasternodeMan::DoFullVerificationStep -- Must be in top %d to send verify request\n", - (int)MAX_POSE_RANK); - return; - } if(it->second.outpoint == activeMasternode.outpoint) { nMyRank = it->first; - LogPrint("masternode", "CMasternodeMan::DoFullVerificationStep -- Found self at rank %d/%d, verifying up to %d masternodes\n", + LogPrintf("CMasternodeMan::DoFullVerificationStep -- Found self at rank %d/%d, verifying up to %d masternodes\n", nMyRank, nRanksTotal, (int)MAX_POSE_CONNECTIONS); + if(it->first > MAX_POSE_RANK) { + LogPrintf("CMasternodeMan::DoFullVerificationStep -- Must be in top %d to send verify request\n", + (int)MAX_POSE_RANK); + return; + } break; } ++it; } - // edge case: list is too short and this masternode is not enabled - if(nMyRank == -1) return; + // edge case: list is too short or this masternode is not enabled + if(nMyRank == -1) { + LogPrintf("CMasternodeMan::DoFullVerificationStep -- list is too short or this masternode is not enabled\n"); + return; + } // send verify requests to up to MAX_POSE_CONNECTIONS masternodes // starting from MAX_POSE_RANK + nMyRank and using MAX_POSE_CONNECTIONS as a step int nOffset = MAX_POSE_RANK + nMyRank - 1; if(nOffset >= (int)vecMasternodeRanks.size()) return; - std::vector vSortedByAddr; - for (const auto& mnpair : mapMasternodes) { - vSortedByAddr.push_back(&mnpair.second); - } - - sort(vSortedByAddr.begin(), vSortedByAddr.end(), CompareByAddr()); - it = vecMasternodeRanks.begin() + nOffset; while(it != vecMasternodeRanks.end()) { if(it->second.IsPoSeVerified() || it->second.IsPoSeBanned()) { @@ -1070,19 +1215,38 @@ void CMasternodeMan::DoFullVerificationStep(CConnman& connman) it += MAX_POSE_CONNECTIONS; continue; } - LogPrint("masternode", "CMasternodeMan::DoFullVerificationStep -- Verifying masternode %s rank %d/%d address %s\n", - it->second.outpoint.ToStringShort(), it->first, nRanksTotal, it->second.addr.ToString()); CAddress addr = CAddress(it->second.addr, NODE_NETWORK); if(VerifyRequest(addr, connman)) { vAddr.push_back(addr); + + // so avoid double AskForMnv + mapWeShouldAskForVerification.erase(it->second.outpoint); + + LogPrintf("CMasternodeMan::DoFullVerificationStep -- Verifying masternode %s rank %d/%d address %s\n", + it->second.outpoint.ToStringShort(), it->first, nRanksTotal, it->second.addr.ToString()); nCount++; if(nCount >= MAX_POSE_CONNECTIONS) break; } + nOffset += MAX_POSE_CONNECTIONS; if(nOffset >= (int)vecMasternodeRanks.size()) break; it += MAX_POSE_CONNECTIONS; } + + // include also the ones we think WeShouldAskForVerification + for (const auto& outpt : mapWeShouldAskForVerification) { + CMasternode mn4v; + if (Get(outpt.first, mn4v)) { + CAddress addr = CAddress(mn4v.addr, NODE_NETWORK); + vAddr.push_back(addr); + int TimePassed = GetTime() - outpt.second; + LogPrintf("CMasternodeMan::DoFullVerificationStep -- Verifying masternode %s after %d secs, address %s\n", + mn4v.outpoint.ToStringShort(), TimePassed, mn4v.addr.ToString()); + } + mapWeShouldAskForVerification.erase(outpt.first); + } + } // end lock CS for (const auto& addr : vAddr) { @@ -1094,63 +1258,160 @@ void CMasternodeMan::DoFullVerificationStep(CConnman& connman) LogPrintf("CMasternodeMan::DoFullVerificationStep -- verifying node using nonce %d addr=%s\n", mnv.nonce, addr.ToString()); } - LogPrint("masternode", "CMasternodeMan::DoFullVerificationStep -- Sent verification requests to %d masternodes\n", nCount); + // show allways how many VerifyRequest we think we have sent + LogPrintf("CMasternodeMan::DoFullVerificationStep -- Sent verification requests to %d masternodes\n", nCount); } // This function tries to find masternodes with the same addr, -// find a verified one and ban all the other. If there are many nodes -// with the same addr but none of them is verified yet, then none of them are banned. -// It could take many times to run this before most of the duplicate nodes are banned. - +// find the lower ban score one and ban all the others. void CMasternodeMan::CheckSameAddr() { if(!masternodeSync.IsSynced() || mapMasternodes.empty()) return; + int mncount = 0; std::vector vBan; std::vector vSortedByAddr; + std::vector vSortedByPoSe; + std::map< CNetAddr, CMasternode*> mapAskForMnv; { LOCK(cs); - CMasternode* pprevMasternode = NULL; - CMasternode* pverifiedMasternode = NULL; + CMasternode* pprevMasternode = NULL; + std::pair pLowerPoSeBanScoreMasternode = std::make_pair( -1, pprevMasternode); for (auto& mnpair : mapMasternodes) { - vSortedByAddr.push_back(&mnpair.second); + // do not auto-ban myself + if(mnpair.second.outpoint == activeMasternode.outpoint) { + continue; + } else { + // someone else is using my address + if(mnpair.second.addr == activeMasternode.service) { + LogPrintf("CMasternodeMan::CheckSameAddr -- Ban masternode %s, at my addr %s\n", + mnpair.second.outpoint.ToStringShort(),mnpair.second.addr.ToString()); + mnpair.second.PoSeBan(); + continue; + } else { + vSortedByAddr.push_back(&mnpair.second); + vSortedByPoSe.push_back(&mnpair.second); + } + } } sort(vSortedByAddr.begin(), vSortedByAddr.end(), CompareByAddr()); + sort(vSortedByPoSe.begin(), vSortedByPoSe.end(), CompareByPoSeBanScore()); for (const auto& pmn : vSortedByAddr) { - // check only (pre)enabled masternodes - if(!pmn->IsEnabled() && !pmn->IsPreEnabled()) continue; + // check all valid masternodes + if(pmn->IsOutpointSpent() || pmn->IsUpdateRequired() || pmn->IsPoSeBanned()) continue; + mncount++; // initial step if(!pprevMasternode) { pprevMasternode = pmn; - pverifiedMasternode = pmn->IsPoSeVerified() ? pmn : NULL; + std::pair result = findInVector( vSortedByPoSe, pmn); + pLowerPoSeBanScoreMasternode = std::make_pair( result.second, pmn); continue; } // second+ step - if(pmn->addr == pprevMasternode->addr) { - if(pverifiedMasternode) { - // another masternode with the same ip is verified, ban this one + CNetAddr ippmm = (CNetAddr)(pmn->addr); + CNetAddr ippvMn = (CNetAddr)(pprevMasternode->addr); + std::pair result = findInVector( vSortedByPoSe, pmn); + std::pair pLPSBSMasternode = std::make_pair( result.second, pmn); + + if(ippmm == ippvMn) { + if(pLPSBSMasternode.first > pLowerPoSeBanScoreMasternode.first) { + // previous masternode with same ip have lower ban score, ban this one vBan.push_back(pmn); - } else if(pmn->IsPoSeVerified()) { - // this masternode with the same ip is verified, ban previous one + } else { + // this masternode with the same ip have lower ban score, ban previous one vBan.push_back(pprevMasternode); // and keep a reference to be able to ban following masternodes with the same ip - pverifiedMasternode = pmn; + pLowerPoSeBanScoreMasternode = pLPSBSMasternode; } + mapAskForMnv.emplace(ippmm,pLowerPoSeBanScoreMasternode.second); } else { - pverifiedMasternode = pmn->IsPoSeVerified() ? pmn : NULL; + // update new 1st search address + pLowerPoSeBanScoreMasternode = pLPSBSMasternode; } pprevMasternode = pmn; } } + int i = (int)vBan.size(); + int j = (int)vSortedByAddr.size(); + LogPrintf("CMasternodeMan::CheckSameAddr -- PoSe ban list num: %d from %d mnodes of total:%d\n", i, mncount, j); // ban duplicates for (auto& pmn : vBan) { - LogPrintf("CMasternodeMan::CheckSameAddr -- increasing PoSe ban score for masternode %s\n", pmn->outpoint.ToStringShort()); + LogPrintf("CMasternodeMan::CheckSameAddr -- PoSe ban for masternode %s\n", pmn->outpoint.ToStringShort()); + pmn->PoSeBan(); + } + + // AskForMnv duplicate PoSeBanScore winners to Verify themselfs + for (auto& pmn : mapAskForMnv) { + if (MnCheckConnect(pmn.second)) { + // ask these MNs to verify when possible + LogPrintf("CMasternodeMan::CheckSameAddr -- should be asked mnv masternode %s, addr %s\n", pmn.second->outpoint.ToStringShort(), pmn.second->addr.ToString()); + mapWeShouldAskForVerification.emplace(pmn.second->outpoint, GetTime()); + //AskForMnv(pmn.second->addr, pmn.second->outpoint); + } else { + LogPrintf("CMasternodeMan::CheckSameAddr -- inc.PoSeBanScore, could not mnv masternode %s, addr %s\n", pmn.second->outpoint.ToStringShort(), pmn.second->addr.ToString()); + // could not check if MN is a true MN + pmn.second->IncreasePoSeBanScore(); + } + } + +} + +void CMasternodeMan::CheckMissingMasternodes() +{ + if(!masternodeSync.IsSynced() || mapMasternodes.empty()) return; + + int mncount = 0; + std::vector vBan; + std::vector vSortedByAddr; + + { + LOCK(cs); + + for (auto& mnpair : mapMasternodes) { + // do not auto-ban myself + if(mnpair.second.outpoint == activeMasternode.outpoint) { + continue; + } else { + // someone else is using my address + if(mnpair.second.addr == activeMasternode.service) { + LogPrintf("CMasternodeMan::CheckMissingMasternodes -- Ban masternode %s, at my addr %s\n", + mnpair.second.outpoint.ToStringShort(),mnpair.second.addr.ToString()); + mnpair.second.PoSeBan(); + continue; + } else vSortedByAddr.push_back(&mnpair.second); + } + } + sort(vSortedByAddr.begin(), vSortedByAddr.end(), CompareByAddr()); + for (const auto& pmn : vSortedByAddr) { + // check only valid masternodes + if(pmn->IsOutpointSpent() || pmn->IsUpdateRequired() || pmn->IsPoSeBanned()) continue; + mncount++; + auto it = mapMissingMNs.find(pmn->addr); + if (it != mapMissingMNs.end()) { + if((it->second == 111 || it->second == 13 || it->second == 113) + && !pmn->addr.IsLocal() && pmn->addr.IsRoutable() + && ((fOkIPv4 && pmn->addr.IsIPv4())||(fOkIPv6 && pmn->addr.IsIPv6()))){ + vBan.push_back(pmn); + mapMissingMNs.erase(pmn->addr); + } + } + } + + } // end LOCK + + int i = (int)vBan.size(); + int j = (int)vSortedByAddr.size(); + LogPrintf("CMasternodeMan::CheckMissingMasternodes -- Increase PoSe Ban Score list num: %d from %d (valid mn) of total:%d\n", i, mncount, j); + + // ban missing service Masternodes + for (auto& pmn : vBan) { + LogPrintf("CMasternodeMan::CheckMissingMasternodes -- Increase PoSe Ban Score for masternode %s\n", pmn->outpoint.ToStringShort()); pmn->IncreasePoSeBanScore(); } } @@ -1158,9 +1419,10 @@ void CMasternodeMan::CheckSameAddr() bool CMasternodeMan::VerifyRequest(const CAddress& addr, CConnman& connman) { if(netfulfilledman.HasFulfilledRequest(addr, strprintf("%s", NetMsgType::MNVERIFY)+"-request")) { - // we already asked for verification, not a good idea to do this too often, skip it - LogPrint("masternode", "CMasternodeMan::SendVerifyRequest -- too many requests, skipping... addr=%s\n", addr.ToString()); - return false; + // we already asked for verification, not a good idea to do this too often, but we can not skip it + LogPrintf("CMasternodeMan::SendVerifyRequest -- do we repeat request, just asking... addr=%s\n", addr.ToString()); + // now, this is a little misbehaving only, we as real nodes we send requests + // return false; } return !connman.IsMasternodeOrDisconnectRequested(addr); @@ -1174,29 +1436,60 @@ void CMasternodeMan::ProcessPendingMnvRequests(CConnman& connman) std::map >::iterator itPendingMNV = mapPendingMNV.begin(); while (itPendingMNV != mapPendingMNV.end()) { - bool fDone = connman.ForNode(itPendingMNV->first, [&](CNode* pnode) { + bool fDoneSending = connman.ForNode(itPendingMNV->first, [&](CNode* pnode) { netfulfilledman.AddFulfilledRequest(pnode->addr, strprintf("%s", NetMsgType::MNVERIFY)+"-request"); // use random nonce, store it and require node to reply with correct one later mWeAskedForVerification[pnode->addr] = itPendingMNV->second.second; - LogPrint("masternode", "-- verifying node using nonce %d addr=%s\n", itPendingMNV->second.second.nonce, pnode->addr.ToString()); + LogPrintf("CMasternodeMan::%s -- verifying node using nonce %d addr=%s\n", __func__, itPendingMNV->second.second.nonce, pnode->addr.ToString()); CNetMsgMaker msgMaker(pnode->GetSendVersion()); // TODO this gives a warning about version not being set (we should wait for VERSION exchange) connman.PushMessage(pnode, msgMaker.Make(NetMsgType::MNVERIFY, itPendingMNV->second.second)); return true; }); int64_t nTimeAdded = itPendingMNV->second.first; - if (fDone || (GetTime() - nTimeAdded > 15)) { - if (!fDone) { - LogPrint("masternode", "CMasternodeMan::%s -- failed to connect to %s\n", __func__, itPendingMNV->first.ToString()); - // Punish not reachable MN , required cs_main - PunishNode(itPendingMNV->first,connman); + int64_t nTimePassed = GetTime() - nTimeAdded; + bool fOver15sPassed = nTimePassed > 15; + if (fDoneSending || fOver15sPassed) { + if (!fDoneSending) { + LogPrintf("CMasternodeMan::%s -- failed to connect to %s, %i sec\n", __func__, itPendingMNV->first.ToString(),(int)nTimePassed); + // Requires cs, cs_main. Punish not reachable Node-peer + PunishNode(itPendingMNV->first, 20, connman); + // give up mnv request + mapPendingMNV.erase(itPendingMNV++); + } else { // fDoneSending + bool fMnvRequest = netfulfilledman.HasFulfilledRequest(itPendingMNV->first, strprintf("%s", NetMsgType::MNVERIFY)+"-request"); + bool fMnvDone = netfulfilledman.HasFulfilledRequest(itPendingMNV->first, strprintf("%s", NetMsgType::MNVERIFY)+"-done"); + if( fMnvRequest && fMnvDone ) { // MNV request && done + // once done: copy of the mnv is at: + // mWeAskedForVerification[pnode->addr] = mnv; + // mapSeenMasternodeVerification.insert(std::make_pair(mnv.GetHash(), mnv)); + LogPrintf("CMasternodeMan::%s -- done verify from %s in %i sec\n", __func__, itPendingMNV->first.ToString(),(int)nTimePassed); + mapPendingMNV.erase(itPendingMNV++); + + } else { // MNV was ignored or failed + LogPrintf("CMasternodeMan::%s -- still pending from %s, %i sec\n", __func__, itPendingMNV->first.ToString(),(int)nTimePassed); + if (fOver15sPassed) { + // failed to connect to address + LogPrintf("CMasternodeMan::ProcessPendingMnvRequests -- Punish not replying addr %s\n", itPendingMNV->first.ToString()); + // Requires cs, cs_main. Punish not replying or failing to send Node-peer + PunishNode(itPendingMNV->first, 20, connman); + // give up mnv request + mapPendingMNV.erase(itPendingMNV++); + } + // Retry: re-ProcessPendingMnvRequests (re-send MNV) + } } - mapPendingMNV.erase(itPendingMNV++); + // in case not send and not received ProcessPendingMnvRequests will be called every 1 sec/clockTick } else { + // process next in PendingMNV list ++itPendingMNV; } } - LogPrint("masternode", "%s -- mapPendingMNV size: %d\n", __func__, mapPendingMNV.size()); + + int sz = mapPendingMNV.size(); + if (sz>0) LogPrintf("CMasternodeMan::ProcessPendingMnvRequests -- mapPendingMNV size: %d\n", sz); + else LogPrint("masternode", "CMasternodeMan::ProcessPendingMnvRequests -- mapPendingMNV size: %d\n", sz); + } void CMasternodeMan::SendVerifyReply(CNode* pnode, CMasternodeVerification& mnv, CConnman& connman) @@ -1212,14 +1505,15 @@ void CMasternodeMan::SendVerifyReply(CNode* pnode, CMasternodeVerification& mnv, if(netfulfilledman.HasFulfilledRequest(pnode->addr, strprintf("%s", NetMsgType::MNVERIFY)+"-reply")) { // peer should not ask us that often - LogPrintf("MasternodeMan::SendVerifyReply -- ERROR: peer already asked me recently, peer=%d\n", pnode->id); - Misbehaving(pnode->id, 20); + LogPrintf("CMasternodeMan::SendVerifyReply -- ERROR: peer already asked me recently, peer=%d\n", pnode->id); + // it is a little misbehaving only, probable only real nodes will send a request + Misbehaving(pnode->id, 02); return; } uint256 blockHash; if(!GetBlockHash(blockHash, mnv.nBlockHeight)) { - LogPrintf("MasternodeMan::SendVerifyReply -- can't get block hash for unknown block height %d, peer=%d\n", mnv.nBlockHeight, pnode->id); + LogPrintf("CMasternodeMan::SendVerifyReply -- can't get block hash for unknown block height %d, peer=%d\n", mnv.nBlockHeight, pnode->id); return; } @@ -1241,12 +1535,12 @@ void CMasternodeMan::SendVerifyReply(CNode* pnode, CMasternodeVerification& mnv, std::string strMessage = strprintf("%s%d%s", activeMasternode.service.ToString(false), mnv.nonce, blockHash.ToString()); if(!CMessageSigner::SignMessage(strMessage, mnv.vchSig1, activeMasternode.keyMasternode)) { - LogPrintf("MasternodeMan::SendVerifyReply -- SignMessage() failed\n"); + LogPrintf("CMasternodeMan::SendVerifyReply -- SignMessage() failed\n"); return; } if(!CMessageSigner::VerifyMessage(activeMasternode.pubKeyMasternode, mnv.vchSig1, strMessage, strError)) { - LogPrintf("MasternodeMan::SendVerifyReply -- VerifyMessage() failed, error: %s\n", strError); + LogPrintf("CMasternodeMan::SendVerifyReply -- VerifyMessage() failed, error: %s\n", strError); return; } } @@ -1265,22 +1559,28 @@ void CMasternodeMan::ProcessVerifyReply(CNode* pnode, CMasternodeVerification& m // did we even ask for it? if that's the case we should have matching fulfilled request if(!netfulfilledman.HasFulfilledRequest(pnode->addr, strprintf("%s", NetMsgType::MNVERIFY)+"-request")) { LogPrintf("CMasternodeMan::ProcessVerifyReply -- ERROR: we didn't ask for verification of %s, peer=%d\n", pnode->addr.ToString(), pnode->id); - Misbehaving(pnode->id, 20); + // we could have crashed and lost the copy requestd + // it is a little misbehaving only, probable only real nodes will send a reply + Misbehaving(pnode->id, 02); return; } // Received nonce for a known address must match the one we sent if(mWeAskedForVerification[pnode->addr].nonce != mnv.nonce) { - LogPrintf("CMasternodeMan::ProcessVerifyReply -- ERROR: wrong nounce: requested=%d, received=%d, peer=%d\n", - mWeAskedForVerification[pnode->addr].nonce, mnv.nonce, pnode->id); + LogPrintf("CMasternodeMan::ProcessVerifyReply -- ERROR: wrong nounce: requested=%d, received=%d, peer=%d, %s\n", + mWeAskedForVerification[pnode->addr].nonce, mnv.nonce, pnode->id, pnode->addr.ToString()); + // Requires cs. Punish wrong MN answer. + IncreasePoSeBanScore((CService)pnode->addr); Misbehaving(pnode->id, 20); return; } // Received nBlockHeight for a known address must match the one we sent if(mWeAskedForVerification[pnode->addr].nBlockHeight != mnv.nBlockHeight) { - LogPrintf("CMasternodeMan::ProcessVerifyReply -- ERROR: wrong nBlockHeight: requested=%d, received=%d, peer=%d\n", - mWeAskedForVerification[pnode->addr].nBlockHeight, mnv.nBlockHeight, pnode->id); + LogPrintf("CMasternodeMan::ProcessVerifyReply -- ERROR: wrong nBlockHeight: requested=%d, received=%d, peer=%d, %s\n", + mWeAskedForVerification[pnode->addr].nBlockHeight, mnv.nBlockHeight, pnode->id, pnode->addr.ToString()); + // Requires cs. Punish wrong MN answer. + IncreasePoSeBanScore((CService)pnode->addr); Misbehaving(pnode->id, 20); return; } @@ -1288,15 +1588,17 @@ void CMasternodeMan::ProcessVerifyReply(CNode* pnode, CMasternodeVerification& m uint256 blockHash; if(!GetBlockHash(blockHash, mnv.nBlockHeight)) { // this shouldn't happen... - LogPrintf("MasternodeMan::ProcessVerifyReply -- can't get block hash for unknown block height %d, peer=%d\n", mnv.nBlockHeight, pnode->id); + LogPrintf("CMasternodeMan::ProcessVerifyReply -- can't get block hash for unknown block height %d, peer=%d, %s\n", + mnv.nBlockHeight, pnode->id, pnode->addr.ToString()); return; } // we already verified this address, why node is spamming? if(netfulfilledman.HasFulfilledRequest(pnode->addr, strprintf("%s", NetMsgType::MNVERIFY)+"-done")) { - LogPrintf("CMasternodeMan::ProcessVerifyReply -- ERROR: already verified %s recently\n", pnode->addr.ToString()); - Misbehaving(pnode->id, 20); - return; + LogPrintf("CMasternodeMan::ProcessVerifyReply -- WARN: already verified %s recently\n", pnode->addr.ToString()); + // it is a little misbehaving only, probable only real nodes will send a reply + Misbehaving(pnode->id, 02); + // process the reply anyway } { @@ -1338,12 +1640,12 @@ void CMasternodeMan::ProcessVerifyReply(CNode* pnode, CMasternodeVerification& m uint256 hash2 = mnv.GetSignatureHash2(blockHash); if(!CHashSigner::SignHash(hash2, activeMasternode.keyMasternode, mnv.vchSig2)) { - LogPrintf("MasternodeMan::ProcessVerifyReply -- SignHash() failed\n"); + LogPrintf("CMasternodeMan::ProcessVerifyReply -- SignHash() failed\n"); return; } if(!CHashSigner::VerifyHash(hash2, activeMasternode.pubKeyMasternode, mnv.vchSig2, strError)) { - LogPrintf("MasternodeMan::ProcessVerifyReply -- VerifyHash() failed, error: %s\n", strError); + LogPrintf("CMasternodeMan::ProcessVerifyReply -- VerifyHash() failed, error: %s\n", strError); return; } } else { @@ -1351,12 +1653,12 @@ void CMasternodeMan::ProcessVerifyReply(CNode* pnode, CMasternodeVerification& m mnv.masternodeOutpoint1.ToStringShort(), mnv.masternodeOutpoint2.ToStringShort()); if(!CMessageSigner::SignMessage(strMessage2, mnv.vchSig2, activeMasternode.keyMasternode)) { - LogPrintf("MasternodeMan::ProcessVerifyReply -- SignMessage() failed\n"); + LogPrintf("CMasternodeMan::ProcessVerifyReply -- SignMessage() failed\n"); return; } if(!CMessageSigner::VerifyMessage(activeMasternode.pubKeyMasternode, mnv.vchSig2, strMessage2, strError)) { - LogPrintf("MasternodeMan::ProcessVerifyReply -- VerifyMessage() failed, error: %s\n", strError); + LogPrintf("CMasternodeMan::ProcessVerifyReply -- VerifyMessage() failed, error: %s\n", strError); return; } } @@ -1370,21 +1672,25 @@ void CMasternodeMan::ProcessVerifyReply(CNode* pnode, CMasternodeVerification& m } } } - // no real masternode found?... - if(!prealMasternode) { + // real masternode found?... + if(prealMasternode) { + LogPrintf("CMasternodeMan::ProcessVerifyReply -- verified real masternode %s for addr %s\n", + prealMasternode->outpoint.ToStringShort(), pnode->addr.ToString()); + } + else { + // no real masternode found?... // this should never be the case normally, // only if someone is trying to game the system in some way or smth like that LogPrintf("CMasternodeMan::ProcessVerifyReply -- ERROR: no real masternode found for addr %s\n", pnode->addr.ToString()); - Misbehaving(pnode->id, 20); - return; + // negative verify costs reputation + Misbehaving(pnode->id, 40); + // return; } - LogPrintf("CMasternodeMan::ProcessVerifyReply -- verified real masternode %s for addr %s\n", - prealMasternode->outpoint.ToStringShort(), pnode->addr.ToString()); - // increase ban score for everyone else + // increase ban score for everyone else found to be fake for (const auto& pmn : vpMasternodesToBan) { pmn->IncreasePoSeBanScore(); - LogPrint("masternode", "CMasternodeMan::ProcessVerifyReply -- increased PoSe ban score for %s addr %s, new score %d\n", - prealMasternode->outpoint.ToStringShort(), pnode->addr.ToString(), pmn->nPoSeBanScore); + LogPrintf("CMasternodeMan::ProcessVerifyReply -- increased PoSe ban score for %s addr %s, new score %d\n", + pmn->outpoint.ToStringShort(), pmn->addr.ToString(), pmn->nPoSeBanScore); } if(!vpMasternodesToBan.empty()) LogPrintf("CMasternodeMan::ProcessVerifyReply -- PoSe score increased for %d fake masternodes, addr %s\n", @@ -1406,15 +1712,17 @@ void CMasternodeMan::ProcessVerifyBroadcast(CNode* pnode, const CMasternodeVerif // we don't care about history if(mnv.nBlockHeight < nCachedBlockHeight - MAX_POSE_BLOCKS) { - LogPrint("masternode", "CMasternodeMan::ProcessVerifyBroadcast -- Outdated: current block %d, verification block %d, peer=%d\n", - nCachedBlockHeight, mnv.nBlockHeight, pnode->id); + LogPrintf("CMasternodeMan::ProcessVerifyBroadcast -- Outdated: current block %d, verification block %d, peer=%d, %s\n", + nCachedBlockHeight, mnv.nBlockHeight, pnode->id, pnode->addr.ToString()); return; } if(mnv.masternodeOutpoint1 == mnv.masternodeOutpoint2) { - LogPrint("masternode", "CMasternodeMan::ProcessVerifyBroadcast -- ERROR: same outpoints %s, peer=%d\n", - mnv.masternodeOutpoint1.ToStringShort(), pnode->id); - // that was NOT a good idea to cheat and verify itself, + LogPrintf("CMasternodeMan::ProcessVerifyBroadcast -- ERROR: same outpoints %s, peer=%d, %s\n", + mnv.masternodeOutpoint1.ToStringShort(), pnode->id, pnode->addr.ToString()); + // that was NOT a good idea to cheat and verify itself + // Requires cs. Punish wrong MN behaviour, but can be victim of a DoS by 3rd party as well + // PoSeBan(mnv.masternodeOutpoint1); // ban the node we received such message from Misbehaving(pnode->id, 100); return; @@ -1423,21 +1731,22 @@ void CMasternodeMan::ProcessVerifyBroadcast(CNode* pnode, const CMasternodeVerif uint256 blockHash; if(!GetBlockHash(blockHash, mnv.nBlockHeight)) { // this shouldn't happen... - LogPrintf("CMasternodeMan::ProcessVerifyBroadcast -- Can't get block hash for unknown block height %d, peer=%d\n", mnv.nBlockHeight, pnode->id); + LogPrintf("CMasternodeMan::ProcessVerifyBroadcast -- Can't get block hash for unknown block height %d, peer=%d, %s\n", + mnv.nBlockHeight, pnode->id, pnode->addr.ToString()); return; } int nRank; if (!GetMasternodeRank(mnv.masternodeOutpoint2, nRank, mnv.nBlockHeight, MIN_POSE_PROTO_VERSION)) { - LogPrint("masternode", "CMasternodeMan::ProcessVerifyBroadcast -- Can't calculate rank for masternode %s\n", + LogPrintf("CMasternodeMan::ProcessVerifyBroadcast -- Can't calculate rank for masternode %s\n", mnv.masternodeOutpoint2.ToStringShort()); return; } if(nRank > MAX_POSE_RANK) { - LogPrint("masternode", "CMasternodeMan::ProcessVerifyBroadcast -- Masternode %s is not in top %d, current rank %d, peer=%d\n", - mnv.masternodeOutpoint2.ToStringShort(), (int)MAX_POSE_RANK, nRank, pnode->id); + LogPrintf("CMasternodeMan::ProcessVerifyBroadcast -- Masternode %s is not in top %d, current rank %d, peer=%d, %s\n", + mnv.masternodeOutpoint2.ToStringShort(), (int)MAX_POSE_RANK, nRank, pnode->id, pnode->addr.ToString()); return; } @@ -1457,7 +1766,12 @@ void CMasternodeMan::ProcessVerifyBroadcast(CNode* pnode, const CMasternodeVerif } if(pmn1->addr != mnv.addr) { - LogPrintf("CMasternodeMan::ProcessVerifyBroadcast -- addr %s does not match %s\n", mnv.addr.ToString(), pmn1->addr.ToString()); + LogPrintf("CMasternodeMan::ProcessVerifyBroadcast -- mnv addr %s does not match our %s for mn1 %s\n", + mnv.addr.ToString(), pmn1->addr.ToString(), mnv.masternodeOutpoint1.ToStringShort()); + // node mn2 is relaying/broadcasting wrong information, but can be victim of a DoS by 3rd party as well + // pmn2->IncreasePoSeBanScore(); + // peer pnode-id is also helping spreading the wrong information + Misbehaving(pnode->id, 20); return; } @@ -1466,12 +1780,12 @@ void CMasternodeMan::ProcessVerifyBroadcast(CNode* pnode, const CMasternodeVerif uint256 hash2 = mnv.GetSignatureHash2(blockHash); if(!CHashSigner::VerifyHash(hash1, pmn1->pubKeyMasternode, mnv.vchSig1, strError)) { - LogPrintf("MasternodeMan::ProcessVerifyBroadcast -- VerifyHash() failed, error: %s\n", strError); + LogPrintf("CMasternodeMan::ProcessVerifyBroadcast -- VerifyHash() failed, error: %s\n", strError); return; } if(!CHashSigner::VerifyHash(hash2, pmn2->pubKeyMasternode, mnv.vchSig2, strError)) { - LogPrintf("MasternodeMan::ProcessVerifyBroadcast -- VerifyHash() failed, error: %s\n", strError); + LogPrintf("CMasternodeMan::ProcessVerifyBroadcast -- VerifyHash() failed, error: %s\n", strError); return; } } else { @@ -1504,7 +1818,7 @@ void CMasternodeMan::ProcessVerifyBroadcast(CNode* pnode, const CMasternodeVerif if(mnpair.second.addr != mnv.addr || mnpair.first == mnv.masternodeOutpoint1) continue; mnpair.second.IncreasePoSeBanScore(); nCount++; - LogPrint("masternode", "CMasternodeMan::ProcessVerifyBroadcast -- increased PoSe ban score for %s addr %s, new score %d\n", + LogPrintf("CMasternodeMan::ProcessVerifyBroadcast -- increased PoSe ban score for %s addr %s, new score %d\n", mnpair.first.ToStringShort(), mnpair.second.addr.ToString(), mnpair.second.nPoSeBanScore); } if(nCount) @@ -1570,10 +1884,10 @@ bool CMasternodeMan::CheckMnbAndUpdateMasternodeList(CNode* pfrom, CMasternodeBr } mapSeenMasternodeBroadcast.insert(std::make_pair(hash, std::make_pair(GetTime(), mnb))); - LogPrint("masternode", "CMasternodeMan::CheckMnbAndUpdateMasternodeList -- masternode=%s new\n", mnb.outpoint.ToStringShort()); + LogPrintf("CMasternodeMan::CheckMnbAndUpdateMasternodeList -- masternode=%s new\n", mnb.outpoint.ToStringShort()); if(!mnb.SimpleCheck(nDos)) { - LogPrint("masternode", "CMasternodeMan::CheckMnbAndUpdateMasternodeList -- SimpleCheck() failed, masternode=%s\n", mnb.outpoint.ToStringShort()); + LogPrintf("CMasternodeMan::CheckMnbAndUpdateMasternodeList -- SimpleCheck() failed, masternode=%s\n", mnb.outpoint.ToStringShort()); return false; } @@ -1582,7 +1896,7 @@ bool CMasternodeMan::CheckMnbAndUpdateMasternodeList(CNode* pfrom, CMasternodeBr if(pmn) { CMasternodeBroadcast mnbOld = mapSeenMasternodeBroadcast[CMasternodeBroadcast(*pmn).GetHash()].second; if(!mnb.Update(pmn, nDos, connman)) { - LogPrint("masternode", "CMasternodeMan::CheckMnbAndUpdateMasternodeList -- Update() failed, masternode=%s\n", mnb.outpoint.ToStringShort()); + LogPrintf("CMasternodeMan::CheckMnbAndUpdateMasternodeList -- Update() failed, masternode=%s\n", mnb.outpoint.ToStringShort()); return false; } if(hash != mnbOld.GetHash()) { @@ -1592,25 +1906,29 @@ bool CMasternodeMan::CheckMnbAndUpdateMasternodeList(CNode* pfrom, CMasternodeBr } } - if(mnb.CheckOutpoint(nDos)) { - Add(mnb); - masternodeSync.BumpAssetLastTime("CMasternodeMan::CheckMnbAndUpdateMasternodeList - new"); - // if it matches our Masternode privkey... - if(fMasternodeMode && mnb.pubKeyMasternode == activeMasternode.pubKeyMasternode) { - mnb.nPoSeBanScore = -MASTERNODE_POSE_BAN_MAX_SCORE; - if(mnb.nProtocolVersion == PROTOCOL_VERSION) { - // ... and PROTOCOL_VERSION, then we've been remotely activated ... - LogPrintf("CMasternodeMan::CheckMnbAndUpdateMasternodeList -- Got NEW Masternode entry: masternode=%s sigTime=%lld addr=%s\n", - mnb.outpoint.ToStringShort(), mnb.sigTime, mnb.addr.ToString()); - activeMasternode.ManageState(connman); - } else { - // ... otherwise we need to reactivate our node, do not add it to the list and do not relay - // but also do not ban the node we get this message from - LogPrintf("CMasternodeMan::CheckMnbAndUpdateMasternodeList -- wrong PROTOCOL_VERSION, re-activate your MN: message nProtocolVersion=%d PROTOCOL_VERSION=%d\n", mnb.nProtocolVersion, PROTOCOL_VERSION); - return false; + if(mnb.CheckOutpoint(nDos) && mnb.CheckAddr(nDos)) { + if(Add(mnb)){ + masternodeSync.BumpAssetLastTime("CMasternodeMan::CheckMnbAndUpdateMasternodeList - new"); + // if it matches our Masternode privkey... + if(fMasternodeMode && mnb.pubKeyMasternode == activeMasternode.pubKeyMasternode) { + mnb.nPoSeBanScore = -MASTERNODE_POSE_BAN_MAX_SCORE; + if(mnb.nProtocolVersion == PROTOCOL_VERSION) { + // ... and PROTOCOL_VERSION, then we've been remotely activated ... + LogPrintf("CMasternodeMan::CheckMnbAndUpdateMasternodeList -- Got NEW Masternode entry: masternode=%s sigTime=%lld addr=%s\n", + mnb.outpoint.ToStringShort(), mnb.sigTime, mnb.addr.ToString()); + activeMasternode.ManageState(connman); + } else { + // ... otherwise we need to reactivate our node, do not add it to the list and do not relay + // but also do not ban the node we get this message from + LogPrintf("CMasternodeMan::CheckMnbAndUpdateMasternodeList -- wrong PROTOCOL_VERSION, re-activate your MN: message nProtocolVersion=%d PROTOCOL_VERSION=%d\n", mnb.nProtocolVersion, PROTOCOL_VERSION); + return false; + } } + mnb.Relay(connman); + } else { + LogPrintf("CMasternodeMan::CheckMnbAndUpdateMasternodeList -- Rejected Add Masternode entry: %s addr=%s\n", mnb.outpoint.ToStringShort(), mnb.addr.ToString()); + return false; } - mnb.Relay(connman); } else { LogPrintf("CMasternodeMan::CheckMnbAndUpdateMasternodeList -- Rejected Masternode entry: %s addr=%s\n", mnb.outpoint.ToStringShort(), mnb.addr.ToString()); return false; @@ -1759,7 +2077,7 @@ void CMasternodeMan::WarnMasternodeDaemonUpdates() // trigger GUI update uiInterface.NotifyAlertChanged(SerializeHash(strWarning), CT_NEW); // trigger cmd-line notification - AlertNotify(strWarning, CT_NEW); + //AlertNotify(strWarning, CT_NEW); fWarned = true; } diff --git a/src/masternodeman.h b/src/masternodeman.h index 8121a1978..a2e901697 100644 --- a/src/masternodeman.h +++ b/src/masternodeman.h @@ -29,7 +29,7 @@ class CMasternodeMan static const int LAST_PAID_SCAN_BLOCKS; - static const int MIN_POSE_PROTO_VERSION = 70210; + static const int MIN_POSE_PROTO_VERSION = 70211; static const int MAX_POSE_CONNECTIONS = 10; static const int MAX_POSE_RANK = 10; static const int MAX_POSE_BLOCKS = 10; @@ -58,6 +58,8 @@ class CMasternodeMan // who we asked for the masternode verification std::map mWeAskedForVerification; + // who we should ask for masternode verification at the last time + std::map mapWeShouldAskForVerification; // these maps are used for masternode recovery from MASTERNODE_NEW_START_REQUIRED state std::map > > mMnbRecoveryRequests; @@ -87,7 +89,8 @@ class CMasternodeMan void SyncAll(CNode* pnode, CConnman& connman); void PushDsegInvs(CNode* pnode, const CMasternode& mn); - void PunishNode(const CService& addr, CConnman& connman); + void PunishNode(const CService& addr, int howmuch, CConnman& connman); + bool MnCheckConnect(CMasternode* pmn); public: // Keep track of all broadcasts I've seen @@ -138,8 +141,14 @@ class CMasternodeMan /// Ask (source) node for mnb void AskForMN(CNode *pnode, const COutPoint& outpoint, CConnman& connman); void AskForMnb(CNode *pnode, const uint256 &hash); + void AskForMnv(const CService& addr, const COutPoint& outpoint); + bool IncreasePoSeBanScore(const COutPoint &outpoint); + bool DecreasePoSeBanScore(const COutPoint &outpoint); bool PoSeBan(const COutPoint &outpoint); + bool IncreasePoSeBanScore(const CService& addr); + bool DecreasePoSeBanScore(const CService& addr); + bool PoSeBan(const CService& addr); bool AllowMixing(const COutPoint &outpoint); bool DisallowMixing(const COutPoint &outpoint); @@ -169,6 +178,7 @@ class CMasternodeMan /// Versions of Find that are safe to use from outside the class bool Get(const COutPoint& outpoint, CMasternode& masternodeRet); bool Has(const COutPoint& outpoint); + bool HasAddr(const CService& addr); bool GetMasternodeInfo(const COutPoint& outpoint, masternode_info_t& mnInfoRet); bool GetMasternodeInfo(const CPubKey& pubKeyMasternode, masternode_info_t& mnInfoRet); @@ -195,6 +205,7 @@ class CMasternodeMan void DoFullVerificationStep(CConnman& connman); void CheckSameAddr(); + void CheckMissingMasternodes(); bool VerifyRequest(const CAddress& addr, CConnman& connman); void ProcessPendingMnvRequests(CConnman& connman); void SendVerifyReply(CNode* pnode, CMasternodeVerification& mnv, CConnman& connman); diff --git a/src/net.cpp b/src/net.cpp index 8cc6f60c1..95f641f62 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -80,6 +80,15 @@ static const uint64_t RANDOMIZER_ID_LOCALHOSTNONCE = 0xd93e69e2bbfa5735ULL; // S bool fDiscover = true; bool fListen = true; bool fRelayTxes = true; + +// Flags for helping guess stacks online +bool fOkIPv4 = false; +bool fOkIPv6 = false; +bool fOkDual = false; + +// Dirty list of missing MNs +std::map mapMissingMNs; + CCriticalSection cs_mapLocalHost; std::map mapLocalHost; static bool vfLimited[NET_MAX] = {}; @@ -1973,13 +1982,23 @@ void CConnman::ThreadOpenMasternodeConnections() continue; } - OpenMasternodeConnection(CAddress(addr, NODE_NETWORK)); + bool fOpenConnection = OpenMasternodeConnection(CAddress(addr, NODE_NETWORK)); + + // Save a guess this is missing Masternode due to some known connect error! + if (!fOpenConnection && !IsLocal(addr)) mapMissingMNs.emplace(addr,nConnectRetCode); + // should be in the list now if connection was opened ForNode(addr, CConnman::AllNodes, [&](CNode* pnode) { if (pnode->fDisconnect) { return false; } grant.MoveTo(pnode->grantMasternodeOutbound); + + // guess which network was used + if (!fOkIPv4 && pnode->addr.IsIPv4() && !pnode->addr.IsLocal() && pnode->addr.IsRoutable()) fOkIPv4=true; + if (!fOkIPv6 && pnode->addr.IsIPv6() && !pnode->addr.IsLocal() && pnode->addr.IsRoutable()) fOkIPv6=true; + if (!fOkDual && fOkIPv4 && fOkIPv6) fOkDual=true; + return true; }); } diff --git a/src/net.h b/src/net.h index 28aa7e48f..82af8d24a 100644 --- a/src/net.h +++ b/src/net.h @@ -588,6 +588,14 @@ extern bool fDiscover; extern bool fListen; extern bool fRelayTxes; +// Flags for helping guess stacks online +extern bool fOkIPv4; +extern bool fOkIPv6; +extern bool fOkDual; + +// Dirty list of missing MNs +extern std::map mapMissingMNs; + extern limitedmap mapAlreadyAskedFor; /** Subversion as sent to the P2P network in `version` messages */ diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 73f4ee2f5..dffc128d0 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -1,5 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2016 The Bitcoin Core developers +// Copyright (c) 2018-2019 The ZeroOne Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -1394,8 +1395,6 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr { // disconnect from peers older than this proto version LogPrintf("peer=%d using obsolete version %i; disconnecting %i\n", pfrom->id, nVersion, pindexBestHeader->nHeight); - connman.PushMessage(pfrom, CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::REJECT, strCommand, REJECT_OBSOLETE, - strprintf("Version must be %d or greater", MIN_PEER_PROTO_VERSION))); pfrom->fDisconnect = true; return false; } diff --git a/src/netbase.cpp b/src/netbase.cpp index cf05e7616..d078b800c 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -1,5 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2015 The Bitcoin Core developers +// Copyright (c) 2014-2019 The Dash Core developers +// Copyright (c) 2018-2019 The ZeroOne Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -34,6 +36,7 @@ static proxyType proxyInfo[NET_MAX]; static proxyType nameProxy; static CCriticalSection cs_proxyInfos; int nConnectTimeout = DEFAULT_CONNECT_TIMEOUT; +int nConnectRetCode = 0; bool fNameLookup = DEFAULT_NAME_LOOKUP; // Need ample time for negotiation for very slow proxies such as Tor (milliseconds) @@ -465,7 +468,8 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe } if (nRet != 0) { - LogPrintf("connect() to %s failed after select(): %s\n", addrConnect.ToString(), NetworkErrorString(nRet)); + nConnectRetCode = nRet; // eg. "Connection refused (111)" + LogPrintf("connect() to %s failed after select(): %s\n", addrConnect.ToString(), NetworkErrorString(nRet)); CloseSocket(hSocket); return false; } @@ -476,7 +480,8 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe else #endif { - LogPrintf("connect() to %s failed: %s\n", addrConnect.ToString(), NetworkErrorString(WSAGetLastError())); + nConnectRetCode = WSAGetLastError(); // eg. "Network is unreachable (101)" + LogPrintf("connect() to %s failed: %s\n", addrConnect.ToString(), NetworkErrorString(nConnectRetCode)); CloseSocket(hSocket); return false; } diff --git a/src/netbase.h b/src/netbase.h index 299378d63..ad809cafe 100644 --- a/src/netbase.h +++ b/src/netbase.h @@ -1,4 +1,5 @@ // Copyright (c) 2009-2015 The Bitcoin Core developers +// Copyright (c) 2018-2019 The ZeroOne Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -18,6 +19,7 @@ #include extern int nConnectTimeout; +extern int nConnectRetCode; extern bool fNameLookup; //! -timeout default diff --git a/src/privatesend-client.cpp b/src/privatesend-client.cpp index 1a5df44f3..0e4d1c6f7 100644 --- a/src/privatesend-client.cpp +++ b/src/privatesend-client.cpp @@ -33,8 +33,6 @@ void CPrivateSendClient::ProcessMessage(CNode* pfrom, const std::string& strComm if(pfrom->nVersion < MIN_PRIVATESEND_PEER_PROTO_VERSION) { LogPrint("privatesend", "DSQUEUE -- peer=%d using obsolete version %i\n", pfrom->id, pfrom->nVersion); - connman.PushMessage(pfrom, CNetMsgMaker(pfrom->GetSendVersion()).Make(NetMsgType::REJECT, strCommand, REJECT_OBSOLETE, - strprintf("Version must be %d or greater", MIN_PRIVATESEND_PEER_PROTO_VERSION))); return; } @@ -106,8 +104,6 @@ void CPrivateSendClient::ProcessMessage(CNode* pfrom, const std::string& strComm if(pfrom->nVersion < MIN_PRIVATESEND_PEER_PROTO_VERSION) { LogPrint("privatesend", "DSSTATUSUPDATE -- peer=%d using obsolete version %i\n", pfrom->id, pfrom->nVersion); - connman.PushMessage(pfrom, CNetMsgMaker(pfrom->GetSendVersion()).Make(NetMsgType::REJECT, strCommand, REJECT_OBSOLETE, - strprintf("Version must be %d or greater", MIN_PRIVATESEND_PEER_PROTO_VERSION))); return; } @@ -150,8 +146,6 @@ void CPrivateSendClient::ProcessMessage(CNode* pfrom, const std::string& strComm if(pfrom->nVersion < MIN_PRIVATESEND_PEER_PROTO_VERSION) { LogPrint("privatesend", "DSFINALTX -- peer=%d using obsolete version %i\n", pfrom->id, pfrom->nVersion); - connman.PushMessage(pfrom, CNetMsgMaker(pfrom->GetSendVersion()).Make(NetMsgType::REJECT, strCommand, REJECT_OBSOLETE, - strprintf("Version must be %d or greater", MIN_PRIVATESEND_PEER_PROTO_VERSION))); return; } @@ -179,8 +173,6 @@ void CPrivateSendClient::ProcessMessage(CNode* pfrom, const std::string& strComm if(pfrom->nVersion < MIN_PRIVATESEND_PEER_PROTO_VERSION) { LogPrint("privatesend", "DSCOMPLETE -- peer=%d using obsolete version %i\n", pfrom->id, pfrom->nVersion); - connman.PushMessage(pfrom, CNetMsgMaker(pfrom->GetSendVersion()).Make(NetMsgType::REJECT, strCommand, REJECT_OBSOLETE, - strprintf("Version must be %d or greater", MIN_PRIVATESEND_PEER_PROTO_VERSION))); return; } @@ -881,7 +873,7 @@ bool CPrivateSendClient::JoinExistingQueue(CAmount nBalanceNeedsAnonymized, CCon CAmount nMaxAmount = nBalanceNeedsAnonymized; // nInputCount is not covered by legacy signature, require SPORK_6_NEW_SIGS to activate to use new algo // (to make sure nInputCount wasn't modified by some intermediary node) - bool fNewAlgo = infoMn.nProtocolVersion > 70208 && sporkManager.IsSporkActive(SPORK_6_NEW_SIGS); + bool fNewAlgo = sporkManager.IsSporkActive(SPORK_6_NEW_SIGS); if (fNewAlgo && dsq.nInputCount != 0) { nMinAmount = nMaxAmount = dsq.nInputCount * vecStandardDenoms[vecBits.front()]; @@ -993,7 +985,7 @@ bool CPrivateSendClient::StartNewQueue(CAmount nValueMin, CAmount nBalanceNeedsA // nInputCount is not covered by legacy signature, require SPORK_6_NEW_SIGS to activate to use new algo // (to make sure nInputCount wasn't modified by some intermediary node) - bool fNewAlgo = infoMn.nProtocolVersion > 70208 && sporkManager.IsSporkActive(SPORK_6_NEW_SIGS); + bool fNewAlgo = sporkManager.IsSporkActive(SPORK_6_NEW_SIGS); nSessionInputCount = fNewAlgo ? std::min(vecTxDSInTmp.size(), size_t(5 + GetRand(PRIVATESEND_ENTRY_MAX_SIZE - 5 + 1))) : 0; diff --git a/src/privatesend-server.cpp b/src/privatesend-server.cpp index d08659445..437528f43 100644 --- a/src/privatesend-server.cpp +++ b/src/privatesend-server.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2014-2017 The Dash Core developers +// Copyright (c) 2018-2019 The ZeroOne Core developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "privatesend-server.h" @@ -27,8 +28,6 @@ void CPrivateSendServer::ProcessMessage(CNode* pfrom, const std::string& strComm if(pfrom->nVersion < MIN_PRIVATESEND_PEER_PROTO_VERSION) { LogPrint("privatesend", "DSACCEPT -- peer=%d using obsolete version %i\n", pfrom->id, pfrom->nVersion); - connman.PushMessage(pfrom, CNetMsgMaker(pfrom->GetSendVersion()).Make(NetMsgType::REJECT, strCommand, REJECT_OBSOLETE, - strprintf("Version must be %d or greater", MIN_PRIVATESEND_PEER_PROTO_VERSION))); PushStatus(pfrom, STATUS_REJECTED, ERR_VERSION, connman); return; } @@ -81,8 +80,6 @@ void CPrivateSendServer::ProcessMessage(CNode* pfrom, const std::string& strComm if(pfrom->nVersion < MIN_PRIVATESEND_PEER_PROTO_VERSION) { LogPrint("privatesend", "DSQUEUE -- peer=%d using obsolete version %i\n", pfrom->id, pfrom->nVersion); - connman.PushMessage(pfrom, CNetMsgMaker(pfrom->GetSendVersion()).Make(NetMsgType::REJECT, strCommand, REJECT_OBSOLETE, - strprintf("Version must be %d or greater", MIN_PRIVATESEND_PEER_PROTO_VERSION))); return; } @@ -138,8 +135,6 @@ void CPrivateSendServer::ProcessMessage(CNode* pfrom, const std::string& strComm if(pfrom->nVersion < MIN_PRIVATESEND_PEER_PROTO_VERSION) { LogPrint("privatesend", "DSVIN -- peer=%d using obsolete version %i\n", pfrom->id, pfrom->nVersion); - connman.PushMessage(pfrom, CNetMsgMaker(pfrom->GetSendVersion()).Make(NetMsgType::REJECT, strCommand, REJECT_OBSOLETE, - strprintf("Version must be %d or greater", MIN_PRIVATESEND_PEER_PROTO_VERSION))); PushStatus(pfrom, STATUS_REJECTED, ERR_VERSION, connman); return; } @@ -250,8 +245,6 @@ void CPrivateSendServer::ProcessMessage(CNode* pfrom, const std::string& strComm if(pfrom->nVersion < MIN_PRIVATESEND_PEER_PROTO_VERSION) { LogPrint("privatesend", "DSSIGNFINALTX -- peer=%d using obsolete version %i\n", pfrom->id, pfrom->nVersion); - connman.PushMessage(pfrom, CNetMsgMaker(pfrom->GetSendVersion()).Make(NetMsgType::REJECT, strCommand, REJECT_OBSOLETE, - strprintf("Version must be %d or greater", MIN_PRIVATESEND_PEER_PROTO_VERSION))); return; } diff --git a/src/privatesend.cpp b/src/privatesend.cpp index 1173f8341..6a9ca740c 100644 --- a/src/privatesend.cpp +++ b/src/privatesend.cpp @@ -269,9 +269,7 @@ bool CPrivateSend::IsCollateralValid(const CTransaction& txCollateral) for (const auto& txout : txCollateral.vout) { nValueOut += txout.nValue; - - bool fAllowData = mnpayments.GetMinMasternodePaymentsProto() > 70208; - if(!txout.scriptPubKey.IsPayToPublicKeyHash() && !(fAllowData && txout.scriptPubKey.IsUnspendable())) { + if(!txout.scriptPubKey.IsPayToPublicKeyHash() && !(txout.scriptPubKey.IsUnspendable())) { LogPrintf ("CPrivateSend::IsCollateralValid -- Invalid Script, txCollateral=%s", txCollateral.ToString()); return false; } @@ -308,13 +306,8 @@ bool CPrivateSend::IsCollateralValid(const CTransaction& txCollateral) bool CPrivateSend::IsCollateralAmount(CAmount nInputAmount) { - if (mnpayments.GetMinMasternodePaymentsProto() > 70208) { - // collateral input can be anything between 1x and "max" (including both) - return (nInputAmount >= GetCollateralAmount() && nInputAmount <= GetMaxCollateralAmount()); - } else { // <= 70208 - // collateral input can be anything between 2x and "max" (including both) - return (nInputAmount >= GetCollateralAmount() * 2 && nInputAmount <= GetMaxCollateralAmount()); - } + // collateral input can be anything between 1x and "max" (including both) + return (nInputAmount >= GetCollateralAmount() && nInputAmount <= GetMaxCollateralAmount()); } /* Create a nice string to show the denominations @@ -554,10 +547,14 @@ void ThreadCheckPrivateSend(CConnman& connman) mnodeman.CheckAndRemove(connman); mnodeman.WarnMasternodeDaemonUpdates(); mnpayments.CheckAndRemove(); - instantsend.CheckAndRemove(); + instantsend.CheckAndRemove(); } + if(fMasternodeMode && (nTick % (60 * 5) == 0)) { + mnodeman.CheckSameAddr(); mnodeman.DoFullVerificationStep(connman); + mnpayments.CheckMissingVotes(); + mnodeman.CheckMissingMasternodes(); } if(nTick % (60 * 5) == 0) { diff --git a/src/privatesend.h b/src/privatesend.h index 04f4eae94..ba7b5cd27 100644 --- a/src/privatesend.h +++ b/src/privatesend.h @@ -120,12 +120,7 @@ class CDarksendAccept template inline void SerializationOp(Stream& s, Operation ser_action) { READWRITE(nDenom); - int nVersion = s.GetVersion(); - if (nVersion > 70208) { - READWRITE(nInputCount); - } else if (ser_action.ForRead()) { - nInputCount = 0; - } + READWRITE(nInputCount); READWRITE(txCollateral); } @@ -212,26 +207,8 @@ class CDarksendQueue template inline void SerializationOp(Stream& s, Operation ser_action) { READWRITE(nDenom); - int nVersion = s.GetVersion(); - if (nVersion > 70208) { - READWRITE(nInputCount); - } else if (ser_action.ForRead()) { - nInputCount = 0; - } - if (nVersion == 70208 && (s.GetType() & SER_NETWORK)) { - // converting from/to old format - CTxIn txin{}; - if (ser_action.ForRead()) { - READWRITE(txin); - masternodeOutpoint = txin.prevout; - } else { - txin = CTxIn(masternodeOutpoint); - READWRITE(txin); - } - } else { - // using new format directly - READWRITE(masternodeOutpoint); - } + READWRITE(nInputCount); + READWRITE(masternodeOutpoint); READWRITE(nTime); READWRITE(fReady); if (!(s.GetType() & SER_GETHASH)) { @@ -304,21 +281,7 @@ class CDarksendBroadcastTx template inline void SerializationOp(Stream& s, Operation ser_action) { READWRITE(tx); - int nVersion = s.GetVersion(); - if (nVersion == 70208 && (s.GetType() & SER_NETWORK)) { - // converting from/to old format - CTxIn txin{}; - if (ser_action.ForRead()) { - READWRITE(txin); - masternodeOutpoint = txin.prevout; - } else { - txin = CTxIn(masternodeOutpoint); - READWRITE(txin); - } - } else { - // using new format directly - READWRITE(masternodeOutpoint); - } + READWRITE(masternodeOutpoint); if (!(s.GetType() & SER_GETHASH)) { READWRITE(vchSig); } diff --git a/src/spork.cpp b/src/spork.cpp index 485e17b7d..b5d704874 100644 --- a/src/spork.cpp +++ b/src/spork.cpp @@ -23,7 +23,7 @@ std::map mapSporkDefaults = { {SPORK_4_MNSIG_REQ, 6}, // ON - MNPAYMENTS_SIGNATURES_REQUIRED (tunable) {SPORK_5_INSTANTSEND_MAX_VALUE, 100001}, // ON - InstaSend up to 100000 ZOC {SPORK_6_NEW_SIGS, 4070908800ULL}, // OFF - {SPORK_7_UNMATURE_SINGLECB_ZEROTXBLK, 4070908800ULL}, // OFF + {SPORK_7_UNMATURE_SINGLECB_ZEROTXBLK, 1567277734ULL}, // ON - GMT: Saturday, 31 Aug 2019 18:55:34 {SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT, 0}, // ON {SPORK_9_SUPERBLOCKS_ENABLED, 4070908800ULL}, // OFF {SPORK_10_MASTERNODE_PAY_UPDATED_NODES, 1563623999ULL}, // ON - GMT: Saturday, 20 July 2019 11:59:59 diff --git a/src/version.h b/src/version.h index 6e208b154..b4cef1fcc 100644 --- a/src/version.h +++ b/src/version.h @@ -20,7 +20,7 @@ static const int INIT_PROTO_VERSION = 209; static const int GETHEADERS_VERSION = 70077; //! disconnect from peers older than this proto version -static const int MIN_PEER_PROTO_VERSION = 70210; +static const int MIN_PEER_PROTO_VERSION = 70211; //! nTime field added to CAddress, starting with this version; //! if possible, avoid requesting addresses nodes older than this