Merge of Komodo and Verus Technologies Post Sapling, Pre-VerusPoP with Support for Time locked coinbases

This commit is contained in:
miketout
2018-11-14 16:40:10 -08:00
81 changed files with 4300 additions and 2785 deletions

View File

@@ -389,7 +389,7 @@ int32_t notarizedtxid_height(char *dest,char *txidstr,int32_t *kmdnotarized_heig
{
if ( (item= jobj(json,(char *)"result")) != 0 )
{
txid_confirmations = jint(item,(char *)"confirmations");
txid_confirmations = jint(item,(char *)"rawconfirmations");
if ( txid_confirmations > 0 && height > txid_confirmations )
txid_height = height - txid_confirmations;
else txid_height = height;
@@ -1099,18 +1099,33 @@ int32_t komodo_validate_interest(const CTransaction &tx,int32_t txheight,uint32_
PoS stake must be without txfee and in the last tx in the block at vout[0]
*/
uint64_t komodo_commission(const CBlock *pblock)
CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams);
uint64_t komodo_commission(const CBlock *pblock,int32_t height)
{
int32_t i,j,n=0,txn_count; uint64_t commission,total = 0;
int32_t i,j,n=0,txn_count; int64_t nSubsidy; uint64_t commission,total = 0;
txn_count = pblock->vtx.size();
for (i=0; i<txn_count; i++)
if ( ASSETCHAINS_FOUNDERS != 0 )
{
n = pblock->vtx[i].vout.size();
nSubsidy = GetBlockSubsidy(height,Params().GetConsensus());
fprintf(stderr,"ht.%d nSubsidy %.8f prod %llu\n",height,(double)nSubsidy/COIN,(long long)(nSubsidy * ASSETCHAINS_COMMISSION));
return((nSubsidy * ASSETCHAINS_COMMISSION) / COIN);
n = pblock->vtx[0].vout.size();
for (j=0; j<n; j++)
if ( j != 1 )
total += pblock->vtx[0].vout[j].nValue;
}
else
{
for (i=0; i<txn_count; i++)
{
//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;
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));
@@ -1157,7 +1172,7 @@ int8_t komodo_segid(int32_t nocache,int32_t height)
return(segid);
}
int32_t komodo_segids(uint8_t *hashbuf,int32_t height,int32_t n)
void komodo_segids(uint8_t *hashbuf,int32_t height,int32_t n)
{
static uint8_t prevhashbuf[100]; static int32_t prevheight;
int32_t i;
@@ -1277,7 +1292,7 @@ uint32_t komodo_stake(int32_t validateflag,arith_uint256 bnTarget,int32_t nHeigh
arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t height,int32_t goalperc)
{
int32_t oldflag = 0;
int32_t oldflag = 0,dispflag = 0;
CBlockIndex *pindex; arith_uint256 easydiff,bnTarget,hashval,sum,ave; bool fNegative,fOverflow; int32_t i,n,m,ht,percPoS,diff,val;
*percPoSp = percPoS = 0;
if ( height <= 10 || (ASSETCHAINS_STAKED == 100 && height <= 100) )
@@ -1296,23 +1311,23 @@ arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t he
{
n++;
percPoS++;
if ( ASSETCHAINS_STAKED < 100 )
if ( dispflag != 0 && ASSETCHAINS_STAKED < 100 )
fprintf(stderr,"0");
}
else
{
if ( ASSETCHAINS_STAKED < 100 )
if ( dispflag != 0 && ASSETCHAINS_STAKED < 100 )
fprintf(stderr,"1");
sum += UintToArith256(pindex->GetBlockHash());
m++;
}
}
if ( ASSETCHAINS_STAKED < 100 && (i % 10) == 9 )
if ( dispflag != 0 && ASSETCHAINS_STAKED < 100 && (i % 10) == 9 )
fprintf(stderr," %d, ",percPoS);
}
if ( m+n < 100 )
percPoS = ((percPoS * n) + (goalperc * (100-n))) / 100;
if ( ASSETCHAINS_STAKED < 100 )
if ( dispflag != 0 && ASSETCHAINS_STAKED < 100 )
fprintf(stderr," -> %d%% percPoS vs goalperc.%d ht.%d\n",percPoS,goalperc,height);
*percPoSp = percPoS;
if ( m > 0 )
@@ -1325,12 +1340,10 @@ arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t he
percPoS = 1;
if ( percPoS < goalperc ) // increase PoW diff -> lower bnTarget
{
//if ( oldflag != 0 )
// bnTarget = (ave * arith_uint256(percPoS * percPoS)) / arith_uint256(goalperc * goalperc * goalperc);
if ( oldflag != 0 )
bnTarget = (ave / arith_uint256(goalperc * goalperc * goalperc)) * arith_uint256(percPoS * percPoS);
else bnTarget = (ave / arith_uint256(goalperc * goalperc * goalperc * goalperc)) * arith_uint256(percPoS * percPoS);
if ( ASSETCHAINS_STAKED < 100 )
if ( dispflag != 0 && ASSETCHAINS_STAKED < 100 )
{
for (i=31; i>=24; i--)
fprintf(stderr,"%02x",((uint8_t *)&ave)[i]);
@@ -1348,7 +1361,6 @@ arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t he
if ( oldflag != 0 )
{
bnTarget = ((ave * arith_uint256(goalperc)) + (easydiff * arith_uint256(percPoS))) / arith_uint256(percPoS + goalperc);
//bnTarget = (bnTarget * arith_uint256(percPoS * percPoS * percPoS)) / arith_uint256(goalperc * goalperc);
bnTarget = (bnTarget / arith_uint256(goalperc * goalperc)) * arith_uint256(percPoS * percPoS * percPoS);
}
else bnTarget = (ave / arith_uint256(goalperc * goalperc)) * arith_uint256(percPoS * percPoS * percPoS);
@@ -1360,7 +1372,7 @@ arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t he
if ( bnTarget < ave )
bnTarget = ave;
}
if ( 1 )
if ( dispflag != 0 )
{
for (i=31; i>=24; i--)
fprintf(stderr,"%02x",((uint8_t *)&ave)[i]);
@@ -1446,7 +1458,7 @@ int32_t komodo_is_PoSblock(int32_t slowflag,int32_t height,CBlock *pblock,arith_
bnTarget = komodo_PoWtarget(&PoSperc,bnTarget,height,ASSETCHAINS_STAKED);
if ( bhash < bnTarget )
{
fprintf(stderr,"ht.%d isPoS but meets PoW diff!\n",height);
//fprintf(stderr,"ht.%d isPoS but meets PoW diff!\n",height);
isPoS = 0;
}
}
@@ -1459,7 +1471,6 @@ int32_t komodo_is_PoSblock(int32_t slowflag,int32_t height,CBlock *pblock,arith_
bool GetStakeParams(const CTransaction &stakeTx, CStakeParams &stakeParams);
bool ValidateMatchingStake(const CTransaction &ccTx, uint32_t voutNum, const CTransaction &stakeTx, bool &cheating);
bool ValidateStakeTransaction(const CTransaction &stakeTx, CStakeParams &stakeParams, bool validateSig = true);
// for now, we will ignore slowFlag in the interest of keeping success/fail simpler for security purposes
bool verusCheckPOSBlock(int32_t slowflag, CBlock *pblock, int32_t height)
@@ -1496,11 +1507,10 @@ bool verusCheckPOSBlock(int32_t slowflag, CBlock *pblock, int32_t height)
{
bool validHash = (value != 0);
bool enablePOSNonce = CPOSNonce::NewPOSActive(height);
bool newPOSEnforcement = enablePOSNonce && (Params().GetConsensus().vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight <= height);
uint256 rawHash;
arith_uint256 posHash;
if (validHash && newPOSEnforcement)
if (validHash && enablePOSNonce)
{
validHash = pblock->GetRawVerusPOSHash(rawHash, height);
posHash = UintToArith256(rawHash) / value;
@@ -1510,29 +1520,6 @@ bool verusCheckPOSBlock(int32_t slowflag, CBlock *pblock, int32_t height)
printf("ERROR: invalid nonce value for PoS block\nnNonce: %s\nrawHash: %s\nposHash: %s\nvalue: %lu\n",
pblock->nNonce.GetHex().c_str(), rawHash.GetHex().c_str(), posHash.GetHex().c_str(), value);
}
// make sure prev block hash and block height are correct
CStakeParams p;
if (validHash && (validHash = GetStakeParams(pblock->vtx[txn_count-1], p)))
{
for (int i = 0; validHash && i < pblock->vtx[0].vout.size(); i++)
{
validHash = false;
if (ValidateMatchingStake(pblock->vtx[0], i, pblock->vtx[txn_count-1], validHash) && !validHash)
{
if ((p.prevHash == pblock->hashPrevBlock) && (int32_t)p.blkHeight == height)
{
validHash = true;
}
else
{
printf("ERROR: invalid block data for stake tx\nblkHash: %s\ntxBlkHash: %s\nblkHeight: %d, txBlkHeight: %d\n",
pblock->hashPrevBlock.GetHex().c_str(), p.prevHash.GetHex().c_str(), height, p.blkHeight);
validHash = false;
}
}
else validHash = false;
}
}
}
if (validHash)
{
@@ -1573,7 +1560,7 @@ bool verusCheckPOSBlock(int32_t slowflag, CBlock *pblock, int32_t height)
//printf("after nNonce: %s, height: %d\n", nonce.GetHex().c_str(), height);
//printf("POShash: %s\n\n", hash.GetHex().c_str());
if ((!newPOSEnforcement || posHash == hash) && hash <= target)
if (posHash == hash && hash <= target)
{
BlockMap::const_iterator it = mapBlockIndex.find(blkHash);
if ((it == mapBlockIndex.end()) ||
@@ -1616,48 +1603,30 @@ bool verusCheckPOSBlock(int32_t slowflag, CBlock *pblock, int32_t height)
}
}
if ( nonceOK && ExtractDestination(pblock->vtx[txn_count-1].vout[0].scriptPubKey, voutaddress) &&
ExtractDestination(tx.vout[voutNum].scriptPubKey, destaddress) &&
CScriptExt::ExtractVoutDestination(pblock->vtx[0], 0, cbaddress) )
ExtractDestination(tx.vout[voutNum].scriptPubKey, destaddress) )
{
strcpy(voutaddr, CBitcoinAddress(voutaddress).ToString().c_str());
strcpy(destaddr, CBitcoinAddress(destaddress).ToString().c_str());
strcpy(cbaddr, CBitcoinAddress(cbaddress).ToString().c_str());
if (newPOSEnforcement)
{
if (!strcmp(destaddr, voutaddr))
{
// allow delegation of stake, but require all ouputs to be
// crypto conditions
CStakeParams p;
// validatestake transaction sets the pubkey of the stake output
// if it has no override into the pubkey
if (ValidateStakeTransaction(pblock->vtx[txn_count-1], p, false))
{
COptCCParams cpp;
// loop through all outputs to make sure they are sent to the proper pubkey
isPOS = true;
for (auto vout : pblock->vtx[0].vout)
{
txnouttype tp;
std::vector<std::vector<unsigned char>> vvch = std::vector<std::vector<unsigned char>>();
// solve all outputs to check that destinations all go only to the pk
// specified in the stake params
if (!Solver(vout.scriptPubKey, tp, vvch) ||
tp != TX_CRYPTOCONDITION ||
vvch.size() < 2 ||
p.pk != CPubKey(vvch[1]))
{
isPOS = false;
break;
}
}
}
}
}
else if ( !strcmp(destaddr,voutaddr) && ( !strcmp(destaddr,cbaddr) || (height < 17840)) )
if ( !strcmp(destaddr,voutaddr) )
{
isPOS = true;
CTransaction &cbtx = pblock->vtx[0];
for (int i = 0; i < cbtx.vout.size(); i++)
{
if (CScriptExt::ExtractVoutDestination(cbtx, i, cbaddress))
{
strcpy(cbaddr, CBitcoinAddress(cbaddress).ToString().c_str());
if (!strcmp(destaddr,cbaddr))
continue;
}
else
{
if (cbtx.vout[i].scriptPubKey.IsOpReturn())
continue;
isPOS = false;
break;
}
}
}
else
{
@@ -1681,17 +1650,39 @@ bool verusCheckPOSBlock(int32_t slowflag, CBlock *pblock, int32_t height)
int64_t komodo_checkcommission(CBlock *pblock,int32_t height)
{
int64_t checktoshis=0; uint8_t *script;
int64_t checktoshis=0; uint8_t *script,scripthex[8192]; int32_t scriptlen,matched = 0;
if ( ASSETCHAINS_COMMISSION != 0 )
{
checktoshis = komodo_commission(pblock);
if ( checktoshis > 10000 && pblock->vtx[0].vout.size() != 2 )
checktoshis = komodo_commission(pblock,height);
fprintf(stderr,"height.%d commission %.8f\n",height,(double)checktoshis/COIN);
/*if ( checktoshis > 10000 && pblock->vtx[0].vout.size() != 2 ) jl777: not sure why this was here
return(-1);
else if ( checktoshis != 0 )
else*/ if ( checktoshis != 0 )
{
script = (uint8_t *)&pblock->vtx[0].vout[1].scriptPubKey[0];
if ( script[0] != 33 || script[34] != OP_CHECKSIG || memcmp(script+1,ASSETCHAINS_OVERRIDE_PUBKEY33,33) != 0 )
scriptlen = (int32_t)pblock->vtx[0].vout[1].scriptPubKey.size();
if ( ASSETCHAINS_SCRIPTPUB.size() > 1 )
{
if ( ASSETCHAINS_SCRIPTPUB.size()/2 == scriptlen && scriptlen < sizeof(scripthex) )
{
decode_hex(scripthex,scriptlen,(char *)ASSETCHAINS_SCRIPTPUB.c_str());
if ( memcmp(scripthex,script,scriptlen) == 0 )
matched = scriptlen;
}
}
else if ( scriptlen == 35 && script[0] == 33 && script[34] == OP_CHECKSIG && memcmp(script+1,ASSETCHAINS_OVERRIDE_PUBKEY33,33) == 0 )
matched = 35;
else if ( scriptlen == 25 && script[0] == OP_DUP && script[1] == OP_HASH160 && script[2] == 20 && script[23] == OP_EQUALVERIFY && script[24] == OP_CHECKSIG && memcmp(script+3,ASSETCHAINS_OVERRIDE_PUBKEYHASH,20) == 0 )
matched = 25;
if ( matched == 0 )
{
int32_t i;
for (i=0; i<25; i++)
fprintf(stderr,"%02x",script[i]);
fprintf(stderr," payment to wrong pubkey scriptlen.%d, scriptpub[%d]\n",scriptlen,(int32_t)ASSETCHAINS_SCRIPTPUB.size()/2);
return(-1);
}
if ( pblock->vtx[0].vout[1].nValue != checktoshis )
{
fprintf(stderr,"ht.%d checktoshis %.8f vs actual vout[1] %.8f\n",height,dstr(checktoshis),dstr(pblock->vtx[0].vout[1].nValue));