Working proof of stake with new algorithm
This commit is contained in:
@@ -244,13 +244,13 @@ void *chainparams_commandline(void *ptr)
|
||||
if (ASSETCHAINS_LWMAPOS != 0)
|
||||
{
|
||||
mainParams.consensus.posLimit = uint256S("000000000f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f");
|
||||
mainParams.consensus.nPOSAveragingWindow = 100;
|
||||
mainParams.consensus.nPOSAveragingWindow = 45;
|
||||
// spacing is 1000 units per block to get better resolution, POS is 50% hard coded for now, we can vary it later
|
||||
// when we get reliable integer math on nLwmaPOSAjustedWeight
|
||||
mainParams.consensus.nPOSTargetSpacing = VERUS_BLOCK_POSUNITS * 2;
|
||||
// nLwmaPOSAjustedWeight = (N+1)/2 * (0.9989^(500/nPOSAveragingWindow)) * nPOSTargetSpacing
|
||||
// this needs to be recalculated if VERUS_BLOCK_POSUNITS is changed
|
||||
mainParams.consensus.nLwmaPOSAjustedWeight = 100446;
|
||||
mainParams.consensus.nLwmaPOSAjustedWeight = 45000;
|
||||
}
|
||||
|
||||
checkpointData = //(Checkpoints::CCheckpointData)
|
||||
|
||||
@@ -31,7 +31,6 @@ class CVerusHash
|
||||
result = buf2;
|
||||
curPos = 0;
|
||||
std::fill(buf1, buf1 + sizeof(buf1), 0);
|
||||
std::fill(buf2, buf2 + sizeof(buf2), 0);
|
||||
}
|
||||
|
||||
void Finalize(unsigned char hash[32])
|
||||
@@ -42,7 +41,7 @@ class CVerusHash
|
||||
haraka512(hash, curBuf);
|
||||
}
|
||||
else
|
||||
std::memcpy(hash, result, 32);
|
||||
std::memcpy(hash, curBuf, 32);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -1266,11 +1266,13 @@ bool verusCheckPOSBlock(int32_t slowflag, CBlock *pblock, int32_t height)
|
||||
int32_t txn_count;
|
||||
uint32_t voutNum;
|
||||
bool isPOS = false;
|
||||
CTxDestination voutaddress;
|
||||
CTxDestination voutaddress, destaddress;
|
||||
arith_uint256 target, hash;
|
||||
CTransaction tx;
|
||||
|
||||
// TODO(miketout) must initialize destaddr properly
|
||||
if (!pblock->isVerusPOSBlock())
|
||||
return false;
|
||||
|
||||
char voutaddr[64],destaddr[64];
|
||||
|
||||
target.SetCompact(pblock->GetVerusPOSTarget());
|
||||
@@ -1295,7 +1297,7 @@ bool verusCheckPOSBlock(int32_t slowflag, CBlock *pblock, int32_t height)
|
||||
}
|
||||
else
|
||||
{
|
||||
hash = UintToArith256(tx.GetVerusPOSHash(voutNum, height, pastBlockIndex->GetBlockHash())) / tx.vout[voutNum].nValue;
|
||||
hash = UintToArith256(tx.GetVerusPOSHash(voutNum, height, pastBlockIndex->GetBlockHash()));
|
||||
if (hash <= target)
|
||||
{
|
||||
if ((mapBlockIndex.count(blkHash) == 0) ||
|
||||
@@ -1316,13 +1318,16 @@ bool verusCheckPOSBlock(int32_t slowflag, CBlock *pblock, int32_t height)
|
||||
{
|
||||
arith_uint256 cTarget;
|
||||
cTarget.SetCompact(lwmaGetNextPOSRequired(previndex, Params().GetConsensus()));
|
||||
|
||||
if (cTarget != target)
|
||||
{
|
||||
fprintf(stderr,"ERROR: invalid PoS block %s - invalid diff target\n",blkHash.ToString().c_str());
|
||||
}
|
||||
else if ( ExtractDestination(pblock->vtx[txn_count-1].vout[0].scriptPubKey,voutaddress) )
|
||||
else if ( ExtractDestination(pblock->vtx[txn_count-1].vout[0].scriptPubKey,voutaddress) &&
|
||||
ExtractDestination(tx.vout[voutNum].scriptPubKey, destaddress) )
|
||||
{
|
||||
strcpy(voutaddr, CBitcoinAddress(voutaddress).ToString().c_str());
|
||||
strcpy(destaddr, CBitcoinAddress(destaddress).ToString().c_str());
|
||||
if ( strcmp(destaddr,voutaddr) == 0 )
|
||||
{
|
||||
isPOS = true;
|
||||
|
||||
@@ -80,8 +80,8 @@ uint32_t ASSETCHAINS_ALGO = _ASSETCHAINS_EQUIHASH;
|
||||
|
||||
// Verus proof of stake controls
|
||||
int32_t ASSETCHAINS_LWMAPOS = 0; // percentage of blocks should be PoS
|
||||
int32_t VERUS_BLOCK_POSUNITS = 1000; // one block is 1000 units
|
||||
int32_t VERUS_MIN_STAKEAGE = 200; // 1/2 this should also be a cap on the POS averaging window, or startup could be too easy
|
||||
int32_t VERUS_BLOCK_POSUNITS = 1000; // one block is 1000 units
|
||||
int32_t VERUS_MIN_STAKEAGE = 150; // 1/2 this should also be a cap on the POS averaging window, or startup could be too easy
|
||||
|
||||
uint64_t KOMODO_INTERESTSUM,KOMODO_WALLETBALANCE;
|
||||
uint64_t ASSETCHAINS_COMMISSION,ASSETCHAINS_STAKED,ASSETCHAINS_SUPPLY = 10;
|
||||
|
||||
203
src/miner.cpp
203
src/miner.cpp
@@ -111,7 +111,7 @@ extern int32_t ASSETCHAINS_SEED,IS_KOMODO_NOTARY,USE_EXTERNAL_PUBKEY,KOMODO_CHOS
|
||||
extern uint64_t ASSETCHAINS_COMMISSION, ASSETCHAINS_STAKED;
|
||||
extern uint64_t ASSETCHAINS_REWARD[ASSETCHAINS_MAX_ERAS], ASSETCHAINS_TIMELOCKGTE, ASSETCHAINS_NONCEMASK[];
|
||||
extern const char *ASSETCHAINS_ALGORITHMS[];
|
||||
extern int32_t ASSETCHAINS_ALGO, ASSETCHAINS_EQUIHASH, ASSETCHAINS_LASTERA, ASSETCHAINS_LWMAPOS, ASSETCHAINS_NONCESHIFT[], ASSETCHAINS_HASHESPERROUND[];
|
||||
extern int32_t VERUS_MIN_STAKEAGE, ASSETCHAINS_ALGO, ASSETCHAINS_EQUIHASH, ASSETCHAINS_LASTERA, ASSETCHAINS_LWMAPOS, ASSETCHAINS_NONCESHIFT[], ASSETCHAINS_HASHESPERROUND[];
|
||||
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
|
||||
extern std::string NOTARY_PUBKEY;
|
||||
extern uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33];
|
||||
@@ -462,6 +462,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, bool isStake)
|
||||
arith_uint256 posHash;
|
||||
siglen = verus_staked(key, txStaked, nBitsPOS, posHash, utxosig);
|
||||
blocktime = GetAdjustedTime();
|
||||
pblock->SetVerusPOSTarget(nBitsPOS);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -530,13 +531,17 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, bool isStake)
|
||||
pblock->vtx[0] = txNew;
|
||||
pblocktemplate->vTxFees[0] = -nFees;
|
||||
|
||||
// Randomise nonce
|
||||
arith_uint256 nonce = UintToArith256(GetRandHash());
|
||||
// if not Verus stake, setup nonce, otherwise, leave it alone
|
||||
if (!isStake || ASSETCHAINS_LWMAPOS == 0)
|
||||
{
|
||||
// Randomise nonce
|
||||
arith_uint256 nonce = UintToArith256(GetRandHash());
|
||||
|
||||
// Clear the top 16 and bottom 16 or 24 bits (for local use as thread flags and counters)
|
||||
nonce <<= ASSETCHAINS_NONCESHIFT[ASSETCHAINS_ALGO];
|
||||
nonce >>= 16;
|
||||
pblock->nNonce = ArithToUint256(nonce);
|
||||
// Clear the top 16 and bottom 16 or 24 bits (for local use as thread flags and counters)
|
||||
nonce <<= ASSETCHAINS_NONCESHIFT[ASSETCHAINS_ALGO];
|
||||
nonce >>= 16;
|
||||
pblock->nNonce = ArithToUint256(nonce);
|
||||
}
|
||||
|
||||
// Fill in header
|
||||
pblock->hashPrevBlock = pindexPrev->GetBlockHash();
|
||||
@@ -544,7 +549,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, bool isStake)
|
||||
if ( ASSETCHAINS_SYMBOL[0] == 0 || ASSETCHAINS_STAKED == 0 || NOTARY_PUBKEY33[0] == 0 )
|
||||
{
|
||||
UpdateTime(pblock, Params().GetConsensus(), pindexPrev);
|
||||
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus());
|
||||
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus());
|
||||
}
|
||||
pblock->nSolution.clear();
|
||||
pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(pblock->vtx[0]);
|
||||
@@ -580,7 +585,6 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, bool isStake)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pblocktemplate.release();
|
||||
}
|
||||
|
||||
@@ -816,22 +820,23 @@ void static VerusStaker(CWallet *pwallet)
|
||||
// try a nice clean peer connection to start
|
||||
waitForPeers(chainparams);
|
||||
sleep(5);
|
||||
CBlockIndex* curTip;
|
||||
CBlockIndex *curTip = chainActive.Tip(), *lastTip;
|
||||
do {
|
||||
lastTip = curTip;
|
||||
printf("Verifying block height %d \n", lastTip->nHeight);
|
||||
MilliSleep(3000 + rand() % 1900);
|
||||
curTip = chainActive.Tip();
|
||||
printf("Verifying block height %d \n", chainActive.Tip()->nHeight);
|
||||
MilliSleep(2000 + rand() % 1900);
|
||||
} while (curTip != chainActive.Tip());
|
||||
} while (curTip != lastTip);
|
||||
|
||||
SetThreadPriority(THREAD_PRIORITY_LOWEST);
|
||||
|
||||
sleep(5);
|
||||
printf("Staking height %d\n", chainActive.Tip()->nHeight + 1);
|
||||
printf("Staking height %d for %s\n", chainActive.Tip()->nHeight + 1, ASSETCHAINS_SYMBOL);
|
||||
//fprintf(stderr,"Staking height %d for %s\n", chainActive.Tip()->nHeight + 1, ASSETCHAINS_SYMBOL);
|
||||
|
||||
miningTimer.start();
|
||||
|
||||
try {
|
||||
fprintf(stderr,"Mining %s with %s\n", ASSETCHAINS_SYMBOL, ASSETCHAINS_ALGORITHMS[ASSETCHAINS_ALGO]);
|
||||
while (true)
|
||||
{
|
||||
miningTimer.stop();
|
||||
@@ -847,13 +852,19 @@ void static VerusStaker(CWallet *pwallet)
|
||||
Mining_start = (uint32_t)time(NULL);
|
||||
}
|
||||
|
||||
// Check for stop or if block needs to be rebuilt
|
||||
boost::this_thread::interruption_point();
|
||||
|
||||
// try to stake a block
|
||||
CBlockTemplate *ptr = CreateNewBlockWithKey(reservekey, true);
|
||||
CBlockTemplate *ptr = NULL;
|
||||
if (Mining_height > VERUS_MIN_STAKEAGE)
|
||||
ptr = CreateNewBlockWithKey(reservekey, true);
|
||||
|
||||
if ( ptr == 0 )
|
||||
{
|
||||
// wait to try another staking block
|
||||
sleep(5);
|
||||
// wait to try another staking block until after the tip moves again
|
||||
while ( chainActive.Tip() == pindexPrev )
|
||||
sleep(5);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -861,44 +872,43 @@ void static VerusStaker(CWallet *pwallet)
|
||||
if (!pblocktemplate.get())
|
||||
{
|
||||
if (GetArg("-mineraddress", "").empty()) {
|
||||
LogPrintf("Error in %s miner: Keypool ran out, please call keypoolrefill before restarting the mining thread\n",
|
||||
LogPrintf("Error in %s staker: Keypool ran out, please call keypoolrefill before restarting the mining thread\n",
|
||||
ASSETCHAINS_ALGORITHMS[ASSETCHAINS_ALGO]);
|
||||
} else {
|
||||
// Should never reach here, because -mineraddress validity is checked in init.cpp
|
||||
LogPrintf("Error in %s miner: Invalid %s -mineraddress\n", ASSETCHAINS_ALGORITHMS[ASSETCHAINS_ALGO], ASSETCHAINS_SYMBOL);
|
||||
LogPrintf("Error in %s staker: Invalid %s -mineraddress\n", ASSETCHAINS_ALGORITHMS[ASSETCHAINS_ALGO], ASSETCHAINS_SYMBOL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
CBlock *pblock = &pblocktemplate->block;
|
||||
if ( ASSETCHAINS_SYMBOL[0] != 0 )
|
||||
{
|
||||
if ( ASSETCHAINS_REWARD[0] == 0 && !ASSETCHAINS_LASTERA )
|
||||
{
|
||||
if ( pblock->vtx.size() == 1 && pblock->vtx[0].vout.size() == 1 && Mining_height > ASSETCHAINS_MINHEIGHT )
|
||||
{
|
||||
static uint32_t counter;
|
||||
if ( counter++ < 10 )
|
||||
fprintf(stderr,"skip generating %s on-demand block, no tx avail\n",ASSETCHAINS_SYMBOL);
|
||||
sleep(10);
|
||||
continue;
|
||||
} else fprintf(stderr,"%s vouts.%d mining.%d vs %d\n",ASSETCHAINS_SYMBOL,(int32_t)pblock->vtx[0].vout.size(),Mining_height,ASSETCHAINS_MINHEIGHT);
|
||||
}
|
||||
}
|
||||
IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);
|
||||
LogPrintf("Running %s miner with %u transactions in block (%u bytes)\n",ASSETCHAINS_ALGORITHMS[ASSETCHAINS_ALGO],
|
||||
pblock->vtx.size(),::GetSerializeSize(*pblock,SER_NETWORK,PROTOCOL_VERSION));
|
||||
LogPrintf("Staking with %u transactions in block (%u bytes)\n", pblock->vtx.size(),::GetSerializeSize(*pblock,SER_NETWORK,PROTOCOL_VERSION));
|
||||
//
|
||||
// Search
|
||||
//
|
||||
uint32_t savebits; int64_t nStart = GetTime();
|
||||
int64_t nStart = GetTime();
|
||||
|
||||
// we don't use this, but IncrementExtraNonce is the function that builds the merkle tree
|
||||
unsigned int nExtraNonce = 0;
|
||||
IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);
|
||||
|
||||
pblock->nSolution = solnPlaceholder;
|
||||
savebits = pblock->nBits;
|
||||
arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits);
|
||||
arith_uint256 mask(ASSETCHAINS_NONCEMASK[ASSETCHAINS_ALGO]);
|
||||
|
||||
Mining_start = 0;
|
||||
if (vNodes.empty() && chainparams.MiningRequiresPeers())
|
||||
{
|
||||
if ( Mining_height > ASSETCHAINS_MINHEIGHT )
|
||||
{
|
||||
fprintf(stderr,"no nodes, attempting reconnect\n");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 60)
|
||||
{
|
||||
fprintf(stderr,"timeout, retrying\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( pindexPrev != chainActive.Tip() )
|
||||
{
|
||||
@@ -907,91 +917,37 @@ void static VerusStaker(CWallet *pwallet)
|
||||
continue;
|
||||
}
|
||||
|
||||
int32_t percPoS,z;
|
||||
SetThreadPriority(THREAD_PRIORITY_NORMAL);
|
||||
|
||||
while (true)
|
||||
{
|
||||
// for speed check multiples at a time
|
||||
for (int i = 0; i < ASSETCHAINS_HASHESPERROUND[ASSETCHAINS_ALGO]; i++)
|
||||
{
|
||||
solutionTargetChecks.increment();
|
||||
int32_t unlockTime = komodo_block_unlocktime(Mining_height);
|
||||
int64_t subsidy = (int64_t)(pblock->vtx[0].vout[0].nValue);
|
||||
|
||||
// Update nNonce and nTime
|
||||
pblock->nNonce = ArithToUint256(UintToArith256(pblock->nNonce) + 1);
|
||||
uint256 hashTarget = ArithToUint256(arith_uint256().SetCompact(pblock->nBits));
|
||||
|
||||
if ( UintToArith256(pblock->GetHash()) <= hashTarget )
|
||||
{
|
||||
SetThreadPriority(THREAD_PRIORITY_NORMAL);
|
||||
LogPrintf("Using %s algorithm:\n", ASSETCHAINS_ALGORITHMS[ASSETCHAINS_ALGO]);
|
||||
LogPrintf("Staked block found \n hash: %s \ntarget: %s\n", pblock->GetHash().GetHex(), hashTarget.GetHex());
|
||||
printf("Found block %d \n", Mining_height );
|
||||
printf("staking reward %.8f %s!\n", (double)subsidy / (double)COIN, ASSETCHAINS_SYMBOL);
|
||||
printf(" hash: %s \ntarget: %s\n", pblock->GetHash().GetHex().c_str(), hashTarget.GetHex().c_str());
|
||||
if (unlockTime > Mining_height && subsidy >= ASSETCHAINS_TIMELOCKGTE)
|
||||
printf("- timelocked until block %i\n", unlockTime);
|
||||
else
|
||||
printf("\n");
|
||||
|
||||
int32_t unlockTime = komodo_block_unlocktime(Mining_height);
|
||||
int64_t subsidy = (int64_t)(pblock->vtx[0].vout[0].nValue);
|
||||
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, chainparams.GetConsensus());
|
||||
|
||||
LogPrintf("Using %s algorithm:\n", ASSETCHAINS_ALGORITHMS[ASSETCHAINS_ALGO]);
|
||||
LogPrintf("Staked block found \n hash: %s \ntarget: %s\n", pblock->GetHash().GetHex(), hashTarget.GetHex());
|
||||
printf("Found block %d \n", Mining_height );
|
||||
printf("mining reward %.8f %s!\n", (double)subsidy / (double)COIN, ASSETCHAINS_SYMBOL);
|
||||
printf(" hash: %s \ntarget: %s\n", pblock->GetHash().GetHex().c_str(), hashTarget.GetHex().c_str());
|
||||
if (unlockTime > Mining_height && subsidy >= ASSETCHAINS_TIMELOCKGTE)
|
||||
printf("- timelocked until block %i\n", unlockTime);
|
||||
else
|
||||
printf("\n");
|
||||
UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev);
|
||||
|
||||
ProcessBlockFound(pblock, *pwallet, reservekey);
|
||||
ProcessBlockFound(pblock, *pwallet, reservekey);
|
||||
|
||||
SetThreadPriority(THREAD_PRIORITY_LOWEST);
|
||||
sleep(3);
|
||||
// Check for stop or if block needs to be rebuilt
|
||||
boost::this_thread::interruption_point();
|
||||
SetThreadPriority(THREAD_PRIORITY_LOWEST);
|
||||
|
||||
// In regression test mode, stop mining after a block is found.
|
||||
if (chainparams.MineBlocksOnDemand()) {
|
||||
throw boost::thread_interrupted();
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((UintToArith256(pblock->nNonce) & mask) == mask)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for stop or if block needs to be rebuilt
|
||||
boost::this_thread::interruption_point();
|
||||
|
||||
if (vNodes.empty() && chainparams.MiningRequiresPeers())
|
||||
{
|
||||
if ( Mining_height > ASSETCHAINS_MINHEIGHT )
|
||||
{
|
||||
fprintf(stderr,"no nodes, attempting reconnect\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((UintToArith256(pblock->nNonce) & mask) == mask)
|
||||
{
|
||||
fprintf(stderr,"%lu mega hashes complete - working\n", (ASSETCHAINS_NONCEMASK[ASSETCHAINS_ALGO] + 1) / 1048576);
|
||||
break;
|
||||
}
|
||||
|
||||
if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 60)
|
||||
{
|
||||
fprintf(stderr,"timeout, retrying\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if ( pindexPrev != chainActive.Tip() )
|
||||
{
|
||||
printf("Block %d added to chain\n", chainActive.Tip()->nHeight);
|
||||
break;
|
||||
}
|
||||
|
||||
pblock->nBits = savebits;
|
||||
UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev);
|
||||
if (chainparams.GetConsensus().fPowAllowMinDifficultyBlocks)
|
||||
{
|
||||
// Changing pblock->nTime can change work required on testnet:
|
||||
hashTarget.SetCompact(pblock->nBits);
|
||||
}
|
||||
// In regression test mode, stop mining after a block is found.
|
||||
if (chainparams.MineBlocksOnDemand()) {
|
||||
throw boost::thread_interrupted();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1040,12 +996,13 @@ void static BitcoinMiner_noeq()
|
||||
// try a nice clean peer connection to start
|
||||
waitForPeers(chainparams);
|
||||
sleep(5);
|
||||
CBlockIndex* curTip;
|
||||
CBlockIndex *curTip = chainActive.Tip(), *lastTip;
|
||||
do {
|
||||
lastTip = curTip;
|
||||
printf("Verifying block height %d \n", lastTip->nHeight);
|
||||
MilliSleep(3000 + rand() % 1900);
|
||||
curTip = chainActive.Tip();
|
||||
printf("Verifying block height %d \n", chainActive.Tip()->nHeight);
|
||||
MilliSleep(2000 + rand() % 1900);
|
||||
} while (curTip != chainActive.Tip());
|
||||
} while (curTip != lastTip);
|
||||
|
||||
SetThreadPriority(THREAD_PRIORITY_LOWEST);
|
||||
|
||||
|
||||
@@ -96,8 +96,8 @@ public:
|
||||
|
||||
for (const unsigned char *p = nNonce.begin() + 3; p >= nNonce.begin(); p--)
|
||||
{
|
||||
nBits += *p;
|
||||
nBits <<= 8;
|
||||
nBits += *p;
|
||||
}
|
||||
return nBits;
|
||||
}
|
||||
@@ -122,6 +122,7 @@ public:
|
||||
|
||||
tmpNonce = ((arNonce << 128) >> 128);
|
||||
hashWriter << ArithToUint256(tmpNonce);
|
||||
|
||||
nNonce = ArithToUint256(UintToArith256(hashWriter.GetHash()) << 128 | tmpNonce);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "script/script.h"
|
||||
#include "serialize.h"
|
||||
#include "uint256.h"
|
||||
#include "arith_uint256.h"
|
||||
#include "consensus/consensus.h"
|
||||
#include "hash.h"
|
||||
|
||||
@@ -489,9 +490,9 @@ public:
|
||||
{
|
||||
uint256 txid = GetHash();
|
||||
if (voutNum >= vout.size())
|
||||
return uint256();
|
||||
return uint256S("ff0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f");
|
||||
|
||||
return _GetVerusPOSHash(txid, voutNum, height, pastHash, (uint64_t)vout[voutNum].nValue);
|
||||
return ArithToUint256(UintToArith256(_GetVerusPOSHash(txid, voutNum, height, pastHash, (uint64_t)vout[voutNum].nValue)) / vout[voutNum].nValue);
|
||||
}
|
||||
|
||||
std::string ToString() const;
|
||||
|
||||
@@ -4663,5 +4663,5 @@ int32_t komodo_staked(CPubKey &pubkey, CMutableTransaction &txNew,uint32_t nBits
|
||||
|
||||
int32_t verus_staked(CPubKey &pubkey, CMutableTransaction &txNew, uint32_t &nBits, arith_uint256 &hashResult, uint8_t *utxosig)
|
||||
{
|
||||
return pwalletMain->VerusStakeTransaction(pubkey, txNew, nBits, hashResult, utxosig);
|
||||
return pwalletMain->VerusStakeTransaction(txNew, nBits, hashResult, utxosig);
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "zcash/Note.hpp"
|
||||
#include "crypter.h"
|
||||
#include "coins.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
@@ -43,6 +44,7 @@ bool fPayAtLeastCustomFee = true;
|
||||
|
||||
extern int32_t KOMODO_EXCHANGEWALLET;
|
||||
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
|
||||
extern int32_t VERUS_MIN_STAKEAGE;
|
||||
CBlockIndex *komodo_chainactive(int32_t height);
|
||||
|
||||
/**
|
||||
@@ -1002,6 +1004,8 @@ bool CWallet::VerusSelectStakeOutput(arith_uint256 &hashResult, CTransaction &st
|
||||
vector<COutput> vecOutputs;
|
||||
COutput *pwinner = NULL;
|
||||
CBlockIndex *pastBlockIndex;
|
||||
txnouttype whichType;
|
||||
std:vector<std::vector<unsigned char>> vSolutions;
|
||||
|
||||
pwalletMain->AvailableCoins(vecOutputs, true, NULL, false, false);
|
||||
|
||||
@@ -1011,11 +1015,11 @@ bool CWallet::VerusSelectStakeOutput(arith_uint256 &hashResult, CTransaction &st
|
||||
|
||||
BOOST_FOREACH(COutput &txout, vecOutputs)
|
||||
{
|
||||
if ((curHash = UintToArith256(txout.tx->GetVerusPOSHash(txout.i, nHeight, pastHash)) / txout.tx->vout[txout.i].nValue) <= target &&
|
||||
txout.fSpendable)
|
||||
if (txout.fSpendable && (UintToArith256(txout.tx->GetVerusPOSHash(txout.i, nHeight, pastHash)) <= target) && (txout.nDepth >= VERUS_MIN_STAKEAGE))
|
||||
{
|
||||
// get the smallest winner
|
||||
if (!pwinner || pwinner->tx->vout[pwinner->i].nValue > txout.tx->vout[txout.i].nValue)
|
||||
if (Solver(txout.tx->vout[txout.i].scriptPubKey, whichType, vSolutions) && (whichType == TX_PUBKEY || whichType == TX_PUBKEYHASH) &&
|
||||
(!pwinner || pwinner->tx->vout[pwinner->i].nValue > txout.tx->vout[txout.i].nValue))
|
||||
pwinner = &txout;
|
||||
}
|
||||
}
|
||||
@@ -1029,18 +1033,21 @@ bool CWallet::VerusSelectStakeOutput(arith_uint256 &hashResult, CTransaction &st
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t CWallet::VerusStakeTransaction(CPubKey &pubkey, CMutableTransaction &txNew, uint32_t &bnTarget, arith_uint256 &hashResult, uint8_t *utxosig) const
|
||||
int32_t CWallet::VerusStakeTransaction(CMutableTransaction &txNew, uint32_t &bnTarget, arith_uint256 &hashResult, uint8_t *utxosig) const
|
||||
{
|
||||
arith_uint256 target;
|
||||
CTransaction stakeSource;
|
||||
int32_t voutNum, siglen = 0;
|
||||
int64_t nValue;
|
||||
txnouttype whichType;
|
||||
std::vector<std::vector<unsigned char>> vSolutions;
|
||||
|
||||
CBlockIndex *tipindex = chainActive.Tip();
|
||||
bnTarget = lwmaGetNextPOSRequired(tipindex, Params().GetConsensus());
|
||||
target.SetCompact(bnTarget);
|
||||
|
||||
if (!VerusSelectStakeOutput(hashResult, stakeSource, voutNum, tipindex->nHeight, target))
|
||||
if (!VerusSelectStakeOutput(hashResult, stakeSource, voutNum, tipindex->nHeight + 1, target) ||
|
||||
!Solver(stakeSource.vout[voutNum].scriptPubKey, whichType, vSolutions))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -1058,20 +1065,16 @@ int32_t CWallet::VerusStakeTransaction(CPubKey &pubkey, CMutableTransaction &txN
|
||||
txNew.vin[0].prevout.hash = stakeSource.GetHash();
|
||||
txNew.vin[0].prevout.n = voutNum;
|
||||
|
||||
/*
|
||||
uint8_t *script;
|
||||
int32_t i;
|
||||
uint8_t *ptr;
|
||||
|
||||
txNew.vout[0].scriptPubKey.resize(35);
|
||||
ptr = (uint8_t *)pubkey.begin();
|
||||
script = (uint8_t *)(txNew.vout[0].scriptPubKey.data());
|
||||
script[0] = 33;
|
||||
for (i=0; i<33; i++)
|
||||
script[i+1] = ptr[i];
|
||||
script[34] = OP_CHECKSIG;
|
||||
*/
|
||||
txNew.vout[0].scriptPubKey << ToByteVector(pubkey) << OP_CHECKSIG;
|
||||
if (whichType == TX_PUBKEY)
|
||||
{
|
||||
txNew.vout[0].scriptPubKey << ToByteVector(vSolutions[0]) << OP_CHECKSIG;
|
||||
}
|
||||
else if (whichType == TX_PUBKEYHASH)
|
||||
{
|
||||
txNew.vout[0].scriptPubKey << OP_DUP << OP_HASH160 << ToByteVector(vSolutions[0]) << OP_EQUALVERIFY << OP_CHECKSIG;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
|
||||
nValue = txNew.vout[0].nValue = voutNum - txfee;
|
||||
txNew.nLockTime = 0;
|
||||
|
||||
@@ -1150,7 +1150,7 @@ public:
|
||||
|
||||
// staking functions
|
||||
bool VerusSelectStakeOutput(arith_uint256 &hashResult, CTransaction &stakeSource, int32_t &voutNum, int32_t nHeight, const arith_uint256 &target) const;
|
||||
int32_t VerusStakeTransaction(CPubKey &pubkey, CMutableTransaction &txNew, uint32_t &bnTarget, arith_uint256 &hashResult, uint8_t *utxosig) const;
|
||||
int32_t VerusStakeTransaction(CMutableTransaction &txNew, uint32_t &bnTarget, arith_uint256 &hashResult, uint8_t *utxosig) const;
|
||||
};
|
||||
|
||||
/** A key allocated from the key pool. */
|
||||
|
||||
Reference in New Issue
Block a user