From 8b70bbf3070578ea5dd0d8f9c35ec38d6d2141fa Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Sat, 27 Apr 2019 22:30:43 +0800 Subject: [PATCH] fix --- src/ac/koin | 2 + src/assetchains.json | 11 ++-- src/assetchains.old | 1 + src/cc/CCPayments.h | 2 +- src/cc/COptCCParams.cpp | 116 ++++++++++++++++++++++++++++++++++++++++ src/cc/payments.cpp | 14 +++-- src/fiat/koin | 2 + src/komodo.h | 2 +- src/main.cpp | 65 +++++++++++++--------- 9 files changed, 177 insertions(+), 38 deletions(-) create mode 100755 src/ac/koin create mode 100644 src/cc/COptCCParams.cpp create mode 100755 src/fiat/koin diff --git a/src/ac/koin b/src/ac/koin new file mode 100755 index 000000000..7e76c6b54 --- /dev/null +++ b/src/ac/koin @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=KOIN $1 $2 $3 $4 $5 $6 diff --git a/src/assetchains.json b/src/assetchains.json index 87173697b..99c6557b6 100644 --- a/src/assetchains.json +++ b/src/assetchains.json @@ -237,8 +237,8 @@ "217.182.129.38", "37.187.225.231" ] - }, - { + }, + { "ac_name": "ILN", "ac_supply": "10000000000", "ac_cc": "2", @@ -258,10 +258,15 @@ "ac_cc": "3", "addnode": ["138.201.136.145"] }, -{ + { "ac_name": "VOTE2019", "ac_supply": "123651638", "ac_public": "1", "addnode": ["95.213.238.98"] + }, + { + "ac_name": "KOIN", + "ac_supply": "125000000", + "addnode": ["3.0.32.10"] } ] diff --git a/src/assetchains.old b/src/assetchains.old index 8f0d763b5..a0cbd3b9c 100755 --- a/src/assetchains.old +++ b/src/assetchains.old @@ -50,3 +50,4 @@ echo $pubkey ./komodod -pubkey=$pubkey -ac_name=RICK -ac_supply=90000000000 -ac_reward=100000000 -ac_cc=3 -addnode=138.201.136.145 & ./komodod -pubkey=$pubkey -ac_name=MORTY -ac_supply=90000000000 -ac_reward=100000000 -ac_cc=3 -addnode=138.201.136.145 & ./komodod -pubkey=$pubkey -ac_name=VOTE2019 -ac_supply=123651638 -ac_public=1 -addnode=95.213.238.98 & +./komodod -pubkey=$pubkey -ac_name=KOIN -ac_supply=125000000 -addnode=3.0.32.10 & diff --git a/src/cc/CCPayments.h b/src/cc/CCPayments.h index 6eeb7bcb3..3f5a10087 100644 --- a/src/cc/CCPayments.h +++ b/src/cc/CCPayments.h @@ -20,7 +20,7 @@ #include "CCinclude.h" #define PAYMENTS_TXFEE 10000 -bool komodo_snapshot2(std::map &addressAmounts); +extern std::vector > vAddressSnapshot; bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn); diff --git a/src/cc/COptCCParams.cpp b/src/cc/COptCCParams.cpp new file mode 100644 index 000000000..41c9ba874 --- /dev/null +++ b/src/cc/COptCCParams.cpp @@ -0,0 +1,116 @@ +/*Descriptson and examples of COptCCParams class found in: + script/standard.h/cpp + class COptCCParams + +structure of data in vData payload attached to end of CCvout: + param + OP_1 + param + OP_2 ... etc until OP_16 + OP_PUSHDATA4 is the last OP code to tell things its at the end. + + taken from standard.cpp line 22: COptCCParams::COptCCParams(std::vector &vch) + +EXAMPLE taken from Verus how to create scriptPubKey from COptCCParams class: +EXAMPLE taken from Verus how to decode scriptPubKey from COptCCParams class: +*/ + +bool MakeGuardedOutput(CAmount value, CPubKey &dest, CTransaction &stakeTx, CTxOut &vout) +{ + CCcontract_info *cp, C; + cp = CCinit(&C,EVAL_STAKEGUARD); + + CPubKey ccAddress = CPubKey(ParseHex(cp->CChexstr)); + + // return an output that is bound to the stake transaction and can be spent by presenting either a signed condition by the original + // destination address or a properly signed stake transaction of the same utxo on a fork + vout = MakeCC1of2vout(EVAL_STAKEGUARD, value, dest, ccAddress); + + std::vector vPubKeys = std::vector(); + vPubKeys.push_back(dest); + vPubKeys.push_back(ccAddress); + + std::vector> vData = std::vector>(); + + CVerusHashWriter hw = CVerusHashWriter(SER_GETHASH, PROTOCOL_VERSION); + + hw << stakeTx.vin[0].prevout.hash; + hw << stakeTx.vin[0].prevout.n; + + uint256 utxo = hw.GetHash(); + vData.push_back(std::vector(utxo.begin(), utxo.end())); // Can we use any data here to construct vector? + + CStakeParams p; + if (GetStakeParams(stakeTx, p)) + { + // prev block hash and height is here to make validation easy + vData.push_back(std::vector(p.prevHash.begin(), p.prevHash.end())); + std::vector height = std::vector(4); + for (int i = 0; i < 4; i++) + { + height[i] = (p.blkHeight >> (8 * i)) & 0xff; + } + vData.push_back(height); + + COptCCParams ccp = COptCCParams(COptCCParams::VERSION, EVAL_STAKEGUARD, 1, 2, vPubKeys, vData); + + vout.scriptPubKey << ccp.AsVector() << OP_DROP; + return true; + } + return false; +} + +bool ValidateMatchingStake(const CTransaction &ccTx, uint32_t voutNum, const CTransaction &stakeTx, bool &cheating) +{ + // an invalid or non-matching stake transaction cannot cheat + cheating = false; + + //printf("ValidateMatchingStake: ccTx.vin[0].prevout.hash: %s, ccTx.vin[0].prevout.n: %d\n", ccTx.vin[0].prevout.hash.GetHex().c_str(), ccTx.vin[0].prevout.n); + + if (ccTx.IsCoinBase()) + { + CStakeParams p; + if (ValidateStakeTransaction(stakeTx, p)) + { + std::vector> vParams = std::vector>(); + CScript dummy; + + if (ccTx.vout[voutNum].scriptPubKey.IsPayToCryptoCondition(&dummy, vParams) && vParams.size() > 0) + { + COptCCParams ccp = COptCCParams(vParams[0]); + if (ccp.IsValid() & ccp.vData.size() >= 3 && ccp.vData[2].size() <= 4) + { + CVerusHashWriter hw = CVerusHashWriter(SER_GETHASH, PROTOCOL_VERSION); + + hw << stakeTx.vin[0].prevout.hash; + hw << stakeTx.vin[0].prevout.n; + uint256 utxo = hw.GetHash(); + + uint32_t height = 0; + int i, dataLen = ccp.vData[2].size(); + for (i = dataLen - 1; i >= 0; i--) + { + height = (height << 8) + ccp.vData[2][i]; + } + // for debugging strange issue + // printf("iterator: %d, height: %d, datalen: %d\n", i, height, dataLen); + + if (utxo == uint256(ccp.vData[0])) + { + if (p.prevHash != uint256(ccp.vData[1]) && p.blkHeight >= height) + { + cheating = true; + return true; + } + // if block height is equal and we are at the else, prevHash must have been equal + else if (p.blkHeight == height) + { + return true; + } + } + } + } + } + } + return false; +} diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index 6f6ae1a84..569c4eb14 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -16,17 +16,18 @@ #include "CCPayments.h" /* +use notarizations DB to scan back from the correct height, then undo ALL blocks back to this notarized height! payments airdrop: - extra RPC to merge all payments inputs to a single utxo, this must be called first and be confirmed before payments release, or tx will be too big, we can check add payments inputs is only 1 input, at RPC and in validation very early on. - - do getsnapshot2 every 1440 blocks and save the result into some global sorted vector or DB? + - do getsnapshot2 every 1440 blocks and save the result into some global sorted vector. -this allows any address balance to be calculated by only iterating each 1439 blocks maximum. - calculate scriptpubkey to pay from each address, set allocations from balance of each address. allocation = balance? -payments airdrop paying a token: ( maybe this is more reasonable speed wise? ) +payments airdrop paying a token: - tokenid, top number of tokens to pay, list of pubkeys to exclude as optional param - - add vector of tokenids to getsnapshot2 - then sort each tokenid by balance. - put the pubkey to pay to as scriptpubkey in the saved vector. + - token airdrop code should be the same as normal snapshot, but call a diffrent snapshot function that only fetches the info for a specific tokenid given. + this should be fine to work in validation/rpc level rather than a global saved result, as a single token id doesnt require iterating the whole DB. 0) txidopret <- allocation, scriptPubKey, opret 1) create <- locked_blocks, minrelease, list of txidopret @@ -793,13 +794,10 @@ UniValue PaymentsCreate(struct CCcontract_info *cp,char *jsonstr) return(result); } -extern bool komodo_dailysnapshot(int32_t height); - UniValue PaymentsAirdrop(struct CCcontract_info *cp,char *jsonstr) { uint64_t start = time(NULL); - komodo_dailysnapshot(chainActive.Height()); - //CScript scriptPubKey = GetScriptForDestination(dest); + return(time(NULL)-start); } diff --git a/src/fiat/koin b/src/fiat/koin new file mode 100755 index 000000000..7e76c6b54 --- /dev/null +++ b/src/fiat/koin @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=KOIN $1 $2 $3 $4 $5 $6 diff --git a/src/komodo.h b/src/komodo.h index 15c1e5c02..b4c7d12bf 100644 --- a/src/komodo.h +++ b/src/komodo.h @@ -621,7 +621,7 @@ int32_t komodo_voutupdate(bool fJustCheck,int32_t *isratificationp,int32_t notar memset(&MoMoMdata,0,sizeof(MoMoMdata)); if ( matched == 0 && signedmask != 0 && bitweight(signedmask) >= KOMODO_MINRATIFY ) notarized = 1; - if ( strcmp("PIZZA",ccdata.symbol) == 0 || strncmp("TXSCL",ccdata.symbol,5) == 0 ) + if ( strcmp("PIZZA",ccdata.symbol) == 0 || strncmp("TXSCL",ccdata.symbol,5) == 0 || strcmp("BEER",ccdata.symbol) == 0) notarized = 1; if ( 0 && opretlen != 149 ) printf("[%s].%d (%s) matched.%d i.%d j.%d notarized.%d %llx opretlen.%d len.%d offset.%d opoffset.%d\n",ASSETCHAINS_SYMBOL,height,ccdata.symbol,matched,i,j,notarized,(long long)signedmask,opretlen,len,offset,opoffset); diff --git a/src/main.cpp b/src/main.cpp index f4511c284..8bace2cb0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -656,19 +656,34 @@ std::vector > vAddressSnapshot; bool komodo_dailysnapshot(int32_t height) { - uint256 notarized_hash,notarized_desttxid; int32_t prevMoMheight,notarized_height,undo_height; - notarized_height = komodo_notarized_height(&prevMoMheight,¬arized_hash,¬arized_desttxid); - if ( notarized_height > height-100 ) + uint256 notarized_hash,notarized_desttxid; int32_t prevMoMheight,notarized_height,undo_height,extraoffset; + if ( (extraoffset= height % KOMODO_SNAPSHOT_INTERVAL) != 0 ) { - // notarized height is higher than 100 blocks before this height, so snapshot the notarized height. - undo_height = notarized_height; + // we are on chain init, and need to scan all the way back to the correct height, other wise our node will have a diffrent snapshot to online nodes. + // use the notarizationsDB to scan back from the consesnus height to get the offset we need. + std::string symbol; Notarisation nota; + symbol.assign(ASSETCHAINS_SYMBOL); + ScanNotarisationsDB(height-extraoffset, symbol, 100, nota); + undo_height = nota.second.height; + if ( undo_height == 0 ) undo_height = height-extraoffset-100; + fprintf(stderr, "height.%i-extraoffset.%i = startscanfrom.%i to get undo_height.%i\n", height, extraoffset, height-extraoffset, undo_height); } - else + else { - //snapshot 100 blocks ago. Could still be reorged but very unlikley and expensive to carry out constantly. - undo_height = height-100; + // we are at the right height in connect block to scan back to last notarized height. + notarized_height = komodo_notarized_height(&prevMoMheight,¬arized_hash,¬arized_desttxid); + if ( notarized_height > height-100 ) + { + // notarized height is higher than 100 blocks before this height, so snapshot the notarized height. + undo_height = notarized_height; + } + else + { + //snapshot 100 blocks ago. Could still be reorged but very unlikley and expensive to carry out constantly. + undo_height = height-100; + } } - fprintf(stderr, "doing snapshot for height.%i lastSnapShotHeight.%i\n", undo_height, lastSnapShotHeight); + fprintf(stderr, "doing snapshot for height.%i undo_height.%i\n", height, undo_height); // if we already did this height dont bother doing it again, this is just a reorg. The actual snapshot height cannot be reorged. if ( undo_height == lastSnapShotHeight ) return true; @@ -690,30 +705,29 @@ bool komodo_dailysnapshot(int32_t height) uint256 hash = tx.GetHash(); CTxDestination vDest; //fprintf(stderr, "undong tx.%s\n",hash.GetHex().c_str()); - // loop vouts reverse order + // loop vouts reverse order, remove value recieved. for (unsigned int k = tx.vout.size(); k-- > 0;) { const CTxOut &out = tx.vout[k]; - //fprintf(stderr, "scriptpubkey.%s\n",out.scriptPubKey.ToString().c_str() ); if ( ExtractDestination(out.scriptPubKey, vDest) ) { - // add outputs to destination - addressAmounts[CBitcoinAddress(vDest).ToString()] += out.nValue; - //fprintf(stderr, "address.%s addcoins.%li\n",CBitcoinAddress(vDest).ToString().c_str(), out.nValue); + addressAmounts[CBitcoinAddress(vDest).ToString()] -= out.nValue; + if ( addressAmounts[CBitcoinAddress(vDest).ToString()] < 1 ) + addressAmounts.erase(CBitcoinAddress(vDest).ToString()); + //fprintf(stderr, "VOUT: address.%s remove_coins.%li\n",CBitcoinAddress(vDest).ToString().c_str(), out.nValue); } } - // loop vins in reverse order, get prevout and remove the balance from its destination + // loop vins in reverse order, get prevout and return the sent balance. for (unsigned int j = tx.vin.size(); j-- > 0;) { uint256 blockhash; CTransaction txin; - if ( !tx.IsCoinImport() && !tx.IsCoinBase() && GetTransaction(tx.vin[j].prevout.hash,txin,blockhash,false) ) // myGetTransaction! + if ( !tx.IsCoinImport() && !tx.IsCoinBase() && myGetTransaction(tx.vin[j].prevout.hash,txin,blockhash) ) // myGetTransaction! { int vout = tx.vin[j].prevout.n; if ( ExtractDestination(txin.vout[vout].scriptPubKey, vDest) ) { - // remove outputs from destination - //fprintf(stderr, "address.%s removecoins.%li\n",CBitcoinAddress(vDest).ToString().c_str(), txin.vout[vout].nValue); - addressAmounts[CBitcoinAddress(vDest).ToString()] -= txin.vout[vout].nValue; + //fprintf(stderr, "VIN: address.%s add_coins.%li\n",CBitcoinAddress(vDest).ToString().c_str(), txin.vout[vout].nValue); + addressAmounts[CBitcoinAddress(vDest).ToString()] += txin.vout[vout].nValue; } } } @@ -725,6 +739,8 @@ bool komodo_dailysnapshot(int32_t height) vAddressSnapshot.push_back(make_pair(element.second, DecodeDestination(element.first))); // sort the vector by amount, highest at top. std::sort(vAddressSnapshot.rbegin(), vAddressSnapshot.rend()); + //for (int j = 0; j < 50; j++) + // fprintf(stderr, "j.%i address.%s nValue.%li\n",j, CBitcoinAddress(vAddressSnapshot[j].second).ToString().c_str(), vAddressSnapshot[j].first ); // include only top 5000 address. if ( vAddressSnapshot.size() > 5000 ) vAddressSnapshot.resize(5000); lastSnapShotHeight = undo_height; @@ -4339,10 +4355,10 @@ static bool ActivateBestChainStep(bool fSkipdpow, CValidationState &state, CBloc // stay on the same chain tip! int32_t notarizedht,prevMoMheight; uint256 notarizedhash,txid; notarizedht = komodo_notarized_height(&prevMoMheight,¬arizedhash,&txid); - if ( !fSkipdpow && pindexFork != 0 && pindexFork->GetHeight() < notarizedht ) + if ( !fSkipdpow && pindexFork != 0 && pindexOldTip->GetHeight() > notarizedht && pindexFork->GetHeight() < notarizedht ) { - fprintf(stderr,"pindexFork->GetHeight().%d is < notarizedht %d, so ignore it\n",(int32_t)pindexFork->GetHeight(),notarizedht); - return state.DoS(100, error("ActivateBestChainStep(): pindexFork->GetHeight().%d is < notarizedht %d, so ignore it",(int32_t)pindexFork->GetHeight(),notarizedht), + fprintf(stderr,"pindexOldTip->GetHeight().%d > notarizedht %d && pindexFork->GetHeight().%d is < notarizedht %d, so ignore it\n",(int32_t)pindexFork->GetHeight(),notarizedht,(int32_t)pindexOldTip->GetHeight(),notarizedht); + return state.DoS(100, error("ActivateBestChainStep(): pindexOldTip->GetHeight().%d > notarizedht %d && pindexFork->GetHeight().%d is < notarizedht %d, so ignore it",(int32_t)pindexFork->GetHeight(),notarizedht,(int32_t)pindexOldTip->GetHeight(),notarizedht), REJECT_INVALID, "past-notarized-height"); } // - On ChainDB initialization, pindexOldTip will be null, so there are no removable blocks. @@ -6192,10 +6208,9 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth LogPrintf("No coin database inconsistencies in last %i blocks (%i transactions)\n", chainActive.Height() - pindexState->GetHeight(), nGoodTransactions); - if ( ASSETCHAINS_CC != 0 && lastSnapShotHeight == 0 ) + if ( ASSETCHAINS_CC != 0 && chainActive.Height() > KOMODO_SNAPSHOT_INTERVAL ) { - int32_t init_SS_height = chainActive.Height() - (chainActive.Height() % KOMODO_SNAPSHOT_INTERVAL); - if ( !komodo_dailysnapshot(init_SS_height) ) + if ( !komodo_dailysnapshot(chainActive.Height()) ) fprintf(stderr, "daily snapshot failed, please reindex your chain\n"); // maybe force shutdown here? }