diff --git a/src/cc/CCPrices.h b/src/cc/CCPrices.h index 933f08e19..e6238533f 100644 --- a/src/cc/CCPrices.h +++ b/src/cc/CCPrices.h @@ -20,6 +20,8 @@ #include "komodo_defs.h" #include "CCinclude.h" int32_t komodo_priceget(int64_t *buf64,int32_t ind,int32_t height,int32_t numblocks); +extern void GetFeeAddress(); +extern CScript KOMODO_PRICES_FEE_SCRIPTPUB; // #define PRICES_DAYWINDOW ((3600*24/ASSETCHAINS_BLOCKTIME) + 1) // defined in komodo_defs.h #define PRICES_TXFEE 10000 diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index f78474e12..6311e393d 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -1192,6 +1192,7 @@ UniValue PaymentsAirdrop(struct CCcontract_info *cp,char *jsonstr) lockedblocks = juint(jitem(params,0),0); minrelease = juint(jitem(params,1),0); minimum = juint(jitem(params,2),0); + if ( minimum < 10000 ) minimum = 10000; top = juint(jitem(params,3),0); bottom = juint(jitem(params,4),0); fixedAmount = juint(jitem(params,5),0); // fixed amount is a flag, set to 7 does game mode, 0 normal snapshot, anything else fixed allocations. diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 507047c27..781483e5d 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -11,7 +11,25 @@ * * * Removal or modification of this copyright notice is prohibited. * * * - ******************************************************************************/ + ***************************************************************************** + To create payments plan start a chain with -ac_snapshot=1440 (or for test something shorter, if you like.) + then in very early block < 10 or so, do paymentsairdrop eg. + `./komodo-cli -ac_name=TESTDP paymentsairdrop '[10,10,0,3999,0,0]' + copy the txid of this transaction after it is confirmed, then do: + './komodo-cli -ac_name=TESTDP opreturn_burn 1 4a8f6469f713251a0381170e275d68899d481270a5e48586276dbbbadff91b57' +copy the hex, and sendrawtransaction, copy the txid returned. +this places the txid that locates the plan into an op_return before block 100, allowing us to retreive it. +Restart the daemon with -earlytxid= +mine the chain past block 100, preventing anyone else, creating another payments plan on chain before block 100. + +We call the following in Validation and RPC where the address is needed. +if ( KOMODO_PRICES_FEE_SCRIPTPUB.size() == 0 ) + GetFeeAddress(); + +This will fetch the op_return, calculate the scriptPubKey and save it to the global. +On daemon restart as soon as validation for BETTX happens the global will be filled, afte this the transaction never needs to be looked up again. +GetFeeAddress is on line #2080 of komodo_bitcoind.h + */ #include "CCassets.h" #include "CCPrices.h" @@ -184,7 +202,8 @@ static bool ValidateBetTx(struct CCcontract_info *cp, Eval *eval, const CTransac int16_t leverage; CPubKey pk, pricespk; std::vector vec; - + if ( KOMODO_PRICES_FEE_SCRIPTPUB.size() == 0 ) + GetFeeAddress(); if (bettx.vout.size() < 5 || bettx.vout.size() > 6) return eval->Invalid("incorrect vout number for bet tx"); @@ -198,8 +217,11 @@ static bool ValidateBetTx(struct CCcontract_info *cp, Eval *eval, const CTransac return eval->Invalid("cannot validate vout0 in bet tx with pk from opreturn"); if (MakeCC1vout(cp->evalcode, bettx.vout[1].nValue, pricespk) != bettx.vout[1]) return eval->Invalid("cannot validate vout1 in bet tx with global pk"); - if( MakeCC1vout(cp->evalcode, bettx.vout[2].nValue, pricespk) != bettx.vout[2] ) + if (MakeCC1vout(cp->evalcode, bettx.vout[2].nValue, pricespk) != bettx.vout[2] ) return eval->Invalid("cannot validate vout2 in bet tx with pk from opreturn"); + // This should be all you need to verify it, maybe also check amount? + if ( bettx.vout[4].scriptPubKey != KOMODO_PRICES_FEE_SCRIPTPUB ) + return eval->Invalid("the fee was paid to wrong address."); int64_t betamount = bettx.vout[2].nValue; if (betamount != (positionsize * 199) / 200) { @@ -1382,14 +1404,22 @@ UniValue PricesBet(int64_t txfee, int64_t amount, int16_t leverage, std::vector< mtx.vout.push_back(MakeCC1vout(cp->evalcode, txfee, pricespk)); // vout1 cc marker (NVOUT_CCMARKER) mtx.vout.push_back(MakeCC1vout(cp->evalcode, betamount, pricespk)); // vout2 betamount mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(HexStr(pricespk)) << OP_CHECKSIG)); // vout3 normal marker NVOUT_NORMALMARKER - TODO: remove it as we have cc marker now, when move to the new chain - + if ( KOMODO_PRICES_FEE_SCRIPTPUB.size() == 0 ) + { + // Lock here, as in validation we cannot call lock in the function itself. + // may not be needed as the validation call to update the global, is called in a LOCK already, and it can only update there and here. + LOCK(cs_main); + GetFeeAddress(); + } + mtx.vout.push_back(CTxOut(amount-betamount, KOMODO_PRICES_FEE_SCRIPTPUB)); + rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_betopret(mypk, nextheight - 1, amount, leverage, firstprice, vec, zeroid)); return(prices_rawtxresult(result, rawtx, 0)); } result.push_back(Pair("result", "error")); result.push_back(Pair("error", "not enough funds")); - return(result); + return(result); } // pricesaddfunding rpc impl: add yet another bet @@ -1988,4 +2018,4 @@ UniValue PricesGetOrderbook() prices_addbookentry(it->first.txhash); } return result; -} \ No newline at end of file +} diff --git a/src/komodo_bitcoind.h b/src/komodo_bitcoind.h index 292d5f8df..e827ea78f 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -29,6 +29,7 @@ int32_t komodo_voutupdate(bool fJustCheck,int32_t *isratificationp,int32_t notar unsigned int lwmaGetNextPOSRequired(const CBlockIndex* pindexLast, const Consensus::Params& params); bool EnsureWalletIsAvailable(bool avoidException); extern bool fRequestShutdown; +extern CScript KOMODO_PRICES_FEE_SCRIPTPUB; int32_t MarmaraSignature(uint8_t *utxosig,CMutableTransaction &txNew); uint8_t DecodeMaramaraCoinbaseOpRet(const CScript scriptPubKey,CPubKey &pk,int32_t &height,int32_t &unlockht); @@ -2076,6 +2077,56 @@ bool komodo_appendACscriptpub() return false; } +void GetFeeAddress() +{ + if ( KOMODO_EARLYTXID == zeroid ) + { + fprintf(stderr, "PLEASE RESTART DAEMON WITH -earlytxid.\n"); + StartShutdown(); + return; + } + if ( KOMODO_SNAPSHOT_INTERVAL == 0 ) + { + fprintf(stderr, "PRICES FEE ADDRESS MUST HAVE -ac_snapshot enabled to pay out.\n"); + StartShutdown(); + return; + } + if ( chainActive.Height() < 100 ) + { + fprintf(stderr, "Cannot fetch -earlytxid before block 100.\n"); + StartShutdown(); + return; + } + CTransaction tx; uint256 blockhash, txid = zeroid; char txidaddr[64]; + // get transaction and check that it occured before height 100. + if ( myGetTransaction(KOMODO_EARLYTXID,tx,blockhash) && mapBlockIndex[blockhash]->GetHeight() < 100 ) + { + for (int i = 0; i < tx.vout.size(); i++) + if ( tx.vout[i].scriptPubKey[0] == OP_RETURN ) + txid = uint256S(HexStr(tx.vout[i].scriptPubKey.begin()+3, tx.vout[i].scriptPubKey.end())); + if ( txid == zeroid ) + { + fprintf(stderr, "INVALID -earlytxid, restart daemon with correct txid.\n"); + StartShutdown(); + } + fprintf(stderr, "txid.%s\n", txid.GetHex().c_str()); + struct CCcontract_info *cp, C; CPubKey Paymentspk,txidpk; + cp = CCinit(&C, EVAL_PAYMENTS); + Paymentspk = GetUnspendable(cp,0); + txidpk = CCtxidaddr(txidaddr,txid); + GetCCaddress1of2(cp,txidaddr,Paymentspk,txidpk); + CC *payoutCond = MakeCCcond1of2(EVAL_PAYMENTS,Paymentspk,txidpk); + KOMODO_PRICES_FEE_SCRIPTPUB = CCPubKey(payoutCond); + cc_free(payoutCond); + fprintf(stderr, "KOMODO_PRICES_FEE_SCRIPTPUB.%s address.%s\n", HexStr(KOMODO_PRICES_FEE_SCRIPTPUB.begin(),KOMODO_PRICES_FEE_SCRIPTPUB.end()).c_str(),txidaddr); + } + else + { + fprintf(stderr, "INVALID -earlytxid, restart daemon with correct txid.\n"); + StartShutdown(); + } +} + int64_t komodo_checkcommission(CBlock *pblock,int32_t height) { int64_t checktoshis=0; uint8_t *script,scripthex[8192]; int32_t scriptlen,matched = 0; static bool didinit = false; diff --git a/src/komodo_globals.h b/src/komodo_globals.h index 8d440cbaf..bc21bab10 100644 --- a/src/komodo_globals.h +++ b/src/komodo_globals.h @@ -110,6 +110,7 @@ extern int32_t KOMODO_LOADINGBLOCKS; unsigned int MAX_BLOCK_SIGOPS = 20000; int32_t KOMODO_TESTNODE, KOMODO_SNAPSHOT_INTERVAL; +CScript KOMODO_PRICES_FEE_SCRIPTPUB; struct komodo_kv *KOMODO_KV; pthread_mutex_t KOMODO_KV_mutex,KOMODO_CC_mutex;