Skip to content

Commit

Permalink
Merge pull request #38 from proletesseract/master
Browse files Browse the repository at this point in the history
Merging master into 4.7.0 RC
  • Loading branch information
proletesseract committed Aug 23, 2019
2 parents 25e9863 + cf37230 commit 505fe04
Show file tree
Hide file tree
Showing 38 changed files with 224 additions and 56 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -140,4 +140,9 @@ ui_*.h
*.cxxflags
*.creator.*

craig-core.files
craig-core.includes
navcoin-core.code-workspace
craig-core.config
craig-core.creator
navcoin-core\.code-workspace
2 changes: 1 addition & 1 deletion .travis/test_06_script_b.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ fi

if [ "$RUN_FUNCTIONAL_TESTS" = "true" ]; then
BEGIN_FOLD functional-tests
DOCKER_EXEC LOCAL_NTP=1 ./qa/pull-tester/rpc-tests.py -parallel=1 --coverage
DOCKER_EXEC LOCAL_NTP=1 ./qa/pull-tester/rpc-tests.py -parallel=3 --coverage --failfast
END_FOLD
fi
16 changes: 13 additions & 3 deletions qa/pull-tester/rpc-tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@
if 'ENABLE_ZMQ' not in vars():
ENABLE_ZMQ=0

ENABLE_COVERAGE=0
ENABLE_COVERAGE = False
FAILFAST = False

#Create a set to store arguments and create the passon string
opts = set()
Expand All @@ -66,7 +67,9 @@
print_help = True
break
if arg == '--coverage':
ENABLE_COVERAGE = 1
ENABLE_COVERAGE = True
elif arg == '--failfast':
FAILFAST = True
elif PASSON_REGEX.match(arg):
passon_args.append(arg)
elif PARALLEL_REGEX.match(arg):
Expand Down Expand Up @@ -173,6 +176,7 @@
'getstakinginfo.py',
'coldstaking_staking.py',
'coldstaking_spending.py',
'coldstaking_fee.py',
'staticr-staking-amount.py',
'hardfork-451.py',
'hardfork-452.py',
Expand All @@ -181,7 +185,7 @@
'mnemonic.py',
'sendtoaddress.py',
'stakeimmaturebalance.py',
'rpc-help.py',
'rpc-help.py',
]
#if ENABLE_ZMQ:
# testScripts.append('zmq_test.py')
Expand Down Expand Up @@ -257,6 +261,12 @@ def runtests():
print('stderr:\n' if not stderr == '' else '', stderr)
results += "%s | %s | %s s\n" % (name.ljust(max_len_name), str(passed).ljust(6), duration)
print("Pass: %s%s%s, Duration: %s s\n" % (BOLD[1], passed, BOLD[0], duration))

# Check if we need to quit
if FAILFAST and not passed:
print("Early exiting after test failure")
break

results += BOLD[1] + "\n%s | %s | %s s (accumulated)" % ("ALL".ljust(max_len_name), str(all_passed).ljust(6), time_sum) + BOLD[0]
print(results)
print("\nRuntime: %s s" % (int(time.time() - time0)))
Expand Down
65 changes: 65 additions & 0 deletions qa/rpc-tests/coldstaking_fee.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#!/usr/bin/env python3
# Copyright (c) 2019 The Navcoin Core 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 NavCoinTestFramework
from test_framework.util import *

class ColdStakingFeeTest(NavCoinTestFramework):
def __init__(self):
super().__init__()
self.setup_clean_chain = True
self.num_nodes = 3

def setup_network(self, split=False):
self.nodes = []
self.nodes.append(start_node(0, self.options.tmpdir, ["-addressindex","-pooladdress=n1hcSEk4ReyLwbStTKodGCq4kEwhJVxXwC","-poolfee=50"]))
self.nodes.append(start_node(1, self.options.tmpdir, ["-addressindex","-pooladdress=n1hcSEk4ReyLwbStTKodGCq4kEwhJVxXwC","-poolfee=100"]))
self.nodes.append(start_node(2, self.options.tmpdir, ["-addressindex","-pooladdress=n1hcSEk4ReyLwbStTKodGCq4kEwhJVxXwC","-poolfee=101"]))

def run_test(self):
slow_gen(self.nodes[0], 300)
assert (get_bip9_status(self.nodes[0], "coldstaking")["status"] == "active")
slow_gen(self.nodes[1], 300)
assert (get_bip9_status(self.nodes[1], "coldstaking")["status"] == "active")
slow_gen(self.nodes[2], 300)
assert (get_bip9_status(self.nodes[2], "coldstaking")["status"] == "active")

csaddress1 = self.nodes[0].getcoldstakingaddress(self.nodes[0].getnewaddress(),"n1wgKgwFPZYcQrm8qBtPrBvz2piqCwc1ry")
csaddress2 = self.nodes[1].getcoldstakingaddress(self.nodes[1].getnewaddress(),"n1wgKgwFPZYcQrm8qBtPrBvz2piqCwc1ry")
csaddress3 = self.nodes[2].getcoldstakingaddress(self.nodes[2].getnewaddress(),"n1wgKgwFPZYcQrm8qBtPrBvz2piqCwc1ry")

self.nodes[0].sendtoaddress(csaddress1, self.nodes[0].getbalance(), "", "", "", True)
self.nodes[1].sendtoaddress(csaddress2, self.nodes[1].getbalance(), "", "", "", True)
self.nodes[2].sendtoaddress(csaddress3, self.nodes[2].getbalance(), "", "", "", True)

self.nodes[0].generatetoaddress(100, "n1wgKgwFPZYcQrm8qBtPrBvz2piqCwc1ry")
self.nodes[1].generatetoaddress(100, "n1wgKgwFPZYcQrm8qBtPrBvz2piqCwc1ry")
self.nodes[2].generatetoaddress(100, "n1wgKgwFPZYcQrm8qBtPrBvz2piqCwc1ry")

tx=self.nodes[0].sendtoaddress(csaddress1, self.nodes[0].getbalance(), "", "", "", True)
fees0=self.nodes[0].gettransaction(tx)["fee"]*100000000/2
tx2=self.nodes[1].sendtoaddress(csaddress2, self.nodes[1].getbalance(), "", "", "", True)
fees1=self.nodes[1].gettransaction(tx2)["fee"]*100000000
self.nodes[2].sendtoaddress(csaddress3, self.nodes[2].getbalance(), "", "", "", True)

while self.nodes[0].getblockcount() < 401:
time.sleep(1)

node0balance = self.nodes[0].getaddressbalance('n1hcSEk4ReyLwbStTKodGCq4kEwhJVxXwC')["balance"]

while self.nodes[1].getblockcount() < 401:
time.sleep(1)

node1balance = self.nodes[1].getaddressbalance('n1hcSEk4ReyLwbStTKodGCq4kEwhJVxXwC')["balance"]

assert(node0balance > 0)
assert(node1balance > 0)
assert_equal((node0balance+fees0) % 100000000, 0)
assert_equal((node1balance+fees1) % 200000000, 0)

assert("Coinstake tried to move cold staking coins to a non authorised script" in open(self.options.tmpdir + '/node2/devnet/debug.log').read())

if __name__ == '__main__':
ColdStakingFeeTest().main()
1 change: 1 addition & 0 deletions qa/rpc-tests/test_framework/test_framework.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ def main(self):
help="The seed to use for assigning port numbers (default: current process id)")
parser.add_option("--coveragedir", dest="coveragedir",
help="Write tested RPC commands into this directory")

self.add_options(parser)
(self.options, self.args) = parser.parse_args()

Expand Down
3 changes: 1 addition & 2 deletions qa/rpc-tests/test_framework/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class PortSeed:

def enable_mocktime():
#For backwared compatibility of the python scripts
#with previous versions of the cache, set MOCKTIME
#with previous versions of the cache, set MOCKTIME
#to Jan 1, 2014 + (201 * 10 * 60)
global MOCKTIME
MOCKTIME = 1388534400 + (201 * 10 * 60)
Expand All @@ -68,7 +68,6 @@ def enable_coverage(dirname):
global COVERAGE_DIR
COVERAGE_DIR = dirname


def get_rpc_proxy(url, node_number, timeout=None):
"""
Args:
Expand Down
2 changes: 1 addition & 1 deletion qa/rpc-tests/wallet-hd.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def run_test (self):
non_hd_add = self.nodes[0].getnewaddress()
self.nodes[1].importprivkey(self.nodes[0].dumpprivkey(non_hd_add))

# This should be enough to keep the master key and the non-HD key
# This should be enough to keep the master key and the non-HD key
self.nodes[1].backupwallet(tmpdir + "hd.bak")
#self.nodes[1].dumpwallet(tmpdir + "hd.dump")

Expand Down
21 changes: 21 additions & 0 deletions src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,12 @@ class CMainParams : public CChainParams {
consensus.vDeployments[Consensus::DEPLOYMENT_QUORUM_CFUND].nStartTime = 1543622400; // Dec 1st, 2018
consensus.vDeployments[Consensus::DEPLOYMENT_QUORUM_CFUND].nTimeout = 1575158400; // Dec 1st, 2019

// Deployment of Cold Staking Pool Fee
consensus.vDeployments[Consensus::DEPLOYMENT_POOL_FEE].bit = 18;
consensus.vDeployments[Consensus::DEPLOYMENT_POOL_FEE].nStartTime = 1559390400; // Jun 1st, 2018
consensus.vDeployments[Consensus::DEPLOYMENT_POOL_FEE].nTimeout = 1622548800; // Jun 1st, 2021


/**
* The message start string is designed to be unlikely to occur in normal data.
* The characters are rarely used upper ASCII, not valid as UTF-8, and produce
Expand Down Expand Up @@ -375,6 +381,11 @@ class CTestNetParams : public CChainParams {
consensus.vDeployments[Consensus::DEPLOYMENT_QUORUM_CFUND].nStartTime = 1543622400; // Dec 1st, 2018
consensus.vDeployments[Consensus::DEPLOYMENT_QUORUM_CFUND].nTimeout = 1622548800; // Jun 1st, 2021

// Deployment of Cold Staking Pool Fee
consensus.vDeployments[Consensus::DEPLOYMENT_POOL_FEE].bit = 18;
consensus.vDeployments[Consensus::DEPLOYMENT_POOL_FEE].nStartTime = 1559390400; // Jun 1st, 2018
consensus.vDeployments[Consensus::DEPLOYMENT_POOL_FEE].nTimeout = 1622548800; // Jun 1st, 2021

/**
* The message start string is designed to be unlikely to occur in normal data.
* The characters are rarely used upper ASCII, not valid as UTF-8, and produce
Expand Down Expand Up @@ -550,6 +561,11 @@ class CDevNetParams : public CChainParams {
consensus.vDeployments[Consensus::DEPLOYMENT_QUORUM_CFUND].nStartTime = 1543622400; // Dec 1st, 2018
consensus.vDeployments[Consensus::DEPLOYMENT_QUORUM_CFUND].nTimeout = 1651363200; // May 1st, 2022

// Deployment of Cold Staking Pool Fee
consensus.vDeployments[Consensus::DEPLOYMENT_POOL_FEE].bit = 18;
consensus.vDeployments[Consensus::DEPLOYMENT_POOL_FEE].nStartTime = 1559390400; // Jun 1st, 2018
consensus.vDeployments[Consensus::DEPLOYMENT_POOL_FEE].nTimeout = 1622548800; // Jun 1st, 2021

/**
* The message start string is designed to be unlikely to occur in normal data.
* The characters are rarely used upper ASCII, not valid as UTF-8, and produce
Expand Down Expand Up @@ -735,6 +751,11 @@ class CRegTestParams : public CChainParams {
consensus.vDeployments[Consensus::DEPLOYMENT_QUORUM_CFUND].nStartTime = 1543622400; // Dec 1st, 2018
consensus.vDeployments[Consensus::DEPLOYMENT_QUORUM_CFUND].nTimeout = 1575158400; // Dec 1st, 2019

// Deployment of Cold Staking Pool Fee
consensus.vDeployments[Consensus::DEPLOYMENT_POOL_FEE].bit = 18;
consensus.vDeployments[Consensus::DEPLOYMENT_POOL_FEE].nStartTime = 1559390400; // Jun 1st, 2018
consensus.vDeployments[Consensus::DEPLOYMENT_POOL_FEE].nTimeout = 1622548800; // Jun 1st, 2021

/**
* The message start string is designed to be unlikely to occur in normal data.
* The characters are rarely used upper ASCII, not valid as UTF-8, and produce
Expand Down
1 change: 1 addition & 0 deletions src/consensus/params.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ enum DeploymentPos
DEPLOYMENT_NTPSYNC,
DEPLOYMENT_STATIC_REWARD,
DEPLOYMENT_QUORUM_CFUND,
DEPLOYMENT_POOL_FEE,
MAX_VERSION_BITS_DEPLOYMENTS
};

Expand Down
69 changes: 52 additions & 17 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2915,7 +2915,6 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
if (pindex->IsProofOfStake())
setStakeSeen.insert(make_pair(pindex->prevoutStake, pindex->nStakeTime));


// Check proof of stake
if (block.nBits != GetNextTargetRequired(pindex->pprev, block.IsProofOfStake())){
return state.DoS(1,error("ContextualCheckBlock() : incorrect %s at height %d (%d)", !block.IsProofOfStake() ? "proof-of-work" : "proof-of-stake",pindex->pprev->nHeight, block.nBits), REJECT_INVALID, "bad-diffbits");
Expand All @@ -2928,25 +2927,25 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
{
arith_uint256 targetProofOfStake;
// Signature will be checked in CheckInputs(), we can avoid it here (fCheckSignature = false)
if (!CheckProofOfStake(pindex->pprev, block.vtx[1], block.nBits, hashProof, targetProofOfStake, NULL, false))
if (!CheckProofOfStake(pindex->pprev, block.vtx[1], block.nBits, hashProof, targetProofOfStake, NULL, view, false))
{
return error("ConnectBlock() : check proof-of-stake signature failed for block %s", block.GetHash().GetHex());
return error("ContextualCheckBlock() : check proof-of-stake signature failed for block %s", block.GetHash().GetHex());
}
}

if (block.IsProofOfWork())
hashProof = UintToArith256(block.GetPoWHash());

if (!pindex->SetStakeEntropyBit(block.GetStakeEntropyBit()))
return state.DoS(1,error("ConnectBlock() : SetStakeEntropyBit() failed"), REJECT_INVALID, "bad-entropy-bit");
return state.DoS(1,error("ContextualCheckBlock() : SetStakeEntropyBit() failed"), REJECT_INVALID, "bad-entropy-bit");

// Record proof hash value
pindex->hashProof = hashProof;

uint64_t nStakeModifier = 0;
bool fGeneratedStakeModifier = false;
if (!ComputeNextStakeModifier(pindex->pprev, nStakeModifier, fGeneratedStakeModifier))
return state.DoS(1, error("ConnectBlock() : ComputeNextStakeModifier() failed"), REJECT_INVALID, "bad-stake-modifier");
return state.DoS(1, error("ContextualCheckBlock() : ComputeNextStakeModifier() failed"), REJECT_INVALID, "bad-stake-modifier");

pindex->SetStakeModifier(nStakeModifier, fGeneratedStakeModifier);

Expand Down Expand Up @@ -4620,6 +4619,12 @@ bool IsColdStakingEnabled(const CBlockIndex* pindexPrev, const Consensus::Params
return (VersionBitsState(pindexPrev, params, Consensus::DEPLOYMENT_COLDSTAKING, versionbitscache) == THRESHOLD_ACTIVE);
}

bool IsColdStakingPoolFeeEnabled(const CBlockIndex* pindexPrev, const Consensus::Params& params)
{
LOCK(cs_main);
return (VersionBitsState(pindexPrev, params, Consensus::DEPLOYMENT_POOL_FEE, versionbitscache) == THRESHOLD_ACTIVE);
}

bool IsStaticRewardLocked(const CBlockIndex* pindexPrev, const Consensus::Params& params)
{
LOCK(cs_main);
Expand Down Expand Up @@ -8604,24 +8609,54 @@ bool CheckStakeKernelHash(CBlockIndex* pindexPrev, unsigned int nBits, CBlockInd
}

//Check kernel hash target and coinstake signature
bool CheckProofOfStake(CBlockIndex* pindexPrev, const CTransaction& tx, unsigned int nBits, arith_uint256& hashProofOfStake, arith_uint256& targetProofOfStake, std::vector<CScriptCheck> *pvChecks, bool fCHeckSignature)
bool CheckProofOfStake(CBlockIndex* pindexPrev, const CTransaction& tx, unsigned int nBits, arith_uint256& hashProofOfStake, arith_uint256& targetProofOfStake, std::vector<CScriptCheck> *pvChecks, CCoinsViewCache& view, bool fCHeckSignature)
{
if (!tx.IsCoinStake())
return error("CheckProofOfStake() : called on non-coinstake %s", tx.GetHash().ToString());
return error("%s: called on non-coinstake %s", __func__, tx.GetHash().ToString());

// Kernel (input 0) must match the stake hash target per coin age (nBits)
const CTxIn& txin = tx.vin[0];

CTransaction txPrev;
uint256 hashBlock = uint256();
if (!GetTransaction(txin.prevout.hash, txPrev, Params().GetConsensus(), hashBlock, true))
return error("CheckProofOfStake() : INFO: read txPrev failed %s",txin.prevout.hash.GetHex()); // previous transaction not in main chain, may occur during initial download
return error("%s: INFO: read txPrev failed %s",__func__, txin.prevout.hash.GetHex()); // previous transaction not in main chain, may occur during initial download

bool fColdStaking = txPrev.vout[txin.prevout.n].scriptPubKey.IsColdStaking();
bool fPoolEnabled = IsColdStakingPoolFeeEnabled(pindexPrev, Params().GetConsensus());
CScript kernelScript = txPrev.vout[txin.prevout.n].scriptPubKey;

if (fPoolEnabled && tx.vin.size() > 1)
{
for (unsigned int i = 1; i < tx.vin.size(); i++)
{
CTransaction txPrev_;
uint256 hashBlock_ = uint256();
if (!GetTransaction(tx.vin[i].prevout.hash, txPrev_, Params().GetConsensus(), hashBlock_, true))
return error("%s: INFO: read txPrev failed %s",__func__, tx.vin[i].prevout.hash.GetHex()); // previous transaction not in main chain, may occur during initial download

if (txPrev.vout[txin.prevout.n].scriptPubKey.IsColdStaking())
for(unsigned int i = 1; i < tx.vout.size() - 1; i++) // First output is empty, last is CFund contribution
if(tx.vout[i].scriptPubKey != txPrev.vout[txin.prevout.n].scriptPubKey)
return error(strprintf("CheckProofOfStake(): Coinstake output %d tried to move cold staking coins to a non authorised script. (%s vs. %s)",
i, ScriptToAsmStr(txPrev.vout[txin.prevout.n].scriptPubKey), ScriptToAsmStr(tx.vout[i].scriptPubKey)));
fColdStaking |= txPrev_.vout[tx.vin[i].prevout.n].scriptPubKey.IsColdStaking();
if (fColdStaking && txPrev_.vout[tx.vin[i].prevout.n].scriptPubKey != kernelScript)
return error("%s: Coinstake spends inputs from more than one different kernel", __func__);
}
}

if (fColdStaking)
{
CAmount valueIn = view.GetValueIn(tx);
CAmount valueOut = 0;

for(unsigned int i = 1; i < tx.vout.size() - (fPoolEnabled?0:1); i++) // First output is empty, last is CFund contribution
if(fPoolEnabled && tx.vout[i].scriptPubKey == txPrev.vout[txin.prevout.n].scriptPubKey)
valueOut += tx.vout[i].nValue;
else if(!fPoolEnabled && tx.vout[i].scriptPubKey != txPrev.vout[txin.prevout.n].scriptPubKey)
return error(strprintf("%s: Coinstake output %d tried to move cold staking coins to a non authorised script. (%s vs. %s)",
__func__, i, ScriptToAsmStr(txPrev.vout[txin.prevout.n].scriptPubKey), ScriptToAsmStr(tx.vout[i].scriptPubKey)));

if (fPoolEnabled && valueIn > valueOut)
return error("%s: Coinstake tried to move cold staking coins to a non authorised script.",__func__);

}

if (pvChecks)
pvChecks->reserve(tx.vin.size());
Expand All @@ -8641,19 +8676,19 @@ bool CheckProofOfStake(CBlockIndex* pindexPrev, const CTransaction& tx, unsigned
pvChecks->push_back(CScriptCheck());
check.swap(pvChecks->back());
} else if (!check())
return error("CheckProofOfStake() : script-verify-failed %s",ScriptErrorString(check.GetScriptError()));
return error("%s: script-verify-failed %s",__func__, ScriptErrorString(check.GetScriptError()));
}

if (mapBlockIndex.count(hashBlock) == 0)
return fDebug? error("CheckProofOfStake() : read block failed") : false; // unable to read block of previous transaction
return fDebug? error("%s: read block failed",__func__) : false; // unable to read block of previous transaction

CBlockIndex* pblockindex = mapBlockIndex[hashBlock];

if (txin.prevout.hash != txPrev.GetHash())
return error("CheckProofOfStake(): Coinstake input does not match previous output %s",txin.prevout.hash.GetHex());
return error("%s: Coinstake input does not match previous output %s",__func__, txin.prevout.hash.GetHex());

if (!CheckStakeKernelHash(pindexPrev, nBits, *pblockindex, txPrev, txin.prevout, tx.nTime, hashProofOfStake, targetProofOfStake, fDebug))
return error("CheckProofOfStake() : INFO: check kernel failed on coinstake %s, hashProof=%s", tx.GetHash().ToString(), hashProofOfStake.ToString()); // may occur during initial download or if behind on block chain sync
return error("%s: INFO: check kernel failed on coinstake %s, hashProof=%s",__func__, tx.GetHash().ToString(), hashProofOfStake.ToString()); // may occur during initial download or if behind on block chain sync

return true;
}
Expand Down
Loading

0 comments on commit 505fe04

Please sign in to comment.