New method of ac_notarypay

This commit is contained in:
blackjok3r
2019-02-03 02:37:04 +08:00
parent f82808e036
commit 0ee5e12f08
4 changed files with 187 additions and 80 deletions

View File

@@ -1772,17 +1772,67 @@ bool verusCheckPOSBlock(int32_t slowflag, CBlock *pblock, int32_t height)
return(isPOS);
}
uint64_t komodo_notarypay(CMutableTransaction &txNew, std::vector<int8_t> &NotarisationNotaries, uint32_t timestamp)
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;
uint64_t total = 0, AmountToPay = 0;
int32_t staked_era; int8_t numSN;
uint8_t staked_pubkeys[64][33];
staked_era = STAKED_era(timestamp);
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, "VALID NOTARIZATION ht.%i\n",notarizedheight);
}
else
{
fprintf(stderr, "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++)
@@ -1798,7 +1848,7 @@ uint64_t komodo_notarypay(CMutableTransaction &txNew, std::vector<int8_t> &Notar
}
ptr[34] = OP_CHECKSIG;
//fprintf(stderr," set notary %i PUBKEY33 into vout[%i]\n",NotarisationNotaries[n],n+1);
txNew.vout[n+1].nValue = ASSETCHAINS_NOTARY_PAY;
txNew.vout[n+1].nValue = AmountToPay;
total += txNew.vout[n+1].nValue;
}
return(total);
@@ -1832,35 +1882,69 @@ uint64_t komodo_checknotarypay(CBlock *pblock,int32_t height)
}
const CChainParams& chainparams = Params();
const Consensus::Params &consensusParams = chainparams.GetConsensus();
uint64_t totalsats = 0;
CMutableTransaction txNew = CreateNewContextualCMutableTransaction(consensusParams, height);
uint64_t totalsats = komodo_notarypay(txNew, NotarisationNotaries, pblock->nTime);
int8_t n = 0, i = 0, matches = 0;
uint64_t total = 0;
//fprintf(stderr, "txNew.vout size = %li\n",txNew.vout.size());
// Check the created coinbase is equal to the coinbase the miner submitted in the block.
BOOST_FOREACH(const CTxOut& txout, txNew.vout)
if ( pblock->vtx[1].vout.size() == 2 && pblock->vtx[1].vout[1].nValue == 0 )
{
if ( n == 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 )
{
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(-1);
}
}
// if notarypay fails, because the notarisation is not valid, exit now as txNew was not created.
if ( totalsats == 0 )
{
fprintf(stderr, "notary pay RETURNED 0!\n");
return(-1);
}
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;
//fprintf(stderr, "txNew.vout size = %li\n",txNew.vout.size());
// Check the created coinbase pays the correct notaries.
BOOST_FOREACH(const CTxOut& txout, pblock->vtx[0].vout)
{
// skip the coinbase
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 ( txout.nValue == ASSETCHAINS_NOTARY_PAY && scriptlen == 35 && script[0] == 33 && script[34] == OP_CHECKSIG && memcmp(script+1,staked_pubkeys[NotarisationNotaries[n-1]],33) == 0 )
if ( scriptlen == 35 && script[0] == 33 && script[34] == OP_CHECKSIG && memcmp(script+1,staked_pubkeys[NotarisationNotaries[n-1]],33) == 0 )
{
matches++;
total += txout.nValue;
fprintf(stderr, "matched.%i\n", NotarisationNotaries[n-1]);
// check the value is correct
if ( pblock->vtx[0].vout[n].nValue == AmountToPay )
{
matches++;
total += txout.nValue;
fprintf(stderr, "matched.%i\n", 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++;
n++;
}
if ( matches = n && matches != 0 && total == totalsats )
if ( matches != 0 && matches == NotarisationNotaries.size() && totalsats == total )
{
fprintf(stderr, "VALIDATED.\n" );
return(totalsats);
}
return(-1);
return(0);
}
int64_t komodo_checkcommission(CBlock *pblock,int32_t height)
@@ -2043,14 +2127,10 @@ int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height)
return(-1);
}
}
if( failed == 0 && ASSETCHAINS_NOTARY_PAY != 0 && pblock->vtx[0].vout.size() != 1 )
if ( failed == 0 && ASSETCHAINS_NOTARY_PAY != 0 && pblock->vtx[0].vout.size() > 1 )
{
if ( slowflag != 0 && komodo_checknotarypay(pblock,height) < 0 )
{
fprintf(stderr, "Komodo notary pay validation failed.%i\n",height);
return(-1);
}
else
// 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 )