Skip to content

Commit

Permalink
[Tests] (squashed) few regtest fixes
Browse files Browse the repository at this point in the history
- fix regtest nStakeMinAge check
- fix zerocoin_public_spend
- fix StakeModifier V2 generation on regtest (0)
- fix stake age on regtest
  • Loading branch information
random-zebra committed Nov 20, 2019
1 parent 3487e58 commit 8ca3979
Show file tree
Hide file tree
Showing 9 changed files with 48 additions and 35 deletions.
12 changes: 5 additions & 7 deletions src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,9 @@ libzerocoin::ZerocoinParams* CChainParams::Zerocoin_Params(bool useModulusV1) co
bool CChainParams::HasStakeMinAgeOrDepth(const int contextHeight, const uint32_t contextTime,
const int utxoFromBlockHeight, const uint32_t utxoFromBlockTime) const
{
// Age not required on regtest
if (NetworkID() == CBaseChainParams::REGTEST)
return true;

// before stake modifier V2, the age required was 60 * 60 (1 hour)
// before stake modifier V2, the age required was 60 * 60 (1 hour). Not required for regtest
if (!IsStakeModifierV2(contextHeight))
return (utxoFromBlockTime + 3600 <= contextTime);
return NetworkID() == CBaseChainParams::REGTEST || (utxoFromBlockTime + nStakeMinAge <= contextTime);

// after stake modifier V2, we require the utxo to be nStakeMinDepth deep in the chain
return (contextHeight - utxoFromBlockHeight >= nStakeMinDepth);
Expand Down Expand Up @@ -186,6 +182,7 @@ class CMainParams : public CChainParams
nTimeSlotLength = 15; // 15 seconds
nTargetTimespan_V2 = 2 * nTimeSlotLength * 60; // 30 minutes
nMaturity = 100;
nStakeMinAge = 60 * 60; // 1 hour
nStakeMinDepth = 600;
nFutureTimeDriftPoW = 7200;
nFutureTimeDriftPoS = 180;
Expand Down Expand Up @@ -440,6 +437,7 @@ class CRegTestParams : public CTestNetParams
bnProofOfWorkLimit = ~uint256(0) >> 1;
nLastPOWBlock = 250;
nMaturity = 100;
nStakeMinAge = 0;
nStakeMinDepth = 0;
nTimeSlotLength = 1; // time not masked on RegNet
nMasternodeCountDrift = 4;
Expand All @@ -452,7 +450,7 @@ class CRegTestParams : public CTestNetParams
nBlockRecalculateAccumulators = 999999999; //Trigger a recalculation of accumulators
nBlockFirstFraudulent = 999999999; //First block that bad serials emerged
nBlockLastGoodCheckpoint = 999999999; //Last valid accumulator checkpoint
nBlockStakeModifierlV2 = 351;
nBlockStakeModifierlV2 = 255;
nBlockTimeProtocolV2 = 999999999;

// Public coin spend enforcement
Expand Down
2 changes: 2 additions & 0 deletions src/chainparams.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class CChainParams
int COINBASE_MATURITY() const { return nMaturity; }

/** returns the coinstake maturity (min depth required) **/
int COINSTAKE_MIN_AGE() const { return nStakeMinAge; }
int COINSTAKE_MIN_DEPTH() const { return nStakeMinDepth; }
bool HasStakeMinAgeOrDepth(const int contextHeight, const uint32_t contextTime, const int utxoFromBlockHeight, const uint32_t utxoFromBlockTime) const;

Expand Down Expand Up @@ -185,6 +186,7 @@ class CChainParams
int nMasternodeCountDrift;
int nMaturity;
int nStakeMinDepth;
int nStakeMinAge;
int nFutureTimeDriftPoW;
int nFutureTimeDriftPoS;
int nTimeSlotLength;
Expand Down
12 changes: 8 additions & 4 deletions src/kernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,10 @@ static bool SelectBlockFromCandidates(
// must hash with a future stake modifier to generate the proof.
uint256 ComputeStakeModifier(const CBlockIndex* pindexPrev, const uint256& kernel)
{
if (!pindexPrev)
return uint256(); // genesis block's modifier is 0
// genesis block's modifier is 0
// all block's modifiers are 0 on regtest
if (!pindexPrev || Params().NetworkID() == CBaseChainParams::REGTEST)
return uint256();

CHashWriter ss(SER_GETHASH, 0);
ss << kernel;
Expand Down Expand Up @@ -371,7 +373,7 @@ bool Stake(const CBlockIndex* pindexPrev, CStakeInput* stakeInput, unsigned int

nTimeTx = GetCurrentTimeSlot();
// double check that we are not on the same slot as prev block
if (nTimeTx <= pindexPrev->nTime)
if (nTimeTx <= pindexPrev->nTime && Params().NetworkID() != CBaseChainParams::REGTEST)
return false;

// check stake kernel
Expand All @@ -389,7 +391,9 @@ bool StakeV1(const CBlockIndex* pindexPrev, CStakeInput* stakeInput, const uint3
// iterate from maxTime down to pindexPrev->nTime (or min time due to maturity, 60 min after blockFrom)
const unsigned int prevBlockTime = pindexPrev->nTime;
const unsigned int maxTime = pindexPrev->MaxFutureBlockTime();
const unsigned int minTime = std::max(prevBlockTime, nTimeBlockFrom + 3600);
unsigned int minTime = std::max(prevBlockTime, nTimeBlockFrom + 3600);
if (Params().NetworkID() == CBaseChainParams::REGTEST)
minTime = prevBlockTime;
unsigned int nTryTime = maxTime;

// check required maturity for stake
Expand Down
6 changes: 2 additions & 4 deletions src/libzerocoin/Accumulator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,9 @@ bool AccumulatorWitness::VerifyWitness(const Accumulator& a, const PublicCoin &p
Accumulator temp(witness);
temp += element;
if (!(temp == a)) {
std::cout << "VerifyWitness: failed verify temp does not equal a\n";
return false;
return error("%s : failed verify temp does not equal a", __func__);
} else if (this->element != publicCoin) {
std::cout << "VerifyWitness: failed verify pubcoins not equal\n";
return false;
return error("%s : failed verify pubcoins not equal", __func__);
}

return true;
Expand Down
8 changes: 3 additions & 5 deletions test/functional/fake_stake/base_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from test_framework.script import CScript, OP_CHECKSIG
from test_framework.util import hash256, bytes_to_hex_str, hex_str_to_bytes, connect_nodes_bi, p2p_port

from .util import TestNode, create_transaction, utxo_to_stakingPrevOuts, dir_size
from .util import TestNode, create_transaction, utxo_to_stakingPrevOuts, dir_size, nBlockStakeModifierlV2
''' -------------------------------------------------------------------------
PIVX_FakeStakeTest CLASS ----------------------------------------------------
Expand Down Expand Up @@ -117,7 +117,7 @@ def create_spam_block(self, hashPrevBlock, stakingPrevOuts, height, fStakeDouble
block = create_block(int(hashPrevBlock, 16), coinbase, nTime)

# Find valid kernel hash - Create a new private key used for block signing.
if not block.solve_stake(stakingPrevOuts):
if not block.solve_stake(stakingPrevOuts, (height >= nBlockStakeModifierlV2)):
raise Exception("Not able to solve for any prev_outpoint")

# Sign coinstake TX and add it to the block
Expand Down Expand Up @@ -317,10 +317,8 @@ def get_prevouts(self, utxo_list, blockHeight, zpos=False):
txBlocktime = utxo_tx['blocktime']
txBlockhash = utxo_tx['blockhash']

# get Stake Modifier
stakeModifier = int(self.node.getblock(txBlockhash)['modifier'], 16)
# assemble prevout object
utxo_to_stakingPrevOuts(utxo, stakingPrevOuts, txBlocktime, stakeModifier, zpos)
utxo_to_stakingPrevOuts(utxo, stakingPrevOuts, txBlocktime, zpos)

return stakingPrevOuts

Expand Down
13 changes: 7 additions & 6 deletions test/functional/fake_stake/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
from test_framework.script import CScript
from test_framework.util import wait_until

nBlockStakeModifierlV2 = 255

''' -------------------------------------------------------------------------
TestNode CLASS --------------------------------------------------------------
Expand Down Expand Up @@ -116,15 +118,14 @@ def create_transaction(outPoint, sig, value, nTime, scriptPubKey=CScript()):
return tx


def utxo_to_stakingPrevOuts(utxo, stakingPrevOuts, txBlocktime, stakeModifier, zpos=False):
def utxo_to_stakingPrevOuts(utxo, stakingPrevOuts, txBlocktime, zpos=False):
'''
Updates a map of unspent outputs to (amount, blocktime) to be used as stake inputs
:param utxo: <if zpos=False> (map) utxo JSON object returned from listunspent
<if zpos=True> (map) mint JSON object returned from listmintedzerocoins
stakingPrevOuts: ({COutPoint --> (int, int, int, str)} dictionary)
map outpoints to amount, block_time, nStakeModifier, hashStake hex
txBlocktime: (int) block time of the stake Modifier
stakeModifier: (int) stake modifier for the current utxo
map outpoints to amount, block_time, hashStake hex
txBlocktime: (int) block time of the utxo
zpos: (bool) if true, utxo holds a zerocoin serial hash
:return
'''
Expand All @@ -133,10 +134,10 @@ def utxo_to_stakingPrevOuts(utxo, stakingPrevOuts, txBlocktime, stakeModifier, z
if utxo['confirmations'] > COINBASE_MATURITY:
if zpos:
outPoint = utxo["serial hash"]
stakingPrevOuts[outPoint] = (int(utxo["denomination"]) * COIN, txBlocktime, stakeModifier, utxo['hash stake'])
stakingPrevOuts[outPoint] = (int(utxo["denomination"]) * COIN, txBlocktime, utxo['hash stake'])
else:
outPoint = COutPoint(int(utxo['txid'], 16), utxo['vout'])
stakingPrevOuts[outPoint] = (int(utxo['amount'])*COIN, txBlocktime, stakeModifier, "")
stakingPrevOuts[outPoint] = (int(utxo['amount'])*COIN, txBlocktime, "")

return

Expand Down
7 changes: 3 additions & 4 deletions test/functional/feature_coldStaking.py
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,7 @@ def generateBlock(self, n=1, nodeid=2):
except JSONRPCException as e:
if ("Couldn't create new block" in str(e)):
# Sleep two seconds and retry
self.log.info("Waiting...")
time.sleep(2)
else:
raise e
Expand Down Expand Up @@ -442,12 +443,10 @@ def get_prevouts(self, coins, node_n, confs=1):
prevtx = api.getrawtransaction(utxo['txid'], 1)
prevScript = prevtx['vout'][utxo['vout']]['scriptPubKey']['hex']
prevtx_btime = prevtx['blocktime']
prevtx_bhash = prevtx['blockhash']
modifier = 0
if utxo['confirmations'] < confs:
continue
o = COutPoint(int(utxo['txid'], 16), utxo['vout'])
prevouts[o] = (int(utxo['amount']) * COIN, prevtx_btime, modifier, prevScript)
prevouts[o] = (int(utxo['amount']) * COIN, prevtx_btime, prevScript)
return prevouts


Expand All @@ -473,7 +472,7 @@ def create_block(self, prev_hash, staking_prevouts, height, node_n, s_address, f
raise Exception("Not able to solve for any prev_outpoint")

# Create coinstake TX
amount, prev_time, modifier, prevScript = staking_prevouts[block.prevoutStake]
amount, prev_time, prevScript = staking_prevouts[block.prevoutStake]
outNValue = int(amount + 250 * COIN)
stake_tx_unsigned = CTransaction()
stake_tx_unsigned.nTime = block.nTime
Expand Down
10 changes: 7 additions & 3 deletions test/functional/test_framework/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -486,15 +486,19 @@ def get_uniqueness(self, prevout):
r += ser_uint256(prevout.hash)
return r

def solve_stake(self, prevouts):
def solve_stake(self, prevouts, isModifierV2=False):
target0 = uint256_from_compact(self.nBits)
loop = True
while loop:
for prevout in prevouts:
nvalue, txBlockTime, stakeModifier, hashStake = prevouts[prevout]
nvalue, txBlockTime, hashStake = prevouts[prevout]
target = int(target0 * nvalue / 100) % 2**256
data = b""
data += ser_uint64(stakeModifier)
if isModifierV2:
data += ser_uint256(0)
else:
data += ser_uint64(0)
#data += ser_uint64(stakeModifier)
data += struct.pack("<I", txBlockTime)
# prevout for zPoS is serial hashes hex strings
if isinstance(prevout, COutPoint):
Expand Down
13 changes: 11 additions & 2 deletions test/functional/zerocoin_valid_public_spend.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,17 @@ def run_test(self):

# 7) Check spend v2 disabled
self.log.info("%s: Trying to spend using the old coin spend method.." % self.__class__.__name__)
assert_raises_rpc_error(-4, "Couldn't generate the accumulator witness",
self.nodes[0].spendzerocoin, DENOM_TO_USE, False, False, "", False)
try:
res = self.nodes[0].spendzerocoin(DENOM_TO_USE, False, False, "", False)
except JSONRPCException as e:
# JSONRPCException was thrown as expected. Check the code and message values are correct.
if e.error["code"] != -4:
raise AssertionError("Unexpected JSONRPC error code %i" % e.error["code"])
if ("Couldn't generate the accumulator witness" not in e.error['message'])\
and ("The transaction was rejected!" not in e.error['message']):
raise AssertionError("Expected substring not found:" + e.error['message'])
except Exception as e:
raise AssertionError("Unexpected exception raised: " + type(e).__name__)
self.log.info("GOOD: spendzerocoin old spend did not verify.")


Expand Down

0 comments on commit 8ca3979

Please sign in to comment.