diff --git a/src/komodo_defs.h b/src/komodo_defs.h index 7c339856c..1efd187d9 100644 --- a/src/komodo_defs.h +++ b/src/komodo_defs.h @@ -10,4 +10,6 @@ #define KOMODO_MAXMEMPOOLTIME 3600 // affects consensus #define CRYPTO777_PUBSECPSTR "020e46e79a2a8d12b9b5d12c7a91adb4e454edfae43c0a0cb805427d2ac7613fd9" +extern uint8_t ASSETCHAINS_TXPOW; + #endif diff --git a/src/komodo_globals.h b/src/komodo_globals.h index 33d269793..68eee6665 100644 --- a/src/komodo_globals.h +++ b/src/komodo_globals.h @@ -48,7 +48,7 @@ int COINBASE_MATURITY = _COINBASE_MATURITY;//100; int32_t KOMODO_MININGTHREADS = -1,IS_KOMODO_NOTARY,ASSETCHAINS_STREAM,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,ASSETCHAINS_SEED,KOMODO_ON_DEMAND,KOMODO_EXTERNAL_NOTARIES,KOMODO_PASSPORT_INITDONE,KOMODO_PAX,KOMODO_EXCHANGEWALLET,KOMODO_REWIND,KOMODO_CONNECTING = -1; int32_t KOMODO_INSYNC,KOMODO_LASTMINED,prevKOMODO_LASTMINED,KOMODO_CCACTIVATE,JUMBLR_PAUSE = 1; std::string ASSETCHAINS_OVERRIDE_ADDRESS,NOTARY_PUBKEY,ASSETCHAINS_NOTARIES,ASSETCHAINS_,ASSETCHAINS_OVERRIDE_PUBKEY,DONATION_PUBKEY; -uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33],ASSETCHAINS_PUBLIC,ASSETCHAINS_PRIVATE; +uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33],ASSETCHAINS_PUBLIC,ASSETCHAINS_PRIVATE,ASSETCHAINS_TXPOW; char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN],ASSETCHAINS_USERPASS[4096]; uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT; diff --git a/src/komodo_utils.h b/src/komodo_utils.h index ef33bd56b..5d41804d2 100644 --- a/src/komodo_utils.h +++ b/src/komodo_utils.h @@ -1554,7 +1554,8 @@ void komodo_args(char *argv0) if ( name.c_str()[0] != 0 ) { MAX_BLOCK_SIGOPS = 60000; - ASSETCHAINS_SUPPLY = GetArg("-ac_supply",10); + ASSETCHAINS_TXPOW = GetArg("-ac_txpow",0) & 3; + ASSETCHAINS_SUPPLY = GetArg("-ac_supply",10); ASSETCHAINS_ENDSUBSIDY = GetArg("-ac_end",0); ASSETCHAINS_REWARD = GetArg("-ac_reward",0); ASSETCHAINS_HALVING = GetArg("-ac_halving",0); @@ -1564,7 +1565,7 @@ void komodo_args(char *argv0) ASSETCHAINS_FOUNDERS_REWARD = GetArg("-ac_freward",0); ASSETCHAINS_OVERRIDE_ADDRESS = GetArg("-ac_address",""); ASSETCHAINS_STREAM = GetArg("-ac_stream",0); - + if ( ASSETCHAINS_STREAM != 0 && ( ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_ENDSUBSIDY != 0 || ASSETCHAINS_REWARD != 0 || ASSETCHAINS_HALVING != 0 || ASSETCHAINS_DECAY != 0 || ASSETCHAINS_PRIVATE != 0 )) { printf("ASSETCHAINS_STREAM cannot be used with:\n ASSETCHAINS_COMMISSION \n ASSETCHAINS_ENDSUBSIDY\n ASSETCHAINS_REWARD\n ASSETCHAINS_HALVING\n ASSETCHAINS_DECAY\n ASSETCHAINS_PRIVATE\n"); exit(0); @@ -1605,7 +1606,7 @@ void komodo_args(char *argv0) ASSETCHAINS_SUPPLY = 1000000; printf("ASSETCHAINS_STREAM is set with no supply, setting supply at 1,000,000 coins. \n"); } - if ( ASSETCHAINS_ENDSUBSIDY != 0 || ASSETCHAINS_REWARD != 0 || ASSETCHAINS_HALVING != 0 || ASSETCHAINS_DECAY != 0 || ASSETCHAINS_STREAM != 0 || ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_PUBLIC != 0 || ASSETCHAINS_PRIVATE != 0 ) + if ( ASSETCHAINS_ENDSUBSIDY != 0 || ASSETCHAINS_REWARD != 0 || ASSETCHAINS_HALVING != 0 || ASSETCHAINS_DECAY != 0 || ASSETCHAINS_STREAM != 0 || ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_PUBLIC != 0 || ASSETCHAINS_PRIVATE != 0 || ASSETCHAINS_TXPOW != 0 ) { fprintf(stderr,"end.%llu blocks, reward %.8f halving.%llu blocks, decay.%llu perc %.4f%% ac_pub=[%02x...]\n",(long long)ASSETCHAINS_ENDSUBSIDY,dstr(ASSETCHAINS_REWARD),(long long)ASSETCHAINS_HALVING,(long long)ASSETCHAINS_DECAY,dstr(ASSETCHAINS_COMMISSION)*100,ASSETCHAINS_OVERRIDE_PUBKEY33[0]); extraptr = extrabuf; @@ -1614,7 +1615,7 @@ void komodo_args(char *argv0) extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_REWARD),(void *)&ASSETCHAINS_REWARD); extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_HALVING),(void *)&ASSETCHAINS_HALVING); extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_DECAY),(void *)&ASSETCHAINS_DECAY); - val = ASSETCHAINS_COMMISSION | (((uint64_t)ASSETCHAINS_STAKED & 0xff) << 32) | (((uint64_t)ASSETCHAINS_CC & 0xffff) << 40) | ((ASSETCHAINS_PUBLIC != 0) << 7) | ((ASSETCHAINS_PRIVATE != 0) << 6); + val = ASSETCHAINS_COMMISSION | (((uint64_t)ASSETCHAINS_STAKED & 0xff) << 32) | (((uint64_t)ASSETCHAINS_CC & 0xffff) << 40) | ((ASSETCHAINS_PUBLIC != 0) << 7) | ((ASSETCHAINS_PRIVATE != 0) << 6) | ASSETCHAINS_TXPOW; extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(val),(void *)&val); } addn = GetArg("-seednode",""); diff --git a/src/main.cpp b/src/main.cpp index 91ec53faf..a06d4a196 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1199,6 +1199,23 @@ bool CheckTransactionWithoutProofVerification(const CTransaction& tx, CValidatio REJECT_INVALID, "bad-txns-txouttotal-toolarge"); } } + if ( ASSETCHAINS_TXPOW != 0 && tx.vjoinsplit.size() == 0 ) + { + // genesis coinbase 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b + uint256 txid = tx.GetHash(); + if ( ((ASSETCHAINS_TXPOW & 2) != 0 && iscoinbase != 0) || ((ASSETCHAINS_TXPOW & 1) != 0 && iscoinbase == 0) ) + { + if ( ((uint8_t *)&txid)[0] != 0 || ((uint8_t *)&txid)[31] != 0 ) + { + uint256 genesistxid = uint256S("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"); + if ( txid != genesistxid ) + { + fprintf(stderr,"private chain iscoinbase.%d invalid txpow.%d txid.%s\n",iscoinbase,ASSETCHAINS_TXPOW,txid.GetHex().c_str()); + return state.DoS(100, error("CheckTransaction(): this is a txpow chain, must have 0x00 ends"),REJECT_INVALID, "bad-txns-actxpow-chain"); + } + } + } + } // Ensure input values do not exceed MAX_MONEY // We have not resolved the txin values at this stage, @@ -2219,7 +2236,7 @@ namespace Consensus { // Ensure that coinbases are matured if (nSpendHeight - coins->nHeight < COINBASE_MATURITY) { return state.Invalid( - error("CheckInputs(): tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight), + error("CheckInputs(): tried to spend coinbase at depth %d/%d", nSpendHeight - coins->nHeight,(int32_t)COINBASE_MATURITY), REJECT_INVALID, "bad-txns-premature-spend-of-coinbase"); } @@ -3207,7 +3224,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin if (!pblocktree->UpdateSpentIndex(spentIndex)) return AbortNode(state, "Failed to write transaction index"); - if (fTimestampIndex) { + if (fTimestampIndex) + { unsigned int logicalTS = pindex->nTime; unsigned int prevLogicalTS = 0; diff --git a/src/miner.cpp b/src/miner.cpp index 2e26cf6cd..6c25a5007 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -335,6 +335,15 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn,int32_t gpucount) //fprintf(stderr,"dont have inputs\n"); continue; } + { + CValidationState state; + auto verifier = libzcash::ProofVerifier::Disabled(); + if ( !CheckTransaction(tx, state, verifier) ) + { + fprintf(stderr,"skip tx.(%s) that failed CheckTransaction\n",hash.GetHex().c_str()); + continue; + } + } CAmount nTxFees = view.GetValueIn(chainActive.LastTip()->nHeight,&interest,tx,chainActive.LastTip()->nTime)-tx.GetValueOut(); nTxSigOps += GetP2SHSigOpCount(tx, view); diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index a1d576d58..86a3a8865 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -60,6 +60,7 @@ extern uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT; extern uint32_t ASSETCHAINS_CC; extern uint32_t ASSETCHAINS_MAGIC; extern uint64_t ASSETCHAINS_ENDSUBSIDY,ASSETCHAINS_REWARD,ASSETCHAINS_HALVING,ASSETCHAINS_DECAY,ASSETCHAINS_COMMISSION,ASSETCHAINS_STAKED,ASSETCHAINS_SUPPLY; +extern std::string NOTARY_PUBKEY; extern uint8_t NOTARY_PUBKEY33[]; UniValue getinfo(const UniValue& params, bool fHelp) { diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index a870d526c..e692e1c84 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -1058,35 +1058,65 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp) // Use CTransaction for the constant parts of the // transaction to avoid rehashing. + CMutableTransaction mergedTxsave = mergedTx; + int32_t txpow,numiters = 0; const CTransaction txConst(mergedTx); - // Sign what we can: - for (unsigned int i = 0; i < mergedTx.vin.size(); i++) { - CTxIn& txin = mergedTx.vin[i]; - const CCoins* coins = view.AccessCoins(txin.prevout.hash); - if (coins == NULL || !coins->IsAvailable(txin.prevout.n)) { - TxInErrorToJSON(txin, vErrors, "Input not found or already spent"); - continue; + if ( (txpow= ASSETCHAINS_TXPOW) != 0 ) + { + if ( txConst.IsCoinBase() != 0 ) + { + if ( (txpow & 2) == 0 ) + txpow == 0; } - const CScript& prevPubKey = coins->vout[txin.prevout.n].scriptPubKey; - const CAmount& amount = coins->vout[txin.prevout.n].nValue; - - SignatureData sigdata; - // Only sign SIGHASH_SINGLE if there's a corresponding output: - if (!fHashSingle || (i < mergedTx.vout.size())) - ProduceSignature(MutableTransactionSignatureCreator(&keystore, &mergedTx, i, amount, nHashType), prevPubKey, sigdata, consensusBranchId); - - // ... and merge in other signatures: - BOOST_FOREACH(const CMutableTransaction& txv, txVariants) { - sigdata = CombineSignatures(prevPubKey, TransactionSignatureChecker(&txConst, i, amount), sigdata, DataFromTransaction(txv, i), consensusBranchId); - } - - UpdateTransaction(mergedTx, i, sigdata); - - ScriptError serror = SCRIPT_ERR_OK; - if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, TransactionSignatureChecker(&txConst, i, amount), consensusBranchId, &serror)) { - TxInErrorToJSON(txin, vErrors, ScriptErrorString(serror)); + else + { + if ( (txpow & 1) == 0 ) + txpow == 0; } } + while ( 1 ) + { + if ( txpow != 0 ) + mergedTx = mergedTxsave; + // Sign what we can: + for (unsigned int i = 0; i < mergedTx.vin.size(); i++) { + CTxIn& txin = mergedTx.vin[i]; + const CCoins* coins = view.AccessCoins(txin.prevout.hash); + if (coins == NULL || !coins->IsAvailable(txin.prevout.n)) { + TxInErrorToJSON(txin, vErrors, "Input not found or already spent"); + continue; + } + const CScript& prevPubKey = coins->vout[txin.prevout.n].scriptPubKey; + const CAmount& amount = coins->vout[txin.prevout.n].nValue; + + SignatureData sigdata; + // Only sign SIGHASH_SINGLE if there's a corresponding output: + if (!fHashSingle || (i < mergedTx.vout.size())) + ProduceSignature(MutableTransactionSignatureCreator(&keystore, &mergedTx, i, amount, nHashType), prevPubKey, sigdata, consensusBranchId); + + // ... and merge in other signatures: + BOOST_FOREACH(const CMutableTransaction& txv, txVariants) { + sigdata = CombineSignatures(prevPubKey, TransactionSignatureChecker(&txConst, i, amount), sigdata, DataFromTransaction(txv, i), consensusBranchId); + } + + UpdateTransaction(mergedTx, i, sigdata); + + ScriptError serror = SCRIPT_ERR_OK; + if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, TransactionSignatureChecker(&txConst, i, amount), consensusBranchId, &serror)) { + TxInErrorToJSON(txin, vErrors, ScriptErrorString(serror)); + } + } + if ( txpow != 0 ) + { + uint256 txid = mergedTx.GetHash(); + if ( ((uint8_t *)&txid)[0] == 0 && ((uint8_t *)&txid)[31] == 0 ) + break; + //fprintf(stderr,"%d: tmp txid.%s\n",numiters,txid.GetHex().c_str()); + } else break; + numiters++; + } + if ( numiters > 0 ) + fprintf(stderr,"ASSETCHAINS_TXPOW.%d txpow.%d numiters.%d for signature\n",ASSETCHAINS_TXPOW,txpow,numiters); bool fComplete = vErrors.empty(); UniValue result(UniValue::VOBJ); diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 653c786fe..2154aa1dc 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -250,7 +250,7 @@ UniValue stop(const UniValue& params, bool fHelp) "\nStop Komodo server."); // Shutdown will take long enough that the response should get back StartShutdown(); - sprintf(buf,"%s Komodo server stopping",ASSETCHAINS_SYMBOL); + sprintf(buf,"%s server stopping",ASSETCHAINS_SYMBOL[0] != 0 ? ASSETCHAINS_SYMBOL : "Komodo"); return buf; } diff --git a/src/script/sign.cpp b/src/script/sign.cpp index 1aade8477..8c152e839 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -16,6 +16,7 @@ using namespace std; typedef vector valtype; +extern uint8_t ASSETCHAINS_TXPOW; TransactionSignatureCreator::TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn) : BaseSignatureCreator(keystoreIn), txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), amount(amountIn), checker(txTo, nIn, amountIn) {} @@ -32,8 +33,16 @@ bool TransactionSignatureCreator::CreateSig(std::vector& vchSig, return false; } - if (!key.Sign(hash, vchSig)) - return false; + if ( ASSETCHAINS_TXPOW == 0 ) + { + if (!key.Sign(hash, vchSig)) + return false; + } + else + { + if (!key.Sign(hash, vchSig, rand())) + return false; + } vchSig.push_back((unsigned char)nHashType); return true; } diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 56793f78b..153a87dc7 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -93,16 +93,17 @@ void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry) //int32_t i,n,txheight; uint32_t locktime; uint64_t interest = 0; int confirms = wtx.GetDepthInMainChain(); entry.push_back(Pair("rawconfirmations", confirms)); - entry.push_back(Pair("confirmations", komodo_dpowconfs((int32_t)mapBlockIndex[wtx.hashBlock]->nHeight,confirms))); if (wtx.IsCoinBase()) entry.push_back(Pair("generated", true)); if (confirms > 0) { + entry.push_back(Pair("confirmations", komodo_dpowconfs((int32_t)mapBlockIndex[wtx.hashBlock]->nHeight,confirms))); entry.push_back(Pair("blockhash", wtx.hashBlock.GetHex())); entry.push_back(Pair("blockindex", wtx.nIndex)); entry.push_back(Pair("blocktime", mapBlockIndex[wtx.hashBlock]->GetBlockTime())); entry.push_back(Pair("expiryheight", (int64_t)wtx.nExpiryHeight)); - } + } else entry.push_back(Pair("confirmations", confirms)); + uint256 hash = wtx.GetHash(); entry.push_back(Pair("txid", hash.GetHex())); UniValue conflicts(UniValue::VARR); @@ -4562,6 +4563,9 @@ int32_t komodo_notaryvin(CMutableTransaction &txNew,uint8_t *notarypub33) set setAddress; uint8_t *script,utxosig[128]; uint256 utxotxid; uint64_t utxovalue; int32_t i,siglen=0,nMinDepth = 1,nMaxDepth = 9999999; vector vecOutputs; uint32_t utxovout,eligible,earliest = 0; CScript best_scriptPubKey; bool fNegative,fOverflow; bool signSuccess; SignatureData sigdata; uint64_t txfee; uint8_t *ptr; auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus()); + if (!EnsureWalletIsAvailable(0)) + return 0; + const CKeyStore& keystore = *pwalletMain; assert(pwalletMain != NULL); LOCK2(cs_main, pwalletMain->cs_wallet); @@ -4722,6 +4726,9 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt { static struct komodo_staking *array; static int32_t numkp,maxkp; static uint32_t lasttime; set setAddress; struct komodo_staking *kp; int32_t winners,segid,minage,nHeight,counter=0,i,m,siglen=0,nMinDepth = 1,nMaxDepth = 99999999; vector vecOutputs; uint32_t block_from_future_rejecttime,besttime,eligible,eligible2,earliest = 0; CScript best_scriptPubKey; arith_uint256 mindiff,ratio,bnTarget; CBlockIndex *tipindex,*pindex; CTxDestination address; bool fNegative,fOverflow; uint8_t hashbuf[256]; CTransaction tx; uint256 hashBlock; + if (!EnsureWalletIsAvailable(0)) + return 0; + bnTarget.SetCompact(nBits, &fNegative, &fOverflow); mindiff.SetCompact(KOMODO_MINDIFF_NBITS,&fNegative,&fOverflow); ratio = (mindiff / bnTarget); @@ -4931,6 +4938,70 @@ UniValue CCaddress(struct CCcontract_info *cp,char *name,std::vectorcs_wallet : NULL); +#else + LOCK(cs_main); +#endif + + char Raddress[18]; + uint8_t pubkey33[33]; + extern uint8_t NOTARY_PUBKEY33[]; + extern std::string NOTARY_PUBKEY; + if ( NOTARY_PUBKEY33[0] == 0 ) { + if (strlen(params[0].get_str().c_str()) == 66) { + decode_hex(pubkey33,33,(char *)params[0].get_str().c_str()); + pubkey2addr((char *)Raddress,(uint8_t *)pubkey33); + if (strcmp("RRmWExvapDM9YbLT9X9xAyzDgxomYf63ng",Raddress) == 0) { + result.push_back(Pair("error", "pubkey entered is invalid.")); + } else { + CBitcoinAddress address(Raddress); + bool isValid = address.IsValid(); + if (isValid) + { + CTxDestination dest = address.Get(); + string currentAddress = address.ToString(); + result.push_back(Pair("address", currentAddress)); +#ifdef ENABLE_WALLET + isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest) : ISMINE_NO; + result.push_back(Pair("ismine", (mine & ISMINE_SPENDABLE) ? true : false)); +#endif + } + NOTARY_PUBKEY = params[0].get_str(); + decode_hex(NOTARY_PUBKEY33,33,(char *)NOTARY_PUBKEY.c_str()); + } + } else { + result.push_back(Pair("error", "pubkey is wrong length, must be 66 char hex string.")); + } + } else { + result.push_back(Pair("error", "Can only set pubkey once, to change it you need to restart your daemon.")); + } + result.push_back(Pair("pubkey", NOTARY_PUBKEY)); + return result; +} + UniValue channelsaddress(const UniValue& params, bool fHelp) { UniValue result(UniValue::VOBJ); struct CCcontract_info *cp,C; std::vector destpubkey; CPubKey pk,pk2; char destaddr[64]; @@ -6696,6 +6767,9 @@ UniValue getbalance64(const UniValue& params, bool fHelp) { set setAddress; vector vecOutputs; UniValue ret(UniValue::VOBJ); UniValue a(UniValue::VARR),b(UniValue::VARR); CTxDestination address; + if (!EnsureWalletIsAvailable(fHelp)) + return NullUniValue; + const CKeyStore& keystore = *pwalletMain; CAmount nValues[64],nValues2[64],nValue,total,total2; int32_t i,segid; assert(pwalletMain != NULL);