Merge branch 'notarytest'
x
This commit is contained in:
68
src/komodo.h
68
src/komodo.h
@@ -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,¬arizedheight,(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,¬arizedheight,(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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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,¬arizedhash,&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,¬arizedheight,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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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","");
|
||||
|
||||
174
src/main.cpp
174
src/main.cpp
@@ -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,¬arized_hash,¬arized_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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -79,7 +79,7 @@ int8_t StakedNotaryID(std::string ¬aryname, 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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user