From 21e05e0495e4ca9b63d9c19f4240d5a30d564aae Mon Sep 17 00:00:00 2001 From: amancera <1596328+alejandromgk@users.noreply.github.com> Date: Wed, 16 Jan 2019 17:09:44 -0600 Subject: [PATCH 1/6] Delayed block penalization --- qa/pull-tester/rpc-tests.py | 1 + qa/rpc-tests/blockdelay.py | 185 ++++++++++++++++++ qa/rpc-tests/test_framework/authproxy.py | 2 +- qa/rpc-tests/test_framework/test_framework.py | 6 +- qa/rpc-tests/test_framework/util.py | 6 +- src/Makefile.am | 2 + src/chain.h | 3 + src/validation.cpp | 25 ++- src/zen/delay.cpp | 41 ++++ src/zen/delay.h | 13 ++ 10 files changed, 276 insertions(+), 8 deletions(-) create mode 100755 qa/rpc-tests/blockdelay.py create mode 100644 src/zen/delay.cpp create mode 100644 src/zen/delay.h diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index b4dfb66d467d..85e1509b925b 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -128,6 +128,7 @@ 'invalidtxrequest.py', # NOTE: needs paccoin_hash to pass 'abandonconflict.py', 'p2p-versionbits-warning.py', + 'blockdelay.py', ] if ENABLE_ZMQ: testScripts.append('zmq_test.py') diff --git a/qa/rpc-tests/blockdelay.py b/qa/rpc-tests/blockdelay.py new file mode 100755 index 000000000000..1766d0052084 --- /dev/null +++ b/qa/rpc-tests/blockdelay.py @@ -0,0 +1,185 @@ +#!/usr/bin/env python2 +# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2018 The Zencash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +from test_framework.test_framework import BitcoinTestFramework +from test_framework.authproxy import JSONRPCException +from test_framework.util import assert_equal, initialize_chain_clean, \ + start_nodes, start_node, connect_nodes, stop_node, stop_nodes, \ + sync_blocks, sync_mempools, connect_nodes_bi, wait_bitcoinds, p2p_port, check_json_precision +import traceback +import os,sys +import shutil +from random import randint +from decimal import Decimal +import logging + +import time +class blockdelay(BitcoinTestFramework): + + alert_filename = None + + def setup_chain(self, split=False): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 4) + self.alert_filename = os.path.join(self.options.tmpdir, "alert.txt") + with open(self.alert_filename, 'w'): + pass # Just open then close to create zero-length file + + def setup_network(self, split=False): + self.nodes = [] + + # -exportdir option means we must provide a valid path to the destination folder for wallet backups + ed0 = "-exportdir=" + self.options.tmpdir + "/node0" + ed1 = "-exportdir=" + self.options.tmpdir + "/node1" + ed2 = "-exportdir=" + self.options.tmpdir + "/node2" + ed3 = "-exportdir=" + self.options.tmpdir + "/node3" + ''' + extra_args = [["-debug","-keypool=100", "-alertnotify=echo %s >> \"" + self.alert_filename + "\"", ed0], + ["-debug", "-keypool=100", "-alertnotify=echo %s >> \"" + self.alert_filename + "\"", ed1], + ["-debug", "-keypool=100", "-alertnotify=echo %s >> \"" + self.alert_filename + "\"", ed2], + ["-debug", "-keypool=100", "-alertnotify=echo %s >> \"" + self.alert_filename + "\"", ed3]] + ''' + + #self.nodes = start_nodes(4, self.options.tmpdir, extra_args) + self.nodes = start_nodes(4, self.options.tmpdir) + + + if not split: + connect_nodes_bi(self.nodes, 1, 2) + sync_blocks(self.nodes[1:3]) + sync_mempools(self.nodes[1:3]) + + connect_nodes_bi(self.nodes, 0, 1) + connect_nodes_bi(self.nodes, 2, 3) + self.is_network_split = split + self.sync_all() + + def disconnect_nodes(self, from_connection, node_num): + ip_port = "127.0.0.1:"+str(p2p_port(node_num)) + from_connection.disconnectnode(ip_port) + # poll until version handshake complete to avoid race conditions + # with transaction relaying + while any(peer['version'] == 0 for peer in from_connection.getpeerinfo()): + time.sleep(0.1) + + def split_network(self): + # Split the network of four nodes into nodes 0/1 and 2/3. + assert not self.is_network_split + self.disconnect_nodes(self.nodes[1], 2) + self.disconnect_nodes(self.nodes[2], 1) + self.is_network_split = True + + + def join_network(self): + #Join the (previously split) network halves together. + assert self.is_network_split + connect_nodes_bi(self.nodes, 0, 3) + connect_nodes_bi(self.nodes, 3, 0) + connect_nodes_bi(self.nodes, 1, 3) + connect_nodes_bi(self.nodes, 3, 1) + #sync_blocks(self.nodes[0:3],1,True) + #sync_mempools(self.nodes[1:3]) + self.sync_all() + self.is_network_split = False + + + def run_test(self): + blocks = [] + + blocks.append(self.nodes[0].getblockhash(0)) + print("\n\nGenesis block is: " + blocks[0]) + # raw_input("press enter to start..") + + + print("\n\nGenerating initial blockchain 4 blocks") + blocks.extend(self.nodes[1].generate(1)) # block height 1 + print(blocks) + print("\n start sync_all #1") + self.sync_all() + print("\n end sync_all #1") + blocks.extend(self.nodes[0].generate(1)) # block height 2 + self.sync_all() + blocks.extend(self.nodes[2].generate(1)) # block height 3 + self.sync_all() + blocks.extend(self.nodes[3].generate(1)) # block height 4 + self.sync_all() + print("Blocks generated") + + print("\n\nSplit network") + self.split_network() + print("The network is split") + + + # Main chain + print("\n\nGenerating 2 parallel chains with different length") + + print("\nGenerating 12 honest blocks") + blocks.extend(self.nodes[0].generate(6)) # block height 5 -6 -7 -8 - 9 - 10 + print("\n start sync_all #1") + self.sync_all() + print("\n end sync_all #1") + blocks.extend(self.nodes[1].generate(6)) # block height 11-12-13-14-15-16 + last_main_blockhash=blocks[len(blocks)-1] + self.sync_all() + print("Honest block generated") + + assert self.nodes[0].getbestblockhash() == last_main_blockhash + + # Malicious nodes mining privately faster + print("\nGenerating 13 malicious blocks") + self.nodes[2].generate(10) # block height 5 - 6 -7 -8 -9-10 -11 12 13 14 + self.sync_all() + self.nodes[3].generate(3) # block height 15 - 16 - 17 + self.sync_all() + print("Malicious block generated") + + + print("\n\nJoin network") + # raw_input("press enter to join the netorks..") + self.join_network() + time.sleep(2) + print("\nNetwork joined") + + print("\nTesting if the current chain is still the honest chain") + assert self.nodes[0].getbestblockhash() == last_main_blockhash + print("Confirmed: malicious chain is under penalty") + + + print("\nGenerating 64 malicious blocks") + self.nodes[3].generate(64) + print("Malicious block generated") + + time.sleep(10) + + print("\nTesting if the current chain is still the honest chain") + assert self.nodes[0].getbestblockhash() == last_main_blockhash + print("Confirmed: malicious chain is under penalty") + + print("\nGenerating 65 more honest blocks") + self.nodes[0].generate(65) + print("Honest block generated") + + print("\nGenerating 1 more malicious block") + last_malicious_blockhash=self.nodes[3].generate(1)[0] + print("Malicious block generated") + + print("\nWaiting that all network nodes are synced with same chain length") + sync_blocks(self.nodes, 1, True) + print("Network nodes are synced") + + print("\nTesting if all the nodes/chains have the same best tip") + assert (self.nodes[0].getbestblockhash() == self.nodes[1].getbestblockhash() + == self.nodes[2].getbestblockhash() == self.nodes[3].getbestblockhash()) + print("Confirmed: all the nodes have the same best tip") + + print("\nTesting if the current chain switched to the malicious chain") + assert self.nodes[0].getbestblockhash() == last_malicious_blockhash + print("Confirmed: malicious chain is the best chain") + + time.sleep(2) + sync_mempools(self.nodes) + +if __name__ == '__main__': + blockdelay().main() diff --git a/qa/rpc-tests/test_framework/authproxy.py b/qa/rpc-tests/test_framework/authproxy.py index 3bc84bc5c1f1..a7bd563d52f9 100644 --- a/qa/rpc-tests/test_framework/authproxy.py +++ b/qa/rpc-tests/test_framework/authproxy.py @@ -49,7 +49,7 @@ USER_AGENT = "AuthServiceProxy/0.1" -HTTP_TIMEOUT = 30 +HTTP_TIMEOUT = 600 log = logging.getLogger("BitcoinRPC") diff --git a/qa/rpc-tests/test_framework/test_framework.py b/qa/rpc-tests/test_framework/test_framework.py index e7f6b18add28..baba25190478 100755 --- a/qa/rpc-tests/test_framework/test_framework.py +++ b/qa/rpc-tests/test_framework/test_framework.py @@ -77,12 +77,12 @@ def split_network(self): def sync_all(self): if self.is_network_split: - sync_blocks(self.nodes[:2]) - sync_blocks(self.nodes[2:]) + sync_blocks(self.nodes[:2], p=False) + sync_blocks(self.nodes[2:], p=False) sync_mempools(self.nodes[:2]) sync_mempools(self.nodes[2:]) else: - sync_blocks(self.nodes) + sync_blocks(self.nodes, p=False) sync_mempools(self.nodes) def join_network(self): diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 49554f867094..094abb923d74 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -114,12 +114,14 @@ def hex_str_to_bytes(hex_str): def str_to_b64str(string): return b64encode(string.encode('utf-8')).decode('ascii') -def sync_blocks(rpc_connections, wait=1): +def sync_blocks(rpc_connections, wait=1, p=False): """ Wait until everybody has the same block count """ while True: counts = [ x.getblockcount() for x in rpc_connections ] + if p: + print counts if counts == [ counts[0] ]*len(counts): break time.sleep(wait) @@ -294,7 +296,7 @@ def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary= url = rpc_url(i, rpchost) wait_for_bitcoind_start(bitcoind_processes[i], url, i) if os.getenv("PYTHON_DEBUG", ""): - print "start_node: RPC succesfully started" + print "start_node: RPC succesfully started at: " + url proxy = get_rpc_proxy(url, i, timeout=timewait) if COVERAGE_DIR: diff --git a/src/Makefile.am b/src/Makefile.am index 88c2990f4f2a..46d554bc0223 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -195,6 +195,7 @@ BITCOIN_CORE_H = \ wallet/wallet.h \ wallet/wallet_ismine.h \ wallet/walletdb.h \ + zen/delay.h \ zmq/zmqabstractnotifier.h \ zmq/zmqconfig.h\ zmq/zmqnotificationinterface.h \ @@ -266,6 +267,7 @@ libbitcoin_server_a_SOURCES = \ validation.cpp \ validationinterface.cpp \ versionbits.cpp \ + zen/delay.cpp \ $(BITCOIN_CORE_H) if ENABLE_ZMQ diff --git a/src/chain.h b/src/chain.h index 5438d8f3d304..bf570836f060 100644 --- a/src/chain.h +++ b/src/chain.h @@ -178,6 +178,8 @@ class CBlockIndex //! (memory only) Total amount of work (expected number of hashes) in the chain up to and including this block arith_uint256 nChainWork; + int64_t nChainDelay; + //! Number of transactions in this block. //! Note: in a potential headers-first mode, this number cannot be relied upon unsigned int nTx; @@ -210,6 +212,7 @@ class CBlockIndex nDataPos = 0; nUndoPos = 0; nChainWork = arith_uint256(); + nChainDelay = 0; nTx = 0; nChainTx = 0; nStatus = 0; diff --git a/src/validation.cpp b/src/validation.cpp index 00c7b243a4e9..57209219a1c2 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -49,6 +49,9 @@ #include #include +//PAC_MOD +#include "zen/delay.h" + using namespace std; #if defined(NDEBUG) @@ -114,7 +117,11 @@ namespace { struct CBlockIndexWorkComparator { bool operator()(CBlockIndex *pa, CBlockIndex *pb) const { - // First sort by most total work, ... + // First sort by total delay in chain. + if (pa->nChainDelay < pb->nChainDelay) return false; + if (pa->nChainDelay > pb->nChainDelay) return true; + + // ... then sort by most total work, ... if (pa->nChainWork > pb->nChainWork) return false; if (pa->nChainWork < pb->nChainWork) return true; @@ -2971,8 +2978,16 @@ CBlockIndex* AddToBlockIndex(const CBlockHeader& block) pindexNew->BuildSkip(); } pindexNew->nChainWork = (pindexNew->pprev ? pindexNew->pprev->nChainWork : 0) + GetBlockProof(*pindexNew); + if (pindexNew->pprev){ + pindexNew->nChainDelay = pindexNew->pprev->nChainDelay + GetBlockDelay(*pindexNew,*(pindexNew->pprev), chainActive.Height(), IsInitialBlockDownload()); + } else { + pindexNew->nChainDelay = 0 ; + } + if(pindexNew->nChainDelay != 0) { + LogPrintf("%s: Block belong to a chain under punishment Delay VAL: %i BLOCKHEIGHT: %d\n",__func__, pindexNew->nChainDelay,pindexNew->nHeight); + } pindexNew->RaiseValidity(BLOCK_VALID_TREE); - if (pindexBestHeader == NULL || pindexBestHeader->nChainWork < pindexNew->nChainWork) + if (pindexBestHeader == NULL || (pindexBestHeader->nChainWork < pindexNew->nChainWork && pindexNew->nChainDelay==0)) pindexBestHeader = pindexNew; setDirtyBlockIndex.insert(pindexNew); @@ -3740,6 +3755,12 @@ bool static LoadBlockIndexDB() { CBlockIndex* pindex = item.second; pindex->nChainWork = (pindex->pprev ? pindex->pprev->nChainWork : 0) + GetBlockProof(*pindex); + if (pindex->pprev){ + pindex->nChainDelay = pindex->pprev->nChainDelay + + GetBlockDelay(*pindex,*(pindex->pprev), chainActive.Height(), IsInitialBlockDownload()); + } else { + pindex->nChainDelay = 0 ; + } // We can link the chain of blocks for which we've received transactions at some point. // Pruned nodes may have deleted the block. if (pindex->nTx > 0) { diff --git a/src/zen/delay.cpp b/src/zen/delay.cpp new file mode 100644 index 000000000000..91a331989664 --- /dev/null +++ b/src/zen/delay.cpp @@ -0,0 +1,41 @@ +#include "zen/delay.h" + +int64_t GetBlockDelay(const CBlockIndex& newBlock, const CBlockIndex& prevBlock, const int activeChainHeight, const bool isStartupSyncing) +{ + const int PENALTY_THRESHOLD = 5; + + if(isStartupSyncing) { + return 0; + } + + if(newBlock.nHeight < activeChainHeight ) { + LogPrintf("Received a delayed block (activeChainHeight: %d, newBlockHeight: %d)!\n", activeChainHeight, newBlock.nHeight); + } + + // if the current chain is penalised. + if (prevBlock.nChainDelay > 0) { + // Positive values to increase the penalty until + // we reach the current active height. + if (activeChainHeight >= newBlock.nHeight ) { + return (activeChainHeight - newBlock.nHeight); + } else { + LogPrintf("Decreasing penalty to chain (activeChainHeight: %d, newBlockHeight: %d, prevBlockChainDelay: %d)!\n", activeChainHeight, newBlock.nHeight, prevBlock.nChainDelay); + // -1 to decrease the penalty afterwards. + return -1; + } + // no penalty yet, or penalty already resolved. + } else { + // Introduce penalty in case we receive a historic block. + // (uses a threshold value) + if (activeChainHeight - newBlock.nHeight > PENALTY_THRESHOLD ){ + return (activeChainHeight - newBlock.nHeight); + // no delay detected. + } else { + return 0; + } + } +} +bool IsChainPenalised(const CChain& chain) +{ + return (chain.Tip()->nChainDelay < 0); +} diff --git a/src/zen/delay.h b/src/zen/delay.h new file mode 100644 index 000000000000..5efb9a7c38d7 --- /dev/null +++ b/src/zen/delay.h @@ -0,0 +1,13 @@ +#include "pow.h" +#include "arith_uint256.h" +#include "primitives/block.h" +#include "streams.h" +#include "uint256.h" +#include "util.h" +#include "chain.h" +#include "chainparams.h" +#include "tinyformat.h" +#include + +int64_t GetBlockDelay (const CBlockIndex& newBlock,const CBlockIndex& prevBlock, const int activeChainHeight, bool isStartupSyncing); +bool IsChainPenalised (const CChain& chain); From 5de94880edd03249d360cc56a367b935b15d9c95 Mon Sep 17 00:00:00 2001 From: amancera <1596328+alejandromgk@users.noreply.github.com> Date: Tue, 22 Jan 2019 20:41:09 -0600 Subject: [PATCH 2/6] reset regtest --- qa/rpc-tests/blockdelay.py | 4 ++-- src/chainparams.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/qa/rpc-tests/blockdelay.py b/qa/rpc-tests/blockdelay.py index 1766d0052084..62c8abad324f 100755 --- a/qa/rpc-tests/blockdelay.py +++ b/qa/rpc-tests/blockdelay.py @@ -94,12 +94,12 @@ def run_test(self): print("\n\nGenerating initial blockchain 4 blocks") - blocks.extend(self.nodes[1].generate(1)) # block height 1 + blocks.extend(self.nodes[0].generate(1)) # block height 1 print(blocks) print("\n start sync_all #1") self.sync_all() print("\n end sync_all #1") - blocks.extend(self.nodes[0].generate(1)) # block height 2 + blocks.extend(self.nodes[1].generate(1)) # block height 2 self.sync_all() blocks.extend(self.nodes[2].generate(1)) # block height 3 self.sync_all() diff --git a/src/chainparams.cpp b/src/chainparams.cpp index f193cbe39547..1b52570111c2 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -30,9 +30,9 @@ #define TESTNET_GENESIS_NONCE 2279587UL #define TESTNET_GENESIS_TIMESTAMP 1517541975UL -#define REGTEST_GENESIS_HASH "0x084c58211fe102add2fb5c3976f14f997e3c27a3a6fd5ab15a1929f7b5db9d95" -#define REGTEST_GENESIS_NONCE 1UL -#define REGTEST_GENESIS_TIMESTAMP 1517542062UL +#define REGTEST_GENESIS_HASH "0x03ddaf131760ea9614a00fd504b035061b6ad367dc91be7a8821bd787484cba0" +#define REGTEST_GENESIS_NONCE 2UL +#define REGTEST_GENESIS_TIMESTAMP 1548210160UL static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward, const Consensus::Params& consensus) { From 33b9dca7baa7bca131039dd715064b67587b0798 Mon Sep 17 00:00:00 2001 From: amancera <1596328+alejandromgk@users.noreply.github.com> Date: Tue, 22 Jan 2019 20:42:09 -0600 Subject: [PATCH 3/6] Change proto --- src/version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.h b/src/version.h index 12348c1d3222..58a70f6598e2 100644 --- a/src/version.h +++ b/src/version.h @@ -10,7 +10,7 @@ * network protocol versioning */ -static const int PROTOCOL_VERSION = 70214; +static const int PROTOCOL_VERSION = 70215; //! initial proto version, to be increased after version/verack negotiation static const int INIT_PROTO_VERSION = 209; @@ -19,7 +19,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 = 70214; +static const int MIN_PEER_PROTO_VERSION = 70215; //! nTime field added to CAddress, starting with this version; //! if possible, avoid requesting addresses nodes older than this From 2af7d60e4ea14b017b60c4584fdfc283bd7f1ddf Mon Sep 17 00:00:00 2001 From: amancera <1596328+alejandromgk@users.noreply.github.com> Date: Mon, 28 Jan 2019 20:30:50 -0600 Subject: [PATCH 4/6] - Update blockdelay RPC test. - Fix min chain work on regtest chain params. - Add chain penalization field to getchaintips method. --- qa/rpc-tests/blockdelay.py | 52 +++++++++++++------------------------- src/chainparams.cpp | 6 ++--- src/rpc/blockchain.cpp | 4 ++- 3 files changed, 24 insertions(+), 38 deletions(-) diff --git a/qa/rpc-tests/blockdelay.py b/qa/rpc-tests/blockdelay.py index 62c8abad324f..6dc6436b8a52 100755 --- a/qa/rpc-tests/blockdelay.py +++ b/qa/rpc-tests/blockdelay.py @@ -29,23 +29,8 @@ def setup_chain(self, split=False): def setup_network(self, split=False): self.nodes = [] - - # -exportdir option means we must provide a valid path to the destination folder for wallet backups - ed0 = "-exportdir=" + self.options.tmpdir + "/node0" - ed1 = "-exportdir=" + self.options.tmpdir + "/node1" - ed2 = "-exportdir=" + self.options.tmpdir + "/node2" - ed3 = "-exportdir=" + self.options.tmpdir + "/node3" - ''' - extra_args = [["-debug","-keypool=100", "-alertnotify=echo %s >> \"" + self.alert_filename + "\"", ed0], - ["-debug", "-keypool=100", "-alertnotify=echo %s >> \"" + self.alert_filename + "\"", ed1], - ["-debug", "-keypool=100", "-alertnotify=echo %s >> \"" + self.alert_filename + "\"", ed2], - ["-debug", "-keypool=100", "-alertnotify=echo %s >> \"" + self.alert_filename + "\"", ed3]] - ''' - - #self.nodes = start_nodes(4, self.options.tmpdir, extra_args) self.nodes = start_nodes(4, self.options.tmpdir) - if not split: connect_nodes_bi(self.nodes, 1, 2) sync_blocks(self.nodes[1:3]) @@ -91,21 +76,18 @@ def run_test(self): blocks.append(self.nodes[0].getblockhash(0)) print("\n\nGenesis block is: " + blocks[0]) # raw_input("press enter to start..") - - - print("\n\nGenerating initial blockchain 4 blocks") + + print("\n\nGenerating initial blockchain of 4 blocks") blocks.extend(self.nodes[0].generate(1)) # block height 1 - print(blocks) - print("\n start sync_all #1") self.sync_all() - print("\n end sync_all #1") blocks.extend(self.nodes[1].generate(1)) # block height 2 self.sync_all() blocks.extend(self.nodes[2].generate(1)) # block height 3 self.sync_all() blocks.extend(self.nodes[3].generate(1)) # block height 4 self.sync_all() - print("Blocks generated") + print("Four blocks generated.") + print("\n\nSplit network") self.split_network() @@ -115,25 +97,23 @@ def run_test(self): # Main chain print("\n\nGenerating 2 parallel chains with different length") - print("\nGenerating 12 honest blocks") + print("\nGenerating 12 honest blocks (blocks 5-16)") blocks.extend(self.nodes[0].generate(6)) # block height 5 -6 -7 -8 - 9 - 10 - print("\n start sync_all #1") self.sync_all() - print("\n end sync_all #1") blocks.extend(self.nodes[1].generate(6)) # block height 11-12-13-14-15-16 last_main_blockhash=blocks[len(blocks)-1] self.sync_all() - print("Honest block generated") + print("Honest blocks generated.") assert self.nodes[0].getbestblockhash() == last_main_blockhash # Malicious nodes mining privately faster - print("\nGenerating 13 malicious blocks") + print("\nGenerating 13 malicious blocks (blocks 5-17)") self.nodes[2].generate(10) # block height 5 - 6 -7 -8 -9-10 -11 12 13 14 self.sync_all() self.nodes[3].generate(3) # block height 15 - 16 - 17 self.sync_all() - print("Malicious block generated") + print("Malicious blocks generated.") print("\n\nJoin network") @@ -146,10 +126,14 @@ def run_test(self): assert self.nodes[0].getbestblockhash() == last_main_blockhash print("Confirmed: malicious chain is under penalty") + print("\nTesting chaintips") + current_chain_tips = self.nodes[0].getchaintips() + assert (current_chain_tips[0]['penalization'] == 65) + print("Malicious chain is correctly penalized with 65 blocks after generating 12 old blocks + 1 new block.") - print("\nGenerating 64 malicious blocks") + print("\nGenerating 64 malicious blocks (New height = 81)") self.nodes[3].generate(64) - print("Malicious block generated") + print("Malicious blocks generated") time.sleep(10) @@ -157,13 +141,13 @@ def run_test(self): assert self.nodes[0].getbestblockhash() == last_main_blockhash print("Confirmed: malicious chain is under penalty") - print("\nGenerating 65 more honest blocks") + print("\nGenerating 65 more honest blocks (New height = 81)") self.nodes[0].generate(65) - print("Honest block generated") + print("Honest blocks generated") - print("\nGenerating 1 more malicious block") + print("\nGenerating 1 more malicious block (New height = 82)") last_malicious_blockhash=self.nodes[3].generate(1)[0] - print("Malicious block generated") + print("Malicious blocks generated") print("\nWaiting that all network nodes are synced with same chain length") sync_blocks(self.nodes, 1, True) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 1b52570111c2..3feccda9b859 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -402,10 +402,10 @@ class CRegTestParams : public CChainParams { consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nTimeout = 999999999999ULL; // The best chain should have at least this much work. - consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000000000000000000000100010"); + consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000000000000000000000000002"); // By default assume that the signatures in ancestors of this block are valid. - consensus.defaultAssumeValid = uint256S("0x084c58211fe102add2fb5c3976f14f997e3c27a3a6fd5ab15a1929f7b5db9d95"); + consensus.defaultAssumeValid = uint256S("0x03ddaf131760ea9614a00fd504b035061b6ad367dc91be7a8821bd787484cba0"); pchMessageStart[0] = 0x96; pchMessageStart[1] = 0xa6; @@ -434,7 +434,7 @@ class CRegTestParams : public CChainParams { checkpointData = (CCheckpointData){ boost::assign::map_list_of - ( 0, uint256S("0x084c58211fe102add2fb5c3976f14f997e3c27a3a6fd5ab15a1929f7b5db9d95")), + ( 0, uint256S("0x03ddaf131760ea9614a00fd504b035061b6ad367dc91be7a8821bd787484cba0")), 0, 0, 0 diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 929cb2b541e3..022845ff26ac 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -924,6 +924,7 @@ UniValue getchaintips(const UniValue& params, bool fHelp) " \"chainwork\" : \"0000...1f3\" (string) Expected number of hashes required to produce the current chain (in hex)\n" " \"branchlen\": 0 (numeric) zero for main chain\n" " \"status\": \"active\" (string) \"active\" for the main chain\n" + " \"penalization\": 0 (numeric) zero for main chain\n" " },\n" " {\n" " \"height\": xxxx,\n" @@ -932,6 +933,7 @@ UniValue getchaintips(const UniValue& params, bool fHelp) " \"chainwork\" : \"0000...1f3\"\n" " \"branchlen\": 1 (numeric) length of branch connecting the tip to the main chain\n" " \"status\": \"xxxx\" (string) status of the chain (active, valid-fork, valid-headers, headers-only, invalid)\n" + " \"penalization\": 0 (numeric) penalization of the chain, zero for the main chain.\n" " }\n" "]\n" "Possible values for status:\n" @@ -1009,7 +1011,7 @@ UniValue getchaintips(const UniValue& params, bool fHelp) status = "unknown"; } obj.push_back(Pair("status", status)); - + obj.push_back(Pair("penalization", block->nChainDelay)); res.push_back(obj); } From 7f4ec853644d4324fddc21b079cbc3c0a533272f Mon Sep 17 00:00:00 2001 From: amancera <1596328+alejandromgk@users.noreply.github.com> Date: Wed, 6 Feb 2019 12:57:24 -0600 Subject: [PATCH 5/6] fix log formating --- src/validation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/validation.cpp b/src/validation.cpp index 57209219a1c2..0c8251d3be8a 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2984,7 +2984,7 @@ CBlockIndex* AddToBlockIndex(const CBlockHeader& block) pindexNew->nChainDelay = 0 ; } if(pindexNew->nChainDelay != 0) { - LogPrintf("%s: Block belong to a chain under punishment Delay VAL: %i BLOCKHEIGHT: %d\n",__func__, pindexNew->nChainDelay,pindexNew->nHeight); + LogPrintf("%s: Block belong to a chain under punishment - Delay value: %i, BlockHeight: %d\n",__func__, pindexNew->nChainDelay,pindexNew->nHeight); } pindexNew->RaiseValidity(BLOCK_VALID_TREE); if (pindexBestHeader == NULL || (pindexBestHeader->nChainWork < pindexNew->nChainWork && pindexNew->nChainDelay==0)) From e7ecee6dd4de1c4553c5aa0649786300f67fc508 Mon Sep 17 00:00:00 2001 From: amancera <1596328+alejandromgk@users.noreply.github.com> Date: Mon, 11 Feb 2019 16:26:36 -0600 Subject: [PATCH 6/6] Change proto and version --- configure.ac | 6 +++--- src/clientversion.h | 6 +++--- src/version.h | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/configure.ac b/configure.ac index f7ffef70eb61..e5c136200c3d 100644 --- a/configure.ac +++ b/configure.ac @@ -2,10 +2,10 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 0) define(_CLIENT_VERSION_MINOR, 12) -define(_CLIENT_VERSION_REVISION, 5) -define(_CLIENT_VERSION_BUILD, 1) +define(_CLIENT_VERSION_REVISION, 6) +define(_CLIENT_VERSION_BUILD, 0) define(_CLIENT_VERSION_IS_RELEASE, true) -define(_COPYRIGHT_YEAR, 2018) +define(_COPYRIGHT_YEAR, 2019) AC_INIT([Paccoin Core],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[https://github.com/PACCommunity/PAC/issues],[paccoincore]) AC_CONFIG_SRCDIR([src/validation.cpp]) AC_CONFIG_HEADERS([src/config/paccoin-config.h]) diff --git a/src/clientversion.h b/src/clientversion.h index 0a47f76836c8..8fdbb850085f 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -16,8 +16,8 @@ //! These need to be macros, as clientversion.cpp's and paccoin*-res.rc's voodoo requires it #define CLIENT_VERSION_MAJOR 0 #define CLIENT_VERSION_MINOR 12 -#define CLIENT_VERSION_REVISION 5 -#define CLIENT_VERSION_BUILD 1 +#define CLIENT_VERSION_REVISION 6 +#define CLIENT_VERSION_BUILD 0 //! Set to true for release, false for prerelease or test build #define CLIENT_VERSION_IS_RELEASE true @@ -26,7 +26,7 @@ * Copyright year (2009-this) * Todo: update this when changing our copyright comments in the source */ -#define COPYRIGHT_YEAR 2018 +#define COPYRIGHT_YEAR 2019 #endif //HAVE_CONFIG_H diff --git a/src/version.h b/src/version.h index 58a70f6598e2..67f461e082db 100644 --- a/src/version.h +++ b/src/version.h @@ -19,7 +19,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 = 70215; +static const int MIN_PEER_PROTO_VERSION = 70214; //! nTime field added to CAddress, starting with this version; //! if possible, avoid requesting addresses nodes older than this