Merge branch 'notarytest'

x
This commit is contained in:
blackjok3r
2019-02-03 14:04:31 +08:00
12 changed files with 482 additions and 111 deletions

View File

@@ -37,7 +37,7 @@
int32_t gettxout_scriptPubKey(uint8_t *scriptPubkey,int32_t maxsize,uint256 txid,int32_t n);
void komodo_event_rewind(struct komodo_state *sp,char *symbol,int32_t height);
int32_t komodo_connectblock(CBlockIndex *pindex,CBlock& block);
int32_t komodo_connectblock(bool fJustCheck, CBlockIndex *pindex,CBlock& block);
#include "komodo_structs.h"
#include "komodo_globals.h"
@@ -531,7 +531,7 @@ int32_t komodo_validate_chain(uint256 srchash,int32_t notarized_height)
} else return(1);
}
int32_t komodo_voutupdate(int32_t *isratificationp,int32_t notaryid,uint8_t *scriptbuf,int32_t scriptlen,int32_t height,uint256 txhash,int32_t i,int32_t j,uint64_t *voutmaskp,int32_t *specialtxp,int32_t *notarizedheightp,uint64_t value,int32_t notarized,uint64_t signedmask,uint32_t timestamp)
int32_t komodo_voutupdate(bool fJustCheck,int32_t *isratificationp,int32_t notaryid,uint8_t *scriptbuf,int32_t scriptlen,int32_t height,uint256 txhash,int32_t i,int32_t j,uint64_t *voutmaskp,int32_t *specialtxp,int32_t *notarizedheightp,uint64_t value,int32_t notarized,uint64_t signedmask,uint32_t timestamp)
{
static uint256 zero; static FILE *signedfp;
int32_t opretlen,nid,offset,k,MoMdepth,matched,len = 0; uint256 MoM,srchash,desttxid; uint8_t crypto777[33]; struct komodo_state *sp; char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN];
@@ -616,7 +616,7 @@ int32_t komodo_voutupdate(int32_t *isratificationp,int32_t notaryid,uint8_t *scr
if ( j == 1 && opretlen >= len+offset-opoffset )
{
memset(&MoMoMdata,0,sizeof(MoMoMdata));
if ( matched == 0 && bitweight(signedmask) >= KOMODO_MINRATIFY )
if ( matched == 0 && signedmask != 0 && bitweight(signedmask) >= KOMODO_MINRATIFY )
notarized = 1;
if ( strcmp("PIZZA",ccdata.symbol) == 0 || strncmp("TXSCL",ccdata.symbol,5) == 0 )
notarized = 1;
@@ -685,7 +685,7 @@ int32_t komodo_voutupdate(int32_t *isratificationp,int32_t notaryid,uint8_t *scr
else
{
komodo_rwccdata(ASSETCHAINS_SYMBOL,1,&ccdata,&MoMoMdata);
if ( matched != 0 )
if ( !fJustCheck && matched != 0 )
printf("[%s] matched.%d VALID (%s) MoM.%s [%d] CCid.%u\n",ASSETCHAINS_SYMBOL,matched,ccdata.symbol,MoM.ToString().c_str(),MoMdepth&0xffff,(MoMdepth>>16)&0xffff);
}
if ( MoMoMdata.pairs != 0 )
@@ -702,6 +702,8 @@ int32_t komodo_voutupdate(int32_t *isratificationp,int32_t notaryid,uint8_t *scr
} */
if ( matched != 0 && *notarizedheightp > sp->NOTARIZED_HEIGHT && *notarizedheightp < height )
{
if ( fJustCheck )
return(-2);
sp->NOTARIZED_HEIGHT = *notarizedheightp;
sp->NOTARIZED_HASH = srchash;
sp->NOTARIZED_DESTTXID = desttxid;
@@ -744,7 +746,7 @@ int32_t komodo_voutupdate(int32_t *isratificationp,int32_t notaryid,uint8_t *scr
}
else if ( matched != 0 && i == 0 && j == 1 && opretlen == 149 )
{
if ( notaryid >= 0 && notaryid < 64 )
if ( !fJustCheck && notaryid >= 0 && notaryid < 64 )
komodo_paxpricefeed(height,&scriptbuf[len],opretlen);
}
else if ( matched != 0 )
@@ -801,18 +803,18 @@ int32_t komodo_notarycmp(uint8_t *scriptPubKey,int32_t scriptlen,uint8_t pubkeys
}
// int32_t !
int32_t komodo_connectblock(CBlockIndex *pindex,CBlock& block)
int32_t komodo_connectblock(bool fJustCheck, CBlockIndex *pindex,CBlock& block)
{
static int32_t hwmheight;
int32_t staked_era; static int32_t lastStakedEra;
std::vector<int32_t> notarisations;
uint64_t signedmask,voutmask; char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; struct komodo_state *sp;
uint8_t scriptbuf[10001],pubkeys[64][33],rmd160[20],scriptPubKey[35]; uint256 zero,btctxid,txhash;
int32_t i,j,k,numnotaries,notarized,scriptlen,isratification,nid,numvalid,specialtx,notarizedheight,notaryid,len,numvouts,numvins,height,txn_count;
if ( pindex == 0 )
{
fprintf(stderr,"komodo_connectblock null pindex\n");
return -1;
return(0);
}
memset(&zero,0,sizeof(zero));
komodo_init(pindex->GetHeight());
@@ -820,13 +822,13 @@ int32_t komodo_connectblock(CBlockIndex *pindex,CBlock& block)
if ( (sp= komodo_stateptr(symbol,dest)) == 0 )
{
fprintf(stderr,"unexpected null komodostateptr.[%s]\n",ASSETCHAINS_SYMBOL);
return -1;
return(0);
}
//fprintf(stderr,"%s connect.%d\n",ASSETCHAINS_SYMBOL,pindex->nHeight);
if ( is_STAKED(ASSETCHAINS_SYMBOL) != 0 || IS_STAKED_NOTARY > -1 )
{
staked_era = STAKED_era(pindex->GetBlockTime());
if ( staked_era != lastStakedEra )
if ( !fJustCheck && staked_era != lastStakedEra )
{
uint8_t tmp_pubkeys[64][33];
int8_t numSN = numStakedNotaries(tmp_pubkeys,staked_era);
@@ -842,8 +844,8 @@ int32_t komodo_connectblock(CBlockIndex *pindex,CBlock& block)
fprintf(stderr, "Staked Notary Protection Active! NotaryID.%d RADD.%s ERA.%d MIN_TX_VALUE.%lu \n",IS_STAKED_NOTARY,NOTARY_ADDRESS.c_str(),staked_era,MIN_RECV_SATS);
}
}
lastStakedEra = staked_era;
}
lastStakedEra = staked_era;
}
numnotaries = komodo_notaries(pubkeys,pindex->GetHeight(),pindex->GetBlockTime());
calc_rmd160_sha256(rmd160,pubkeys[0],33);
@@ -857,8 +859,11 @@ int32_t komodo_connectblock(CBlockIndex *pindex,CBlock& block)
komodo_purge_ccdata((int32_t)pindex->GetHeight());
hwmheight = pindex->GetHeight();
}
komodo_event_rewind(sp,symbol,pindex->GetHeight());
komodo_stateupdate(pindex->GetHeight(),0,0,0,zero,0,0,0,0,-pindex->GetHeight(),pindex->nTime,0,0,0,0,zero,0);
if (!fJustCheck)
{
komodo_event_rewind(sp,symbol,pindex->GetHeight());
komodo_stateupdate(pindex->GetHeight(),0,0,0,zero,0,0,0,0,-pindex->GetHeight(),pindex->nTime,0,0,0,0,zero,0);
}
}
komodo_currentheight_set(chainActive.LastTip()->GetHeight());
int transaction = 0;
@@ -869,9 +874,12 @@ int32_t komodo_connectblock(CBlockIndex *pindex,CBlock& block)
for (i=0; i<txn_count; i++)
{
if ( (is_STAKED(ASSETCHAINS_SYMBOL) != 0 && staked_era == 0) || (is_STAKED(ASSETCHAINS_SYMBOL) == 255) ) {
// in era gap no point checking any invlaid notarisations.
// in era gap or chain banned, no point checking any invlaid notarisations.
break;
}
// Notary pay chains need notarisation in position 1, ignore the rest on validation. Check notarisation is 1 on check.
if ( !fJustCheck && ASSETCHAINS_NOTARY_PAY != 0 && i > 1)
break;
txhash = block.vtx[i].GetHash();
numvouts = block.vtx[i].vout.size();
notaryid = -1;
@@ -900,7 +908,7 @@ int32_t komodo_connectblock(CBlockIndex *pindex,CBlock& block)
(numvalid >= KOMODO_MINRATIFY && ASSETCHAINS_SYMBOL[0] != 0) ||
numvalid > (numnotaries/5) )
{
if ( ASSETCHAINS_SYMBOL[0] != 0)
if ( !fJustCheck && ASSETCHAINS_SYMBOL[0] != 0)
{
static FILE *signedfp;
if ( signedfp == 0 )
@@ -947,9 +955,13 @@ int32_t komodo_connectblock(CBlockIndex *pindex,CBlock& block)
if ( len >= sizeof(uint32_t) && len <= sizeof(scriptbuf) )
{
memcpy(scriptbuf,(uint8_t *)&block.vtx[i].vout[j].scriptPubKey[0],len);
notaryid = komodo_voutupdate(&isratification,notaryid,scriptbuf,len,height,txhash,i,j,&voutmask,&specialtx,&notarizedheight,(uint64_t)block.vtx[i].vout[j].nValue,notarized,signedmask,(uint32_t)chainActive.LastTip()->GetBlockTime());
if ( notaryid == -2 )
return(-1);
notaryid = komodo_voutupdate(fJustCheck,&isratification,notaryid,scriptbuf,len,height,txhash,i,j,&voutmask,&specialtx,&notarizedheight,(uint64_t)block.vtx[i].vout[j].nValue,notarized,signedmask,(uint32_t)chainActive.LastTip()->GetBlockTime());
if ( fJustCheck && notaryid == -2 )
{
// We see a valid notarisation here, save its location.
notarisations.push_back(i);
}
//fprintf(stderr, "notaryid.%i\n",notaryid);
if ( 0 && i > 0 )
{
for (k=0; k<len; k++)
@@ -962,7 +974,7 @@ int32_t komodo_connectblock(CBlockIndex *pindex,CBlock& block)
printf(") ");
if ( 0 && ASSETCHAINS_SYMBOL[0] == 0 )
printf("[%s] ht.%d txi.%d signedmask.%llx numvins.%d numvouts.%d notarized.%d special.%d isratification.%d\n",ASSETCHAINS_SYMBOL,height,i,(long long)signedmask,numvins,numvouts,notarized,specialtx,isratification);
if ( notarized != 0 && (notarizedheight != 0 || specialtx != 0) )
if ( !fJustCheck && (notarized != 0 && (notarizedheight != 0 || specialtx != 0)) )
{
if ( isratification != 0 )
{
@@ -1000,17 +1012,23 @@ int32_t komodo_connectblock(CBlockIndex *pindex,CBlock& block)
}
}
}
if ( IS_KOMODO_NOTARY != 0 && ASSETCHAINS_SYMBOL[0] == 0 )
if ( !fJustCheck && IS_KOMODO_NOTARY != 0 && ASSETCHAINS_SYMBOL[0] == 0 )
printf("%s ht.%d\n",ASSETCHAINS_SYMBOL[0] == 0 ? "KMD" : ASSETCHAINS_SYMBOL,height);
if ( pindex->GetHeight() == hwmheight )
if ( !fJustCheck && pindex->GetHeight() == hwmheight )
komodo_stateupdate(height,0,0,0,zero,0,0,0,0,height,(uint32_t)pindex->nTime,0,0,0,0,zero,0);
} else fprintf(stderr,"komodo_connectblock: unexpected null pindex\n");
//KOMODO_INITDONE = (uint32_t)time(NULL);
//fprintf(stderr,"%s end connect.%d\n",ASSETCHAINS_SYMBOL,pindex->GetHeight());
if (notarized = 1)
return(transaction);
else
return(-1);
if (fJustCheck)
{
if (notarisations.size() == 0)
return(0);
if ( notarisations.size() == 1 && notarisations[0] == 1 )
return(1);
else
return(-1);
}
else return(0);
}

View File

@@ -1772,6 +1772,188 @@ bool verusCheckPOSBlock(int32_t slowflag, CBlock *pblock, int32_t height)
return(isPOS);
}
int32_t komodo_notarized_height(int32_t *prevMoMheightp,uint256 *hashp,uint256 *txidp);
uint64_t komodo_notarypayamount(int32_t height, int64_t numnotaries)
{
if ( numnotaries == 0 )
return(0);
// fetch notarised height
int32_t notarizedht,prevMoMheight; uint256 notarizedhash,txid;
uint64_t AmountToPay=0,ret=0;
notarizedht = komodo_notarized_height(&prevMoMheight,&notarizedhash,&txid);
// dont think this can happen, just sanity check.
if ( height == notarizedht )
return(0);
// how many block since last notarisation.
int32_t n = height - notarizedht;
fprintf(stderr, "blocks since last notarisation: %i\n",n);
// multiply the amount possible to be used for each block by the amount of blocks passed
// to get the total posible to be paid for this notarisation.
AmountToPay = ASSETCHAINS_NOTARY_PAY*n;
//fprintf(stderr, "AmountToPay.%lu\n",AmountToPay);
ret = AmountToPay / numnotaries;
fprintf(stderr, "payment per notary.%lu\n",ret);
return(ret);
}
int32_t komodo_voutupdate(bool fJustCheck,int32_t *isratificationp,int32_t notaryid,uint8_t *scriptbuf,int32_t scriptlen,int32_t height,uint256 txhash,int32_t i,int32_t j,uint64_t *voutmaskp,int32_t *specialtxp,int32_t *notarizedheightp,uint64_t value,int32_t notarized,uint64_t signedmask,uint32_t timestamp);
uint64_t komodo_notarypay(CMutableTransaction &txNew, std::vector<int8_t> &NotarisationNotaries, uint32_t timestamp, int32_t height, uint8_t *script, int32_t len)
{
// fetch notary pubkey array.
// Need a better/safer way for notaries era, should really be height based rather than timestamp?
uint64_t total = 0, AmountToPay = 0;
int32_t staked_era; int8_t numSN;
uint8_t staked_pubkeys[64][33];
staked_era = STAKED_era(timestamp);
// No point going further, no notaries can be paid.
if ( staked_era == 0 )
return(0);
numSN = numStakedNotaries(staked_pubkeys,staked_era);
// resize coinbase vouts to number of notary nodes +1 for coinbase itself.
txNew.vout.resize(NotarisationNotaries.size()+1);
// Check the notarisation is valid, and extract notarised height.
uint64_t voutmask;
uint8_t scriptbuf[10001];
int32_t isratification,specialtx,notarizedheight;
if ( len >= sizeof(uint32_t) && len <= sizeof(scriptbuf) )
{
memcpy(scriptbuf,script,len);
if ( komodo_voutupdate(true,&isratification,0,scriptbuf,len,height,uint256(),1,1,&voutmask,&specialtx,&notarizedheight,0,1,0,timestamp) == -2 )
{
fprintf(stderr, "notarypay found VALID NOTARIZATION ht.%i\n",notarizedheight);
}
else
{
fprintf(stderr, "notarypay found INVALID NOTARIZATION ht.%i\n",notarizedheight);
return(0);
}
} else return(0);
// Calcualte the amount to pay.
AmountToPay = komodo_notarypayamount(notarizedheight,NotarisationNotaries.size());
// loop over notarisation vins and add transaction to coinbase.
// Commented prints here can be used to verify manually the pubkeys match.
for (int8_t n = 0; n < NotarisationNotaries.size(); n++)
{
uint8_t *ptr;
txNew.vout[n+1].scriptPubKey.resize(35);
ptr = (uint8_t *)&txNew.vout[n+1].scriptPubKey[0];
ptr[0] = 33;
for (int8_t i=0; i<33; i++)
{
ptr[i+1] = staked_pubkeys[NotarisationNotaries[n]][i];
//fprintf(stderr,"%02x",ptr[i+1]);
}
ptr[34] = OP_CHECKSIG;
//fprintf(stderr," set notary %i PUBKEY33 into vout[%i]\n",NotarisationNotaries[n],n+1);
txNew.vout[n+1].nValue = AmountToPay;
total += txNew.vout[n+1].nValue;
}
return(total);
}
uint64_t komodo_checknotarypay(CBlock *pblock,int32_t height)
{
std::vector<int8_t> NotarisationNotaries;
uint32_t timestamp = pblock->nTime;
int32_t staked_era; int8_t numSN;
uint8_t staked_pubkeys[64][33];
staked_era = STAKED_era(timestamp);
// No point going further, no notaries can be paid.
if ( staked_era == 0 )
return(0);
numSN = numStakedNotaries(staked_pubkeys,staked_era);
uint8_t *script; int32_t scriptlen;
// Loop over the notarisation and extract the position of the participating notaries in the array of pukeys for this era.
BOOST_FOREACH(const CTxIn& txin, pblock->vtx[1].vin)
{
uint256 hash; CTransaction tx1;
if ( GetTransaction(txin.prevout.hash,tx1,hash,false) )
{
for (int8_t i = 0; i < numSN; i++)
{
script = (uint8_t *)&tx1.vout[txin.prevout.n].scriptPubKey[0];
scriptlen = (int32_t)tx1.vout[txin.prevout.n].scriptPubKey.size();
if ( scriptlen == 35 && script[0] == 33 && script[34] == OP_CHECKSIG && memcmp(script+1,staked_pubkeys[i],33) == 0 )
NotarisationNotaries.push_back(i);
}
}
}
const CChainParams& chainparams = Params();
const Consensus::Params &consensusParams = chainparams.GetConsensus();
uint64_t totalsats = 0;
CMutableTransaction txNew = CreateNewContextualCMutableTransaction(consensusParams, height);
if ( pblock->vtx[1].vout.size() == 2 && pblock->vtx[1].vout[1].nValue == 0 )
{
// Get the OP_RETURN for the notarisation
uint8_t *script = (uint8_t *)&pblock->vtx[1].vout[1].scriptPubKey[0];
int32_t scriptlen = (int32_t)pblock->vtx[1].vout[1].scriptPubKey.size();
if ( script[0] == OP_RETURN )
{
// Create the coinbase tx again, using the extracted data, this is the same function the miner uses, with the same data.
// This allows us to know exactly that the coinbase is correct.
totalsats = komodo_notarypay(txNew, NotarisationNotaries, pblock->nTime, height, script, scriptlen);
}
else
{
fprintf(stderr, "vout 2 of notarisation is not OP_RETURN scriptlen.%i\n", scriptlen);
return(0);
}
}
// if notarypay fails, because the notarisation is not valid, exit now as txNew was not created.
// This should never happen, as the notarisation is checked before this function is called.
if ( totalsats == 0 )
{
fprintf(stderr, "notary pay returned 0!\n");
return(0);
}
int8_t n = 0, i = 0, matches = 0;
uint64_t total = 0, AmountToPay = 0;
// get the pay amount from the created tx.
AmountToPay = txNew.vout[1].nValue;
// Check the created coinbase pays the correct notaries.
BOOST_FOREACH(const CTxOut& txout, pblock->vtx[0].vout)
{
// skip the coinbase paid to the miner.
if ( n == 0 )
{
n++;
continue;
}
// Check the pubkeys match the pubkeys in the notarisation.
script = (uint8_t *)&txout.scriptPubKey[0];
scriptlen = (int32_t)txout.scriptPubKey.size();
if ( scriptlen == 35 && script[0] == 33 && script[34] == OP_CHECKSIG && memcmp(script+1,staked_pubkeys[NotarisationNotaries[n-1]],33) == 0 )
{
// check the value is correct
if ( pblock->vtx[0].vout[n].nValue == AmountToPay )
{
matches++;
total += txout.nValue;
fprintf(stderr, "MATCHED AmountPaid.%lu notaryid.%i\n",AmountToPay,NotarisationNotaries[n-1]);
}
else fprintf(stderr, "NOT MATCHED AmountPaid.%lu AmountToPay.%lu notaryid.%i\n", pblock->vtx[0].vout[n].nValue, AmountToPay, NotarisationNotaries[n-1]);
}
n++;
}
if ( matches != 0 && matches == NotarisationNotaries.size() && totalsats == total )
{
fprintf(stderr, "Validated coinbase matches notarisation in tx position 1.\n" );
return(totalsats);
}
return(0);
}
int64_t komodo_checkcommission(CBlock *pblock,int32_t height)
{
int64_t checktoshis=0; uint8_t *script,scripthex[8192]; int32_t scriptlen,matched = 0;
@@ -1952,6 +2134,30 @@ int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height)
return(-1);
}
}
// Consensus rule to force miners to mine the notary coinbase payment happens in ConnectBlock
// the default daemon miner, checks the actual vins so the only way this will fail, is if someone changes the miner,
// and then creates txs to the crypto address meeting min sigs and puts it in tx position 1.
// If they go through this effort, the block will still fail at connect block, and will be auto purged by the temp file fix.
if ( failed == 0 && ASSETCHAINS_NOTARY_PAY != 0 && pblock->vtx[0].vout.size() > 1 )
{
// We check the full validation in ConnectBlock directly to get the amount for coinbase. So just approx here.
if ( slowflag == 0 )
{
// Check the notarisation tx is to the crypto address.
if ( !komodo_is_notarytx(pblock->vtx[1]) == 1 )
{
fprintf(stderr, "notarisation is not to crypto address ht.%i\n",height);
return(-1);
}
// Check min sigs.
if ( pblock->vtx[1].vin.size() < (num_notaries_STAKED[STAKED_era(pblock->nTime)]/5) )
{
fprintf(stderr, "ht.%i does not meet minsigs.%i sigs.%li\n",height,(num_notaries_STAKED[STAKED_era(pblock->nTime)]/5),pblock->vtx[1].vin.size());
return(-1);
}
}
}
//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 )
return(-1);

View File

@@ -40,7 +40,7 @@ extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
extern uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT;
extern uint32_t ASSETCHAIN_INIT, ASSETCHAINS_MAGIC;
extern int32_t VERUS_BLOCK_POSUNITS, ASSETCHAINS_LWMAPOS, ASSETCHAINS_SAPLING, ASSETCHAINS_OVERWINTER;
extern uint64_t ASSETCHAINS_SUPPLY, ASSETCHAINS_FOUNDERS_REWARD;
extern uint64_t ASSETCHAINS_SUPPLY, ASSETCHAINS_FOUNDERS_REWARD, ASSETCHAINS_NOTARY_PAY;
extern uint64_t ASSETCHAINS_TIMELOCKGTE;
extern uint32_t ASSETCHAINS_ALGO, ASSETCHAINS_VERUSHASH,ASSETCHAINS_EQUIHASH,KOMODO_INITDONE;

View File

@@ -97,7 +97,7 @@ int32_t ASSETCHAINS_OVERWINTER = -1;
uint64_t KOMODO_INTERESTSUM,KOMODO_WALLETBALANCE;
int32_t ASSETCHAINS_STAKED;
uint64_t ASSETCHAINS_COMMISSION,ASSETCHAINS_SUPPLY = 10,MIN_RECV_SATS,ASSETCHAINS_FOUNDERS_REWARD;
uint64_t ASSETCHAINS_COMMISSION,ASSETCHAINS_SUPPLY = 10,MIN_RECV_SATS,ASSETCHAINS_FOUNDERS_REWARD,ASSETCHAINS_NOTARY_PAY;
uint32_t KOMODO_INITDONE;
char KMDUSERPASS[8192+512+1],BTCUSERPASS[8192]; uint16_t KMD_PORT = 7771,BITCOIND_RPCPORT = 7771;

View File

@@ -1749,7 +1749,6 @@ void komodo_args(char *argv0)
printf("ASSETCHAINS_LASTERA, if specified, must be between 1 and %u. ASSETCHAINS_LASTERA set to %lu\n", ASSETCHAINS_MAX_ERAS, ASSETCHAINS_LASTERA);
}
ASSETCHAINS_LASTERA -= 1;
printf("ASSETCHAINS_LASTERA = %lu\n", ASSETCHAINS_LASTERA);
ASSETCHAINS_TIMELOCKGTE = (uint64_t)GetArg("-ac_timelockgte", _ASSETCHAINS_TIMELOCKOFF);
ASSETCHAINS_TIMEUNLOCKFROM = GetArg("-ac_timeunlockfrom", 0);
@@ -1895,6 +1894,9 @@ void komodo_args(char *argv0)
}
else
{
ASSETCHAINS_NOTARY_PAY = GetArg("-ac_notarypay",0);
if ( ASSETCHAINS_NOTARY_PAY != 0 )
printf("Assetchains NOTARY PAY set to %lu sats per notarisation per notary. Cannot work with ac_script or ac_pubkey!\n",ASSETCHAINS_NOTARY_PAY);
if ( ASSETCHAINS_COMMISSION != 0 )
{
ASSETCHAINS_COMMISSION = 0;
@@ -1911,7 +1913,7 @@ void komodo_args(char *argv0)
fprintf(stderr,"-ac_script and -ac_marmara are mutually exclusive\n");
exit(0);
}
if ( ASSETCHAINS_ENDSUBSIDY[0] != 0 || ASSETCHAINS_REWARD[0] != 0 || ASSETCHAINS_HALVING[0] != 0 || ASSETCHAINS_DECAY[0] != 0 || ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_PUBLIC != 0 || ASSETCHAINS_PRIVATE != 0 || ASSETCHAINS_TXPOW != 0 || ASSETCHAINS_FOUNDERS != 0 || ASSETCHAINS_SCRIPTPUB.size() > 1 || ASSETCHAINS_SELFIMPORT.size() > 0 || ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 || ASSETCHAINS_TIMELOCKGTE != _ASSETCHAINS_TIMELOCKOFF|| ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH || ASSETCHAINS_LWMAPOS != 0 || ASSETCHAINS_LASTERA > 0 || ASSETCHAINS_BEAMPORT != 0 || ASSETCHAINS_CODAPORT != 0 || ASSETCHAINS_MARMARA != 0 || nonz > 0 || ASSETCHAINS_CCLIB.size() > 0 || ASSETCHAINS_FOUNDERS_REWARD != 0 )
if ( ASSETCHAINS_ENDSUBSIDY[0] != 0 || ASSETCHAINS_REWARD[0] != 0 || ASSETCHAINS_HALVING[0] != 0 || ASSETCHAINS_DECAY[0] != 0 || ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_PUBLIC != 0 || ASSETCHAINS_PRIVATE != 0 || ASSETCHAINS_TXPOW != 0 || ASSETCHAINS_FOUNDERS != 0 || ASSETCHAINS_SCRIPTPUB.size() > 1 || ASSETCHAINS_SELFIMPORT.size() > 0 || ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 || ASSETCHAINS_TIMELOCKGTE != _ASSETCHAINS_TIMELOCKOFF|| ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH || ASSETCHAINS_LWMAPOS != 0 || ASSETCHAINS_LASTERA > 0 || ASSETCHAINS_BEAMPORT != 0 || ASSETCHAINS_CODAPORT != 0 || ASSETCHAINS_MARMARA != 0 || nonz > 0 || ASSETCHAINS_CCLIB.size() > 0 || ASSETCHAINS_FOUNDERS_REWARD != 0 || ASSETCHAINS_NOTARY_PAY != 0 )
{
fprintf(stderr,"perc %.4f%% ac_pub=[%02x%02x%02x...] acsize.%d\n",dstr(ASSETCHAINS_COMMISSION)*100,ASSETCHAINS_OVERRIDE_PUBKEY33[0],ASSETCHAINS_OVERRIDE_PUBKEY33[1],ASSETCHAINS_OVERRIDE_PUBKEY33[2],(int32_t)ASSETCHAINS_SCRIPTPUB.size());
extraptr = extrabuf;
@@ -2006,6 +2008,8 @@ void komodo_args(char *argv0)
}
fprintf(stderr," <- CCLIB name\n");
}
if ( ASSETCHAINS_NOTARY_PAY != 0 )
extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_NOTARY_PAY),(void *)&ASSETCHAINS_NOTARY_PAY);
}
addn = GetArg("-seednode","");

View File

@@ -187,6 +187,8 @@ namespace {
std::vector<CBlockFileInfo> vinfoBlockFile,tmpBlockFiles;
int nLastBlockFile = 0;
int nLastTmpFile = 0;
unsigned int maxTempFileSize0 = MAX_TEMPFILE_SIZE;
unsigned int maxTempFileSize1 = MAX_TEMPFILE_SIZE;
/** Global flag to indicate we should check to see if there are
* block/undo files that should be deleted. Set on startup
* or if we allocate more file space when we're in prune mode
@@ -3265,6 +3267,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
auto verifier = libzcash::ProofVerifier::Strict();
auto disabledVerifier = libzcash::ProofVerifier::Disabled();
int32_t futureblock;
CAmount blockReward = 0;
// Check it again to verify JoinSplit proofs, and in case a previous version let a bad block in
if (!CheckBlock(&futureblock,pindex->GetHeight(),pindex,block, state, fExpensiveChecks ? verifier : disabledVerifier, fCheckPOW, !fJustCheck) || futureblock != 0 )
{
@@ -3278,6 +3281,34 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
return false;
fprintf(stderr,"grandfathered exception, until jan 15th 2019\n");
}
// Do this here before the block is moved to the main block files.
if ( ASSETCHAINS_NOTARY_PAY != 0 && pindex->GetHeight() != 0 )
{
// do a full block scan to get notarisation position and to enforce 1 notarisation is in block only.
// if notarisation in the block, must be position 1 and the coinbase must pay notaries.
int notarisationTx = komodo_connectblock(true,pindex,*(CBlock *)&block);
// -1 means that more than 1 notarisation is in a block, or the notarisation is not in order.
if ( notarisationTx == -1 )
return state.DoS(100, error("ConnectBlock(): Notarisation is not in TX position 1! Invalid Block!"),
REJECT_INVALID, "bad-notarization-position");
// 1 means this block contains a valid notarisation
if ( notarisationTx == 1 )
{
// Check if the notaries have been paid.
if ( block.vtx[0].vout.size() == 1 )
return state.DoS(100, error("ConnectBlock(): Notaries have not been paid!"),
REJECT_INVALID, "bad-cb-amount");
// calculate the notaries compensation and validate the amounts and pubkeys are correct.
uint64_t notarypaycheque = komodo_checknotarypay((CBlock *)&block,(int32_t)pindex->GetHeight());
fprintf(stderr, "notarypaycheque.%lu\n", notarypaycheque);
if ( notarypaycheque > 0 )
blockReward += notarypaycheque;
else
return state.DoS(100, error("ConnectBlock(): Notary pay validation failed!"),
REJECT_INVALID, "bad-cb-amount");
}
}
// Move the block to the main block file, we need this to create the TxIndex in the following loop.
if ( (pindex->nStatus & BLOCK_IN_TMPFILE) != 0 )
{
unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
@@ -3560,7 +3591,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
int64_t nTime1 = GetTimeMicros(); nTimeConnect += nTime1 - nTimeStart;
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->GetHeight(), chainparams.GetConsensus()) + sum;
blockReward += nFees + GetBlockSubsidy(pindex->GetHeight(), chainparams.GetConsensus()) + sum;
if ( ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_FOUNDERS_REWARD != 0 ) //ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 &&
{
uint64_t checktoshis;
@@ -3581,6 +3612,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
{
if ( ASSETCHAINS_SYMBOL[0] != 0 || pindex->GetHeight() >= KOMODO_NOTARIES_HEIGHT1 || block.vtx[0].vout[0].nValue > blockReward )
{
//fprintf(stderr, "coinbase pays too much\n");
//sleepflag = true;
return state.DoS(100,
error("ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)",
block.vtx[0].GetValueOut(), blockReward),
@@ -3628,7 +3661,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
setDirtyBlockIndex.insert(pindex);
}
ConnectNotarisations(block, pindex->GetHeight());
ConnectNotarisations(block, pindex->GetHeight()); // MoMoM notarisation DB.
if (fTxIndex)
if (!pblocktree->WriteTxIndex(vPos))
@@ -3684,11 +3717,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
LogPrint("bench", " - Callbacks: %.2fms [%.2fs]\n", 0.001 * (nTime4 - nTime3), nTimeCallbacks * 0.000001);
//FlushStateToDisk();
int tmp = komodo_connectblock(pindex,*(CBlock *)&block); // != block-nVersion-7000000;
if ( tmp > 0 )
{
printf("VALID NOTARISATION connect block.%i tx.%i\n",pindex->GetHeight(),tmp);
}
komodo_connectblock(false,pindex,*(CBlock *)&block); // dPoW state update.
return true;
}
@@ -4605,7 +4634,7 @@ bool FindBlockPos(int32_t tmpflag,CValidationState &state, CDiskBlockPos &pos, u
std::vector<CBlockFileInfo> *ptr; int *lastfilep;
LOCK(cs_LastBlockFile);
unsigned int nFile;
unsigned int nFile,maxTempFileSize;
if ( tmpflag != 0 )
{
@@ -4615,6 +4644,10 @@ bool FindBlockPos(int32_t tmpflag,CValidationState &state, CDiskBlockPos &pos, u
if (tmpBlockFiles.size() <= nFile) {
tmpBlockFiles.resize(nFile + 1);
}
if ( nFile == 0 )
maxTempFileSize = maxTempFileSize0;
else if ( nFile == 1 )
maxTempFileSize = maxTempFileSize1;
}
else
{
@@ -4625,49 +4658,86 @@ bool FindBlockPos(int32_t tmpflag,CValidationState &state, CDiskBlockPos &pos, u
vinfoBlockFile.resize(nFile + 1);
}
}
if (!fKnown) {
while ( (*ptr)[nFile].nSize + nAddSize >= ((tmpflag != 0) ? MAX_TEMPFILE_SIZE : MAX_BLOCKFILE_SIZE) ) {
bool tmpfileflag = false;
while ( (*ptr)[nFile].nSize + nAddSize >= ((tmpflag != 0) ? maxTempFileSize : MAX_BLOCKFILE_SIZE) ) {
if ( tmpflag != 0 && tmpfileflag )
break;
nFile++;
if ((*ptr).size() <= nFile) {
(*ptr).resize(nFile + 1);
}
tmpfileflag = true;
}
pos.nFile = nFile + tmpflag*TMPFILE_START;
pos.nPos = (*ptr)[nFile].nSize;
if ( 0 && tmpflag != 0 )
fprintf(stderr,"pos.nFile %d nPos %u\n",pos.nFile,pos.nPos);
}
if (nFile != *lastfilep) {
if (!fKnown) {
LogPrintf("Leaving block file %i: %s\n", nFile, (*ptr)[nFile].ToString());
}
FlushBlockFile(!fKnown);
//fprintf(stderr, "nFile = %i size.%li\n",nFile,tmpBlockFiles.size());
if ( tmpflag != 0 && tmpBlockFiles.size() >= 4 )
//fprintf(stderr, "nFile = %i size.%li maxTempFileSize0.%u maxTempFileSize1.%u\n",nFile,tmpBlockFiles.size(),maxTempFileSize0,maxTempFileSize1);
if ( tmpflag != 0 && tmpBlockFiles.size() >= 3 )
{
if ( nFile == 1 )
if ( nFile == 1 ) // Trying to get to second temp file.
{
PruneOneBlockFile(true,TMPFILE_START+2);
tmpBlockFiles[2].SetNull();
LogPrintf("Reset tempfile 2\n");
if (!PruneOneBlockFile(true,TMPFILE_START+1))
{
// file 1 is not ready to be used yet increase file 0's size.
fprintf(stderr, "Cant clear file 1!\n");
// We will reset the position to the end of the first file, even if its over max size.
nFile = 0;
pos.nFile = TMPFILE_START;
pos.nPos = (*ptr)[0].nSize;
// Increase temp file one's max size by a chunk, so we wait a reasonable time to recheck the other file.
maxTempFileSize0 += BLOCKFILE_CHUNK_SIZE;
}
else
{
// The file 1 is able to be used now. Reset max size, and set nfile to use file 1.
fprintf(stderr, "CLEARED file 1!\n");
maxTempFileSize0 = MAX_TEMPFILE_SIZE;
nFile = 1;
tmpBlockFiles[1].SetNull();
pos.nFile = TMPFILE_START+1;
pos.nPos = (*ptr)[1].nSize;
boost::filesystem::remove(GetBlockPosFilename(pos, "blk"));
LogPrintf("Prune: deleted temp blk (%05u)\n",nFile);
}
if ( 0 && tmpflag != 0 )
fprintf(stderr,"pos.nFile %d nPos %u\n",pos.nFile,pos.nPos);
}
else if ( nFile == 2 )
else if ( nFile == 2 ) // Trying to get to third temp file.
{
PruneOneBlockFile(true,TMPFILE_START+3);
tmpBlockFiles[3].SetNull();
LogPrintf("Reset tempfile 3\n");
if (!PruneOneBlockFile(true,TMPFILE_START))
{
fprintf(stderr, "Cant clear file 0!\n");
// We will reset the position to the end of the second block file, even if its over max size.
nFile = 1;
pos.nFile = TMPFILE_START+1;
pos.nPos = (*ptr)[1].nSize;
// Increase temp file one's max size by a chunk, so we wait a reasonable time to recheck the other file.
maxTempFileSize1 += BLOCKFILE_CHUNK_SIZE;
}
else
{
// The file 0 is able to be used now. Reset max size, and set nfile to use file 0.
fprintf(stderr, "CLEARED file 0!\n");
maxTempFileSize1 = MAX_TEMPFILE_SIZE;
nFile = 0;
tmpBlockFiles[0].SetNull();
pos.nFile = TMPFILE_START;
pos.nPos = (*ptr)[0].nSize;
boost::filesystem::remove(GetBlockPosFilename(pos, "blk"));
LogPrintf("Prune: deleted temp blk (%05u)\n",nFile);
}
if ( 0 && tmpflag != 0 )
fprintf(stderr,"pos.nFile %d nPos %u\n",pos.nFile,pos.nPos);
}
}
if ( tmpflag != 0 && nFile == 3 )
{
PruneOneBlockFile(true,TMPFILE_START);
tmpBlockFiles[0].SetNull();
PruneOneBlockFile(true,TMPFILE_START+1);
tmpBlockFiles[1].SetNull();
nFile = 0;
LogPrintf("Reset tempfile 0 and 1\n");
}
//fprintf(stderr, "nFile = %i size.%li maxTempFileSize0.%u maxTempFileSize1.%u\n",nFile,tmpBlockFiles.size(),maxTempFileSize0,maxTempFileSize1); sleep(30);
*lastfilep = nFile;
//fprintf(stderr, "*lastfilep = %i\n",*lastfilep);
}
@@ -5499,32 +5569,53 @@ uint64_t CalculateCurrentUsage()
}
/* Prune a block file (modify associated database entries)*/
void PruneOneBlockFile(bool tempfile, const int fileNumber)
bool PruneOneBlockFile(bool tempfile, const int fileNumber)
{
uint256 notarized_hash,notarized_desttxid; int32_t prevMoMheight,notarized_height;
notarized_height = komodo_notarized_height(&prevMoMheight,&notarized_hash,&notarized_desttxid);
//fprintf(stderr, "pruneblockfile.%i\n",fileNumber); sleep(15);
for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); ++it) {
for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); ++it)
{
CBlockIndex* pindex = it->second;
if (pindex && pindex->nFile == fileNumber) {
if (pindex && pindex->nFile == fileNumber)
{
if ( tempfile && (pindex->nStatus & BLOCK_IN_TMPFILE != 0) )
{
if ( chainActive.Contains(pindex) )
{
// Block is in main chain so we cant clear this file!
return(false);
}
if ( pindex->GetHeight() > notarized_height ) // Need to check this, does an invalid block have a height?
{
// This blocks height is not older than last notarization so it can be reorged into the main chain.
// We cant clear this file!
return(false);
}
else
{
// Block is not in main chain and is older than last notarised block so its safe for removal.
fprintf(stderr, "Block [%i] in tempfile.%i We can clear this block!\n",pindex->GetHeight(),fileNumber);
// Add index to list and remove after loop?
}
}
pindex->nStatus &= ~BLOCK_HAVE_DATA;
pindex->nStatus &= ~BLOCK_HAVE_UNDO;
pindex->nFile = 0;
pindex->nDataPos = 0;
pindex->nUndoPos = 0;
setDirtyBlockIndex.insert(pindex);
if (pindex->nStatus & BLOCK_IN_TMPFILE != 0 )
{
// We should be able to clear these blocks from the index as they are not in the main chains block files.
fprintf(stderr, "Block still in tempfile.%i\n",fileNumber);
}
// Prune from mapBlocksUnlinked -- any block we prune would have
// to be downloaded again in order to consider its chain, at which
// point it would be considered as a candidate for
// mapBlocksUnlinked or setBlockIndexCandidates.
std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = mapBlocksUnlinked.equal_range(pindex->pprev);
while (range.first != range.second) {
while (range.first != range.second)
{
std::multimap<CBlockIndex *, CBlockIndex *>::iterator it = range.first;
range.first++;
if (it->second == pindex) {
if (it->second == pindex)
{
mapBlocksUnlinked.erase(it);
}
}
@@ -5533,6 +5624,7 @@ void PruneOneBlockFile(bool tempfile, const int fileNumber)
if (!tempfile)
vinfoBlockFile[fileNumber].SetNull();
setDirtyFileInfo.insert(fileNumber);
return(true);
}

View File

@@ -808,7 +808,7 @@ bool WriteBlockToDisk(const CBlock& block, CDiskBlockPos& pos, const CMessageHea
bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos,bool checkPOW);
bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex,bool checkPOW);
bool RemoveOrphanedBlocks(int32_t notarized_height);
void PruneOneBlockFile(bool tempfile, const int fileNumber);
bool PruneOneBlockFile(bool tempfile, const int fileNumber);
/** Functions for validating blocks and updating the block tree */

View File

@@ -55,6 +55,8 @@
#include "sodium.h"
#include "notaries_staked.h"
#include <boost/thread.hpp>
#include <boost/tuple/tuple.hpp>
#ifdef ENABLE_MINING
@@ -151,6 +153,7 @@ int32_t komodo_is_notarytx(const CTransaction& tx);
CScript Marmara_scriptPubKey(int32_t height,CPubKey pk);
CScript MarmaraCoinbaseOpret(uint8_t funcid,int32_t height,CPubKey pk);
int32_t komodo_is_notarytx(const CTransaction& tx);
uint64_t komodo_notarypay(CMutableTransaction &txNew, std::vector<int8_t> &NotarisationNotaries, uint32_t timestamp, int32_t height, uint8_t *script, int32_t len);
CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32_t gpucount, bool isStake)
{
@@ -170,6 +173,8 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
} else pk = _pk;
uint64_t deposits; int32_t isrealtime,kmdheight; uint32_t blocktime; const CChainParams& chainparams = Params();
bool fNotarisationBlock = false; std::vector<int8_t> NotarisationNotaries;
//fprintf(stderr,"create new block\n");
// Create new block
if ( gpucount < 0 )
@@ -239,6 +244,11 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
}
}
pblock->nTime = GetAdjustedTime();
// Now we have the block time, we can get the active notaries.
int32_t staked_era; int8_t numSN;
uint8_t staked_pubkeys[64][33];
staked_era = STAKED_era(pblock->nTime);
numSN = numStakedNotaries(staked_pubkeys,staked_era);
CCoinsViewCache view(pcoinsTip);
uint32_t expired; uint64_t commission;
@@ -249,13 +259,14 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
// Priority order to process transactions
list<COrphan> vOrphan; // list memory doesn't move
map<uint256, vector<COrphan*> > mapDependers;
bool fPrintPriority = GetBoolArg("-printpriority", false);
bool fPrintPriority = GetBoolArg("-printpriority", true);
// This vector will be sorted into a priority queue:
vector<TxPriority> vecPriority;
vecPriority.reserve(mempool.mapTx.size() + 1);
// now add transactions from the mem pool
int32_t Notarisations = 0;
for (CTxMemPool::indexed_transaction_set::iterator mi = mempool.mapTx.begin();
mi != mempool.mapTx.end(); ++mi)
{
@@ -329,22 +340,33 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
nTotalIn += nValueIn;
int nConf = nHeight - coins->nHeight;
// This is to test is a tx is a notarisation and assign it max priotity.
if ( fToCryptoAddress && NOTARYADDRS[0][0] != 0 && NUM_NOTARIES != 0 )
uint8_t *script; int32_t scriptlen; uint256 hash; CTransaction tx1;
// loop over notaries array and extract index of signers.
if ( fToCryptoAddress && staked_pubkeys[0][0] != 0 && GetTransaction(txin.prevout.hash,tx1,hash,false) )
{
uint256 hash; CTransaction tx1; CTxDestination address;
if ( GetTransaction(txin.prevout.hash,tx1,hash,false) && (ExtractDestination(tx1.vout[txin.prevout.n].scriptPubKey, address)) )
for (int8_t i = 0; i < numSN; i++)
{
for (int i = 0; i < NUM_NOTARIES; i++)
if ( strcmp(NOTARYADDRS[i],CBitcoinAddress(address).ToString().c_str()) == 0 )
numNotaryVins++;
script = (uint8_t *)&tx1.vout[txin.prevout.n].scriptPubKey[0];
scriptlen = (int32_t)tx1.vout[txin.prevout.n].scriptPubKey.size();
if ( scriptlen == 35 && script[0] == 33 && script[34] == OP_CHECKSIG && memcmp(script+1,staked_pubkeys[i],33) == 0 )
{
numNotaryVins++;
if ( Notarisations == 0 )
{
// Until we get a valid notarization this will always be 0.
// We can add the index of each notary to vector, and clear it if this notarisation is not valid later on.
NotarisationNotaries.push_back(i);
}
}
}
}
dPriority += (double)nValueIn * nConf;
}
if ( NUM_NOTARIES != 0 && numNotaryVins >= NUM_NOTARIES / 5 )
if ( numSN != 0 && numNotaryVins >= numSN / 5 )
fNotarisation = true;
else
NotarisationNotaries.clear();
nTotalIn += tx.GetShieldedValueIn();
}
@@ -360,16 +382,27 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
CFeeRate feeRate(nTotalIn-tx.GetValueOut(), nTxSize);
if (fNotarisation) {
if (fNotarisation)
{
dPriority = 1e16;
//fprintf(stderr, "Notarisation.%s set to maximum priority.\n",hash.ToString().c_str());
Notarisations++;
fNotarisationBlock = true;
fprintf(stderr, "Notarisation[%i] %s set to maximum priority\n",Notarisations,hash.ToString().c_str());
}
else if ( dPriority == 1e16 )
{
dPriority -= 10;
// make sure notarisation is tx[1] in block.
// Need to check this? Tried sapling tx and it was not set to max priotity, maybe missing something.
}
if (porphan)
{
porphan->dPriority = dPriority;
porphan->feeRate = feeRate;
}
else
else if ( fNotarisation && Notarisations != 1 && is_STAKED(ASSETCHAINS_SYMBOL) != 0)
continue; // If we have added a notarisation already skip the next one. There can only be one per block.
else
vecPriority.push_back(TxPriority(dPriority, feeRate, &(mi->GetTx())));
}
@@ -637,7 +670,19 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
txNew.vout[0].scriptPubKey = CScriptExt().PayToScriptHash(CScriptID(opretScript));
txNew.vout[1].scriptPubKey = CScriptExt().OpReturnScript(opretScript, OPRETTYPE_TIMELOCK);
txNew.vout[1].nValue = 0;
} // timelocks and commissions are currently incompatible due to validation complexity of the combination
// timelocks and commissions are currently incompatible due to validation complexity of the combination
}
else if ( fNotarisationBlock && ASSETCHAINS_NOTARY_PAY != 0 && pblock->vtx[1].vout.size() == 2 && pblock->vtx[1].vout[1].nValue == 0 )
{
// Get the OP_RETURN for the notarisation
uint8_t *script = (uint8_t *)&pblock->vtx[1].vout[1].scriptPubKey[0];
int32_t scriptlen = (int32_t)pblock->vtx[1].vout[1].scriptPubKey.size();
if ( script[0] == OP_RETURN )
{
uint64_t totalsats = komodo_notarypay(txNew, NotarisationNotaries, pblock->nTime, nHeight, script, scriptlen);
fprintf(stderr, "Created notary payment coinbase totalsat.%lu\n",totalsats);
} else fprintf(stderr, "vout 2 of notarisation is not OP_RETURN scriptlen.%i\n", scriptlen);
}
pblock->vtx[0] = txNew;
pblocktemplate->vTxFees[0] = -nFees;

View File

@@ -21,7 +21,9 @@ int8_t is_STAKED(const char *chain_name) {
else if ( (strncmp(chain_name, "LABS", 4) == 0) )
STAKED = 2;
else if ( (strcmp(chain_name, "CFEK") == 0) || (strncmp(chain_name, "CFEK", 4) == 0) )
STAKED = 3;
STAKED = 3;
else if ( (strcmp(chain_name, "NOTARYTEST") == 0) )
STAKED = 4;
else if ( (strcmp(chain_name, "THIS_CHAIN_IS_BANNED") == 0) )
STAKED = 255; // This means that all notarisations for chains that are in 255 group are invalid.
doneinit = 1;

View File

@@ -23,7 +23,7 @@ static const char *iguanaSeeds[8][1] =
static const int STAKED_ERA_GAP = 777;
static const int NUM_STAKED_ERAS = 4;
static const int STAKED_NOTARIES_TIMESTAMP[NUM_STAKED_ERAS] = {1542964044, 1604222222, 1604233333, 1604244444};
static const int STAKED_NOTARIES_TIMESTAMP[NUM_STAKED_ERAS] = {1542964044, 1549184400, 1604233333, 1604244444};
// Era array of pubkeys.
static const char *notaries_STAKED[NUM_STAKED_ERAS][64][2] =
@@ -78,20 +78,22 @@ static const char *notaries_STAKED[NUM_STAKED_ERAS][64][2] =
{"blackjok3r", "021914947402d936a89fbdd1b12be49eb894a1568e5e17bb18c8a6cffbd3dc106e" }, // RTVti13NP4eeeZaCCmQxc2bnPdHxCJFP9x
{"alright", "0285657c689b903218c97f5f10fe1d10ace2ed6595112d9017f54fb42ea1c1dda8" }, //RXmXeQ8LfJK6Y1aTM97cRz9Gu5f6fmR3sg
{"webworker01", "031d1fb39ae4dca28965c3abdbd21faa0f685f6d7b87a60561afa7c448343fef6d" }, //RGsQiArk5sTmjXZV9UzGMW5njyvtSnsTN8
{"CrisF", "03f87f1bccb744d90fdbf7fad1515a98e9fc7feb1800e460d2e7565b88c3971bf3" }, //RMwEpnaVe3cesWbMqqKYPPkaLcDkooTDgZ
{"smk762", "02eacef682d2f86e0103c18f4da46116e17196f3fb8f73ed931acb78e81d8e1aa5" }, // RQVvzJ8gepCDVjhqCAc5Tia1kTmt8KDPL9
{"jorian", "02150c410a606b898bcab4f083e48e0f98a510e0d48d4db367d37f318d26ae72e3" }, // RFgzxZe2P4RWKx6E9QGPK3rx3TXeWxSqa8
{"CrisF", "024d19acf0d5de212cdd50326cd143292545d366a71b2b9c6df9f2110de2dfa1f2" }, // RKtAD2kyRRMx4EiG1eeTNprF5h2nmGbzzu
{"smk762", "029f6c1f38c4d6825acb3b4b5147f7992e943b617cdaa0f4f5f36187e239d52d5a" }, // RPy6Xj2LWrxNoEW9YyREDgBZDZZ5qURXBU
{"jorian", "0288e682c1ac449f1b85c4acb2d0bcd216d5df34c15fd18b8a8dd5fa64b8ece8ef" }, // RR1yT5aB19VwFoUCGTW4q4pk4qmhHEEE4t
{"TonyL", "021a559101e355c907d9c553671044d619769a6e71d624f68bfec7d0afa6bd6a96" }, // RHq3JsvLxU45Z8ufYS6RsDpSG4wi6ucDev
{"Emman", "038f642dcdacbdf510b7869d74544dbc6792548d9d1f8d73a999dd9f45f513c935" }, //RN2KsQGW36Ah4NorJDxLJp2xiYJJEzk9Y6
{"CHMEX", "03ed125d1beb118d12ff0a052bdb0cee32591386d718309b2924f2c36b4e7388e6" }, // RF4HiVeuYpaznRPs7fkRAKKYqT5tuxQQTL
{"metaphilibert", "0344182c376f054e3755d712361672138660bda8005abb64067eb5aa98bdb40d10" }, // RG28QSnYFADBg1dAVkH1uPGYS6F8ioEUM2
{"jusoaresf", "02dfb7ed72a23f6d07f0ea2f28192ee174733cc8412ec0f97b073007b78fab6346" }, // RBQGfE5Hxsjm1BPraTxbneRuNasPDuoLnu
{"mylo", "03f6b7fcaf0b8b8ec432d0de839a76598b78418dadd50c8e5594c0e557d914ec09" }, // RXN4hoZkhUkkrnef9nTUDw3E3vVALAD8Kx
{"blackjok3r2", "02f7597468703c1c5c8465dd6d43acaae697df9df30bed21494d193412a1ea193e" }, // RWHGbrLSP89fTzNVF9U9xiekDYJqcibTca
{"blackjok3r3", "03c3e4c0206551dbf3a4b24d18e5d2737080541184211e3bfd2b1092177410b9c2" }, // RMMav2AVse5XHPvDfTzRpMbFhK3GqFmtSN
{"kmdkrazy", "02f7597468703c1c5c8465dd6d43acaae697df9df30bed21494d193412a1ea193e" }, // RWHGbrLSP89fTzNVF9U9xiekDYJqcibTca
{"alrighttest", "02e9dfe248f453b499315a90375e58a1c9ad79f5f3932ecb2205399a0f262d65fc" }, // RBevSstS8JtDXMEFNcJws4QTYN4PcE2VL5
{"alrighttest1", "03527c7ecd6a8c5db6d685a64e6e18c1edb49e2f057a434f56c3f1253a26e9c6a2" }, // RBw2jNU3dnGk86ZLqPMadJwRwg3NU8eC6s
{"greentea", "02054c14ae81838a063d22a75eaa3c961415f6825a57c8b8e4148d19dad64f128e" }, // REF7R76WpL1v7nSXjjiNHtRa2xYtq5qk1p
{"CMaurice", "025830ce81bd1301fb67d5872344efa7a9ff99ae85fe1234f18c085db9072b740f" }, // RX7pXUaV24xFn6DVKV8t3PrRF3gKw6TBjf
{"Bar_F1sh_Rel", "0395f2d9dd9ccb78caf74bff49b6d959afb95af746462e1b35f4a167d8e82b3666" }, // RBbLxJagCA9QHDazQvfnDZe874V1K4Gu8t
{"zatJUM", "030fff499b6dc0215344b28a0b6b4becdfb00cd34cd1b36b983ec14f47965fd4bc" }, // RSoEDLBasth7anxS8gbkg6KgeGiz8rhqv1
{"dwy", "03669457b2934d98b5761121dd01b243aed336479625b293be9f8c43a6ae7aaeff" }, // RKhZMqRF361FSGFAzstP5AhozekPjoVh5q
{"gcharang", "03336ca9db27cb6e882830e20dc525884e27dc94d557a5e68b972a5cbf9e8c62a8" }, // RJYiWn3FRCSSLf9Pe5RJcbrKQYosaMburP
{"computergenie", "03448ce28fb21748e8b05bbe32d6b1e758b589ac1eb359e5d552f8868f2b75dc92" }, // RGeniexxkjnR34hg7ZnCf36kmfuJusf6rE
{"daemonfox", "0383484bdc745b2b953c85b5a0c496a1f27bc42ae971f15779ed1532421b3dd943" }, //
{"SHossain", "02791f5c215b8a19c143a98e3371ff03b5613df9ac430c4a331ca55fed5761c800" }, // RKdLoHkyeorXmMtj91B1AAnAGiwsdt9MdF
{"Nabob", "03ee91c20b6d26e3604022f42df6bb8de6f669da4591f93b568778cba13d9e9ddf" }, // RRwCLPZDzpHEFJnLev4phy51e2stHRUAaU
},
{
{"blackjok3r", "021914947402d936a89fbdd1b12be49eb894a1568e5e17bb18c8a6cffbd3dc106e" }, // RTVti13NP4eeeZaCCmQxc2bnPdHxCJFP9x
@@ -114,7 +116,7 @@ static const char *notaries_STAKED[NUM_STAKED_ERAS][64][2] =
}
};
static const int32_t num_notaries_STAKED[NUM_STAKED_ERAS] = { 17, 25, 17, 17 };
static const int32_t num_notaries_STAKED[NUM_STAKED_ERAS] = { 17, 25, 19, 17 };
int8_t is_STAKED(const char *chain_name);
int32_t STAKED_era(int timestamp);

View File

@@ -79,7 +79,7 @@ int8_t StakedNotaryID(std::string &notaryname, char *Raddress);
#define VERUS_VERSION "0.4.0g"
extern uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT;
extern uint32_t ASSETCHAINS_CC;
extern uint32_t ASSETCHAINS_MAGIC;
extern uint32_t ASSETCHAINS_MAGIC,ASSETCHAINS_ALGO;
extern uint64_t ASSETCHAINS_COMMISSION,ASSETCHAINS_SUPPLY;
extern int32_t ASSETCHAINS_LWMAPOS,ASSETCHAINS_SAPLING,ASSETCHAINS_STAKED;
extern uint64_t ASSETCHAINS_ENDSUBSIDY[],ASSETCHAINS_REWARD[],ASSETCHAINS_HALVING[],ASSETCHAINS_DECAY[];
@@ -319,6 +319,8 @@ UniValue getinfo(const UniValue& params, bool fHelp)
obj.push_back(Pair("staked", ASSETCHAINS_STAKED));
if ( ASSETCHAINS_LWMAPOS != 0 )
obj.push_back(Pair("veruspos", ASSETCHAINS_LWMAPOS));
if ( ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH )
obj.push_back(Pair("algo",ASSETCHAINS_ALGORITHMS[ASSETCHAINS_ALGO]));
}
return obj;
}

View File

@@ -4777,7 +4777,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
+ strprintf("%d", MERGE_TO_ADDRESS_DEFAULT_TRANSPARENT_LIMIT) + ") Limit on the maximum number of UTXOs to merge. Set to 0 to use node option -mempooltxinputlimit (before Overwinter), or as many as will fit in the transaction (after Overwinter).\n"
"4. shielded_limit (numeric, optional, default="
+ strprintf("%d Sprout or %d Sapling Notes", MERGE_TO_ADDRESS_DEFAULT_SPROUT_LIMIT, MERGE_TO_ADDRESS_DEFAULT_SAPLING_LIMIT) + ") Limit on the maximum number of notes to merge. Set to 0 to merge as many as will fit in the transaction.\n"
"5. maximum_utxo_size (numeric, optional) eg, 0.0001 anything under 10000 satoshies will be merged, ignores p2pk utxo!\n"
"5. maximum_utxo_size (numeric, optional) eg, 0.0001 anything under 10000 satoshies will be merged, ignores 10,000 sat p2pk utxo that iguana uses, and merges coinbase utxo.\n"
"6. \"memo\" (string, optional) Encoded as hex. When toaddress is a z-addr, this will be stored in the memo field of the new note.\n"
"\nResult:\n"
@@ -4960,7 +4960,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
if (useAnyUTXO || taddrs.size() > 0) {
// Get available utxos
vector<COutput> vecOutputs;
pwalletMain->AvailableCoins(vecOutputs, true, NULL, false, false);
pwalletMain->AvailableCoins(vecOutputs, true, NULL, false, maximum_utxo_size != 0 ? true : false);
// Find unspent utxos and update estimated size
for (const COutput& out : vecOutputs) {
@@ -4981,14 +4981,13 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
CAmount nValue = out.tx->vout[out.i].nValue;
if (maximum_utxo_size != 0) {
if (nValue > maximum_utxo_size) {
continue;
} else {
if (out.tx->vout[out.i].scriptPubKey.size() == 35 && nValue == 10000) {
continue;
}
}
if (maximum_utxo_size != 0)
{
//fprintf(stderr, "utxo txid.%s vout.%i nValue.%li scriptpubkeylength.%i\n",out.tx->GetHash().ToString().c_str(),out.i,nValue,out.tx->vout[out.i].scriptPubKey.size());
if (nValue > maximum_utxo_size)
continue;
if (nValue == 10000 && out.tx->vout[out.i].scriptPubKey.size() == 35)
continue;
}
utxoCounter++;
@@ -5093,10 +5092,11 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
size_t numUtxos = utxoInputs.size();
size_t numNotes = sproutNoteInputs.size() + saplingNoteInputs.size();
fprintf(stderr, "num utxos.%li\n", numUtxos);
if (numUtxos < 2 && numNotes == 0) {
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Could not find any funds to merge.");
}
// Sanity check: Don't do anything if:
// - We only have one from address
// - It's equal to toaddress