Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/kernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ bool Stake(CStakeInput* stakeInput, unsigned int nBits, unsigned int nTimeBlockF
bool fSuccess = false;
unsigned int nTryTime = 0;
int nHeightStart = chainActive.Height();
int nHashDrift = 30;
int nHashDrift = 60;
CDataStream ssUniqueID = stakeInput->GetUniqueness();
CAmount nValueIn = stakeInput->GetValue();
for (int i = 0; i < nHashDrift; i++) //iterate the hashing
Expand Down
9 changes: 6 additions & 3 deletions src/miner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,7 @@ void BitcoinMiner(CWallet* pwallet, bool fProofOfStake)
// Each thread has its own key and counter
CReserveKey reservekey(pwallet);
unsigned int nExtraNonce = 0;
int nHeightLast = 0;

while (fGenerateBitcoins || fProofOfStake) {
if (fProofOfStake) {
Expand Down Expand Up @@ -610,14 +611,16 @@ void BitcoinMiner(CWallet* pwallet, bool fProofOfStake)
continue;
}

if (mapHashedBlocks.count(chainActive.Tip()->nHeight)) //search our map of hashed blocks, see if bestblock has been hashed yet
if (nHeightLast == chainActive.Tip()->nHeight)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this accomplishes anything differently than how the code was before.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed it to a code that I can understand.
If it is the same, there is no problem.

{
if (GetTime() - mapHashedBlocks[chainActive.Tip()->nHeight] < max(pwallet->nHashInterval, (unsigned int)1)) // wait half of the nHashDrift with max wait of 3 minutes
{
MilliSleep(5000);
MilliSleep(1000);
continue;
}
}

nHeightLast = chainActive.Tip()->nHeight;
}

//
Expand Down Expand Up @@ -790,4 +793,4 @@ void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads)
minerThreads->create_thread(boost::bind(&ThreadBitcoinMiner, pwallet));
}

#endif // ENABLE_WALLET
#endif // ENABLE_WALLET
8 changes: 7 additions & 1 deletion src/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2959,11 +2959,13 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int
return false;

if (GetAdjustedTime() - chainActive.Tip()->GetBlockTime() < 60)
MilliSleep(10000);
MilliSleep(100);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably fine. I delete these two lines completely when I test.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. Sleep code is not required.


CAmount nCredit = 0;
CScript scriptPubKeyKernel;
bool fKernelFound = false;
int nHeightStart = chainActive.Height();

for (std::unique_ptr<CStakeInput>& stakeInput : listInputs) {
// Make sure the wallet is unlocked and shutdown hasn't been requested
if (IsLocked() || ShutdownRequested())
Expand All @@ -2976,6 +2978,10 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int
continue;
}

if (chainActive.Height() != nHeightStart) {
return false;
}

// Read block header
CBlockHeader block = pindex->GetBlockHeader();
uint256 hashProofOfStake = 0;
Expand Down
4 changes: 2 additions & 2 deletions src/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -304,9 +304,9 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface
fBackupMints = false;

// Stake Settings
nHashDrift = 45;
nHashDrift = 60;
nStakeSplitThreshold = 2000;
nHashInterval = 22;
nHashInterval = 2;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This means that every 2 seconds you will be hashing the next 60 seconds of timestamps on each UTXO that you have.
So the first round of hashing would do seconds 0-60 for each UTXO, the next round of hashing would do seconds 2-62 for each UTXO. That creates 58 redundant hashes per UTXO held for each round of hashing.

Right now the settings are at 22/30 because that seemed to be a decent balance between having some overlapping hashes as well as not hashing too far out into the future.

Hashing out into the future can be more likely to create an orphan stake. If two people get a valid stake at the same time, whoever has the stake with the lowest timestamp will win the block. The second person is better off waiting until the time is closer and then publishing the stake when there is less time for someone else to produce a stake that orphans it.

Copy link
Copy Markdown
Author

@gitagy gitagy Jun 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The frequency of hash searches is intended. (Every 2 seconds)
Duplicate nTimeTx(hash) searches only occur to consume more CPU time for testing. I agree that it is the part that should be optimized.

Currently, orphans occur more frequently due to longer interval + long zpiv spending time.
(I wanted to reduce the possibility.)

Do not change the nHashDrift. I hope it works as follows.

before : 0-30 scan > sleep 22 sec > 31-60 scan
after : 0-30 scan > sleep 1 sec > 1-31 scan > sleep 1 sec > 2-32 scan

It is right to eliminate the duplication.

There is one more important thing.

In the code example below, nTimeBlockFrom and nStakeModifier are the UTXO fixed values. That is correct for CPivStake. However, it is no longer fixed in the CZPivStake.
Therefore, the next round of navigation requires a full hash search and short interval.


for (std::unique_ptr<CStakeInput>& stakeInput : listInputs)
{
    CBlockIndex* pindex = stakeInput->GetIndexFrom();
    CBlockHeader block = pindex->GetBlockHeader();

    unsigned int nTimeBlockFrom;

    nTimeBlockFrom = block.GetBlockTime();

    uint64_t nStakeModifier = 0;
    stakeInput->GetModifier(nStakeModifier); 
}

Copy link
Copy Markdown

@presstab presstab Jun 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The nStakeModifier for the zpiv stake changes less often since it is based on the first accumulator checkpoint that occurs 60 minutes after pindexFrom. Accumulator checkpoints change maximum of every 10 blocks, sometimes it can be an even longer span than that too. So this part of the hash is redundant a lot of the time, but not always.

Since all of the zpivstake's will have the same modifier, it might make sense to cache the previous round's modifier and then compare it with the current round to see if a complete new set of hashes needs to be generated or if it should only generate the incremental change.

nStakeSetUpdateTime = 300; // 5 minutes

//MultiSend
Expand Down