Merge pull request #27 from StakedChain/streamer_recv
merge streamer branch into copy of master to check conflicts
This commit is contained in:
@@ -169,7 +169,7 @@ try_again:
|
||||
curl_handle = curl_easy_init();
|
||||
init_string(&s);
|
||||
headers = curl_slist_append(0,"Expect:");
|
||||
|
||||
|
||||
curl_easy_setopt(curl_handle,CURLOPT_USERAGENT,"mozilla/4.0");//"Mozilla/4.0 (compatible; )");
|
||||
curl_easy_setopt(curl_handle,CURLOPT_HTTPHEADER, headers);
|
||||
curl_easy_setopt(curl_handle,CURLOPT_URL, url);
|
||||
@@ -198,7 +198,7 @@ try_again:
|
||||
bracket0 = (char *)"[";
|
||||
bracket1 = (char *)"]";
|
||||
}
|
||||
|
||||
|
||||
databuf = (char *)malloc(256 + strlen(command) + strlen(params));
|
||||
sprintf(databuf,"{\"id\":\"jl777\",\"method\":\"%s\",\"params\":%s%s%s}",command,bracket0,params,bracket1);
|
||||
//printf("url.(%s) userpass.(%s) databuf.(%s)\n",url,userpass,databuf);
|
||||
@@ -238,7 +238,7 @@ try_again:
|
||||
free(s.ptr);
|
||||
sleep((1<<numretries));
|
||||
goto try_again;
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -524,7 +524,7 @@ int32_t komodo_verifynotarization(char *symbol,char *dest,int32_t height,int32_t
|
||||
}
|
||||
return(hash);
|
||||
}
|
||||
|
||||
|
||||
uint256 _komodo_getblockhash(int32_t height);*/
|
||||
|
||||
uint64_t komodo_seed(int32_t height)
|
||||
@@ -1099,31 +1099,39 @@ int32_t komodo_validate_interest(const CTransaction &tx,int32_t txheight,uint32_
|
||||
|
||||
/*
|
||||
komodo_checkPOW (fast) is called early in the process and should only refer to data immediately available. it is a filter to prevent bad blocks from going into the local DB. The more blocks we can filter out at this stage, the less junk in the local DB that will just get purged later on.
|
||||
|
||||
|
||||
komodo_checkPOW (slow) is called right before connecting blocks so all prior blocks can be assumed to be there and all checks must pass
|
||||
|
||||
|
||||
commission must be in coinbase.vout[1] and must be >= 10000 sats
|
||||
PoS stake must be without txfee and in the last tx in the block at vout[0]
|
||||
*/
|
||||
extern int32_t ASSETCHAINS_STREAM;
|
||||
|
||||
uint64_t komodo_commission(const CBlock *pblock)
|
||||
{
|
||||
int32_t i,j,n=0,txn_count; uint64_t commission,total = 0;
|
||||
txn_count = pblock->vtx.size();
|
||||
for (i=0; i<txn_count; i++)
|
||||
if ( ASSETCHAINS_STREAM == 0 )
|
||||
{
|
||||
n = pblock->vtx[i].vout.size();
|
||||
for (j=0; j<n; j++)
|
||||
{
|
||||
//fprintf(stderr,"(%d %.8f).%d ",i,dstr(block.vtx[i].vout[j].nValue),j);
|
||||
if ( i != 0 || j != 1 )
|
||||
total += pblock->vtx[i].vout[j].nValue;
|
||||
}
|
||||
txn_count = pblock->vtx.size();
|
||||
for (i=0; i<txn_count; i++)
|
||||
{
|
||||
n = pblock->vtx[i].vout.size();
|
||||
for (j=0; j<n; j++)
|
||||
{
|
||||
//fprintf(stderr,"(%d %.8f).%d ",i,dstr(block.vtx[i].vout[j].nValue),j);
|
||||
if ( i != 0 || j != 1 )
|
||||
total += pblock->vtx[i].vout[j].nValue;
|
||||
}
|
||||
}
|
||||
//fprintf(stderr,"txn.%d n.%d commission total %.8f -> %.8f\n",txn_count,n,dstr(total),dstr((total * ASSETCHAINS_COMMISSION) / COIN));
|
||||
commission = ((total * ASSETCHAINS_COMMISSION) / COIN);
|
||||
if ( commission < 10000 )
|
||||
commission = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
commission = 10000;
|
||||
}
|
||||
//fprintf(stderr,"txn.%d n.%d commission total %.8f -> %.8f\n",txn_count,n,dstr(total),dstr((total * ASSETCHAINS_COMMISSION) / COIN));
|
||||
commission = ((total * ASSETCHAINS_COMMISSION) / COIN);
|
||||
if ( commission < 10000 )
|
||||
commission = 0;
|
||||
return(commission);
|
||||
}
|
||||
|
||||
@@ -1464,7 +1472,7 @@ int32_t komodo_is_PoSblock(int32_t slowflag,int32_t height,CBlock *pblock,arith_
|
||||
int64_t komodo_checkcommission(CBlock *pblock,int32_t height)
|
||||
{
|
||||
int64_t checktoshis=0; uint8_t *script;
|
||||
if ( ASSETCHAINS_COMMISSION != 0 )
|
||||
if ( ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_STREAM != 0)
|
||||
{
|
||||
checktoshis = komodo_commission(pblock);
|
||||
if ( checktoshis > 10000 && pblock->vtx[0].vout.size() != 2 )
|
||||
@@ -1570,14 +1578,33 @@ int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height)
|
||||
if ( height == 1 )
|
||||
{
|
||||
script = (uint8_t *)pblock->vtx[0].vout[0].scriptPubKey.data();
|
||||
if ( script[0] != 33 || script[34] != OP_CHECKSIG || memcmp(script+1,ASSETCHAINS_OVERRIDE_PUBKEY33,33) != 0 )
|
||||
if ( script[0] != 33 || script[34] != OP_CHECKSIG || memcmp(script+1,ASSETCHAINS_OVERRIDE_PUBKEY33,33) != 0 ) {
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( komodo_checkcommission(pblock,height) < 0 )
|
||||
return(-1);
|
||||
}
|
||||
if ( ASSETCHAINS_STREAM != 0 && height > 128 )
|
||||
{
|
||||
int lasttx = ( pblock->vtx.size() -1 );
|
||||
printf("ABOUT TO CHECK LAST TX: %d\n",lasttx);
|
||||
if ( lasttx == 0 )
|
||||
return(-1);
|
||||
uint256 hash; CTransaction tx;
|
||||
if (GetTransaction(pblock->vtx[lasttx].vin[0].prevout.hash,tx,hash,false))
|
||||
{
|
||||
printf("CHECKING THE script pubkey\n");
|
||||
script = (uint8_t *)tx.vout[pblock->vtx[lasttx].vin[0].prevout.n].scriptPubKey.data();
|
||||
if ( script[0] != 33 || script[34] != OP_CHECKSIG || memcmp(script+1,ASSETCHAINS_OVERRIDE_PUBKEY33,33) != 0 ) {
|
||||
printf("THE PUBKEY IS WRONG!\n");
|
||||
return(-1);
|
||||
}
|
||||
printf("THE PUBKEY IS RIGHT! \n");
|
||||
}
|
||||
}
|
||||
}
|
||||
//fprintf(stderr,"komodo_checkPOW possible.%d slowflag.%d ht.%d notaryid.%d failed.%d\n",possible,slowflag,height,notaryid,failed);
|
||||
if ( failed != 0 && possible == 0 && notaryid < 0 )
|
||||
|
||||
@@ -90,7 +90,7 @@ struct pax_transaction *komodo_paxmark(int32_t height,uint256 txid,uint16_t vout
|
||||
pax->marked = mark;
|
||||
//if ( height > 214700 || pax->height > 214700 )
|
||||
// printf("mark ht.%d %.8f %.8f\n",pax->height,dstr(pax->komodoshis),dstr(pax->fiatoshis));
|
||||
|
||||
|
||||
}
|
||||
pthread_mutex_unlock(&komodo_mutex);
|
||||
return(pax);
|
||||
@@ -203,9 +203,9 @@ int32_t komodo_issued_opreturn(char *base,uint256 *txids,uint16_t *vouts,int64_t
|
||||
// return(0);
|
||||
incr = 34 + (iskomodo * (2*sizeof(fiatoshis) + 2*sizeof(height) + 20 + 4));
|
||||
//41e77b91cb68dc2aa02fa88550eae6b6d44db676a7e935337b6d1392d9718f03cb0200305c90660400000000fbcbeb1f000000bde801006201000058e7945ad08ddba1eac9c9b6c8e1e97e8016a2d152
|
||||
|
||||
|
||||
// 41e94d736ec69d88c08b5d238abeeca609c02357a8317e0d56c328bcb1c259be5d0200485bc80200000000404b4c000000000059470200b80b000061f22ba7d19fe29ac3baebd839af8b7127d1f9075553440046bb4cc7a3b5cd39dffe7206507a3482a00780e617f68b273cce9817ed69298d02001069ca1b0000000080f0fa02000000005b470200b90b000061f22ba7d19fe29ac3baebd839af8b7127d1f90755
|
||||
|
||||
|
||||
//for (i=0; i<opretlen; i++)
|
||||
// printf("%02x",opretbuf[i]);
|
||||
//printf(" opretlen.%d (%s)\n",opretlen,base);
|
||||
@@ -744,7 +744,7 @@ int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtim
|
||||
else
|
||||
{
|
||||
checktoshis = 0;
|
||||
if ( ASSETCHAINS_COMMISSION != 0 && height > 1 )
|
||||
if ( (ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_STREAM != 0) && height > 1 )
|
||||
{
|
||||
if ( (checktoshis= komodo_checkcommission((CBlock *)&block,height)) < 0 )
|
||||
{
|
||||
@@ -772,7 +772,7 @@ int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtim
|
||||
|
||||
const char *komodo_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int32_t opretlen,uint256 txid,uint16_t vout,char *source)
|
||||
{
|
||||
uint8_t rmd160[20],rmd160s[64*20],addrtype,shortflag,pubkey33[33]; int32_t didstats,i,j,n,kvheight,len,tokomodo,kmdheight,otherheights[64],kmdheights[64]; int8_t baseids[64]; char base[4],coinaddr[64],destaddr[64]; uint256 txids[64]; uint16_t vouts[64]; uint64_t convtoshis,seed; int64_t fee,fiatoshis,komodoshis,checktoshis,values[64],srcvalues[64]; struct pax_transaction *pax,*pax2; struct komodo_state *basesp; double diff;
|
||||
uint8_t rmd160[20],rmd160s[64*20],addrtype,shortflag,pubkey33[33]; int32_t didstats,i,j,n,kvheight,len,tokomodo,kmdheight,otherheights[64],kmdheights[64]; int8_t baseids[64]; char base[4],coinaddr[64],destaddr[64]; uint256 txids[64]; uint16_t vouts[64]; uint64_t convtoshis,seed; int64_t fee,fiatoshis,komodoshis,checktoshis,values[64],srcvalues[64]; struct pax_transaction *pax,*pax2; struct komodo_state *basesp; double diff;
|
||||
const char *typestr = "unknown";
|
||||
if ( ASSETCHAINS_SYMBOL[0] != 0 && komodo_baseid(ASSETCHAINS_SYMBOL) < 0 && opretbuf[0] != 'K' )
|
||||
{
|
||||
@@ -1185,7 +1185,7 @@ void komodo_stateind_set(struct komodo_state *sp,uint32_t *inds,int32_t n,uint8_
|
||||
printf("numR.%d numV.%d numN.%d count.%d\n",numR,numV,numN,count);
|
||||
/*else if ( func == 'K' ) // KMD height: stop after 1st
|
||||
else if ( func == 'T' ) // KMD height+timestamp: stop after 1st
|
||||
|
||||
|
||||
else if ( func == 'N' ) // notarization, scan backwards 1440+ blocks;
|
||||
else if ( func == 'V' ) // price feed: can stop after 1440+
|
||||
else if ( func == 'R' ) // opreturn:*/
|
||||
@@ -1518,4 +1518,3 @@ void komodo_passport_iteration()
|
||||
printf("READY for %s RPC calls at %u! done PASSPORT %s refid.%d\n",ASSETCHAINS_SYMBOL,(uint32_t)time(NULL),ASSETCHAINS_SYMBOL,refid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ struct komodo_state KOMODO_STATES[34];
|
||||
#define _COINBASE_MATURITY 100
|
||||
int COINBASE_MATURITY = _COINBASE_MATURITY;//100;
|
||||
|
||||
int32_t KOMODO_MININGTHREADS = -1,IS_KOMODO_NOTARY,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,ASSETCHAINS_SEED,KOMODO_ON_DEMAND,KOMODO_EXTERNAL_NOTARIES,KOMODO_PASSPORT_INITDONE,KOMODO_PAX,KOMODO_EXCHANGEWALLET,KOMODO_REWIND,KOMODO_CONNECTING = -1;
|
||||
int32_t KOMODO_MININGTHREADS = -1,IS_KOMODO_NOTARY,ASSETCHAINS_STREAM,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,ASSETCHAINS_SEED,KOMODO_ON_DEMAND,KOMODO_EXTERNAL_NOTARIES,KOMODO_PASSPORT_INITDONE,KOMODO_PAX,KOMODO_EXCHANGEWALLET,KOMODO_REWIND,KOMODO_CONNECTING = -1;
|
||||
int32_t KOMODO_INSYNC,KOMODO_LASTMINED,prevKOMODO_LASTMINED,KOMODO_CCACTIVATE,JUMBLR_PAUSE = 1;
|
||||
std::string NOTARY_PUBKEY,ASSETCHAINS_NOTARIES,ASSETCHAINS_OVERRIDE_PUBKEY,DONATION_PUBKEY;
|
||||
uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33],ASSETCHAINS_PUBLIC,ASSETCHAINS_PRIVATE;
|
||||
|
||||
@@ -1561,6 +1561,11 @@ void komodo_args(char *argv0)
|
||||
ASSETCHAINS_DECAY = GetArg("-ac_decay",0);
|
||||
ASSETCHAINS_COMMISSION = GetArg("-ac_perc",0);
|
||||
ASSETCHAINS_OVERRIDE_PUBKEY = GetArg("-ac_pubkey","");
|
||||
ASSETCHAINS_STREAM = GetArg("-ac_stream",0);
|
||||
if ( ASSETCHAINS_STREAM != 0 && ( ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_ENDSUBSIDY != 0 || ASSETCHAINS_REWARD != 0 || ASSETCHAINS_HALVING != 0 || ASSETCHAINS_DECAY != 0 || ASSETCHAINS_PRIVATE != 0 )) {
|
||||
printf("ASSETCHAINS_STREAM cannot be used with:\n ASSETCHAINS_COMMISSION \n ASSETCHAINS_ENDSUBSIDY\n ASSETCHAINS_REWARD\n ASSETCHAINS_HALVING\n ASSETCHAINS_DECAY\n ASSETCHAINS_PRIVATE\n");
|
||||
exit(0);
|
||||
}
|
||||
if ( (ASSETCHAINS_STAKED= GetArg("-ac_staked",0)) > 100 )
|
||||
ASSETCHAINS_STAKED = 100;
|
||||
if ( ASSETCHAINS_STAKED != 0 && ASSETCHAINS_PRIVATE != 0 )
|
||||
@@ -1589,8 +1594,15 @@ void komodo_args(char *argv0)
|
||||
{
|
||||
ASSETCHAINS_COMMISSION = 0;
|
||||
printf("ASSETCHAINS_COMMISSION needs an ASETCHAINS_OVERRIDE_PUBKEY and cant be more than 100000000 (100%%)\n");
|
||||
}
|
||||
if ( ASSETCHAINS_ENDSUBSIDY != 0 || ASSETCHAINS_REWARD != 0 || ASSETCHAINS_HALVING != 0 || ASSETCHAINS_DECAY != 0 || ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_PUBLIC != 0 || ASSETCHAINS_PRIVATE != 0 )
|
||||
} else if ( ASSETCHAINS_STREAM != 0) {
|
||||
ASSETCHAINS_STREAM = 0;
|
||||
printf("ASSETCHAINS_STREAM needs ASSETCHAINS_OVERRIDE_PUBKEY! This parameter has been ignored! \n");
|
||||
}
|
||||
if ( ASSETCHAINS_STREAM != 0 && ASSETCHAINS_SUPPLY == 10 ) {
|
||||
ASSETCHAINS_SUPPLY = 1000000;
|
||||
printf("ASSETCHAINS_STREAM is set with no supply, setting supply at 1,000,000 coins. \n");
|
||||
}
|
||||
if ( ASSETCHAINS_ENDSUBSIDY != 0 || ASSETCHAINS_REWARD != 0 || ASSETCHAINS_HALVING != 0 || ASSETCHAINS_DECAY != 0 || ASSETCHAINS_STREAM != 0 || ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_PUBLIC != 0 || ASSETCHAINS_PRIVATE != 0 )
|
||||
{
|
||||
fprintf(stderr,"end.%llu blocks, reward %.8f halving.%llu blocks, decay.%llu perc %.4f%% ac_pub=[%02x...]\n",(long long)ASSETCHAINS_ENDSUBSIDY,dstr(ASSETCHAINS_REWARD),(long long)ASSETCHAINS_HALVING,(long long)ASSETCHAINS_DECAY,dstr(ASSETCHAINS_COMMISSION)*100,ASSETCHAINS_OVERRIDE_PUBKEY33[0]);
|
||||
extraptr = extrabuf;
|
||||
|
||||
25
src/main.cpp
25
src/main.cpp
@@ -1866,6 +1866,7 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex,bool checkPOW)
|
||||
//uint64_t komodo_moneysupply(int32_t height);
|
||||
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
|
||||
extern uint32_t ASSETCHAINS_MAGIC;
|
||||
extern int32_t ASSETCHAINS_STREAM;
|
||||
extern uint64_t ASSETCHAINS_STAKED,ASSETCHAINS_ENDSUBSIDY,ASSETCHAINS_REWARD,ASSETCHAINS_HALVING,ASSETCHAINS_LINEAR,ASSETCHAINS_COMMISSION,ASSETCHAINS_SUPPLY;
|
||||
extern uint8_t ASSETCHAINS_PUBLIC,ASSETCHAINS_PRIVATE;
|
||||
|
||||
@@ -1894,8 +1895,13 @@ CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams)
|
||||
else if ( ASSETCHAINS_ENDSUBSIDY == 0 || nHeight < ASSETCHAINS_ENDSUBSIDY )
|
||||
{
|
||||
if ( ASSETCHAINS_REWARD == 0 )
|
||||
return(10000);
|
||||
else if ( ASSETCHAINS_ENDSUBSIDY != 0 && nHeight >= ASSETCHAINS_ENDSUBSIDY )
|
||||
{
|
||||
if ( ASSETCHAINS_STREAM != 0 && nHeight > 128 )
|
||||
return(0);
|
||||
else
|
||||
return(10000);
|
||||
}
|
||||
else if ( ASSETCHAINS_ENDSUBSIDY != 0 && nHeight >= ASSETCHAINS_ENDSUBSIDY )
|
||||
return(0);
|
||||
else
|
||||
{
|
||||
@@ -2961,6 +2967,19 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
||||
if (!view.HaveJoinSplitRequirements(tx))
|
||||
return state.DoS(100, error("ConnectBlock(): JoinSplit requirements not met"),
|
||||
REJECT_INVALID, "bad-txns-joinsplit-requirements-not-met");
|
||||
|
||||
if ( ASSETCHAINS_SYMBOL[0] != 0 )
|
||||
{
|
||||
if ( ASSETCHAINS_STREAM != 0 )
|
||||
{
|
||||
if ( block.vtx.size() == 1 && block.vtx[0].vout.size() == 2 && pindex->nHeight > ASSETCHAINS_MINHEIGHT)
|
||||
{
|
||||
return state.DoS(100, error("ConnectBlock(): There are no TX in this block, it is invalid!"),
|
||||
REJECT_INVALID, "bad-block-no-transactions");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fAddressIndex || fSpentIndex)
|
||||
{
|
||||
for (size_t j = 0; j < tx.vin.size(); j++) {
|
||||
@@ -3110,7 +3129,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
||||
LogPrint("bench", " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs]\n", (unsigned)block.vtx.size(), 0.001 * (nTime1 - nTimeStart), 0.001 * (nTime1 - nTimeStart) / block.vtx.size(), nInputs <= 1 ? 0 : 0.001 * (nTime1 - nTimeStart) / (nInputs-1), nTimeConnect * 0.000001);
|
||||
|
||||
CAmount blockReward = nFees + GetBlockSubsidy(pindex->nHeight, chainparams.GetConsensus()) + sum;
|
||||
if ( ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && ASSETCHAINS_COMMISSION != 0 )
|
||||
if ( ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && (ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_STREAM != 0) )
|
||||
{
|
||||
uint64_t checktoshis;
|
||||
if ( (checktoshis= komodo_commission((CBlock *)&block)) != 0 )
|
||||
|
||||
159
src/miner.cpp
159
src/miner.cpp
@@ -64,7 +64,7 @@ public:
|
||||
set<uint256> setDependsOn;
|
||||
CFeeRate feeRate;
|
||||
double dPriority;
|
||||
|
||||
|
||||
COrphan(const CTransaction* ptxIn) : ptx(ptxIn), feeRate(0), dPriority(0)
|
||||
{
|
||||
}
|
||||
@@ -78,10 +78,10 @@ typedef boost::tuple<double, CFeeRate, const CTransaction*> TxPriority;
|
||||
class TxPriorityCompare
|
||||
{
|
||||
bool byFee;
|
||||
|
||||
|
||||
public:
|
||||
TxPriorityCompare(bool _byFee) : byFee(_byFee) { }
|
||||
|
||||
|
||||
bool operator()(const TxPriority& a, const TxPriority& b)
|
||||
{
|
||||
if (byFee)
|
||||
@@ -106,7 +106,7 @@ void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams,
|
||||
|
||||
#include "komodo_defs.h"
|
||||
|
||||
extern int32_t KOMODO_MININGTHREADS,KOMODO_LONGESTCHAIN,ASSETCHAINS_SEED,IS_KOMODO_NOTARY,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,ASSETCHAIN_INIT,KOMODO_INITDONE,KOMODO_ON_DEMAND,KOMODO_INITDONE,KOMODO_PASSPORT_INITDONE;
|
||||
extern int32_t KOMODO_MININGTHREADS,KOMODO_LONGESTCHAIN,ASSETCHAINS_SEED,IS_KOMODO_NOTARY,ASSETCHAINS_STREAM,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,ASSETCHAIN_INIT,KOMODO_INITDONE,KOMODO_ON_DEMAND,KOMODO_INITDONE,KOMODO_PASSPORT_INITDONE;
|
||||
extern uint64_t ASSETCHAINS_REWARD,ASSETCHAINS_COMMISSION,ASSETCHAINS_STAKED;
|
||||
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
|
||||
extern std::string NOTARY_PUBKEY,ASSETCHAINS_OVERRIDE_PUBKEY;
|
||||
@@ -141,27 +141,27 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn,int32_t gpucount)
|
||||
// -blockversion=N to test forking scenarios
|
||||
if (Params().MineBlocksOnDemand())
|
||||
pblock->nVersion = GetArg("-blockversion", pblock->nVersion);
|
||||
|
||||
|
||||
// Add dummy coinbase tx as first transaction
|
||||
pblock->vtx.push_back(CTransaction());
|
||||
pblocktemplate->vTxFees.push_back(-1); // updated at end
|
||||
pblocktemplate->vTxSigOps.push_back(-1); // updated at end
|
||||
|
||||
|
||||
// Largest block you're willing to create:
|
||||
unsigned int nBlockMaxSize = GetArg("-blockmaxsize", DEFAULT_BLOCK_MAX_SIZE);
|
||||
// Limit to betweeen 1K and MAX_BLOCK_SIZE-1K for sanity:
|
||||
nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SIZE-1000), nBlockMaxSize));
|
||||
|
||||
|
||||
// How much of the block should be dedicated to high-priority transactions,
|
||||
// included regardless of the fees they pay
|
||||
unsigned int nBlockPrioritySize = GetArg("-blockprioritysize", DEFAULT_BLOCK_PRIORITY_SIZE);
|
||||
nBlockPrioritySize = std::min(nBlockMaxSize, nBlockPrioritySize);
|
||||
|
||||
|
||||
// Minimum block size you want to create; block will be filled with free transactions
|
||||
// until there are no more or the block reaches this size:
|
||||
unsigned int nBlockMinSize = GetArg("-blockminsize", DEFAULT_BLOCK_MIN_SIZE);
|
||||
nBlockMinSize = std::min(nBlockMaxSize, nBlockMinSize);
|
||||
|
||||
|
||||
// Collect memory pool transactions into the block
|
||||
CAmount nFees = 0;
|
||||
CBlockIndex* pindexPrev = 0;
|
||||
@@ -174,12 +174,12 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn,int32_t gpucount)
|
||||
const int64_t nMedianTimePast = pindexPrev->GetMedianTimePast();
|
||||
CCoinsViewCache view(pcoinsTip);
|
||||
uint32_t expired; uint64_t commission;
|
||||
|
||||
|
||||
// Priority order to process transactions
|
||||
list<COrphan> vOrphan; // list memory doesn't move
|
||||
map<uint256, vector<COrphan*> > mapDependers;
|
||||
bool fPrintPriority = GetBoolArg("-printpriority", false);
|
||||
|
||||
|
||||
// This vector will be sorted into a priority queue:
|
||||
vector<TxPriority> vecPriority;
|
||||
vecPriority.reserve(mempool.mapTx.size());
|
||||
@@ -187,11 +187,11 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn,int32_t gpucount)
|
||||
mi != mempool.mapTx.end(); ++mi)
|
||||
{
|
||||
const CTransaction& tx = mi->GetTx();
|
||||
|
||||
|
||||
int64_t nLockTimeCutoff = (STANDARD_LOCKTIME_VERIFY_FLAGS & LOCKTIME_MEDIAN_TIME_PAST)
|
||||
? nMedianTimePast
|
||||
: pblock->GetBlockTime();
|
||||
|
||||
|
||||
if (tx.IsCoinBase() || !IsFinalTx(tx, nHeight, nLockTimeCutoff) || IsExpiredTx(tx, nHeight))
|
||||
{
|
||||
//fprintf(stderr,"coinbase.%d finaltx.%d expired.%d\n",tx.IsCoinBase(),IsFinalTx(tx, nHeight, nLockTimeCutoff),IsExpiredTx(tx, nHeight));
|
||||
@@ -256,16 +256,16 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn,int32_t gpucount)
|
||||
}
|
||||
|
||||
if (fMissingInputs) continue;
|
||||
|
||||
|
||||
// Priority is sum(valuein * age) / modified_txsize
|
||||
unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
|
||||
dPriority = tx.ComputePriority(dPriority, nTxSize);
|
||||
|
||||
|
||||
uint256 hash = tx.GetHash();
|
||||
mempool.ApplyDeltas(hash, dPriority, nTotalIn);
|
||||
|
||||
|
||||
CFeeRate feeRate(nTotalIn-tx.GetValueOut(), nTxSize);
|
||||
|
||||
|
||||
if (porphan)
|
||||
{
|
||||
porphan->dPriority = dPriority;
|
||||
@@ -274,27 +274,27 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn,int32_t gpucount)
|
||||
else
|
||||
vecPriority.push_back(TxPriority(dPriority, feeRate, &(mi->GetTx())));
|
||||
}
|
||||
|
||||
|
||||
// Collect transactions into block
|
||||
uint64_t nBlockSize = 1000;
|
||||
uint64_t nBlockTx = 0;
|
||||
int64_t interest;
|
||||
int nBlockSigOps = 100;
|
||||
bool fSortedByFee = (nBlockPrioritySize <= 0);
|
||||
|
||||
|
||||
TxPriorityCompare comparer(fSortedByFee);
|
||||
std::make_heap(vecPriority.begin(), vecPriority.end(), comparer);
|
||||
|
||||
|
||||
while (!vecPriority.empty())
|
||||
{
|
||||
// Take highest priority transaction off the priority queue:
|
||||
double dPriority = vecPriority.front().get<0>();
|
||||
CFeeRate feeRate = vecPriority.front().get<1>();
|
||||
const CTransaction& tx = *(vecPriority.front().get<2>());
|
||||
|
||||
|
||||
std::pop_heap(vecPriority.begin(), vecPriority.end(), comparer);
|
||||
vecPriority.pop_back();
|
||||
|
||||
|
||||
// Size limits
|
||||
unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
|
||||
if (nBlockSize + nTxSize >= nBlockMaxSize-512) // room for extra autotx
|
||||
@@ -302,7 +302,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn,int32_t gpucount)
|
||||
//fprintf(stderr,"nBlockSize %d + %d nTxSize >= %d nBlockMaxSize\n",(int32_t)nBlockSize,(int32_t)nTxSize,(int32_t)nBlockMaxSize);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// Legacy limits on sigOps:
|
||||
unsigned int nTxSigOps = GetLegacySigOpCount(tx);
|
||||
if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS-1)
|
||||
@@ -329,14 +329,14 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn,int32_t gpucount)
|
||||
comparer = TxPriorityCompare(fSortedByFee);
|
||||
std::make_heap(vecPriority.begin(), vecPriority.end(), comparer);
|
||||
}
|
||||
|
||||
|
||||
if (!view.HaveInputs(tx))
|
||||
{
|
||||
//fprintf(stderr,"dont have inputs\n");
|
||||
continue;
|
||||
}
|
||||
CAmount nTxFees = view.GetValueIn(chainActive.LastTip()->nHeight,&interest,tx,chainActive.LastTip()->nTime)-tx.GetValueOut();
|
||||
|
||||
|
||||
nTxSigOps += GetP2SHSigOpCount(tx, view);
|
||||
if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS-1)
|
||||
{
|
||||
@@ -354,7 +354,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn,int32_t gpucount)
|
||||
continue;
|
||||
}
|
||||
UpdateCoins(tx, view, nHeight);
|
||||
|
||||
|
||||
// Added
|
||||
pblock->vtx.push_back(tx);
|
||||
pblocktemplate->vTxFees.push_back(nTxFees);
|
||||
@@ -363,12 +363,12 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn,int32_t gpucount)
|
||||
++nBlockTx;
|
||||
nBlockSigOps += nTxSigOps;
|
||||
nFees += nTxFees;
|
||||
|
||||
|
||||
if (fPrintPriority)
|
||||
{
|
||||
LogPrintf("priority %.1f fee %s txid %s\n",dPriority, feeRate.ToString(), tx.GetHash().ToString());
|
||||
}
|
||||
|
||||
|
||||
// Add transactions that depend on this one to the priority queue
|
||||
if (mapDependers.count(hash))
|
||||
{
|
||||
@@ -386,7 +386,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn,int32_t gpucount)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nLastBlockTx = nBlockTx;
|
||||
nLastBlockSize = nBlockSize;
|
||||
blocktime = 1 + std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
|
||||
@@ -411,7 +411,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn,int32_t gpucount)
|
||||
//printf("staking PoS ht.%d t%u lag.%u\n",(int32_t)chainActive.LastTip()->nHeight+1,blocktime,(uint32_t)(GetAdjustedTime() - (blocktime-13)));
|
||||
} else return(0); //fprintf(stderr,"no utxos eligible for staking\n");
|
||||
}
|
||||
|
||||
|
||||
// Create coinbase tx
|
||||
CMutableTransaction txNew = CreateNewContextualCMutableTransaction(chainparams.GetConsensus(), nHeight);
|
||||
txNew.vin.resize(1);
|
||||
@@ -426,9 +426,9 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn,int32_t gpucount)
|
||||
// Add fees
|
||||
txNew.vout[0].nValue += nFees;
|
||||
txNew.vin[0].scriptSig = CScript() << nHeight << OP_0;
|
||||
|
||||
|
||||
pblock->vtx[0] = txNew;
|
||||
if ( nHeight > 1 && ASSETCHAINS_SYMBOL[0] != 0 && ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && ASSETCHAINS_COMMISSION != 0 && (commission= komodo_commission((CBlock*)&pblocktemplate->block)) != 0 )
|
||||
if ( nHeight > 1 && ASSETCHAINS_SYMBOL[0] != 0 && ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && (ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_STREAM != 0) && (commission= komodo_commission((CBlock*)&pblocktemplate->block)) != 0 )
|
||||
{
|
||||
int32_t i; uint8_t *ptr;
|
||||
txNew.vout.resize(2);
|
||||
@@ -439,7 +439,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn,int32_t gpucount)
|
||||
for (i=0; i<33; i++)
|
||||
ptr[i+1] = ASSETCHAINS_OVERRIDE_PUBKEY33[i];
|
||||
ptr[34] = OP_CHECKSIG;
|
||||
//printf("autocreate commision vout\n");
|
||||
//printf("autocreate commission vout\n");
|
||||
pblock->vtx[0] = txNew;
|
||||
}
|
||||
pblocktemplate->vTxFees[0] = -nFees;
|
||||
@@ -449,7 +449,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn,int32_t gpucount)
|
||||
nonce <<= 32;
|
||||
nonce >>= 16;
|
||||
pblock->nNonce = ArithToUint256(nonce);
|
||||
|
||||
|
||||
// Fill in header
|
||||
pblock->hashPrevBlock = pindexPrev->GetBlockHash();
|
||||
pblock->hashReserved = uint256();
|
||||
@@ -493,6 +493,26 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn,int32_t gpucount)
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
else if ( ASSETCHAINS_STREAM != 0 && ASSETCHAINS_SYMBOL[0] != 0 && nHeight > 128 )
|
||||
{
|
||||
CMutableTransaction txStream = CreateNewContextualCMutableTransaction(Params().GetConsensus(), chainActive.Height() + 1);
|
||||
if ( komodo_notaryvin(txStream,ASSETCHAINS_OVERRIDE_PUBKEY33) > 0 )
|
||||
{
|
||||
CAmount txfees = 10000;
|
||||
pblock->vtx.push_back(txStream);
|
||||
pblocktemplate->vTxFees.push_back(txfees);
|
||||
pblocktemplate->vTxSigOps.push_back(GetLegacySigOpCount(txStream));
|
||||
nFees += txfees;
|
||||
pblocktemplate->vTxFees[0] = -nFees;
|
||||
//*(uint64_t *)(&pblock->vtx[0].vout[0].nValue) += txfees;
|
||||
//fprintf(stderr,"added notaryvin\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"error adding streamer vin, the chain broke! \n");
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
else if ( ASSETCHAINS_CC == 0 && pindexPrev != 0 && ASSETCHAINS_STAKED == 0 && (ASSETCHAINS_SYMBOL[0] != 0 || IS_KOMODO_NOTARY == 0 || My_notaryid < 0) )
|
||||
{
|
||||
CValidationState state;
|
||||
@@ -527,7 +547,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn,int32_t gpucount)
|
||||
|
||||
return pblocktemplate.release();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
#ifdef ENABLE_WALLET
|
||||
boost::optional<CScript> GetMinerScriptPubKey(CReserveKey& reservekey)
|
||||
@@ -550,11 +570,11 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn,int32_t gpucount)
|
||||
return boost::optional<CScript>();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
CScript scriptPubKey = CScript() << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG;
|
||||
return scriptPubKey;
|
||||
}
|
||||
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey)
|
||||
{
|
||||
@@ -564,7 +584,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn,int32_t gpucount)
|
||||
{
|
||||
boost::optional<CScript> scriptPubKey = GetMinerScriptPubKey();
|
||||
#endif
|
||||
|
||||
|
||||
if (!scriptPubKey) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -592,7 +612,7 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int&
|
||||
CMutableTransaction txCoinbase(pblock->vtx[0]);
|
||||
txCoinbase.vin[0].scriptSig = (CScript() << nHeight << CScriptNum(nExtraNonce)) + COINBASE_FLAGS;
|
||||
assert(txCoinbase.vin[0].scriptSig.size() <= 100);
|
||||
|
||||
|
||||
pblock->vtx[0] = txCoinbase;
|
||||
pblock->hashMerkleRoot = pblock->BuildMerkleTree();
|
||||
}
|
||||
@@ -610,12 +630,18 @@ CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey,int32_t nHeight,in
|
||||
{
|
||||
scriptPubKey = CScript() << ParseHex(ASSETCHAINS_OVERRIDE_PUBKEY) << OP_CHECKSIG;
|
||||
}
|
||||
else if ( ASSETCHAINS_STREAM != 0 )
|
||||
{
|
||||
if ( nHeight < 128 )
|
||||
scriptPubKey = CScript() << ParseHex(ASSETCHAINS_OVERRIDE_PUBKEY) << OP_CHECKSIG;
|
||||
else
|
||||
scriptPubKey = CScript() << ParseHex(CRYPTO777_PUBSECPSTR) << OP_CHECKSIG;
|
||||
}
|
||||
else if ( USE_EXTERNAL_PUBKEY != 0 )
|
||||
{
|
||||
//fprintf(stderr,"use notary pubkey\n");
|
||||
scriptPubKey = CScript() << ParseHex(NOTARY_PUBKEY) << OP_CHECKSIG;
|
||||
}
|
||||
else
|
||||
} else
|
||||
{
|
||||
if (!reservekey.GetReservedKey(pubkey))
|
||||
{
|
||||
@@ -661,7 +687,7 @@ static bool ProcessBlockFound(CBlock* pblock)
|
||||
{
|
||||
LogPrintf("%s\n", pblock->ToString());
|
||||
LogPrintf("generated %s height.%d\n", FormatMoney(pblock->vtx[0].vout[0].nValue),chainActive.LastTip()->nHeight+1);
|
||||
|
||||
|
||||
// Found a solution
|
||||
{
|
||||
//LOCK(cs_main);
|
||||
@@ -676,11 +702,11 @@ static bool ProcessBlockFound(CBlock* pblock)
|
||||
for (i=31; i>=0; i--)
|
||||
fprintf(stderr,"%02x",((uint8_t *)&hash)[i]);
|
||||
fprintf(stderr," <- chainTip (stale)\n");
|
||||
|
||||
|
||||
return error("KomodoMiner: generated block is stale");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
// Remove key from key pool
|
||||
if ( IS_KOMODO_NOTARY == 0 )
|
||||
@@ -704,7 +730,7 @@ static bool ProcessBlockFound(CBlock* pblock)
|
||||
CValidationState state;
|
||||
if (!ProcessNewBlock(1,chainActive.LastTip()->nHeight+1,state, NULL, pblock, true, NULL))
|
||||
return error("KomodoMiner: ProcessNewBlock, block not accepted");
|
||||
|
||||
|
||||
TrackMinedBlock(pblock->GetHash());
|
||||
komodo_broadcast(pblock,16);
|
||||
return true;
|
||||
@@ -728,15 +754,15 @@ void static BitcoinMiner()
|
||||
SetThreadPriority(THREAD_PRIORITY_LOWEST);
|
||||
RenameThread("komodo-miner");
|
||||
const CChainParams& chainparams = Params();
|
||||
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
// Each thread has its own key
|
||||
CReserveKey reservekey(pwallet);
|
||||
#endif
|
||||
|
||||
|
||||
// Each thread has its own counter
|
||||
unsigned int nExtraNonce = 0;
|
||||
|
||||
|
||||
unsigned int n = chainparams.EquihashN();
|
||||
unsigned int k = chainparams.EquihashK();
|
||||
uint8_t *script; uint64_t total,checktoshis; int32_t i,j,gpucount=KOMODO_MAXGPUCOUNT,notaryid = -1;
|
||||
@@ -767,7 +793,7 @@ void static BitcoinMiner()
|
||||
}
|
||||
);
|
||||
miningTimer.start();
|
||||
|
||||
|
||||
try {
|
||||
if ( ASSETCHAINS_SYMBOL[0] != 0 )
|
||||
fprintf(stderr,"try %s Mining with %s\n",ASSETCHAINS_SYMBOL,solver.c_str());
|
||||
@@ -790,7 +816,7 @@ void static BitcoinMiner()
|
||||
break;
|
||||
MilliSleep(15000);
|
||||
//fprintf(stderr,"fvNodesEmpty %d IsInitialBlockDownload(%s) %d\n",(int32_t)fvNodesEmpty,ASSETCHAINS_SYMBOL,(int32_t)IsInitialBlockDownload());
|
||||
|
||||
|
||||
} while (true);
|
||||
//fprintf(stderr,"%s Found peers\n",ASSETCHAINS_SYMBOL);
|
||||
miningTimer.start();
|
||||
@@ -840,14 +866,19 @@ void static BitcoinMiner()
|
||||
{
|
||||
if ( ASSETCHAINS_REWARD == 0 )
|
||||
{
|
||||
if ( pblock->vtx.size() == 1 && pblock->vtx[0].vout.size() == 1 && Mining_height > ASSETCHAINS_MINHEIGHT )
|
||||
int minvoutsize = 1;
|
||||
int minvtxsize = 1;
|
||||
if ( ASSETCHAINS_STREAM != 0 )
|
||||
minvoutsize = 2;
|
||||
minvtxsize = 2;
|
||||
if ( pblock->vtx.size() == minvtxsize && pblock->vtx[0].vout.size() == minvoutsize && 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);
|
||||
} else fprintf(stderr,"%s tx.%d vouts.%d mining.%d vs %d\n",ASSETCHAINS_SYMBOL,(int32_t)pblock->vtx.size(),(int32_t)pblock->vtx[0].vout.size(),Mining_height,ASSETCHAINS_MINHEIGHT);
|
||||
}
|
||||
}
|
||||
IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);
|
||||
@@ -926,13 +957,13 @@ void static BitcoinMiner()
|
||||
}
|
||||
while (true)
|
||||
{
|
||||
if ( KOMODO_INSYNC == 0 )
|
||||
/*if ( KOMODO_INSYNC == 0 && Mining_height > ASSETCHAINS_MINHEIGHT )
|
||||
{
|
||||
fprintf(stderr,"Mining when blockchain might not be in sync longest.%d vs %d\n",KOMODO_LONGESTCHAIN,Mining_height);
|
||||
if ( KOMODO_LONGESTCHAIN != 0 && Mining_height >= KOMODO_LONGESTCHAIN )
|
||||
KOMODO_INSYNC = 1;
|
||||
sleep(3);
|
||||
}
|
||||
} */
|
||||
// Hash state
|
||||
KOMODO_CHOSEN_ONE = 0;
|
||||
crypto_generichash_blake2b_state state;
|
||||
@@ -1054,13 +1085,13 @@ void static BitcoinMiner()
|
||||
std::lock_guard<std::mutex> lock{m_cs};
|
||||
return cancelSolver;
|
||||
};
|
||||
|
||||
|
||||
// TODO: factor this out into a function with the same API for each solver.
|
||||
if (solver == "tromp" ) { //&& notaryid >= 0 ) {
|
||||
// Create solver and initialize it.
|
||||
equi eq(1);
|
||||
eq.setstate(&curr_state);
|
||||
|
||||
|
||||
// Initialization done, start algo driver.
|
||||
eq.digit0(0);
|
||||
eq.xfull = eq.bfull = eq.hfull = 0;
|
||||
@@ -1072,7 +1103,7 @@ void static BitcoinMiner()
|
||||
}
|
||||
eq.digitK(0);
|
||||
ehSolverRuns.increment();
|
||||
|
||||
|
||||
// Convert solution indices to byte array (decompress) and pass it to validBlock method.
|
||||
for (size_t s = 0; s < eq.nsols; s++) {
|
||||
LogPrint("pow", "Checking solution %d\n", s+1);
|
||||
@@ -1081,7 +1112,7 @@ void static BitcoinMiner()
|
||||
index_vector[i] = eq.sols[s][i];
|
||||
}
|
||||
std::vector<unsigned char> sol_char = GetMinimalFromIndices(index_vector, DIGITBITS);
|
||||
|
||||
|
||||
if (validBlock(sol_char)) {
|
||||
// If we find a POW solution, do not try other solutions
|
||||
// because they become invalid as we created a new block in blockchain.
|
||||
@@ -1108,7 +1139,7 @@ void static BitcoinMiner()
|
||||
cancelSolver = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Check for stop or if block needs to be rebuilt
|
||||
boost::this_thread::interruption_point();
|
||||
// Regtest mode doesn't require peers
|
||||
@@ -1178,7 +1209,7 @@ void static BitcoinMiner()
|
||||
miningTimer.stop();
|
||||
c.disconnect();
|
||||
}
|
||||
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads)
|
||||
#else
|
||||
@@ -1186,10 +1217,10 @@ void static BitcoinMiner()
|
||||
#endif
|
||||
{
|
||||
static boost::thread_group* minerThreads = NULL;
|
||||
|
||||
|
||||
if (nThreads < 0)
|
||||
nThreads = GetNumCores();
|
||||
|
||||
|
||||
if (minerThreads != NULL)
|
||||
{
|
||||
minerThreads->interrupt_all();
|
||||
@@ -1201,7 +1232,7 @@ void static BitcoinMiner()
|
||||
nThreads = 1;
|
||||
if (nThreads == 0 || !fGenerate)
|
||||
return;
|
||||
|
||||
|
||||
minerThreads = new boost::thread_group();
|
||||
for (int i = 0; i < nThreads; i++) {
|
||||
#ifdef ENABLE_WALLET
|
||||
@@ -1211,5 +1242,5 @@ void static BitcoinMiner()
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif // ENABLE_MINING
|
||||
|
||||
48
src/pow.cpp
48
src/pow.cpp
@@ -20,31 +20,39 @@
|
||||
#include "librustzcash.h"
|
||||
#endif // ENABLE_RUST
|
||||
uint32_t komodo_chainactive_timestamp();
|
||||
extern int32_t ASSETCHAINS_STREAM;
|
||||
|
||||
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
|
||||
{
|
||||
unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact();
|
||||
// Genesis block
|
||||
if (pindexLast == NULL )
|
||||
return nProofOfWorkLimit;
|
||||
if ( ASSETCHAINS_STREAM == 0)
|
||||
{
|
||||
unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact();
|
||||
// Genesis block
|
||||
if (pindexLast == NULL )
|
||||
return nProofOfWorkLimit;
|
||||
|
||||
// Find the first block in the averaging interval
|
||||
const CBlockIndex* pindexFirst = pindexLast;
|
||||
arith_uint256 bnTot {0};
|
||||
for (int i = 0; pindexFirst && i < params.nPowAveragingWindow; i++) {
|
||||
arith_uint256 bnTmp;
|
||||
bnTmp.SetCompact(pindexFirst->nBits);
|
||||
bnTot += bnTmp;
|
||||
pindexFirst = pindexFirst->pprev;
|
||||
// Find the first block in the averaging interval
|
||||
const CBlockIndex* pindexFirst = pindexLast;
|
||||
arith_uint256 bnTot {0};
|
||||
for (int i = 0; pindexFirst && i < params.nPowAveragingWindow; i++) {
|
||||
arith_uint256 bnTmp;
|
||||
bnTmp.SetCompact(pindexFirst->nBits);
|
||||
bnTot += bnTmp;
|
||||
pindexFirst = pindexFirst->pprev;
|
||||
}
|
||||
|
||||
// Check we have enough blocks
|
||||
if (pindexFirst == NULL)
|
||||
return nProofOfWorkLimit;
|
||||
|
||||
arith_uint256 bnAvg {bnTot / params.nPowAveragingWindow};
|
||||
|
||||
return CalculateNextWorkRequired(bnAvg, pindexLast->GetMedianTimePast(), pindexFirst->GetMedianTimePast(), params);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 537857807;
|
||||
}
|
||||
|
||||
// Check we have enough blocks
|
||||
if (pindexFirst == NULL)
|
||||
return nProofOfWorkLimit;
|
||||
|
||||
arith_uint256 bnAvg {bnTot / params.nPowAveragingWindow};
|
||||
|
||||
return CalculateNextWorkRequired(bnAvg, pindexLast->GetMedianTimePast(), pindexFirst->GetMedianTimePast(), params);
|
||||
}
|
||||
|
||||
unsigned int CalculateNextWorkRequired(arith_uint256 bnAvg,
|
||||
|
||||
@@ -257,6 +257,218 @@ UniValue blockToDeltasJSON(const CBlock& block, const CBlockIndex* blockindex)
|
||||
return result;
|
||||
}
|
||||
|
||||
unsigned char hexval(unsigned char c)
|
||||
{
|
||||
if ('0' <= c && c <= '9')
|
||||
return c - '0';
|
||||
else if ('a' <= c && c <= 'f')
|
||||
return c - 'a' + 10;
|
||||
else if ('A' <= c && c <= 'F')
|
||||
return c - 'A' + 10;
|
||||
else abort();
|
||||
}
|
||||
|
||||
void hex2ascii(const string& in, string& out)
|
||||
{
|
||||
out.clear();
|
||||
out.reserve(in.length() / 2);
|
||||
for (string::const_iterator p = in.begin(); p != in.end(); p++)
|
||||
{
|
||||
unsigned char c = hexval(*p);
|
||||
p++;
|
||||
if (p == in.end()) break; // incomplete last digit - should report error
|
||||
c = (c << 4) + hexval(*p); // + takes precedence over <<
|
||||
out.push_back(c);
|
||||
}
|
||||
}
|
||||
|
||||
UniValue getdatafromblock(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() < 1 || params.size() > 2)
|
||||
throw runtime_error(
|
||||
"getdatafromblock \"hash|height\" true/false\n"
|
||||
"\nReturns all the data sent via streamer in block if there was any data in it.\n"
|
||||
"\nArguments:\n"
|
||||
"1. \"hash|height\" (string, required) The block hash or height\n"
|
||||
"2. \"true/false\" (bool, optional) if false do not return the actual data. Default true.\n"
|
||||
"\nResult (for verbose = true):\n"
|
||||
"{\n"
|
||||
" \"streamid\" : \"string\", (string) the name of the stream.\n"
|
||||
" \"firsttxid\" : \"hash\", (string) the first transaction of the stream.\n"
|
||||
" \"firstblockheight\" : \"n\", (numeric) the block the stream starts in.\n"
|
||||
" \"firstdeqid\" : n, (numeric) The sequence id of the first data chunk in this block\n"
|
||||
" \"lastseqid\" : n, (numeric) The sequence id of the last data chunk in this block\n"
|
||||
" \"data\" : \"xxxx\", (string) A hex string containing all the data chunks in this block.\n"
|
||||
"}\n"
|
||||
"\nResult (for verbose=false):\n"
|
||||
" \"streamid\" : \"string\", (string) the name of the stream.\n"
|
||||
" \"firsttxid\" : \"hash\", (string) the first transaction of the stream.\n"
|
||||
" \"firstblockheight\" : \"n\", (numeric) the block the stream starts in.\n"
|
||||
" \"firstdeqid\" : n, (numeric) The sequence id of the first data chunk in this block\n"
|
||||
" \"lastseqid\" : n, (numeric) The sequence id of the last data chunk in this block\n"
|
||||
+ HelpExampleCli("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09 false\"")
|
||||
+ HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
|
||||
+ HelpExampleCli("getblock", "12800")
|
||||
+ HelpExampleRpc("getblock", "12800 false")
|
||||
);
|
||||
|
||||
LOCK(cs_main);
|
||||
|
||||
std::string strHash = params[0].get_str();
|
||||
bool fVerbose = true;
|
||||
if (params.size() > 1) {
|
||||
std::string verboseflag = params[1].get_str();
|
||||
if ( verboseflag == "false" )
|
||||
fVerbose = false;
|
||||
}
|
||||
|
||||
// If height is supplied, find the hash
|
||||
if (strHash.size() < (2 * sizeof(uint256))) {
|
||||
// std::stoi allows characters, whereas we want to be strict
|
||||
regex r("[[:digit:]]+");
|
||||
if (!regex_match(strHash, r)) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block height parameter");
|
||||
}
|
||||
|
||||
int nHeight = -1;
|
||||
try {
|
||||
nHeight = std::stoi(strHash);
|
||||
}
|
||||
catch (const std::exception &e) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block height parameter");
|
||||
}
|
||||
|
||||
if (nHeight < 0 || nHeight > chainActive.Height()) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
|
||||
}
|
||||
strHash = chainActive[nHeight]->GetBlockHash().GetHex();
|
||||
}
|
||||
|
||||
uint256 hash(uint256S(strHash));
|
||||
|
||||
if (mapBlockIndex.count(hash) == 0)
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
|
||||
|
||||
CBlock block;
|
||||
CBlockIndex* pblockindex = mapBlockIndex[hash];
|
||||
|
||||
if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0)
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)");
|
||||
|
||||
if(!ReadBlockFromDisk(block, pblockindex,1))
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
|
||||
|
||||
UniValue result(UniValue::VOBJ);
|
||||
int firstseqid = 0;
|
||||
int lastseqid = 0;
|
||||
int i = 0;
|
||||
int did1 = 0;
|
||||
int skippedtxs = 0;
|
||||
int failed = 0;
|
||||
int getfirstblock = 0;
|
||||
static std::string streamid,firsttxid;
|
||||
static int firsttxnHeight;
|
||||
std::string blockdata;
|
||||
fprintf(stderr, "number of tx in block: %ld\n", block.vtx.size());
|
||||
// Iif block tx size is > 2 then we can do this
|
||||
if ( block.vtx.size() > 2 )
|
||||
{
|
||||
BOOST_FOREACH(const CTransaction&tx, block.vtx)
|
||||
{
|
||||
// ignore first and last TX and any TX that does not have 3 vouts.
|
||||
if ( (i == 0) || (i == (block.vtx.size() -1)) || (tx.vout.size() != 3) )
|
||||
{
|
||||
fprintf(stderr, "skipped tx number: %d\n",i);
|
||||
skippedtxs = skippedtxs + 1;
|
||||
} else {
|
||||
std::string opretstr = HexStr(tx.vout[2].scriptPubKey.begin(), tx.vout[2].scriptPubKey.end());
|
||||
// scriptPubKey is longer than 81, should mean its an OP_RETURN, maybe also check vout == 0 ?
|
||||
if ( opretstr.size() > 81 ) {
|
||||
std::string idstr = opretstr.substr (8,64); // stream ID or txid
|
||||
std::string seqidstr = opretstr.substr (72,8); // sequence ID
|
||||
std::string data = opretstr.substr (80); // data chunk
|
||||
unsigned int seqid;
|
||||
std::stringstream ss;
|
||||
ss << std::hex << seqidstr;
|
||||
ss >> seqid;
|
||||
if ( seqid == 1 ) {
|
||||
streamid = idstr;
|
||||
getfirstblock = 1;
|
||||
} else if ( seqid == 2 ) {
|
||||
firsttxid = idstr;
|
||||
} else if (firsttxid.empty()) {
|
||||
firsttxid.append(idstr);
|
||||
} else if ( firsttxid != idstr ) {
|
||||
printf("firsttxid.%s idstr.%s change firsttxid and wipe streamid?\n",firsttxid.c_str(),idstr.c_str());
|
||||
firsttxid.clear();
|
||||
firsttxid.append(idstr);
|
||||
streamid.clear();
|
||||
firsttxnHeight = 0;
|
||||
}
|
||||
if ( seqid == (lastseqid + 1) || did1 == 0 ) {
|
||||
blockdata.append(data);
|
||||
} else {
|
||||
result.push_back(Pair("error","chunck out of order or missing in this block!"));
|
||||
result.push_back(Pair("lastvalidseqid", (int)lastseqid));
|
||||
break;
|
||||
}
|
||||
if ( did1 == 0 ) {
|
||||
firstseqid = seqid;
|
||||
did1 = 1;
|
||||
}
|
||||
lastseqid = seqid;
|
||||
} else {
|
||||
skippedtxs = skippedtxs + 1;
|
||||
fprintf(stderr, "skipped tx number: %d\n",i);
|
||||
}
|
||||
// function here to extract seqid from first and last TX
|
||||
// we an push the data or not depending on input from RPC.
|
||||
}
|
||||
i = i + 1;
|
||||
}
|
||||
if (streamid.empty() || getfirstblock == 1) {
|
||||
if ( lastseqid == 1) {
|
||||
firsttxid = block.vtx[1].GetHash().GetHex();
|
||||
}
|
||||
uint256 hash; CTransaction firsttx;
|
||||
uint256 firsttxid_256(uint256S(firsttxid));
|
||||
if (GetTransaction(firsttxid_256,firsttx,hash,false)) {
|
||||
if ( streamid.empty() ) {
|
||||
std::string firststreamid = HexStr(firsttx.vout[2].scriptPubKey.begin(), firsttx.vout[2].scriptPubKey.end());
|
||||
streamid.append(firststreamid.substr (8,64));
|
||||
}
|
||||
printf("first stream id changed to: %s\n", streamid.c_str());
|
||||
BlockMap::iterator mi = mapBlockIndex.find(hash);
|
||||
if (mi != mapBlockIndex.end() && (*mi).second) {
|
||||
CBlockIndex* pindex = (*mi).second;
|
||||
printf("found block height: %d\n",pindex->nHeight);
|
||||
if (chainActive.Contains(pindex)) {
|
||||
firsttxnHeight = pindex->nHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
failed = 1;
|
||||
}
|
||||
|
||||
if ( failed == 1 || skippedtxs == i ) {
|
||||
result.push_back(Pair("error","there is no data in this block."));
|
||||
} else {
|
||||
std::string decodedstreamid;
|
||||
hex2ascii(streamid, decodedstreamid);
|
||||
result.push_back(Pair("streamid", decodedstreamid.c_str()));
|
||||
result.push_back(Pair("firsttxid", firsttxid));
|
||||
result.push_back(Pair("firstblockheight", (int)firsttxnHeight));
|
||||
result.push_back(Pair("firstseqid", (int)firstseqid));
|
||||
result.push_back(Pair("lastseqid", (int)lastseqid));
|
||||
if (fVerbose == true) {
|
||||
result.push_back(Pair("data", blockdata));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ);
|
||||
@@ -816,7 +1028,7 @@ UniValue kvsearch(const UniValue& params, bool fHelp)
|
||||
" \"currentheight\": xxxxx, (numeric) current height of the chain\n"
|
||||
" \"key\": \"xxxxx\", (string) key\n"
|
||||
" \"keylen\": xxxxx, (string) length of the key \n"
|
||||
" \"owner\": \"xxxxx\" (string) hex string representing the owner of the key \n"
|
||||
" \"owner\": \"xxxxx\" (string) hex string representing the owner of the key \n"
|
||||
" \"height\": xxxxx, (numeric) height the key was stored at\n"
|
||||
" \"expiration\": xxxxx, (numeric) height the key will expire\n"
|
||||
" \"flags\": x (numeric) 1 if the key was created with a password; 0 otherwise.\n"
|
||||
|
||||
@@ -264,6 +264,7 @@ static const CRPCCommand vRPCCommands[] =
|
||||
{ "control", "getinfo", &getinfo, true }, /* uses wallet if enabled */
|
||||
{ "control", "help", &help, true },
|
||||
{ "control", "stop", &stop, true },
|
||||
{ "control", "setpubkey", &setpubkey, true },
|
||||
|
||||
/* P2P networking */
|
||||
{ "network", "getnetworkinfo", &getnetworkinfo, true },
|
||||
@@ -285,6 +286,7 @@ static const CRPCCommand vRPCCommands[] =
|
||||
{ "blockchain", "getbestblockhash", &getbestblockhash, true },
|
||||
{ "blockchain", "getblockcount", &getblockcount, true },
|
||||
{ "blockchain", "getblock", &getblock, true },
|
||||
{ "blockchain", "getdatafromblock", &getdatafromblock, true },
|
||||
{ "blockchain", "getblockdeltas", &getblockdeltas, false },
|
||||
{ "blockchain", "getblockhashes", &getblockhashes, true },
|
||||
{ "blockchain", "getblockhash", &getblockhash, true },
|
||||
|
||||
@@ -364,6 +364,7 @@ extern UniValue getblockdeltas(const UniValue& params, bool fHelp);
|
||||
extern UniValue getblockhash(const UniValue& params, bool fHelp);
|
||||
extern UniValue getblockheader(const UniValue& params, bool fHelp);
|
||||
extern UniValue getblock(const UniValue& params, bool fHelp);
|
||||
extern UniValue getdatafromblock(const UniValue& params, bool fHelp);
|
||||
extern UniValue gettxoutsetinfo(const UniValue& params, bool fHelp);
|
||||
extern UniValue gettxout(const UniValue& params, bool fHelp);
|
||||
extern UniValue verifychain(const UniValue& params, bool fHelp);
|
||||
|
||||
@@ -44,6 +44,8 @@ using namespace std;
|
||||
using namespace libzcash;
|
||||
|
||||
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
|
||||
extern std::string ASSETCHAINS_OVERRIDE_PUBKEY;
|
||||
extern int32_t ASSETCHAINS_STREAM;
|
||||
extern UniValue TxJoinSplitToJSON(const CTransaction& tx);
|
||||
extern uint8_t ASSETCHAINS_PRIVATE;
|
||||
uint32_t komodo_segid32(char *coinaddr);
|
||||
@@ -4606,8 +4608,8 @@ int32_t komodo_notaryvin(CMutableTransaction &txNew,uint8_t *notarypub33)
|
||||
// ((uint8_t *)&revtxid)[i] = ((uint8_t *)&utxotxid)[31 - i];
|
||||
txNew.vin[0].prevout.hash = utxotxid; //revtxid;
|
||||
txNew.vin[0].prevout.n = utxovout;
|
||||
txNew.vout[0].scriptPubKey = CScript() << ParseHex(CRYPTO777_PUBSECPSTR) << OP_CHECKSIG;
|
||||
txNew.vout[0].nValue = utxovalue - txfee;
|
||||
txNew.vout[0].scriptPubKey = CScript() << ParseHex(CRYPTO777_PUBSECPSTR) << OP_CHECKSIG;
|
||||
CTransaction txNewConst(txNew);
|
||||
signSuccess = ProduceSignature(TransactionSignatureCreator(&keystore, &txNewConst, 0, utxovalue, SIGHASH_ALL), best_scriptPubKey, sigdata, consensusBranchId);
|
||||
if (!signSuccess)
|
||||
|
||||
Reference in New Issue
Block a user