diff --git a/README.md b/README.md index 6c0002ba4..af67cfd48 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ This is the official Komodo sourcecode repository based on https://github.com/jl ## Tech Specification - Max Supply: 200 million KMD -- Block Time: 1m 2s +- Block Time: 60 seconds - Block Reward: 3 KMD - Mining Algorithm: Equihash diff --git a/src/ac/k64 b/src/ac/k64 new file mode 100755 index 000000000..a3b3bc835 --- /dev/null +++ b/src/ac/k64 @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=K64 $1 $2 $3 $4 $5 $6 diff --git a/src/ac/zex b/src/ac/zex deleted file mode 100755 index f4573c093..000000000 --- a/src/ac/zex +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -./komodo-cli -ac_name=ZEX $1 $2 $3 $4 $5 $6 diff --git a/src/ac/zexo b/src/ac/zexo new file mode 100755 index 000000000..b6fd508f2 --- /dev/null +++ b/src/ac/zexo @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=ZEXO $1 $2 $3 $4 $5 $6 diff --git a/src/assetchains.json b/src/assetchains.json index 99c6557b6..86dc77565 100644 --- a/src/assetchains.json +++ b/src/assetchains.json @@ -159,18 +159,6 @@ "136.243.102.225" ] }, - { - "ac_name": "MGNX", - "ac_supply": "12465003", - "ac_staked": "90", - "ac_reward": "2000000000", - "ac_halving": "525960", - "ac_cc": "2", - "ac_end": "2629800", - "addnode": [ - "142.93.27.180" - ] - }, { "ac_name": "PGT", "ac_supply": "10000000", @@ -202,17 +190,6 @@ "144.76.217.232" ] }, - { - "ac_name": "ZEX", - "ac_founders": "1", - "ac_reward": "13000000000", - "ac_halving": "525600", - "ac_cc": "2", - "ac_pubkey": "039d4a50cc70d1184e462a22edb3b66385da97cc8059196f8305c184a3e21440af", - "addnode": [ - "5.9.102.210" - ] - }, { "ac_name": "KSB", "ac_supply": "1000000000", @@ -268,5 +245,28 @@ "ac_name": "KOIN", "ac_supply": "125000000", "addnode": ["3.0.32.10"] + }, + { + "ac_name": "ZEXO", + "ac_reward": "1478310502", + "ac_halving": "525600", + "ac_cc": "42", + "ac_ccenable": "236", + "ac_supply": "100000000", + "ac_perc": "77700", + "ac_staked": "93", + "ac_pubkey": "02713bd85e054db923694b6b7a85306264edf4d6bd6d331814f2b40af444b3ebbc", + "ac_public": "1", + "addnode": [ + "195.201.20.230", + "80.240.17.222" + ] + }, + { + "ac_name": "K64", + "ac_reward": "0", + "ac_supply": "64000777", + "ac_staked": "10", + "addnode": ["18.197.20.21"] } ] diff --git a/src/assetchains.old b/src/assetchains.old index fd472eff9..4cf427c4d 100755 --- a/src/assetchains.old +++ b/src/assetchains.old @@ -39,11 +39,10 @@ echo $pubkey ./komodod -pubkey=$pubkey -ac_name=SEC -ac_cc=333 -ac_supply=1000000000 -addnode=185.148.145.43 & ./komodod -pubkey=$pubkey -ac_name=CCL -ac_supply=200000000 -ac_end=1 -ac_cc=2 -addressindex=1 -spentindex=1 -addnode=142.93.136.89 -addnode=195.201.22.89 & ./komodod -pubkey=$pubkey -ac_name=PIRATE -ac_supply=0 -ac_reward=25600000000 -ac_halving=77777 -ac_private=1 -addnode=178.63.77.56 & -./komodod -pubkey=$pubkey -ac_name=MGNX -ac_supply=12465003 -ac_staked=90 -ac_reward=2000000000 -ac_halving=525960 -ac_cc=2 -ac_end=2629800 -addnode=142.93.27.180 & +#./komodod -pubkey=$pubkey -ac_name=MGNX -ac_supply=12465003 -ac_staked=90 -ac_reward=2000000000 -ac_halving=525960 -ac_cc=2 -ac_end=2629800 -addnode=142.93.27.180 & ./komodod -pubkey=$pubkey -ac_name=PGT -ac_supply=10000000 -ac_end=1 -addnode=190.114.254.104 & ./komodod -pubkey=$pubkey -ac_name=KMDICE -ac_supply=10500000 -ac_reward=2500000000 -ac_halving=210000 -ac_cc=2 -addressindex=1 -spentindex=1 -addnode=144.76.217.232 & ./komodod -pubkey=$pubkey -ac_name=DION -ac_supply=3900000000 -ac_reward=22260000000 -ac_staked=100 -ac_cc=1 -ac_end=4300000000 -addnode=51.75.124.34 & -./komodod -pubkey=$pubkey -ac_name=ZEX -ac_cc=2 -ac_founders=1 -ac_halving=525600 -ac_reward=13000000000 -ac_pubkey=039d4a50cc70d1184e462a22edb3b66385da97cc8059196f8305c184a3e21440af -addnode=5.9.102.210 & ./komodod -pubkey=$pubkey -ac_name=KSB -ac_supply=1000000000 -ac_end=1 -ac_public=1 -addnode=37.187.225.231 & ./komodod -pubkey=$pubkey -ac_name=OUR -ac_reward=1478310502 -ac_halving=525600 -ac_cc=42 -ac_supply=100000000 -ac_perc=77700 -ac_staked=93 -ac_pubkey=02652a3f3e00b3a1875a918314f0bac838d6dd189a346fa623f5efe9541ac0b98c -ac_public=1 -addnode=51.255.195.65 -addnode=217.182.129.38 -addnode=37.187.225.231 & ./komodod -pubkey=$pubkey -ac_name=ILN -ac_supply=10000000000 -ac_cc=2 -addressindex=1 -spentindex=1 -addnode=51.75.122.83 & @@ -51,4 +50,5 @@ echo $pubkey ./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 & -~/hush3/src/komodod -pubkey=$pubkey -ac_name=HUSH3 -ac_sapling=1 -ac_reward=0,1125000000,562500000 -ac_halving=129,340000,840000 -ac_end=128,340000,5422111 -ac_eras=3 -ac_blocktime=150 -ac_cc=2 -ac_ccenable=228,234,235,236,241 -ac_founders=1 -ac_supply=6178674 -ac_perc=11111111 -clientname=GoldenSandtrout -addnode=188.165.212.101 -ac_cclib=hush3 -ac_script=76a9145eb10cf64f2bab1b457f1f25e658526155928fac88ac & +./komodod -pubkey=$pubkey -ac_name=ZEXO -ac_supply=100000000 -ac_reward=1478310502 -ac_halving=525600 -ac_cc=42 -ac_ccenable=236 -ac_perc=77700 -ac_staked=93 -ac_pubkey=02713bd85e054db923694b6b7a85306264edf4d6bd6d331814f2b40af444b3ebbc -ac_public=1 -addnode=80.240.17.222 & +./komodod -pubkey=$pubkey -ac_name=K64 -ac_supply=64000777 -ac_reward=0 -ac_staked=10 -addnode=18.197.20.211 & diff --git a/src/cc/CCPrices.h b/src/cc/CCPrices.h index 238131d59..3779111a6 100644 --- a/src/cc/CCPrices.h +++ b/src/cc/CCPrices.h @@ -38,8 +38,12 @@ extern CScript KOMODO_EARLYTXID_SCRIPTPUB; #define PRICES_MMM (KOMODO_MAXPRICES * 7) // 0011 1000 0000 0000 #define PRICES_DDD (KOMODO_MAXPRICES * 8) // 0100 0000 0000 0000 -#define PRICES_NORMFACTOR (int64_t)(SATOSHIDEN) -#define PRICES_POINTFACTOR (int64_t)10000 +//#define PRICES_NORMFACTOR (int64_t)(SATOSHIDEN) +//#define PRICES_POINTFACTOR (int64_t)10000 + +#define PRICES_REVSHAREDUST 10000 +#define PRICES_SUBREVSHAREFEE(amount) ((amount) * 199 / 200) // revshare fee percentage == 0.005 +#define PRICES_MINAVAILFUNDFRACTION 0.1 // leveraged bet limit < fund fraction bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn); @@ -52,6 +56,7 @@ UniValue PricesCashout(int64_t txfee,uint256 bettxid); UniValue PricesInfo(uint256 bettxid,int32_t refheight); UniValue PricesList(uint32_t filter, CPubKey mypk); UniValue PricesGetOrderbook(); +UniValue PricesRefillFund(int64_t amount); #endif diff --git a/src/cc/makecclib b/src/cc/makecclib index e9a015e2f..5241ea675 100755 --- a/src/cc/makecclib +++ b/src/cc/makecclib @@ -7,7 +7,7 @@ make -f Makefile_rogue rm ../libcc.so cp librogue.so ../libcc.so -exit 0 +#exit 0 echo sudoku/musig/dilithium gcc -O3 -std=c++11 -I../secp256k1/include -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -shared -c -o sudokucc.so cclib.cpp diff --git a/src/cc/oracles.cpp b/src/cc/oracles.cpp index a5d61d404..7cd429182 100644 --- a/src/cc/oracles.cpp +++ b/src/cc/oracles.cpp @@ -924,14 +924,13 @@ std::string OracleData(int64_t txfee,uint256 oracletxid,std::vector da UniValue OracleFormat(uint8_t *data,int32_t datalen,char *format,int32_t formatlen) { - UniValue obj(UniValue::VARR); uint256 hash; int32_t i,j=0; int64_t val; char str[IGUANA_MAXSCRIPTSIZE*2+1]; + uint256 hash; int32_t i,j=0; int64_t val; char str[IGUANA_MAXSCRIPTSIZE*2+1]; for (i=0; i= datalen ) break; } @@ -954,9 +953,9 @@ UniValue OracleDataSamples(uint256 reforacletxid,uint256 batontxid,int32_t num) { if ( (formatstr= (char *)format.c_str()) == 0 ) formatstr = (char *)""; - UniValue a(UniValue::VARR); - a.push_back(OracleFormat((uint8_t *)data.data(),(int32_t)data.size(),formatstr,(int32_t)format.size())); - a.push_back(uint256_str(str,batontxid)); + UniValue a(UniValue::VOBJ); + a.push_back(Pair("data",OracleFormat((uint8_t *)data.data(),(int32_t)data.size(),formatstr,(int32_t)format.size()))); + a.push_back(Pair("txid",uint256_str(str,batontxid))); b.push_back(a); batontxid = btxid; if ( ++n >= num && num != 0) diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index ecdeb3e75..b6e85480c 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -406,6 +406,7 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & { // token snapshot // payments_gettokenallocations(top, bottom, excludeScriptPubKeys, tokenid, mpzTotalAllocations, scriptPubKeys, allocations); + return(eval->Invalid("tokens not yet implemented")); } } // sanity check to make sure we got all the required info, skip for merge type tx @@ -519,8 +520,8 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & else if ( i == dust+1 ) return(eval->Invalid("cannot merge only dust")); } - } else return(eval->Invalid("create transaction cannot decode")); - } else return(eval->Invalid("Could not get contract transaction")); + } else return(eval->Invalid("cannot decode create transaction")); + } else return(eval->Invalid("could not get contract transaction")); return(true); } // end of consensus code @@ -1102,7 +1103,7 @@ UniValue PaymentsTxidopret(struct CCcontract_info *cp,char *jsonstr) rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,EncodePaymentsTxidOpRet(allocation,scriptPubKey,opret)); if ( params != 0 ) free_json(params); - return(payments_rawtxresult(result,rawtx,0)); + return(payments_rawtxresult(result,rawtx,1)); } result.push_back(Pair("result","error")); result.push_back(Pair("error","invalid params or cant find txfee")); @@ -1291,7 +1292,8 @@ UniValue PaymentsAirdropTokens(struct CCcontract_info *cp,char *jsonstr) uint256 hashBlock, tokenid = zeroid; CTransaction tx; CPubKey Paymentspk,mypk; char markeraddr[64]; std::string rawtx; int32_t lockedblocks,minrelease,top,bottom,n,i,minimum=10000; std::vector> excludeScriptPubKeys; int8_t fixedAmount; cJSON *params = payments_reparse(&n,jsonstr); - if ( params != 0 && n >= 6 ) + // disable for now. Need token snapshot function. + if ( 0 ) //params != 0 && n >= 6 ) { tokenid = payments_juint256(jitem(params,0)); lockedblocks = juint(jitem(params,1),0); @@ -1358,7 +1360,8 @@ UniValue PaymentsAirdropTokens(struct CCcontract_info *cp,char *jsonstr) else { result.push_back(Pair("result","error")); - result.push_back(Pair("error","parameters error")); + //result.push_back(Pair("error","parameters error")); + result.push_back(Pair("error","tokens airdrop not yet impmlemented")); } if ( params != 0 ) free_json(params); diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 2116f2e8e..2c0a33b20 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -11,7 +11,34 @@ * * * Removal or modification of this copyright notice is prohibited. * * * - ***************************************************************************** + *****************************************************************************/ + + /* + CBOPRET creates trustless oracles, which can be used for making a synthetic cash settlement system based on real world prices; + + 0.5% fee based on betamount, NOT leveraged betamount!! + 0.1% collected by price basis determinant + 0.2% collected by rekt tx + + PricesBet -> +/-leverage, amount, synthetic -> opreturn includes current price + funds are locked into 1of2 global CC address + for first day, long basis is MAX(correlated,smoothed), short is MIN() + reference price is the smoothed of the previous block + if synthetic value + amount goes negative, then anybody can rekt it to collect a rektfee, proof of rekt must be included to show cost basis, rekt price + original creator can liquidate at anytime and collect (synthetic value + amount) from globalfund + 0.5% of bet -> globalfund + + PricesStatus -> bettxid maxsamples returns initial params, cost basis, amount left, rekt:true/false, rektheight, initial synthetic price, current synthetic price, net gain + + PricesRekt -> bettxid height -> 0.1% to miner, rest to global CC + + PricesClose -> bettxid returns (synthetic value + amount) + + PricesList -> all bettxid -> list [bettxid, netgain] + + */ + +/* To create payments plan start a chain with the following ac_params: -ac_snapshot=1440 (or for test chain something smaller, if you like.) - this enables the payments airdrop cc to work. @@ -45,6 +72,7 @@ GetKomodoEarlytxidScriptPub is on line #2080 of komodo_bitcoind.h #include "CCassets.h" #include "CCPrices.h" +#include #include #define IS_CHARINSTR(c, str) (std::string(str).find((char)(c)) != std::string::npos) @@ -62,53 +90,50 @@ typedef struct OneBetData { } onebetdata; typedef struct BetInfo { + uint256 txid; int64_t averageCostbasis, firstprice, lastprice, liquidationprice, equity; - int64_t rektfee; + int64_t exitfee; int32_t lastheight; int16_t leverage; bool isOpen, isRekt; uint256 tokenid; - std::vector parsed; + std::vector vecparsed; std::vector bets; CPubKey pk; + bool isUp; + BetInfo() { averageCostbasis = firstprice = lastprice = liquidationprice = equity = 0; lastheight = 0; leverage = 0; - rektfee = 0; - isOpen = isRekt = false; + exitfee = 0; + isOpen = isRekt = isUp = false; } } BetInfo; -/* -CBOPRET creates trustless oracles, which can be used for making a synthetic cash settlement system based on real world prices; - - 0.5% fee based on betamount, NOT leveraged betamount!! - 0.1% collected by price basis determinant - 0.2% collected by rekt tx - - PricesBet -> +/-leverage, amount, synthetic -> opreturn includes current price - funds are locked into 1of2 global CC address - for first day, long basis is MAX(correlated,smoothed), short is MIN() - reference price is the smoothed of the previous block - if synthetic value + amount goes negative, then anybody can rekt it to collect a rektfee, proof of rekt must be included to show cost basis, rekt price - original creator can liquidate at anytime and collect (synthetic value + amount) from globalfund - 0.5% of bet -> globalfund - - PricesStatus -> bettxid maxsamples returns initial params, cost basis, amount left, rekt:true/false, rektheight, initial synthetic price, current synthetic price, net gain - - PricesRekt -> bettxid height -> 0.1% to miner, rest to global CC - - PricesClose -> bettxid returns (synthetic value + amount) - - PricesList -> all bettxid -> list [bettxid, netgain] - - -*/ +typedef struct MatchedBookTotal { + + int64_t diffLeveragedPosition; + +} MatchedBookTotal; + +typedef struct TotalFund { + int64_t totalFund; + int64_t totalActiveBets; + int64_t totalCashout; + int64_t totalRekt; + int64_t totalEquity; + + TotalFund() { + totalFund = totalActiveBets = totalCashout = totalRekt = totalEquity = 0; + } + +} TotalFund; int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t height, int16_t leverage, std::vector vec, int64_t positionsize, int64_t &profits, int64_t &outprice); +static bool prices_isacceptableamount(const std::vector &vecparsed, int64_t amount, int16_t leverage); // helpers: @@ -177,18 +202,20 @@ uint8_t prices_costbasisopretdecode(CScript scriptPubKey,uint256 &bettxid,CPubKe return(0); } -CScript prices_finalopret(uint256 bettxid,int64_t profits,int32_t height,CPubKey mypk,int64_t firstprice,int64_t costbasis,int64_t addedbets,int64_t positionsize,int16_t leverage) +CScript prices_finalopret(bool isRekt, uint256 bettxid, CPubKey pk, int32_t lastheight, int64_t costbasis, int64_t lastprice, int64_t liquidationprice, int64_t equity, int64_t exitfee, uint32_t nonce) { CScript opret; - opret << OP_RETURN << E_MARSHAL(ss << EVAL_PRICES << 'F' << bettxid << profits << height << mypk << firstprice << costbasis << addedbets << positionsize << leverage); + opret << OP_RETURN << E_MARSHAL(ss << EVAL_PRICES << (isRekt ? 'R' : 'F') << bettxid << pk << lastheight << costbasis << lastprice << liquidationprice << equity << exitfee << nonce); return(opret); } -uint8_t prices_finalopretdecode(CScript scriptPubKey,uint256 &bettxid,int64_t &profits,int32_t &height,CPubKey &pk,int64_t &firstprice,int64_t &costbasis,int64_t &addedbets,int64_t &positionsize,int16_t &leverage) +uint8_t prices_finalopretdecode(CScript scriptPubKey, uint256 &bettxid, CPubKey &pk, int32_t &lastheight, int64_t &costbasis, int64_t &lastprice, int64_t &liquidationprice, int64_t &equity, int64_t &exitfee) { std::vector vopret; uint8_t e,f; + uint32_t nonce; + GetOpReturnData(scriptPubKey,vopret); - if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> bettxid; ss >> profits; ss >> height; ss >> pk; ss >> firstprice; ss >> costbasis; ss >> addedbets; ss >> positionsize; ss >> leverage) != 0 && e == EVAL_PRICES && f == 'F' ) + if (vopret.size() > 2 && E_UNMARSHAL(vopret, ss >> e; ss >> f; ss >> bettxid; ss >> pk; ss >> lastheight; ss >> costbasis; ss >> lastprice; ss >> liquidationprice; ss >> equity; ss >> exitfee; if (!ss.eof()) ss >> nonce; ) != 0 && e == EVAL_PRICES && (f == 'F' || f == 'R')) { return(f); } @@ -198,7 +225,7 @@ uint8_t prices_finalopretdecode(CScript scriptPubKey,uint256 &bettxid,int64_t &p // price opret basic validation and retrieval static uint8_t PricesCheckOpret(const CTransaction & tx, vscript_t &opret) { - if (tx.vout.size() > 0 && GetOpReturnData(tx.vout.back().scriptPubKey, opret) && opret.size() > 2 && opret.begin()[0] == EVAL_PRICES && IS_CHARINSTR(opret.begin()[1], "BACF")) + if (tx.vout.size() > 0 && GetOpReturnData(tx.vout.back().scriptPubKey, opret) && opret.size() > 2 && opret.begin()[0] == EVAL_PRICES && IS_CHARINSTR(opret.begin()[1], "BACFR")) return opret.begin()[1]; else return (uint8_t)0; @@ -213,9 +240,12 @@ static bool ValidateBetTx(struct CCcontract_info *cp, Eval *eval, const CTransac int16_t leverage; CPubKey pk, pricespk; std::vector vec; + + // check payment cc config: if ( ASSETCHAINS_EARLYTXIDCONTRACT == EVAL_PRICES && KOMODO_EARLYTXID_SCRIPTPUB.size() == 0 ) GetKomodoEarlytxidScriptPub(); - if (bettx.vout.size() < 5 || bettx.vout.size() > 6) + + if (bettx.vout.size() < 6 || bettx.vout.size() > 7) return eval->Invalid("incorrect vout number for bet tx"); vscript_t opret; @@ -235,7 +265,7 @@ static bool ValidateBetTx(struct CCcontract_info *cp, Eval *eval, const CTransac return eval->Invalid("the fee was paid to wrong address."); int64_t betamount = bettx.vout[2].nValue; - if (betamount != (positionsize * 199) / 200) { + if (betamount != PRICES_SUBREVSHAREFEE(positionsize)) { return eval->Invalid("invalid position size in the opreturn"); } @@ -264,7 +294,11 @@ static bool ValidateAddFundingTx(struct CCcontract_info *cp, Eval *eval, const C CPubKey pk, pricespk; vscript_t vintxOpret; - if (addfundingtx.vout.size() < 3 || addfundingtx.vout.size() > 4) + // check payment cc config: + if (ASSETCHAINS_EARLYTXIDCONTRACT == EVAL_PRICES && KOMODO_EARLYTXID_SCRIPTPUB.size() == 0) + GetKomodoEarlytxidScriptPub(); + + if (addfundingtx.vout.size() < 4 || addfundingtx.vout.size() > 5) return eval->Invalid("incorrect vout number for add funding tx"); vscript_t opret; @@ -286,10 +320,20 @@ static bool ValidateAddFundingTx(struct CCcontract_info *cp, Eval *eval, const C if (MakeCC1vout(cp->evalcode, addfundingtx.vout[1].nValue, pricespk) != addfundingtx.vout[1]) return eval->Invalid("cannot validate vout1 in add funding tx with global pk"); + // This should be all you need to verify it, maybe also check amount? + if (addfundingtx.vout[2].scriptPubKey != KOMODO_EARLYTXID_SCRIPTPUB) + return eval->Invalid("the fee was paid to wrong address."); + + int64_t betamount = addfundingtx.vout[1].nValue; + if (betamount != PRICES_SUBREVSHAREFEE(amount)) { + return eval->Invalid("invalid bet position size in the opreturn"); + } + return true; } -// validate costbasis tx helper +// validate costbasis tx helper (deprecated) +/* static bool ValidateCostbasisTx(struct CCcontract_info *cp, Eval *eval, const CTransaction & costbasistx, const CTransaction & bettx) { uint256 bettxid; @@ -349,6 +393,7 @@ static bool ValidateCostbasisTx(struct CCcontract_info *cp, Eval *eval, const CT return true; } +*/ // validate final tx helper static bool ValidateFinalTx(struct CCcontract_info *cp, Eval *eval, const CTransaction & finaltx, const CTransaction & bettx) @@ -357,8 +402,8 @@ static bool ValidateFinalTx(struct CCcontract_info *cp, Eval *eval, const CTrans int64_t amount; CPubKey pk, pricespk; int64_t profits; - int32_t height; - int64_t firstprice, costbasis, addedbets, positionsize; + int32_t lastheight; + int64_t firstprice, costbasis, lastprice, liquidationprice, equity, fee; int16_t leverage; if (finaltx.vout.size() < 3 || finaltx.vout.size() > 4) { @@ -367,9 +412,14 @@ static bool ValidateFinalTx(struct CCcontract_info *cp, Eval *eval, const CTrans } vscript_t opret; - if (prices_finalopretdecode(finaltx.vout.back().scriptPubKey, bettxid, profits, height, pk, firstprice, costbasis, addedbets, positionsize, leverage) != 'F') + uint8_t funcId; + if ((funcId = prices_finalopretdecode(finaltx.vout.back().scriptPubKey, bettxid, pk, lastheight, costbasis, lastprice, liquidationprice, equity, fee)) == 0) return eval->Invalid("cannot decode opreturn for final tx"); + // check rekt txid mining: +// if( funcId == 'R' && (finaltx.GetHash().begin()[0] != 0 || finaltx.GetHash().begin()[31] != 0) ) +// return eval->Invalid("incorrect rekt txid"); + if (bettx.GetHash() != bettxid) return eval->Invalid("incorrect bettx id"); @@ -381,6 +431,9 @@ static bool ValidateFinalTx(struct CCcontract_info *cp, Eval *eval, const CTrans if( finaltx.vout.size() == 3 && MakeCC1vout(cp->evalcode, finaltx.vout[1].nValue, pricespk) != finaltx.vout[1] ) return eval->Invalid("cannot validate vout1 in final tx with global pk"); + // TODO: validate exitfee for 'R' + // TODO: validate amount for 'F' + return true; } @@ -404,7 +457,7 @@ bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx { vscript_t vopret; - if (strcmp(ASSETCHAINS_SYMBOL, "REKT0") == 0 && chainActive.Height() < 2965) + if (strcmp(ASSETCHAINS_SYMBOL, "REKT0") == 0 && chainActive.Height() < 5851) return true; // check basic opret rules: if (PricesCheckOpret(tx, vopret) == 0) @@ -416,7 +469,7 @@ bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx vscript_t firstVinTxOpret; bool foundFirst = false; int32_t ccVinCount = 0; - uint32_t prevoutN = 0; + uint32_t prevCCoutN = 0; // check basic rules: @@ -435,13 +488,13 @@ bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx std::cerr << "PricesValidate() " << "cannot find prices opret in vintx" << std::endl; } - if (funcId != 'F' && vintxOpret.begin()[1] == 'B' && prevoutN == 1) { + if (!IS_CHARINSTR(funcId, "FR") && vintxOpret.begin()[1] == 'B' && prevCCoutN == 1) { //return eval->Invalid("cannot spend bet marker"); - std::cerr << "PricesValidate() " << " non-final tx cannot spend cc marker vout=" << prevoutN << std::endl; + std::cerr << "PricesValidate() " << " non-final tx cannot spend cc marker vout=" << prevCCoutN << std::endl; } if (!foundFirst) { - prevoutN = vin.prevout.n; + prevCCoutN = vin.prevout.n; firstVinTx = vintx; firstVinTxOpret = vintxOpret; foundFirst = true; @@ -452,7 +505,7 @@ bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx if (!foundFirst) return eval->Invalid("prices cc vin not found"); - if (funcId != 'F' && ccVinCount > 1) {// for all prices tx except final tx only one cc vin is allowed + if (!IS_CHARINSTR(funcId, "FR") && ccVinCount > 1) {// for all prices tx except final tx only one cc vin is allowed //return eval->Invalid("only one prices cc vin allowed for this tx"); std::cerr << "PricesValidate() " << "only one prices cc vin allowed for this tx" << std::endl; } @@ -464,26 +517,24 @@ bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx case 'A': // add funding // check tx structure: if (!ValidateAddFundingTx(cp, eval, tx, firstVinTx)) { - //return false; // invalid state is already set in the func std::cerr << "PricesValidate() " << "ValidateAddFundingTx = false " << eval->state.GetRejectReason() << std::endl; + return false; // invalid state is already set in the func } if (firstVinTxOpret.begin()[1] == 'B') { if (!ValidateBetTx(cp, eval, firstVinTx)) {// check tx structure - // return false; std::cerr << "PricesValidate() " << "funcId=A ValidatebetTx = false " << eval->state.GetRejectReason() << std::endl; + return false; // invalid state is already set in the func } } - else if (firstVinTxOpret.begin()[1] == 'A') { - // no need to validate the previous addfunding tx (it was validated when added) - } - if (prevoutN != 0) { // check spending rules - // return eval->Invalid("incorrect vintx vout to spend"); - std::cerr << "PricesValidate() " << "add fund tx incorrect vout to spend=" << prevoutN << std::endl; + if (prevCCoutN != 0) { // check spending rules + std::cerr << "PricesValidate() " << "addfunding tx incorrect vout to spend=" << prevCCoutN << std::endl; + return eval->Invalid("incorrect vintx vout to spend"); } break; + /* not used: case 'C': // set costbasis if (!ValidateCostbasisTx(cp, eval, tx, firstVinTx)) { //return false; @@ -498,20 +549,21 @@ bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx std::cerr << "PricesValidate() " << "costbasis tx incorrect vout to spend=" << prevoutN << std::endl; } //return eval->Invalid("test: costbasis is good"); - break; + break; */ case 'F': // final tx + case 'R': if (!ValidateFinalTx(cp, eval, tx, firstVinTx)) { - ///return false; std::cerr << "PricesValidate() " << "ValidateFinalTx=false " << eval->state.GetRejectReason() << std::endl; + return false; } if (!ValidateBetTx(cp, eval, firstVinTx)) { - // return false; std::cerr << "PricesValidate() " << "ValidateBetTx=false " << eval->state.GetRejectReason() << std::endl; + return false; } - if (prevoutN != 1) { // check spending rules - // return eval->Invalid("incorrect vout to spend"); - std::cerr << "PricesValidate() "<< "final tx incorrect vout to spend=" << prevoutN << std::endl; + if (prevCCoutN != 1) { // check spending rules + std::cerr << "PricesValidate() "<< "final tx incorrect vout to spend=" << prevCCoutN << std::endl; + return eval->Invalid("incorrect vout to spend"); } break; @@ -560,6 +612,19 @@ int64_t AddPricesInputs(struct CCcontract_info *cp, CMutableTransaction &mtx, ch return(totalinputs); } +// return min equity percentage depending on leverage value +// for lev=1 2% +// for lev>=100 10% +double prices_minmarginpercent(int16_t leverage) +{ + int16_t absleverage = std::abs(leverage); + if (absleverage < 100) + return (absleverage * 0.080808 + 1.9191919) / 100.0; + else + return 0.1; +} + + UniValue prices_rawtxresult(UniValue &result, std::string rawtx, int32_t broadcastflag) { CTransaction tx; @@ -881,10 +946,10 @@ int32_t prices_syntheticvec(std::vector &vec, std::vector return(-3); } depth -= need; - std::cerr << "prices_syntheticvec() opcode=" << opcode << " opstr=" << opstr << " need=" << need << " depth=" << depth << std::endl; + ///std::cerr << "prices_syntheticvec() opcode=" << opcode << " opstr=" << opstr << " need=" << need << " depth=" << depth << std::endl; if ((opcode & KOMODO_PRICEMASK) != PRICES_WEIGHT) { // skip weight depth++; // increase operands count - std::cerr << "depth++=" << depth << std::endl; + ///std::cerr << "depth++=" << depth << std::endl; } if (depth > 3) { std::cerr << "prices_syntheticvec() too many operands, last=" << opstr << std::endl; @@ -930,14 +995,14 @@ int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t mpz_set_ui(mpzResult, 0); // clear result to test overflow (see below) - std::cerr << "prices_syntheticprice" << " i=" << i << " mpzTotalPrice=" << mpz_get_si(mpzTotalPrice) << " value=" << value << " depth=" << depth << " opcode&KOMODO_PRICEMASK=" << (opcode & KOMODO_PRICEMASK) < 0 ) + // std::cerr << "prices_syntheticprice top pricestack[depth-1=" << depth-1 << "]=" << pricestack[depth-1] << std::endl; + // else + // std::cerr << "prices_syntheticprice pricestack empty" << std::endl; } free(pricedata); @@ -1134,14 +1199,22 @@ int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t mpz_clear(mpzTotalPrice); mpz_clear(mpzPriceValue); - if (errcode != 0) + if (errcode != 0) std::cerr << "prices_syntheticprice errcode in switch=" << errcode << std::endl; + + if( errcode == -1 ) { + std::cerr << "prices_syntheticprice error getting price (could be end of chain)" << std::endl; + return errcode; + } if (errcode == -13) { std::cerr << "prices_syntheticprice overflow in price" << std::endl; return errcode; } - + if (errcode == -14) { + std::cerr << "prices_syntheticprice price is zero, not enough historic data yet" << std::endl; + return errcode; + } if (den == 0) { std::cerr << "prices_syntheticprice den==0 return err=-11" << std::endl; return(-11); @@ -1154,7 +1227,7 @@ int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t std::cerr << "prices_syntheticprice err=" << errcode << std::endl; return(errcode); } - std::cerr << "prices_syntheticprice priceIndex=" << priceIndex << " den=" << den << std::endl; +// std::cerr << "prices_syntheticprice priceIndex=totalprice/den=" << priceIndex << " den=" << den << std::endl; return priceIndex; } @@ -1191,24 +1264,24 @@ int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t if (minmax) { // if we are within day window, set temp costbasis to max (or min) price value if (leverage > 0 && price > costbasis) { costbasis = price; // set temp costbasis - std::cerr << "prices_syntheticprofits() minmax costbasis=" << costbasis << std::endl; + //std::cerr << "prices_syntheticprofits() minmax costbasis=" << costbasis << std::endl; } else if (leverage < 0 && (costbasis == 0 || price < costbasis)) { costbasis = price; - std::cerr << "prices_syntheticprofits() minmax costbasis=" << costbasis << std::endl; + //std::cerr << "prices_syntheticprofits() minmax costbasis=" << costbasis << std::endl; } //else { //-> use the previous value // std::cerr << "prices_syntheticprofits() unchanged costbasis=" << costbasis << " price=" << price << " leverage=" << leverage << std::endl; //} } else { - if (height == firstheight + COSTBASIS_PERIOD) { + //if (height == firstheight + COSTBASIS_PERIOD) { // if costbasis not set, just set it //costbasis = price; // use calculated minmax costbasis - std::cerr << "prices_syntheticprofits() use permanent costbasis=" << costbasis << " at height=" << height << std::endl; - } + //std::cerr << "prices_syntheticprofits() use permanent costbasis=" << costbasis << " at height=" << height << std::endl; + //} } // normalize to 10,000,000 to prevent underflow @@ -1265,7 +1338,7 @@ int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t else profits = 0; - std::cerr << "prices_syntheticprofits() profits=" << profits << std::endl; + //std::cerr << "prices_syntheticprofits() profits=" << profits << std::endl; return 0; // (positionsize + addedbets + profits); } @@ -1274,7 +1347,7 @@ void prices_betjson(UniValue &result, std::vector bets, int16_t leve { UniValue resultbets(UniValue::VARR); - int64_t totalbets = 0; + int64_t totalposition = 0; int64_t totalprofits = 0; for (auto b : bets) { @@ -1284,14 +1357,14 @@ void prices_betjson(UniValue &result, std::vector bets, int16_t leve entry.push_back(Pair("costbasis", ValueFromAmount(b.costbasis))); entry.push_back(Pair("firstheight", b.firstheight)); resultbets.push_back(entry); - totalbets += b.positionsize; + totalposition += b.positionsize; totalprofits += b.profits; } - int64_t equity = totalbets + totalprofits; + int64_t equity = totalposition + totalprofits; result.push_back(Pair("bets", resultbets)); result.push_back(Pair("leverage", (int64_t)leverage)); - result.push_back(Pair("TotalPositionSize", ValueFromAmount(totalbets))); + result.push_back(Pair("TotalPositionSize", ValueFromAmount(totalposition))); result.push_back(Pair("TotalProfits", ValueFromAmount(totalprofits))); result.push_back(Pair("equity", ValueFromAmount(equity))); result.push_back(Pair("LastPrice", ValueFromAmount(lastprice))); @@ -1363,9 +1436,9 @@ int64_t prices_enumaddedbets(uint256 &batontxid, std::vector &bets, addedBetsTotal += amount; added.positionsize = amount; - added.firstheight = blockIdx.GetHeight(); + added.firstheight = blockIdx.GetHeight(); //TODO: check if this is correct (to get height from the block not from the opret) bets.push_back(added); - std::cerr << "prices_batontxid() added amount=" << amount << std::endl; + //std::cerr << "prices_batontxid() added amount=" << amount << std::endl; } else { std::cerr << "prices_batontxid() cannot load or decode add bet tx, isLoaded=" << isLoaded << " funcId=" << (int)funcId << std::endl; @@ -1407,9 +1480,24 @@ UniValue PricesBet(int64_t txfee, int64_t amount, int16_t leverage, std::vector< result.push_back(Pair("error", "invalid synthetic")); return(result); } + + if (!prices_isacceptableamount(vec, amount, leverage)) { + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "too big amount and leverage")); + return(result); + } + if (AddNormalinputs(mtx, mypk, amount + 4 * txfee, 64) >= amount + 4 * txfee) { - betamount = (amount * 199) / 200; + betamount = PRICES_SUBREVSHAREFEE(amount); + + /*if( amount - betamount < PRICES_REVSHAREDUST) { + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "bet amount too small")); + return(result); + }*/ + + mtx.vout.push_back(MakeCC1vout(cp->evalcode, txfee, mypk)); // vout0 baton for total funding // mtx.vout.push_back(MakeCC1vout(cp->evalcode, (amount - betamount) + 2 * txfee, pricespk)); // vout1, when spent, costbasis is set mtx.vout.push_back(MakeCC1vout(cp->evalcode, txfee, pricespk)); // vout1 cc marker (NVOUT_CCMARKER) @@ -1422,7 +1510,8 @@ UniValue PricesBet(int64_t txfee, int64_t amount, int16_t leverage, std::vector< LOCK(cs_main); GetKomodoEarlytxidScriptPub(); } - mtx.vout.push_back(CTxOut(amount-betamount, KOMODO_EARLYTXID_SCRIPTPUB)); + mtx.vout.push_back(CTxOut(amount-betamount, KOMODO_EARLYTXID_SCRIPTPUB)); + //test: mtx.vout.push_back(CTxOut(amount - betamount, CScript() << ParseHex("037c803ec82d12da939ac04379bbc1130a9065c53d8244a61eece1db942cf0efa7") << OP_CHECKSIG)); // vout4 test revshare fee rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_betopret(mypk, nextheight - 1, amount, leverage, firstprice, vec, zeroid)); return(prices_rawtxresult(result, rawtx, 0)); @@ -1437,11 +1526,14 @@ UniValue PricesAddFunding(int64_t txfee, uint256 bettxid, int64_t amount) { int32_t nextheight = komodo_nextheight(); CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nextheight); UniValue result(UniValue::VOBJ); - struct CCcontract_info *cp, C; CTransaction bettx; - CPubKey pricespk, mypk; - //int64_t addedbets = 0, betamount, firstprice; - std::vector vec; - uint256 batontxid; + struct CCcontract_info *cp, C; + CTransaction bettx; + CPubKey pricespk, mypk, pk; + int64_t positionsize, betamount, firstprice; + int32_t firstheight; + std::vector vecparsed; + uint256 batontxid, tokenid, hashBlock; + int16_t leverage = 0; std::string rawtx; //char myaddr[64]; @@ -1450,15 +1542,48 @@ UniValue PricesAddFunding(int64_t txfee, uint256 bettxid, int64_t amount) txfee = PRICES_TXFEE; mypk = pubkey2pk(Mypubkey()); pricespk = GetUnspendable(cp, 0); - //GetCCaddress(cp, myaddr, mypk); + + if (!myGetTransaction(bettxid, bettx, hashBlock) || + bettx.vout.size() <= 3 || + hashBlock.IsNull() || + prices_betopretdecode(bettx.vout.back().scriptPubKey, pk, firstheight, positionsize, leverage, firstprice, vecparsed, tokenid) != 'B') { + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "invalid bet tx")); + return(result); + } + + if (!prices_isacceptableamount(vecparsed, amount, leverage)) { + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "too big amount and leverage")); + return(result); + } + if (AddNormalinputs(mtx, mypk, amount + 2*txfee, 64) >= amount + 2*txfee) { + betamount = PRICES_SUBREVSHAREFEE(amount); + /*if (amount - betamount < PRICES_REVSHAREDUST) { + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "bet amount too small")); + return(result); + }*/ + std::vector bets; if (prices_enumaddedbets(batontxid, bets, bettxid) >= 0) { mtx.vin.push_back(CTxIn(batontxid, 0, CScript())); mtx.vout.push_back(MakeCC1vout(cp->evalcode, txfee, mypk)); // vout0 baton for total funding - mtx.vout.push_back(MakeCC1vout(cp->evalcode, amount, pricespk)); // vout1 added amount + mtx.vout.push_back(MakeCC1vout(cp->evalcode, betamount, pricespk)); // vout1 added amount + + if (ASSETCHAINS_EARLYTXIDCONTRACT == EVAL_PRICES && KOMODO_EARLYTXID_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); + GetKomodoEarlytxidScriptPub(); + } + mtx.vout.push_back(CTxOut(amount - betamount, KOMODO_EARLYTXID_SCRIPTPUB)); + // test: mtx.vout.push_back(CTxOut(amount - betamount, CScript() << ParseHex("037c803ec82d12da939ac04379bbc1130a9065c53d8244a61eece1db942cf0efa7") << OP_CHECKSIG)); //vout2 test revshare fee + rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_addopret(bettxid, mypk, amount)); return(prices_rawtxresult(result, rawtx, 0)); } @@ -1481,9 +1606,9 @@ int32_t prices_scanchain(std::vector &bets, int16_t leverage, std::v return -1; bool stop = false; - for (int32_t height = bets[0].firstheight; ; height++) // the last datum for 24h is the costbasis value + for (int32_t height = bets[0].firstheight+1; ; height++) // the last datum for 24h is the costbasis value { - int64_t totalbets = 0; + int64_t totalposition = 0; int64_t totalprofits = 0; // scan upto the chain tip @@ -1493,11 +1618,11 @@ int32_t prices_scanchain(std::vector &bets, int16_t leverage, std::v int32_t retcode = prices_syntheticprofits(bets[i].costbasis, bets[i].firstheight, height, leverage, vec, bets[i].positionsize, bets[i].profits, lastprice); if (retcode < 0) { - std::cerr << "prices_scanchain() prices_syntheticprofits returned -1, breaking" << std::endl; + std::cerr << "prices_scanchain() prices_syntheticprofits returned -1, finishing..." << std::endl; stop = true; break; } - totalbets += bets[i].positionsize; + totalposition += bets[i].positionsize; totalprofits += bets[i].profits; } } @@ -1506,8 +1631,8 @@ int32_t prices_scanchain(std::vector &bets, int16_t leverage, std::v break; endheight = height; - int64_t equity = totalbets + totalprofits; - if (equity < 0) + int64_t equity = totalposition + totalprofits; + if (equity <= (int64_t)((double)totalposition * prices_minmarginpercent(leverage))) { // we are in loss break; } @@ -1588,6 +1713,34 @@ UniValue PricesSetcostbasis(int64_t txfee, uint256 bettxid) } +// pricesaddfunding rpc impl: add yet another bet +UniValue PricesRefillFund(int64_t amount) +{ + int32_t nextheight = komodo_nextheight(); + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nextheight); UniValue result(UniValue::VOBJ); + struct CCcontract_info *cp, C; + CPubKey pricespk, mypk, pk; + std::string rawtx; + //char myaddr[64]; + + cp = CCinit(&C, EVAL_PRICES); + const int64_t txfee = PRICES_TXFEE; + mypk = pubkey2pk(Mypubkey()); + pricespk = GetUnspendable(cp, 0); + + if (AddNormalinputs(mtx, mypk, amount + txfee, 64) >= amount + txfee) + { + mtx.vout.push_back(MakeCC1vout(cp->evalcode, amount, pricespk)); // vout1 added amount + rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, CScript()); + return(prices_rawtxresult(result, rawtx, 0)); + + } + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "not enough funds")); + return(result); +} + + int32_t prices_getbetinfo(uint256 bettxid, BetInfo &betinfo) { CTransaction bettx; @@ -1598,39 +1751,64 @@ int32_t prices_getbetinfo(uint256 bettxid, BetInfo &betinfo) if (hashBlock.IsNull()) return -2; + + // TODO: forget old tx + //CBlockIndex *bi = komodo_getblockindex(hashBlock); + //if (bi && bi->GetHeight() < 5342) + // return -5; + OneBetData bet1; - if (prices_betopretdecode(bettx.vout.back().scriptPubKey, betinfo.pk, bet1.firstheight, bet1.positionsize, betinfo.leverage, betinfo.firstprice, betinfo.parsed, betinfo.tokenid) == 'B') + if (prices_betopretdecode(bettx.vout.back().scriptPubKey, betinfo.pk, bet1.firstheight, bet1.positionsize, betinfo.leverage, betinfo.firstprice, betinfo.vecparsed, betinfo.tokenid) == 'B') { uint256 finaltxid; int32_t vini; int32_t finaltxheight; //, endheight; //std::vector bets; - + betinfo.txid = bettxid; if (CCgetspenttxid(finaltxid, vini, finaltxheight, bettxid, NVOUT_CCMARKER) == 0) betinfo.isOpen = false; else betinfo.isOpen = true; - //bet1.amount = betinfo.positionsize; - //bet1.firstheight = firstheight; + // override with real amount (TODO: check this) + //bet1.positionsize = bettx.vout[2].nValue; + betinfo.bets.push_back(bet1); prices_enumaddedbets(batontxid, betinfo.bets, bettxid); - if (prices_scanchain(betinfo.bets, betinfo.leverage, betinfo.parsed, betinfo.lastprice, betinfo.lastheight) < 0) { + if (!betinfo.isOpen) { + CTransaction finaltx; + uint256 hashBlock; + vscript_t vopret; + if (myGetTransaction(finaltxid, finaltx, hashBlock) && finaltx.vout.size() > 0 && PricesCheckOpret(finaltx, vopret) != 0) { + uint8_t funcId = prices_finalopretdecode(finaltx.vout.back().scriptPubKey, betinfo.txid, betinfo.pk, betinfo.lastheight, betinfo.averageCostbasis, betinfo.lastprice, betinfo.liquidationprice, betinfo.equity, betinfo.exitfee); + if (funcId == 0) + return -3; + + betinfo.isRekt = (funcId == 'R'); + + // return 0; + } + else + return -6; + } + + + if (prices_scanchain(betinfo.bets, betinfo.leverage, betinfo.vecparsed, betinfo.lastprice, betinfo.lastheight) < 0) { return -4; } - mpz_t mpzTotalbets; + mpz_t mpzTotalPosition; mpz_t mpzTotalprofits; mpz_t mpzTotalcostbasis; - mpz_init(mpzTotalbets); + mpz_init(mpzTotalPosition); mpz_init(mpzTotalprofits); mpz_init(mpzTotalcostbasis); - int64_t totalbets = 0; + int64_t totalposition = 0; int64_t totalprofits = 0; for (auto b : betinfo.bets) { @@ -1649,26 +1827,26 @@ int32_t prices_getbetinfo(uint256 bettxid, BetInfo &betinfo) mpz_mul_ui(mpzProduct, mpzProduct, (uint64_t)b.positionsize); // b.costbasis * b.amount mpz_add(mpzTotalcostbasis, mpzTotalcostbasis, mpzProduct); //averageCostbasis += b.costbasis * b.amount; - mpz_add_ui(mpzTotalbets, mpzTotalbets, (uint64_t)b.positionsize); //totalbets += b.amount; + mpz_add_ui(mpzTotalPosition, mpzTotalPosition, (uint64_t)b.positionsize); //totalposition += b.amount; mpz_add(mpzTotalprofits, mpzTotalprofits, mpzProfits); //totalprofits += b.profits; - totalbets += b.positionsize; + totalposition += b.positionsize; totalprofits += b.profits; mpz_clear(mpzProduct); mpz_clear(mpzProfits); } - betinfo.equity = totalbets + totalprofits; + betinfo.equity = totalposition + totalprofits; //int64_t averageCostbasis = 0; - if (mpz_get_ui(mpzTotalbets) != 0) { //prevent zero div + if (mpz_get_ui(mpzTotalPosition) != 0) { //prevent zero div mpz_t mpzAverageCostbasis; mpz_init(mpzAverageCostbasis); - //averageCostbasis = totalcostbasis / totalbets; + //averageCostbasis = totalcostbasis / totalposition; mpz_mul_ui(mpzTotalcostbasis, mpzTotalcostbasis, SATOSHIDEN); // profits *= SATOSHIDEN normalization to prevent loss of significance while division - mpz_tdiv_q(mpzAverageCostbasis, mpzTotalcostbasis, mpzTotalbets); + mpz_tdiv_q(mpzAverageCostbasis, mpzTotalcostbasis, mpzTotalPosition); mpz_tdiv_q_ui(mpzAverageCostbasis, mpzAverageCostbasis, SATOSHIDEN); // profits /= SATOSHIDEN de-normalization @@ -1678,18 +1856,21 @@ int32_t prices_getbetinfo(uint256 bettxid, BetInfo &betinfo) betinfo.liquidationprice = 0; if (betinfo.leverage != 0) {// prevent zero div - betinfo.liquidationprice = betinfo.averageCostbasis - betinfo.averageCostbasis / betinfo.leverage; + betinfo.liquidationprice = betinfo.averageCostbasis - (betinfo.averageCostbasis * (1 - prices_minmarginpercent(betinfo.leverage))) / betinfo.leverage; } - if (betinfo.equity >= 0) - betinfo.isRekt = false; - else - { - betinfo.isRekt = true; - betinfo.rektfee = totalbets / 500; + if (!betinfo.isRekt) { // not set by check for final tx + + if (betinfo.equity > (int64_t)((double)totalposition * prices_minmarginpercent(betinfo.leverage))) + betinfo.isRekt = false; + else + { + betinfo.isRekt = true; + betinfo.exitfee = (int64_t)(((double)totalposition * prices_minmarginpercent(betinfo.leverage)) / 10); // was: totalposition / 500 + } } - mpz_clear(mpzTotalbets); + mpz_clear(mpzTotalPosition); mpz_clear(mpzTotalprofits); mpz_clear(mpzTotalcostbasis); return 0; @@ -1706,18 +1887,13 @@ UniValue PricesRekt(int64_t txfee, uint256 bettxid, int32_t rektheight) CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nextheight); UniValue result(UniValue::VOBJ); struct CCcontract_info *cp, C; CTransaction bettx; -/* uint256 hashBlock, tokenid, batontxid; - int64_t firstprice, lastprice = 0, positionsize; - int32_t firstheight; - int16_t leverage; - std::vector vec; */ int64_t myfee = 0; CPubKey pk, mypk, pricespk; std::string rawtx; char destaddr[64]; cp = CCinit(&C, EVAL_PRICES); - if (txfee == 0) // TODO: what did we want tot do with txfee in prices? + if (txfee == 0) // TODO: what did we want to do with txfee in prices? txfee = PRICES_TXFEE; mypk = pubkey2pk(Mypubkey()); pricespk = GetUnspendable(cp, 0); @@ -1746,11 +1922,11 @@ UniValue PricesRekt(int64_t txfee, uint256 bettxid, int32_t rektheight) return(result); } - int64_t totalbets = 0; + int64_t totalposition = 0; int64_t totalprofits = 0; for (auto b : betinfo.bets) { - totalbets += b.positionsize; + totalposition += b.positionsize; totalprofits += b.profits; } @@ -1764,7 +1940,7 @@ UniValue PricesRekt(int64_t txfee, uint256 bettxid, int32_t rektheight) prices_betjson(result, betinfo.bets, betinfo.leverage, betinfo.lastheight, betinfo.lastprice); // fill output if (betinfo.isRekt) { - myfee = betinfo.rektfee; // consolation fee for loss + myfee = betinfo.exitfee; // consolation fee for loss } if (myfee != 0) { @@ -1778,8 +1954,37 @@ UniValue PricesRekt(int64_t txfee, uint256 bettxid, int32_t rektheight) mtx.vout.push_back(MakeCC1vout(cp->evalcode, CCchange, pricespk)); /// mtx.vout.push_back(MakeCC1vout(cp->evalcode, bettx.vout[2].nValue - myfee - txfee, pricespk)); // change - rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_finalopret(bettxid, totalprofits, rektheight, mypk, betinfo.firstprice, 0, totalbets /*- positionsize*/, 0/*positionsize*/, betinfo.leverage)); - return(prices_rawtxresult(result, rawtx, 0)); + + // make some PoW to get txid=0x00.....00 to 'faucet' rekts + fprintf(stderr, "start PoW at %u\n", (uint32_t)time(NULL)); + uint32_t nonce = rand() & 0xfffffff; + for (int i = 0; i<1000000; i++, nonce++) + { + CMutableTransaction tmpmtx = mtx; + //int32_t len; + //uint8_t txbuf[32768]; + + rawtx = FinalizeCCTx(0, cp, tmpmtx, mypk, txfee, prices_finalopret(true, bettxid, mypk, betinfo.lastheight, betinfo.averageCostbasis, betinfo.lastprice, betinfo.liquidationprice, betinfo.equity, myfee, nonce)); + //if ((len = (int32_t)rawtx.size()) > 0 && len < sizeof(txbuf) / sizeof(txbuf[0]) * 2) + //{ + // len >>= 1; // sizeof hex divide by 2 + //decode_hex(txbuf, len, (char *)rawtx.c_str()); + //bits256 hash = bits256_doublesha256(0, txbuf, len); + uint256 hash = tmpmtx.GetHash(); + //if ((hash.bytes[0] & 0xff) == 0 && (hash.bytes[31] & 0xff) == 0) + if ((hash.begin()[0] & 0xff) == 0 && (hash.begin()[31] & 0xff) == 0) + { + fprintf(stderr, "found valid txid after %d iterations %u\n", i, (uint32_t)time(NULL)); + return(prices_rawtxresult(result, rawtx, 0)); + } + //fprintf(stderr,"%02x%02x ",hash.bytes[0],hash.bytes[31]); + //} + } + fprintf(stderr, "couldnt generate valid txid %u\n", (uint32_t)time(NULL)); + + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "could not generate valid txid")); + return(result); } else { @@ -1796,12 +2001,6 @@ UniValue PricesCashout(int64_t txfee, uint256 bettxid) CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nextheight); UniValue result(UniValue::VOBJ); struct CCcontract_info *cp, C; char destaddr[64]; -/* CTransaction bettx; - uint256 hashBlock, batontxid, tokenid; - int64_t positionsize, firstprice, lastprice = 0; - int32_t firstheight; - int16_t leverage; - std::vector vec;*/ int64_t CCchange = 0, inputsum; CPubKey pk, mypk, pricespk; std::string rawtx; @@ -1837,11 +2036,11 @@ UniValue PricesCashout(int64_t txfee, uint256 bettxid) return(result); } - int64_t totalbets = 0; + int64_t totalposition = 0; int64_t totalprofits = 0; for (auto b : betinfo.bets) { - totalbets += b.positionsize; + totalposition += b.positionsize; totalprofits += b.profits; } @@ -1862,20 +2061,18 @@ UniValue PricesCashout(int64_t txfee, uint256 bettxid) } mtx.vin.push_back(CTxIn(bettxid, NVOUT_CCMARKER, CScript())); // spend cc marker - if ((inputsum = AddPricesInputs(cp, mtx, destaddr, betinfo.equity + txfee, 64)) > betinfo.equity + txfee) + if ((inputsum = AddPricesInputs(cp, mtx, destaddr, betinfo.equity + txfee, 64)) > betinfo.equity + txfee) // TODO: why txfee from the fund? CCchange = (inputsum - betinfo.equity); mtx.vout.push_back(CTxOut(betinfo.equity, CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); if (CCchange >= txfee) mtx.vout.push_back(MakeCC1vout(cp->evalcode, CCchange, pricespk)); // TODO: what should the opret param be: - rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_finalopret(bettxid, totalprofits, nextheight - 1, mypk, betinfo.firstprice, 0, totalbets/*- betinfo.positionsize*/, 0/*betinfo.positionsize*/, betinfo.leverage)); + rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_finalopret(false, bettxid, mypk, nextheight-1, betinfo.averageCostbasis, betinfo.lastprice, betinfo.liquidationprice, betinfo.equity, txfee, 0)); return(prices_rawtxresult(result, rawtx, 0)); } - - // pricesinfo rpc impl UniValue PricesInfo(uint256 bettxid, int32_t refheight) { @@ -1908,6 +2105,10 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) else if (retcode == -4) { result.push_back(Pair("result", "error")); result.push_back(Pair("error", "error scanning chain")); + } + else { + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", retcode)); } return(result); } @@ -1917,11 +2118,13 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) else { result.push_back(Pair("rekt", (int64_t)1)); - result.push_back(Pair("rektfee", betinfo.rektfee)); + result.push_back(Pair("rektfee", betinfo.exitfee)); result.push_back(Pair("rektheight", betinfo.lastheight)); } - std::string expr = prices_getsourceexpression(betinfo.parsed); + result.push_back(Pair("open", betinfo.isOpen ? 1 : 0 )); + + std::string expr = prices_getsourceexpression(betinfo.vecparsed); result.push_back(Pair("expression", expr)); result.push_back(Pair("reduced", prices_getreducedexpr(expr))); // result.push_back(Pair("batontxid", batontxid.GetHex())); @@ -1960,6 +2163,12 @@ UniValue PricesList(uint32_t filter, CPubKey mypk) if (GetTransaction(txid, vintx, hashBlock, false) != 0) { + + // TODO: forget old tx + //CBlockIndex *bi = komodo_getblockindex(hashBlock); + //if (bi && bi->GetHeight() < 5342) + // return; + bool bAppend = false; if (vintx.vout.size() > 0 && prices_betopretdecode(vintx.vout.back().scriptPubKey, pk, height, amount, leverage, firstprice, vec, tokenid) == 'B' && (mypk == CPubKey() || mypk == pk)) // if only mypubkey to list @@ -1987,7 +2196,7 @@ UniValue PricesList(uint32_t filter, CPubKey mypk) SetCCtxids(addressIndex, cp->normaladdr, false); // old normal marker for (std::vector >::const_iterator it = addressIndex.begin(); it != addressIndex.end(); it++) { - if( it->first.txindex == NVOUT_NORMALMARKER ) + if( it->first.index == NVOUT_NORMALMARKER ) AddBetToList(it->first.txhash); } @@ -2002,12 +2211,244 @@ UniValue PricesList(uint32_t filter, CPubKey mypk) } -void prices_addbookentry(uint256 txid) +static bool prices_addbookentry(uint256 txid, std::vector &book) { BetInfo betinfo; - //if( prices_getbetinfo(txid, betinfo) == 0 ) + if (prices_getbetinfo(txid, betinfo) == 0) { + book.push_back(betinfo); + return true; + } + return false; } + +static bool prices_ispositionup(const std::vector &vecparsed, int16_t leverage) { + if (vecparsed.size() > 1 && vecparsed.size() <= 3) { + uint16_t opcode = vecparsed[0]; + + int32_t value = (opcode & (KOMODO_MAXPRICES - 1)); // filter index or weight = opcode & (2048-1) + + if ((opcode & KOMODO_PRICEMASK) == 0) { + char name[65]; + if (komodo_pricename(name, value)) { + std::string upperquote, bottomquote; + prices_splitpair(std::string(name), upperquote, bottomquote); + + uint16_t opcode1 = vecparsed[1]; + bool isInverted = ((opcode1 & KOMODO_PRICEMASK) == PRICES_INV); + + //std::cerr << "prices_ispositionup upperquote=" << upperquote << " bottomquote=" << bottomquote << " opcode1=" << opcode1 << " (opcode1 & KOMODO_PRICEMASK)=" << (opcode1 & KOMODO_PRICEMASK) << std::endl; + + if (upperquote == "BTC" || bottomquote == "BTC") { // it is relatively btc + if (upperquote == "BTC" && (leverage > 0 && !isInverted || leverage < 0 && isInverted) || + bottomquote == "BTC" && (leverage < 0 && !isInverted || leverage > 0 && isInverted)) { + std::cerr << "prices_ispositionup returns true for BTC for expr=" << prices_getsourceexpression(vecparsed) << " lev=" << leverage << std::endl; + return true; + } + else { + std::cerr << "prices_ispositionup returns false for BTC for expr=" << prices_getsourceexpression(vecparsed) << " lev=" << leverage << std::endl; + return false; + } + } + + if (upperquote == "USD" || bottomquote == "USD") { // it is relatively usd + if (upperquote == "USD" && (leverage > 0 && !isInverted || leverage < 0 && isInverted) || + bottomquote == "USD" && (leverage < 0 && !isInverted || leverage > 0 && isInverted)) { + std::cerr << "prices_ispositionup returns true for USD for expr=" << prices_getsourceexpression(vecparsed) << " lev=" << leverage << std::endl; + return true; + } + else { + std::cerr << "prices_ispositionup returns false for USD for expr=" << prices_getsourceexpression(vecparsed) << " lev=" << leverage << std::endl; + return false; + } + } + } + } + } + std::cerr << "prices_ispositionup returns false for expr=" << prices_getsourceexpression(vecparsed) << " lev=" << leverage << std::endl; + return false; +} + +static bool prices_isopposite(BetInfo p1, BetInfo p2) { + if (p1.vecparsed.size() <= 3 && p2.vecparsed.size() <= 3) { // simple synthetic exp + + uint16_t opcode1 = p1.vecparsed[0]; + uint16_t opcode2 = p2.vecparsed[0]; + + int32_t value1 = (opcode1 & (KOMODO_MAXPRICES - 1)); // index or weight + int32_t value2 = (opcode2 & (KOMODO_MAXPRICES - 1)); // index or weight + + if ( (opcode1 & KOMODO_PRICEMASK) == 0 && (opcode2 & KOMODO_PRICEMASK) == 0 ) { + char name1[65]; + char name2[65]; + if (komodo_pricename(name1, value1) && komodo_pricename(name2, value2)) { + + uint16_t opcode1 = p1.vecparsed[1]; + uint16_t opcode2 = p2.vecparsed[1]; + + std::string upperquote1, bottomquote1, upperquote2, bottomquote2; + prices_splitpair(std::string(name1), upperquote1, bottomquote1); + prices_splitpair(std::string(name2), upperquote2, bottomquote2); + + bool isInverted1 = ((opcode1 & KOMODO_PRICEMASK) != PRICES_INV); + bool isInverted2 = ((opcode2 & KOMODO_PRICEMASK) != PRICES_INV); + + if (/*upperquote1 == bottomquote2 && bottomquote1 == upperquote2 && (p1.leverage > 0 == p2.leverage > 0 || (opcode1 & KOMODO_PRICEMASK) == PRICES_INV == (opcode2 & KOMODO_PRICEMASK) == PRICES_INV) ||*/ + upperquote1 == upperquote2 && bottomquote1 == bottomquote2 && ((p1.leverage > 0) != (p2.leverage > 0) || isInverted1 != isInverted2) ) + return true; + } + } + } + return false; +} + + + +static std::string findMatchedBook(const std::vector &vecparsed, const std::map > & bookmatched) { + + if (vecparsed.size() > 1 && vecparsed.size() <= 3) { + uint16_t opcode = vecparsed[0]; + + int32_t value = (opcode & (KOMODO_MAXPRICES - 1)); // filter index or weight = opcode & (2048-1) + + if ((opcode & KOMODO_PRICEMASK) == 0) { + char name[65]; + if (komodo_pricename(name, value)) { + auto it = bookmatched.find(std::string(name)); + if (it != bookmatched.end()) + return it->first; + } + } + } + return std::string(""); +} + + +void prices_getorderbook(std::map > & bookmatched, std::map &matchedTotals, TotalFund &fundTotals) +{ + std::vector book; + std::vector > addressIndex; + struct CCcontract_info *cp, C; + + cp = CCinit(&C, EVAL_PRICES); + + // add all bets: + SetCCtxids(addressIndex, cp->normaladdr, false); // old normal marker + for (std::vector >::const_iterator it = addressIndex.begin(); it != addressIndex.end(); it++) + { + if (it->first.index == NVOUT_NORMALMARKER) + prices_addbookentry(it->first.txhash, book); + } + + + // calc total fund amount + fundTotals.totalFund = 0; + fundTotals.totalRekt = 0; + fundTotals.totalEquity = 0; + fundTotals.totalActiveBets = 0; + + std::vector > addressCCunspents; + SetCCunspents(addressCCunspents, cp->unspendableCCaddr, true); // cc marker + for (std::vector >::const_iterator it = addressCCunspents.begin(); it != addressCCunspents.end(); it++) + { + //std::cerr << "totalfund calc txid=" << it->first.txhash.GetHex() << " nvout=" << it->first.index << " satoshis=" << it->second.satoshis << std::endl; + fundTotals.totalFund += it->second.satoshis; + } + + // extract out opposite bets: + while (book.size() > 0) { + + int64_t totalPos = 0; + for (auto bet : book[0].bets) totalPos += bet.positionsize; + + if (book[0].isOpen) { + + fundTotals.totalActiveBets += totalPos; + fundTotals.totalEquity += book[0].equity; + + if (book[0].vecparsed.size() <= 3) { // only short expr check for match: "BTC_USD,1" or "BTC_USD,!,1" + char name[65]; + komodo_pricename(name, (book[0].vecparsed[0] & (KOMODO_MAXPRICES - 1))); + std::string sname = name; + bookmatched[sname].push_back(book[0]); + + for (int j = 1; j < book.size(); j++) { + if (book[0].isOpen && book[j].isOpen) { + if (prices_isopposite(book[0], book[j])) { + + bookmatched[sname].push_back(book[j]); + book.erase(book.begin() + j); + } + } + } + } + else { + // store as is + std::string sname = prices_getsourceexpression(book[0].vecparsed); + bookmatched[sname].push_back(book[0]); + } + } + else { + if( book[0].isRekt ) + fundTotals.totalRekt += (totalPos - book[0].exitfee); + else + fundTotals.totalCashout += (totalPos - book[0].exitfee); + + //TODO: store rekt + } + book.erase(book.begin()); + } + + // calculate cancelling amount + for (auto &m : bookmatched) { // note: use reference &m otherwise isUp will be changed only in a copy + int64_t totalLeveragedPositionUp = 0; + int64_t totalLeveragedPositionDown = 0; + + for (int i = 0; i < m.second.size(); i++) { + int64_t totalPos = 0; + for (auto bet : m.second[i].bets) totalPos += bet.positionsize; + m.second[i].isUp = prices_ispositionup(m.second[i].vecparsed, m.second[i].leverage); + if (m.second[i].isUp) + totalLeveragedPositionUp += totalPos * abs(m.second[i].leverage); + else + totalLeveragedPositionDown += totalPos * abs(m.second[i].leverage); + //std::cerr << "PricesGetOrderbook 0 m.second[i].isUp=" << m.second[i].isUp << " i=" << i << std::endl; + + } + matchedTotals[m.first].diffLeveragedPosition = totalLeveragedPositionUp - totalLeveragedPositionDown; + } +} + +static bool prices_isacceptableamount(const std::vector &vecparsed, int64_t amount, int16_t leverage) { + + std::map > matchedBook; + std::map matchedTotals; + TotalFund fundTotals; + + prices_getorderbook(matchedBook, matchedTotals, fundTotals); + std::string pricename = findMatchedBook(vecparsed, matchedBook); + if (!pricename.empty()) { + std::cerr << "prices_isacceptableamount() found matched book=" << pricename << " diffLeveragedPosition=" << matchedTotals[pricename].diffLeveragedPosition << " expr=" << prices_getsourceexpression(vecparsed) << std::endl; + // could fit into leveraged amount + if (prices_ispositionup(vecparsed, leverage) && amount*abs(leverage) + matchedTotals[pricename].diffLeveragedPosition <= 0) { + std::cerr << "prices_isacceptableamount() could fit into opposite negative lev amount" << std::endl; + return true; + } + if (!prices_ispositionup(vecparsed, leverage) && -amount*abs(leverage) + matchedTotals[pricename].diffLeveragedPosition >= 0) { + std::cerr << "prices_isacceptableamount() could fit into opposite positive lev amount" << std::endl; + return true; + } + } + + std::cerr << "prices_isacceptableamount() amount=" << amount << " leverage=" << leverage << " fundTotals.totalFund=" << fundTotals.totalFund << " fundTotals.totalEquity=" << fundTotals.totalEquity << std::endl; + // if not fit to matched = allow to bet for leveraged amount no more than 10% from free fund + if (amount * leverage < (fundTotals.totalFund - fundTotals.totalEquity) * PRICES_MINAVAILFUNDFRACTION) + return true; + + return false; +} + + // walk through uxtos on the global address // calculate the balance: // + rekt positions @@ -2015,17 +2456,65 @@ void prices_addbookentry(uint256 txid) // - unbalanced positions UniValue PricesGetOrderbook() { - UniValue result(UniValue::VARR); - std::vector > addressIndex, addressIndexCC; - struct CCcontract_info *cp, C; + UniValue result(UniValue::VOBJ); + std::map > matchedBook; + std::map matchedTotals; + TotalFund fundTotals; - cp = CCinit(&C, EVAL_PRICES); + prices_getorderbook(matchedBook, matchedTotals, fundTotals); - SetCCtxids(addressIndex, cp->normaladdr, false); // old normal marker - for (std::vector >::const_iterator it = addressIndex.begin(); it != addressIndex.end(); it++) - { - if (it->first.txindex == NVOUT_NORMALMARKER) - prices_addbookentry(it->first.txhash); + /*UniValue resbook (UniValue::VARR); + for (int i = 0; i < book.size(); i++) { + UniValue entry(UniValue::VOBJ); + entry.push_back(Pair("expression", prices_getsourceexpression(book[i].vecparsed))); + entry.push_back(Pair("costbasis", book[i].averageCostbasis)); + entry.push_back(Pair("leverage", book[i].leverage)); + entry.push_back(Pair("equity", book[i].equity)); + resbook.push_back(entry); } + result.push_back(Pair("unmatched", resbook)); */ + + // copy to rpc UniResult + for (auto &m : matchedBook) { + UniValue resheader(UniValue::VOBJ); + UniValue resbook(UniValue::VARR); + for (int i = 0; i < m.second.size(); i++) { + UniValue entry(UniValue::VOBJ); + + int64_t totalPos = 0; + for (auto bet : m.second[i].bets) totalPos += bet.positionsize; + entry.push_back(Pair("isOpen", (m.second[i].isOpen ? 1 : 0 ))); + entry.push_back(Pair("expression", prices_getsourceexpression(m.second[i].vecparsed))); + entry.push_back(Pair("positionsize", totalPos)); + entry.push_back(Pair("leverage", m.second[i].leverage)); + entry.push_back(Pair("costbasis", m.second[i].averageCostbasis)); + entry.push_back(Pair("lastprice", m.second[i].lastprice)); + entry.push_back(Pair("equity", m.second[i].equity)); + entry.push_back(Pair("isUpPosition", (m.second[i].isUp ? 1 : 0))); + resbook.push_back(entry); + } + resheader.push_back(Pair("positions", resbook)); + resheader.push_back(Pair("DiffLeveragedPosition", matchedTotals[m.first].diffLeveragedPosition)); + result.push_back(Pair(m.first, resheader)); + } + + //int64_t totalLiabilities = 0; + /* empty + for (int i = 0; i < book.size(); i++) { + if (book[i].isOpen) { + int64_t t = 0; + for (auto b : book[i].bets) t += b.positionsize; + std::cerr << "book[i].txid=" << book[i].txid.GetHex() << " exp=" << prices_getsourceexpression(book[i].vecparsed) << " totalpos=" << t << " equity=" << book[i].equity << std::endl; + totalLiabilities += book[i].equity; + } + } */ + + result.push_back(Pair("TotalFund", ValueFromAmount(fundTotals.totalFund))); + result.push_back(Pair("TotalEquity", ValueFromAmount(fundTotals.totalEquity))); + result.push_back(Pair("TotalRekt", ValueFromAmount(fundTotals.totalRekt))); + result.push_back(Pair("TotalBets", ValueFromAmount(fundTotals.totalActiveBets))); + result.push_back(Pair("TotalCashoutBets", ValueFromAmount(fundTotals.totalCashout))); + +// result.push_back(Pair("TotalLiabilities", ValueFromAmount(totalLiabilities))); return result; } diff --git a/src/fiat/k64 b/src/fiat/k64 new file mode 100755 index 000000000..a3b3bc835 --- /dev/null +++ b/src/fiat/k64 @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=K64 $1 $2 $3 $4 $5 $6 diff --git a/src/fiat/zex b/src/fiat/zex deleted file mode 100755 index f4573c093..000000000 --- a/src/fiat/zex +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -./komodo-cli -ac_name=ZEX $1 $2 $3 $4 $5 $6 diff --git a/src/fiat/zexo b/src/fiat/zexo new file mode 100755 index 000000000..b6fd508f2 --- /dev/null +++ b/src/fiat/zexo @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=ZEXO $1 $2 $3 $4 $5 $6 diff --git a/src/komodo.h b/src/komodo.h index b4c7d12bf..cd7c6573a 100644 --- a/src/komodo.h +++ b/src/komodo.h @@ -713,9 +713,9 @@ int32_t komodo_voutupdate(bool fJustCheck,int32_t *isratificationp,int32_t notar sp->MoMdepth = MoMdepth; } komodo_stateupdate(height,0,0,0,zero,0,0,0,0,0,0,0,0,0,0,sp->MoM,sp->MoMdepth); - if ( ASSETCHAINS_SYMBOL[0] != 0 ) + //if ( ASSETCHAINS_SYMBOL[0] != 0 ) printf("[%s] ht.%d NOTARIZED.%d %s.%s %sTXID.%s lens.(%d %d) MoM.%s %d\n",ASSETCHAINS_SYMBOL,height,sp->NOTARIZED_HEIGHT,ASSETCHAINS_SYMBOL[0]==0?"KMD":ASSETCHAINS_SYMBOL,srchash.ToString().c_str(),ASSETCHAINS_SYMBOL[0]==0?"BTC":"KMD",desttxid.ToString().c_str(),opretlen,len,sp->MoM.ToString().c_str(),sp->MoMdepth); - + if ( ASSETCHAINS_SYMBOL[0] == 0 ) { if ( signedfp == 0 ) diff --git a/src/komodo_defs.h b/src/komodo_defs.h index 5efbe58fb..cf15f0b19 100644 --- a/src/komodo_defs.h +++ b/src/komodo_defs.h @@ -31,6 +31,158 @@ #define KOMODO_SAPLING_DEADLINE 1550188800 // Feb 15th, 2019 #define _COINBASE_MATURITY 100 +// KMD Notary Seasons +// 1: May 1st 2018 1530921600 +// 2: July 15th 2019 1563148800 -> estimated height 1444000 +// 3: 3rd season ending isnt known, so use very far times in future. + // 1751328000 = dummy timestamp, 1 July 2025! + // 7113400 = 5x current KMD blockheight. +// to add 4th season, change NUM_KMD_SEASONS to 4, and add timestamp and height of activation to these arrays. +#define NUM_KMD_SEASONS 3 +#define NUM_KMD_NOTARIES 64 +static const uint32_t KMD_SEASON_TIMESTAMPS[NUM_KMD_SEASONS] = {1525132800, 1563148800, 1751328000}; +static const int32_t KMD_SEASON_HEIGHTS[NUM_KMD_SEASONS] = {814000, 1444000, 7113400}; + +// Era array of pubkeys. Add extra seasons to bottom as requried, after adding appropriate info above. +static const char *notaries_elected[NUM_KMD_SEASONS][NUM_KMD_NOTARIES][2] = +{ + { + { "0_jl777_testA", "03b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828" }, + { "0_jl777_testB", "02ebfc784a4ba768aad88d44d1045d240d47b26e248cafaf1c5169a42d7a61d344" }, + { "0_kolo_testA", "0287aa4b73988ba26cf6565d815786caf0d2c4af704d7883d163ee89cd9977edec" }, + { "artik_AR", "029acf1dcd9f5ff9c455f8bb717d4ae0c703e089d16cf8424619c491dff5994c90" }, + { "artik_EU", "03f54b2c24f82632e3cdebe4568ba0acf487a80f8a89779173cdb78f74514847ce" }, + { "artik_NA", "0224e31f93eff0cc30eaf0b2389fbc591085c0e122c4d11862c1729d090106c842" }, + { "artik_SH", "02bdd8840a34486f38305f311c0e2ae73e84046f6e9c3dd3571e32e58339d20937" }, + { "badass_EU", "0209d48554768dd8dada988b98aca23405057ac4b5b46838a9378b95c3e79b9b9e" }, + { "badass_NA", "02afa1a9f948e1634a29dc718d218e9d150c531cfa852843a1643a02184a63c1a7" }, + { "badass_SH", "026b49dd3923b78a592c1b475f208e23698d3f085c4c3b4906a59faf659fd9530b" }, + { "crackers_EU", "03bc819982d3c6feb801ec3b720425b017d9b6ee9a40746b84422cbbf929dc73c3" }, // 10 + { "crackers_NA", "03205049103113d48c7c7af811b4c8f194dafc43a50d5313e61a22900fc1805b45" }, + { "crackers_SH", "02be28310e6312d1dd44651fd96f6a44ccc269a321f907502aae81d246fabdb03e" }, + { "durerus_EU", "02bcbd287670bdca2c31e5d50130adb5dea1b53198f18abeec7211825f47485d57" }, + { "etszombi_AR", "031c79168d15edabf17d9ec99531ea9baa20039d0cdc14d9525863b83341b210e9" }, + { "etszombi_EU", "0281b1ad28d238a2b217e0af123ce020b79e91b9b10ad65a7917216eda6fe64bf7" }, // 15 + { "etszombi_SH", "025d7a193c0757f7437fad3431f027e7b5ed6c925b77daba52a8755d24bf682dde" }, + { "farl4web_EU", "0300ecf9121cccf14cf9423e2adb5d98ce0c4e251721fa345dec2e03abeffbab3f" }, + { "farl4web_SH", "0396bb5ed3c57aa1221d7775ae0ff751e4c7dc9be220d0917fa8bbdf670586c030" }, + { "fullmoon_AR", "0254b1d64840ce9ff6bec9dd10e33beb92af5f7cee628f999cb6bc0fea833347cc" }, + { "fullmoon_NA", "031fb362323b06e165231c887836a8faadb96eda88a79ca434e28b3520b47d235b" }, // 20 + { "fullmoon_SH", "030e12b42ec33a80e12e570b6c8274ce664565b5c3da106859e96a7208b93afd0d" }, + { "grewal_NA", "03adc0834c203d172bce814df7c7a5e13dc603105e6b0adabc942d0421aefd2132" }, + { "grewal_SH", "03212a73f5d38a675ee3cdc6e82542a96c38c3d1c79d25a1ed2e42fcf6a8be4e68" }, + { "indenodes_AR", "02ec0fa5a40f47fd4a38ea5c89e375ad0b6ddf4807c99733c9c3dc15fb978ee147" }, + { "indenodes_EU", "0221387ff95c44cb52b86552e3ec118a3c311ca65b75bf807c6c07eaeb1be8303c" }, + { "indenodes_NA", "02698c6f1c9e43b66e82dbb163e8df0e5a2f62f3a7a882ca387d82f86e0b3fa988" }, + { "indenodes_SH", "0334e6e1ec8285c4b85bd6dae67e17d67d1f20e7328efad17ce6fd24ae97cdd65e" }, + { "jeezy_EU", "023cb3e593fb85c5659688528e9a4f1c4c7f19206edc7e517d20f794ba686fd6d6" }, + { "jsgalt_NA", "027b3fb6fede798cd17c30dbfb7baf9332b3f8b1c7c513f443070874c410232446" }, + { "karasugoi_NA", "02a348b03b9c1a8eac1b56f85c402b041c9bce918833f2ea16d13452309052a982" }, // 30 + { "kashifali_EU", "033777c52a0190f261c6f66bd0e2bb299d30f012dcb8bfff384103211edb8bb207" }, + { "kolo_AR", "03016d19344c45341e023b72f9fb6e6152fdcfe105f3b4f50b82a4790ff54e9dc6" }, + { "kolo_SH", "02aa24064500756d9b0959b44d5325f2391d8e95c6127e109184937152c384e185" }, + { "metaphilibert_AR", "02adad675fae12b25fdd0f57250b0caf7f795c43f346153a31fe3e72e7db1d6ac6" }, + { "movecrypto_AR", "022783d94518e4dc77cbdf1a97915b29f427d7bc15ea867900a76665d3112be6f3" }, + { "movecrypto_EU", "021ab53bc6cf2c46b8a5456759f9d608966eff87384c2b52c0ac4cc8dd51e9cc42" }, + { "movecrypto_NA", "02efb12f4d78f44b0542d1c60146738e4d5506d27ec98a469142c5c84b29de0a80" }, + { "movecrypto_SH", "031f9739a3ebd6037a967ce1582cde66e79ea9a0551c54731c59c6b80f635bc859" }, + { "muros_AR", "022d77402fd7179335da39479c829be73428b0ef33fb360a4de6890f37c2aa005e" }, + { "noashh_AR", "029d93ef78197dc93892d2a30e5a54865f41e0ca3ab7eb8e3dcbc59c8756b6e355" }, // 40 + { "noashh_EU", "02061c6278b91fd4ac5cab4401100ffa3b2d5a277e8f71db23401cc071b3665546" }, + { "noashh_NA", "033c073366152b6b01535e15dd966a3a8039169584d06e27d92a69889b720d44e1" }, + { "nxtswe_EU", "032fb104e5eaa704a38a52c126af8f67e870d70f82977e5b2f093d5c1c21ae5899" }, + { "polycryptoblog_NA", "02708dcda7c45fb54b78469673c2587bfdd126e381654819c4c23df0e00b679622" }, + { "pondsea_AR", "032e1c213787312099158f2d74a89e8240a991d162d4ce8017d8504d1d7004f735" }, + { "pondsea_EU", "0225aa6f6f19e543180b31153d9e6d55d41bc7ec2ba191fd29f19a2f973544e29d" }, + { "pondsea_NA", "031bcfdbb62268e2ff8dfffeb9ddff7fe95fca46778c77eebff9c3829dfa1bb411" }, + { "pondsea_SH", "02209073bc0943451498de57f802650311b1f12aa6deffcd893da198a544c04f36" }, + { "popcornbag_AR", "02761f106fb34fbfc5ddcc0c0aa831ed98e462a908550b280a1f7bd32c060c6fa3" }, + { "popcornbag_NA", "03c6085c7fdfff70988fda9b197371f1caf8397f1729a844790e421ee07b3a93e8" }, // 50 + { "ptytrader_NA", "0328c61467148b207400b23875234f8a825cce65b9c4c9b664f47410b8b8e3c222" }, + { "ptytrader_SH", "0250c93c492d8d5a6b565b90c22bee07c2d8701d6118c6267e99a4efd3c7748fa4" }, + { "rnr_AR", "029bdb08f931c0e98c2c4ba4ef45c8e33a34168cb2e6bf953cef335c359d77bfcd" }, + { "rnr_EU", "03f5c08dadffa0ffcafb8dd7ffc38c22887bd02702a6c9ac3440deddcf2837692b" }, + { "rnr_NA", "02e17c5f8c3c80f584ed343b8dcfa6d710dfef0889ec1e7728ce45ce559347c58c" }, + { "rnr_SH", "037536fb9bdfed10251f71543fb42679e7c52308bcd12146b2568b9a818d8b8377" }, + { "titomane_AR", "03cda6ca5c2d02db201488a54a548dbfc10533bdc275d5ea11928e8d6ab33c2185" }, + { "titomane_EU", "02e41feded94f0cc59f55f82f3c2c005d41da024e9a805b41105207ef89aa4bfbd" }, + { "titomane_SH", "035f49d7a308dd9a209e894321f010d21b7793461b0c89d6d9231a3fe5f68d9960" }, + { "vanbreuk_EU", "024f3cad7601d2399c131fd070e797d9cd8533868685ddbe515daa53c2e26004c3" }, // 60 + { "xrobesx_NA", "03f0cc6d142d14a40937f12dbd99dbd9021328f45759e26f1877f2a838876709e1" }, + { "xxspot1_XX", "02ef445a392fcaf3ad4176a5da7f43580e8056594e003eba6559a713711a27f955" }, + { "xxspot2_XX", "03d85b221ea72ebcd25373e7961f4983d12add66a92f899deaf07bab1d8b6f5573" } + }, + { + {"0dev1_jl777", "03b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828" }, + {"0dev2_kolo", "030f34af4b908fb8eb2099accb56b8d157d49f6cfb691baa80fdd34f385efed961" }, + {"0dev3_kolo", "025af9d2b2a05338478159e9ac84543968fd18c45fd9307866b56f33898653b014" }, + {"0dev4_decker", "028eea44a09674dda00d88ffd199a09c9b75ba9782382cc8f1e97c0fd565fe5707" }, + {"a-team_SH", "03b59ad322b17cb94080dc8e6dc10a0a865de6d47c16fb5b1a0b5f77f9507f3cce" }, + {"artik_AR", "029acf1dcd9f5ff9c455f8bb717d4ae0c703e089d16cf8424619c491dff5994c90" }, + {"artik_EU", "03f54b2c24f82632e3cdebe4568ba0acf487a80f8a89779173cdb78f74514847ce" }, + {"artik_NA", "0224e31f93eff0cc30eaf0b2389fbc591085c0e122c4d11862c1729d090106c842" }, + {"artik_SH", "02bdd8840a34486f38305f311c0e2ae73e84046f6e9c3dd3571e32e58339d20937" }, + {"badass_EU", "0209d48554768dd8dada988b98aca23405057ac4b5b46838a9378b95c3e79b9b9e" }, + {"badass_NA", "02afa1a9f948e1634a29dc718d218e9d150c531cfa852843a1643a02184a63c1a7" }, // 10 + {"batman_AR", "033ecb640ec5852f42be24c3bf33ca123fb32ced134bed6aa2ba249cf31b0f2563" }, + {"batman_SH", "02ca5898931181d0b8aafc75ef56fce9c43656c0b6c9f64306e7c8542f6207018c" }, + {"ca333_EU", "03fc87b8c804f12a6bd18efd43b0ba2828e4e38834f6b44c0bfee19f966a12ba99" }, + {"chainmakers_EU", "02f3b08938a7f8d2609d567aebc4989eeded6e2e880c058fdf092c5da82c3bc5ee" }, + {"chainmakers_NA", "0276c6d1c65abc64c8559710b8aff4b9e33787072d3dda4ec9a47b30da0725f57a" }, + {"chainstrike_SH", "0370bcf10575d8fb0291afad7bf3a76929734f888228bc49e35c5c49b336002153" }, + {"cipi_AR", "02c4f89a5b382750836cb787880d30e23502265054e1c327a5bfce67116d757ce8" }, + {"cipi_NA", "02858904a2a1a0b44df4c937b65ee1f5b66186ab87a751858cf270dee1d5031f18" }, + {"crackers_EU", "03bc819982d3c6feb801ec3b720425b017d9b6ee9a40746b84422cbbf929dc73c3" }, + {"crackers_NA", "03205049103113d48c7c7af811b4c8f194dafc43a50d5313e61a22900fc1805b45" }, // 20 + {"dwy_EU", "0259c646288580221fdf0e92dbeecaee214504fdc8bbdf4a3019d6ec18b7540424" }, + {"emmanux_SH", "033f316114d950497fc1d9348f03770cd420f14f662ab2db6172df44c389a2667a" }, + {"etszombi_EU", "0281b1ad28d238a2b217e0af123ce020b79e91b9b10ad65a7917216eda6fe64bf7" }, + {"fullmoon_AR", "03380314c4f42fa854df8c471618751879f9e8f0ff5dbabda2bd77d0f96cb35676" }, + {"fullmoon_NA", "030216211d8e2a48bae9e5d7eb3a42ca2b7aae8770979a791f883869aea2fa6eef" }, + {"fullmoon_SH", "03f34282fa57ecc7aba8afaf66c30099b5601e98dcbfd0d8a58c86c20d8b692c64" }, + {"goldenman_EU", "02d6f13a8f745921cdb811e32237bb98950af1a5952be7b3d429abd9152f8e388d" }, + {"indenodes_AR", "02ec0fa5a40f47fd4a38ea5c89e375ad0b6ddf4807c99733c9c3dc15fb978ee147" }, + {"indenodes_EU", "0221387ff95c44cb52b86552e3ec118a3c311ca65b75bf807c6c07eaeb1be8303c" }, + {"indenodes_NA", "02698c6f1c9e43b66e82dbb163e8df0e5a2f62f3a7a882ca387d82f86e0b3fa988" }, // 30 + {"indenodes_SH", "0334e6e1ec8285c4b85bd6dae67e17d67d1f20e7328efad17ce6fd24ae97cdd65e" }, + {"jackson_AR", "038ff7cfe34cb13b524e0941d5cf710beca2ffb7e05ddf15ced7d4f14fbb0a6f69" }, + {"jeezy_EU", "023cb3e593fb85c5659688528e9a4f1c4c7f19206edc7e517d20f794ba686fd6d6" }, + {"karasugoi_NA", "02a348b03b9c1a8eac1b56f85c402b041c9bce918833f2ea16d13452309052a982" }, + {"komodoninja_EU", "038e567b99806b200b267b27bbca2abf6a3e8576406df5f872e3b38d30843cd5ba" }, + {"komodoninja_SH", "033178586896915e8456ebf407b1915351a617f46984001790f0cce3d6f3ada5c2" }, + {"komodopioneers_SH", "033ace50aedf8df70035b962a805431363a61cc4e69d99d90726a2d48fb195f68c" }, + {"libscott_SH", "03301a8248d41bc5dc926088a8cf31b65e2daf49eed7eb26af4fb03aae19682b95" }, + {"lukechilds_AR", "031aa66313ee024bbee8c17915cf7d105656d0ace5b4a43a3ab5eae1e14ec02696" }, + {"madmax_AR", "03891555b4a4393d655bf76f0ad0fb74e5159a615b6925907678edc2aac5e06a75" }, // 40 + {"meshbits_AR", "02957fd48ae6cb361b8a28cdb1b8ccf5067ff68eb1f90cba7df5f7934ed8eb4b2c" }, + {"meshbits_SH", "025c6e94877515dfd7b05682b9cc2fe4a49e076efe291e54fcec3add78183c1edb" }, + {"metaphilibert_AR", "02adad675fae12b25fdd0f57250b0caf7f795c43f346153a31fe3e72e7db1d6ac6" }, + {"metaphilibert_SH", "0284af1a5ef01503e6316a2ca4abf8423a794e9fc17ac6846f042b6f4adedc3309" }, + {"patchkez_SH", "0296270f394140640f8fa15684fc11255371abb6b9f253416ea2734e34607799c4" }, + {"pbca26_NA", "0276aca53a058556c485bbb60bdc54b600efe402a8b97f0341a7c04803ce204cb5" }, + {"peer2cloud_AR", "034e5563cb885999ae1530bd66fab728e580016629e8377579493b386bf6cebb15" }, + {"peer2cloud_SH", "03396ac453b3f23e20f30d4793c5b8ab6ded6993242df4f09fd91eb9a4f8aede84" }, + {"polycryptoblog_NA", "02708dcda7c45fb54b78469673c2587bfdd126e381654819c4c23df0e00b679622" }, + {"hyper_AR", "020f2f984d522051bd5247b61b080b4374a7ab389d959408313e8062acad3266b4" }, // 50 + {"hyper_EU", "03d00cf9ceace209c59fb013e112a786ad583d7de5ca45b1e0df3b4023bb14bf51" }, + {"hyper_SH", "0383d0b37f59f4ee5e3e98a47e461c861d49d0d90c80e9e16f7e63686a2dc071f3" }, + {"hyper_NA", "03d91c43230336c0d4b769c9c940145a8c53168bf62e34d1bccd7f6cfc7e5592de" }, + {"popcornbag_AR", "02761f106fb34fbfc5ddcc0c0aa831ed98e462a908550b280a1f7bd32c060c6fa3" }, + {"popcornbag_NA", "03c6085c7fdfff70988fda9b197371f1caf8397f1729a844790e421ee07b3a93e8" }, + {"alien_AR", "0348d9b1fc6acf81290405580f525ee49b4749ed4637b51a28b18caa26543b20f0" }, + {"alien_EU", "020aab8308d4df375a846a9e3b1c7e99597b90497efa021d50bcf1bbba23246527" }, + {"thegaltmines_NA", "031bea28bec98b6380958a493a703ddc3353d7b05eb452109a773eefd15a32e421" }, + {"titomane_AR", "029d19215440d8cb9cc6c6b7a4744ae7fb9fb18d986e371b06aeb34b64845f9325" }, + {"titomane_EU", "0360b4805d885ff596f94312eed3e4e17cb56aa8077c6dd78d905f8de89da9499f" }, // 60 + {"titomane_SH", "03573713c5b20c1e682a2e8c0f8437625b3530f278e705af9b6614de29277a435b" }, + {"webworker01_NA", "03bb7d005e052779b1586f071834c5facbb83470094cff5112f0072b64989f97d7" }, + {"xrobesx_NA", "03f0cc6d142d14a40937f12dbd99dbd9021328f45759e26f1877f2a838876709e1" }, + }, + { + {"webworker01_NA", "03bb7d005e052779b1586f071834c5facbb83470094cff5112f0072b64989f97d7" } + } +}; + #define SETBIT(bits,bitoffset) (((uint8_t *)bits)[(bitoffset) >> 3] |= (1 << ((bitoffset) & 7))) #define GETBIT(bits,bitoffset) (((uint8_t *)bits)[(bitoffset) >> 3] & (1 << ((bitoffset) & 7))) #define CLEARBIT(bits,bitoffset) (((uint8_t *)bits)[(bitoffset) >> 3] &= ~(1 << ((bitoffset) & 7))) @@ -82,7 +234,8 @@ extern int32_t VERUS_MIN_STAKEAGE; extern std::string DONATION_PUBKEY; extern uint8_t ASSETCHAINS_PRIVATE; extern int32_t USE_EXTERNAL_PUBKEY; -extern char NOTARYADDRS[64][64]; +extern char NOTARYADDRS[64][64]; // should be depreciated later. Only affects labs. +extern char NOTARY_ADDRESSES[NUM_KMD_SEASONS][64][64]; extern int32_t KOMODO_TESTNODE, KOMODO_SNAPSHOT_INTERVAL; extern int32_t ASSETCHAINS_EARLYTXIDCONTRACT; int tx_height( const uint256 &hash ); diff --git a/src/komodo_globals.h b/src/komodo_globals.h index 08c633ee7..099cddd4b 100644 --- a/src/komodo_globals.h +++ b/src/komodo_globals.h @@ -53,6 +53,7 @@ bool VERUS_MINTBLOCKS; std::vector Mineropret; std::vector vWhiteListAddress; char NOTARYADDRS[64][64]; +char NOTARY_ADDRESSES[NUM_KMD_SEASONS][64][64]; char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN],ASSETCHAINS_USERPASS[4096]; uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT,ASSETCHAINS_BEAMPORT,ASSETCHAINS_CODAPORT; diff --git a/src/komodo_notary.h b/src/komodo_notary.h index 5cdbf237d..e2c7dfb4c 100644 --- a/src/komodo_notary.h +++ b/src/komodo_notary.h @@ -20,6 +20,7 @@ #include "notaries_staked.h" #define KOMODO_MAINNET_START 178999 +#define KOMODO_NOTARIES_HEIGHT1 814000 const char *Notaries_genesis[][2] = { @@ -60,194 +61,80 @@ const char *Notaries_genesis[][2] = { "titomane_SH", "035f49d7a308dd9a209e894321f010d21b7793461b0c89d6d9231a3fe5f68d9960" }, }; -const char *Notaries_elected0[][2] = -{ - { "0_jl777_testA", "03b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828" }, - { "0_jl777_testB", "02ebfc784a4ba768aad88d44d1045d240d47b26e248cafaf1c5169a42d7a61d344" }, - { "0_kolo_testA", "0287aa4b73988ba26cf6565d815786caf0d2c4af704d7883d163ee89cd9977edec" }, - { "artik_AR", "029acf1dcd9f5ff9c455f8bb717d4ae0c703e089d16cf8424619c491dff5994c90" }, - { "artik_EU", "03f54b2c24f82632e3cdebe4568ba0acf487a80f8a89779173cdb78f74514847ce" }, - { "artik_NA", "0224e31f93eff0cc30eaf0b2389fbc591085c0e122c4d11862c1729d090106c842" }, - { "artik_SH", "02bdd8840a34486f38305f311c0e2ae73e84046f6e9c3dd3571e32e58339d20937" }, - { "badass_EU", "0209d48554768dd8dada988b98aca23405057ac4b5b46838a9378b95c3e79b9b9e" }, - { "badass_NA", "02afa1a9f948e1634a29dc718d218e9d150c531cfa852843a1643a02184a63c1a7" }, - { "badass_SH", "026b49dd3923b78a592c1b475f208e23698d3f085c4c3b4906a59faf659fd9530b" }, - { "crackers_EU", "03bc819982d3c6feb801ec3b720425b017d9b6ee9a40746b84422cbbf929dc73c3" }, // 10 - { "crackers_NA", "03205049103113d48c7c7af811b4c8f194dafc43a50d5313e61a22900fc1805b45" }, - { "crackers_SH", "02be28310e6312d1dd44651fd96f6a44ccc269a321f907502aae81d246fabdb03e" }, - { "durerus_EU", "02bcbd287670bdca2c31e5d50130adb5dea1b53198f18abeec7211825f47485d57" }, - { "etszombi_AR", "031c79168d15edabf17d9ec99531ea9baa20039d0cdc14d9525863b83341b210e9" }, - { "etszombi_EU", "0281b1ad28d238a2b217e0af123ce020b79e91b9b10ad65a7917216eda6fe64bf7" }, // 15 - { "etszombi_SH", "025d7a193c0757f7437fad3431f027e7b5ed6c925b77daba52a8755d24bf682dde" }, - { "farl4web_EU", "0300ecf9121cccf14cf9423e2adb5d98ce0c4e251721fa345dec2e03abeffbab3f" }, - { "farl4web_SH", "0396bb5ed3c57aa1221d7775ae0ff751e4c7dc9be220d0917fa8bbdf670586c030" }, - { "fullmoon_AR", "0254b1d64840ce9ff6bec9dd10e33beb92af5f7cee628f999cb6bc0fea833347cc" }, - { "fullmoon_NA", "031fb362323b06e165231c887836a8faadb96eda88a79ca434e28b3520b47d235b" }, // 20 - { "fullmoon_SH", "030e12b42ec33a80e12e570b6c8274ce664565b5c3da106859e96a7208b93afd0d" }, - { "grewal_NA", "03adc0834c203d172bce814df7c7a5e13dc603105e6b0adabc942d0421aefd2132" }, - { "grewal_SH", "03212a73f5d38a675ee3cdc6e82542a96c38c3d1c79d25a1ed2e42fcf6a8be4e68" }, - { "indenodes_AR", "02ec0fa5a40f47fd4a38ea5c89e375ad0b6ddf4807c99733c9c3dc15fb978ee147" }, - { "indenodes_EU", "0221387ff95c44cb52b86552e3ec118a3c311ca65b75bf807c6c07eaeb1be8303c" }, - { "indenodes_NA", "02698c6f1c9e43b66e82dbb163e8df0e5a2f62f3a7a882ca387d82f86e0b3fa988" }, - { "indenodes_SH", "0334e6e1ec8285c4b85bd6dae67e17d67d1f20e7328efad17ce6fd24ae97cdd65e" }, - { "jeezy_EU", "023cb3e593fb85c5659688528e9a4f1c4c7f19206edc7e517d20f794ba686fd6d6" }, - { "jsgalt_NA", "027b3fb6fede798cd17c30dbfb7baf9332b3f8b1c7c513f443070874c410232446" }, - { "karasugoi_NA", "02a348b03b9c1a8eac1b56f85c402b041c9bce918833f2ea16d13452309052a982" }, // 30 - { "kashifali_EU", "033777c52a0190f261c6f66bd0e2bb299d30f012dcb8bfff384103211edb8bb207" }, - { "kolo_AR", "03016d19344c45341e023b72f9fb6e6152fdcfe105f3b4f50b82a4790ff54e9dc6" }, - { "kolo_SH", "02aa24064500756d9b0959b44d5325f2391d8e95c6127e109184937152c384e185" }, - { "metaphilibert_AR", "02adad675fae12b25fdd0f57250b0caf7f795c43f346153a31fe3e72e7db1d6ac6" }, - { "movecrypto_AR", "022783d94518e4dc77cbdf1a97915b29f427d7bc15ea867900a76665d3112be6f3" }, - { "movecrypto_EU", "021ab53bc6cf2c46b8a5456759f9d608966eff87384c2b52c0ac4cc8dd51e9cc42" }, - { "movecrypto_NA", "02efb12f4d78f44b0542d1c60146738e4d5506d27ec98a469142c5c84b29de0a80" }, - { "movecrypto_SH", "031f9739a3ebd6037a967ce1582cde66e79ea9a0551c54731c59c6b80f635bc859" }, - { "muros_AR", "022d77402fd7179335da39479c829be73428b0ef33fb360a4de6890f37c2aa005e" }, - { "noashh_AR", "029d93ef78197dc93892d2a30e5a54865f41e0ca3ab7eb8e3dcbc59c8756b6e355" }, // 40 - { "noashh_EU", "02061c6278b91fd4ac5cab4401100ffa3b2d5a277e8f71db23401cc071b3665546" }, - { "noashh_NA", "033c073366152b6b01535e15dd966a3a8039169584d06e27d92a69889b720d44e1" }, - { "nxtswe_EU", "032fb104e5eaa704a38a52c126af8f67e870d70f82977e5b2f093d5c1c21ae5899" }, - { "polycryptoblog_NA", "02708dcda7c45fb54b78469673c2587bfdd126e381654819c4c23df0e00b679622" }, - { "pondsea_AR", "032e1c213787312099158f2d74a89e8240a991d162d4ce8017d8504d1d7004f735" }, - { "pondsea_EU", "0225aa6f6f19e543180b31153d9e6d55d41bc7ec2ba191fd29f19a2f973544e29d" }, - { "pondsea_NA", "031bcfdbb62268e2ff8dfffeb9ddff7fe95fca46778c77eebff9c3829dfa1bb411" }, - { "pondsea_SH", "02209073bc0943451498de57f802650311b1f12aa6deffcd893da198a544c04f36" }, - { "popcornbag_AR", "02761f106fb34fbfc5ddcc0c0aa831ed98e462a908550b280a1f7bd32c060c6fa3" }, - { "popcornbag_NA", "03c6085c7fdfff70988fda9b197371f1caf8397f1729a844790e421ee07b3a93e8" }, // 50 - { "ptytrader_NA", "0328c61467148b207400b23875234f8a825cce65b9c4c9b664f47410b8b8e3c222" }, - { "ptytrader_SH", "0250c93c492d8d5a6b565b90c22bee07c2d8701d6118c6267e99a4efd3c7748fa4" }, - { "rnr_AR", "029bdb08f931c0e98c2c4ba4ef45c8e33a34168cb2e6bf953cef335c359d77bfcd" }, - { "rnr_EU", "03f5c08dadffa0ffcafb8dd7ffc38c22887bd02702a6c9ac3440deddcf2837692b" }, - { "rnr_NA", "02e17c5f8c3c80f584ed343b8dcfa6d710dfef0889ec1e7728ce45ce559347c58c" }, - { "rnr_SH", "037536fb9bdfed10251f71543fb42679e7c52308bcd12146b2568b9a818d8b8377" }, - { "titomane_AR", "03cda6ca5c2d02db201488a54a548dbfc10533bdc275d5ea11928e8d6ab33c2185" }, - { "titomane_EU", "02e41feded94f0cc59f55f82f3c2c005d41da024e9a805b41105207ef89aa4bfbd" }, - { "titomane_SH", "035f49d7a308dd9a209e894321f010d21b7793461b0c89d6d9231a3fe5f68d9960" }, - { "vanbreuk_EU", "024f3cad7601d2399c131fd070e797d9cd8533868685ddbe515daa53c2e26004c3" }, // 60 - { "xrobesx_NA", "03f0cc6d142d14a40937f12dbd99dbd9021328f45759e26f1877f2a838876709e1" }, - { "xxspot1_XX", "02ef445a392fcaf3ad4176a5da7f43580e8056594e003eba6559a713711a27f955" }, - { "xxspot2_XX", "03d85b221ea72ebcd25373e7961f4983d12add66a92f899deaf07bab1d8b6f5573" } -}; - -#define KOMODO_NOTARIES_TIMESTAMP1 1525132800 // May 1st 2018 1530921600 // 7/7/2017 -#define KOMODO_NOTARIES_HEIGHT1 ((814000 / KOMODO_ELECTION_GAP) * KOMODO_ELECTION_GAP) - -const char *Notaries_elected1[][2] = -{ - {"0dev1_jl777", "03b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828" }, - {"0dev2_kolo", "030f34af4b908fb8eb2099accb56b8d157d49f6cfb691baa80fdd34f385efed961" }, - {"0dev3_kolo", "025af9d2b2a05338478159e9ac84543968fd18c45fd9307866b56f33898653b014" }, - {"0dev4_decker", "028eea44a09674dda00d88ffd199a09c9b75ba9782382cc8f1e97c0fd565fe5707" }, - {"a-team_SH", "03b59ad322b17cb94080dc8e6dc10a0a865de6d47c16fb5b1a0b5f77f9507f3cce" }, - {"artik_AR", "029acf1dcd9f5ff9c455f8bb717d4ae0c703e089d16cf8424619c491dff5994c90" }, - {"artik_EU", "03f54b2c24f82632e3cdebe4568ba0acf487a80f8a89779173cdb78f74514847ce" }, - {"artik_NA", "0224e31f93eff0cc30eaf0b2389fbc591085c0e122c4d11862c1729d090106c842" }, - {"artik_SH", "02bdd8840a34486f38305f311c0e2ae73e84046f6e9c3dd3571e32e58339d20937" }, - {"badass_EU", "0209d48554768dd8dada988b98aca23405057ac4b5b46838a9378b95c3e79b9b9e" }, - {"badass_NA", "02afa1a9f948e1634a29dc718d218e9d150c531cfa852843a1643a02184a63c1a7" }, // 10 - {"batman_AR", "033ecb640ec5852f42be24c3bf33ca123fb32ced134bed6aa2ba249cf31b0f2563" }, - {"batman_SH", "02ca5898931181d0b8aafc75ef56fce9c43656c0b6c9f64306e7c8542f6207018c" }, - {"ca333_EU", "03fc87b8c804f12a6bd18efd43b0ba2828e4e38834f6b44c0bfee19f966a12ba99" }, - {"chainmakers_EU", "02f3b08938a7f8d2609d567aebc4989eeded6e2e880c058fdf092c5da82c3bc5ee" }, - {"chainmakers_NA", "0276c6d1c65abc64c8559710b8aff4b9e33787072d3dda4ec9a47b30da0725f57a" }, - {"chainstrike_SH", "0370bcf10575d8fb0291afad7bf3a76929734f888228bc49e35c5c49b336002153" }, - {"cipi_AR", "02c4f89a5b382750836cb787880d30e23502265054e1c327a5bfce67116d757ce8" }, - {"cipi_NA", "02858904a2a1a0b44df4c937b65ee1f5b66186ab87a751858cf270dee1d5031f18" }, - {"crackers_EU", "03bc819982d3c6feb801ec3b720425b017d9b6ee9a40746b84422cbbf929dc73c3" }, - {"crackers_NA", "03205049103113d48c7c7af811b4c8f194dafc43a50d5313e61a22900fc1805b45" }, // 20 - {"dwy_EU", "0259c646288580221fdf0e92dbeecaee214504fdc8bbdf4a3019d6ec18b7540424" }, - {"emmanux_SH", "033f316114d950497fc1d9348f03770cd420f14f662ab2db6172df44c389a2667a" }, - {"etszombi_EU", "0281b1ad28d238a2b217e0af123ce020b79e91b9b10ad65a7917216eda6fe64bf7" }, - {"fullmoon_AR", "03380314c4f42fa854df8c471618751879f9e8f0ff5dbabda2bd77d0f96cb35676" }, - {"fullmoon_NA", "030216211d8e2a48bae9e5d7eb3a42ca2b7aae8770979a791f883869aea2fa6eef" }, - {"fullmoon_SH", "03f34282fa57ecc7aba8afaf66c30099b5601e98dcbfd0d8a58c86c20d8b692c64" }, - {"goldenman_EU", "02d6f13a8f745921cdb811e32237bb98950af1a5952be7b3d429abd9152f8e388d" }, - {"indenodes_AR", "02ec0fa5a40f47fd4a38ea5c89e375ad0b6ddf4807c99733c9c3dc15fb978ee147" }, - {"indenodes_EU", "0221387ff95c44cb52b86552e3ec118a3c311ca65b75bf807c6c07eaeb1be8303c" }, - {"indenodes_NA", "02698c6f1c9e43b66e82dbb163e8df0e5a2f62f3a7a882ca387d82f86e0b3fa988" }, // 30 - {"indenodes_SH", "0334e6e1ec8285c4b85bd6dae67e17d67d1f20e7328efad17ce6fd24ae97cdd65e" }, - {"jackson_AR", "038ff7cfe34cb13b524e0941d5cf710beca2ffb7e05ddf15ced7d4f14fbb0a6f69" }, - {"jeezy_EU", "023cb3e593fb85c5659688528e9a4f1c4c7f19206edc7e517d20f794ba686fd6d6" }, - {"karasugoi_NA", "02a348b03b9c1a8eac1b56f85c402b041c9bce918833f2ea16d13452309052a982" }, - {"komodoninja_EU", "038e567b99806b200b267b27bbca2abf6a3e8576406df5f872e3b38d30843cd5ba" }, - {"komodoninja_SH", "033178586896915e8456ebf407b1915351a617f46984001790f0cce3d6f3ada5c2" }, - {"komodopioneers_SH", "033ace50aedf8df70035b962a805431363a61cc4e69d99d90726a2d48fb195f68c" }, - {"libscott_SH", "03301a8248d41bc5dc926088a8cf31b65e2daf49eed7eb26af4fb03aae19682b95" }, - {"lukechilds_AR", "031aa66313ee024bbee8c17915cf7d105656d0ace5b4a43a3ab5eae1e14ec02696" }, - {"madmax_AR", "03891555b4a4393d655bf76f0ad0fb74e5159a615b6925907678edc2aac5e06a75" }, // 40 - {"meshbits_AR", "02957fd48ae6cb361b8a28cdb1b8ccf5067ff68eb1f90cba7df5f7934ed8eb4b2c" }, - {"meshbits_SH", "025c6e94877515dfd7b05682b9cc2fe4a49e076efe291e54fcec3add78183c1edb" }, - {"metaphilibert_AR", "02adad675fae12b25fdd0f57250b0caf7f795c43f346153a31fe3e72e7db1d6ac6" }, - {"metaphilibert_SH", "0284af1a5ef01503e6316a2ca4abf8423a794e9fc17ac6846f042b6f4adedc3309" }, - {"patchkez_SH", "0296270f394140640f8fa15684fc11255371abb6b9f253416ea2734e34607799c4" }, - {"pbca26_NA", "0276aca53a058556c485bbb60bdc54b600efe402a8b97f0341a7c04803ce204cb5" }, - {"peer2cloud_AR", "034e5563cb885999ae1530bd66fab728e580016629e8377579493b386bf6cebb15" }, - {"peer2cloud_SH", "03396ac453b3f23e20f30d4793c5b8ab6ded6993242df4f09fd91eb9a4f8aede84" }, - {"polycryptoblog_NA", "02708dcda7c45fb54b78469673c2587bfdd126e381654819c4c23df0e00b679622" }, - {"hyper_AR", "020f2f984d522051bd5247b61b080b4374a7ab389d959408313e8062acad3266b4" }, // 50 - {"hyper_EU", "03d00cf9ceace209c59fb013e112a786ad583d7de5ca45b1e0df3b4023bb14bf51" }, - {"hyper_SH", "0383d0b37f59f4ee5e3e98a47e461c861d49d0d90c80e9e16f7e63686a2dc071f3" }, - {"hyper_NA", "03d91c43230336c0d4b769c9c940145a8c53168bf62e34d1bccd7f6cfc7e5592de" }, - {"popcornbag_AR", "02761f106fb34fbfc5ddcc0c0aa831ed98e462a908550b280a1f7bd32c060c6fa3" }, - {"popcornbag_NA", "03c6085c7fdfff70988fda9b197371f1caf8397f1729a844790e421ee07b3a93e8" }, - {"alien_AR", "0348d9b1fc6acf81290405580f525ee49b4749ed4637b51a28b18caa26543b20f0" }, - {"alien_EU", "020aab8308d4df375a846a9e3b1c7e99597b90497efa021d50bcf1bbba23246527" }, - {"thegaltmines_NA", "031bea28bec98b6380958a493a703ddc3353d7b05eb452109a773eefd15a32e421" }, - {"titomane_AR", "029d19215440d8cb9cc6c6b7a4744ae7fb9fb18d986e371b06aeb34b64845f9325" }, - {"titomane_EU", "0360b4805d885ff596f94312eed3e4e17cb56aa8077c6dd78d905f8de89da9499f" }, // 60 - {"titomane_SH", "03573713c5b20c1e682a2e8c0f8437625b3530f278e705af9b6614de29277a435b" }, - {"webworker01_NA", "03bb7d005e052779b1586f071834c5facbb83470094cff5112f0072b64989f97d7" }, - {"xrobesx_NA", "03f0cc6d142d14a40937f12dbd99dbd9021328f45759e26f1877f2a838876709e1" }, -}; #define CRYPTO777_PUBSECPSTR "020e46e79a2a8d12b9b5d12c7a91adb4e454edfae43c0a0cb805427d2ac7613fd9" +int32_t getkmdseason(int32_t height) +{ + int8_t season = 0; + if ( height <= KMD_SEASON_HEIGHTS[0] ) + return(1); + for (int32_t i = 1; i < NUM_KMD_SEASONS; i++) + { + if ( height <= KMD_SEASON_HEIGHTS[i] && height >= KMD_SEASON_HEIGHTS[i-1] ) + return(i+1); + } + return(0); +}; + +int32_t getacseason(int32_t timestamp) +{ + int8_t season = 0; + if ( timestamp <= KMD_SEASON_TIMESTAMPS[0] ) + return(1); + for (int32_t i = 1; i < NUM_KMD_SEASONS; i++) + { + if ( timestamp <= KMD_SEASON_TIMESTAMPS[i] && timestamp >= KMD_SEASON_TIMESTAMPS[i-1] ) + return(i+1); + } + return(0); +}; + int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp) { - static uint8_t elected_pubkeys0[64][33],elected_pubkeys1[64][33],did0,did1; static int32_t n0,n1; int32_t i,htind,n; uint64_t mask = 0; struct knotary_entry *kp,*tmp; - + static uint8_t kmd_pubkeys[NUM_KMD_SEASONS][64][33],didinit[NUM_KMD_SEASONS]; + if ( timestamp == 0 && ASSETCHAINS_SYMBOL[0] != 0 ) timestamp = komodo_heightstamp(height); else if ( ASSETCHAINS_SYMBOL[0] == 0 ) timestamp = 0; // If this chain is not a staked chain, use the normal Komodo logic to determine notaries. This allows KMD to still sync and use its proper pubkeys for dPoW. - if (is_STAKED(ASSETCHAINS_SYMBOL) == 0) + if ( is_STAKED(ASSETCHAINS_SYMBOL) == 0 ) { - if ( height >= KOMODO_NOTARIES_HARDCODED || ASSETCHAINS_SYMBOL[0] != 0 ) - timestamp = 0; - if ( (timestamp != 0 && timestamp <= KOMODO_NOTARIES_TIMESTAMP1) || (ASSETCHAINS_SYMBOL[0] == 0 && height <= KOMODO_NOTARIES_HEIGHT1) ) + int32_t kmd_season = 0; + if ( ASSETCHAINS_SYMBOL[0] == 0 ) { - if ( did0 == 0 ) - { - n0 = (int32_t)(sizeof(Notaries_elected0)/sizeof(*Notaries_elected0)); - for (i=0; i= KOMODO_NOTARIES_HARDCODED ) + kmd_season = getkmdseason(height); } - else //if ( (timestamp != 0 && timestamp <= KOMODO_NOTARIES_TIMESTAMP2) || height <= KOMODO_NOTARIES_HEIGHT2 ) + else { - if ( did1 == 0 ) + // This is a non LABS assetchain, use timestamp to detemine notary pubkeys. + kmd_season = getacseason(timestamp); + } + if ( kmd_season != 0 ) + { + if ( didinit[kmd_season-1] == 0 ) { - n1 = (int32_t)(sizeof(Notaries_elected1)/sizeof(*Notaries_elected1)); - for (i=0; i &outVals); int8_t equihash_params_possible(uint64_t n, uint64_t k) @@ -1691,14 +1692,9 @@ int8_t equihash_params_possible(uint64_t n, uint64_t k) void komodo_args(char *argv0) { - extern const char *Notaries_elected1[][2]; std::string name,addn,hexstr,symbol; char *dirname,fname[512],arg0str[64],magicstr[9]; uint8_t magic[4],extrabuf[32756],disablebits[32],*extraptr=0; FILE *fp; uint64_t val; uint16_t port; int32_t i,nonz=0,baseid,len,n,extralen = 0; uint64_t ccenables[256]; IS_KOMODO_NOTARY = GetBoolArg("-notary", false); IS_STAKED_NOTARY = GetArg("-stakednotary", -1); - if ( IS_STAKED_NOTARY != -1 && IS_KOMODO_NOTARY == true ) { - fprintf(stderr, "Cannot be STAKED and KMD notary at the same time!\n"); - StartShutdown(); - } memset(ccenables,0,sizeof(ccenables)); memset(disablebits,0,sizeof(disablebits)); if ( GetBoolArg("-gen", false) != 0 ) @@ -1717,17 +1713,24 @@ void komodo_args(char *argv0) USE_EXTERNAL_PUBKEY = 1; if ( IS_KOMODO_NOTARY == 0 ) { + // We dont have any chain data yet, so use system clock to guess. + // I think on season change should reccomend notaries to use -notary to avoid needing this. + int32_t kmd_season = getacseason(time(NULL)); for (i=0; i<64; i++) - if ( strcmp(NOTARY_PUBKEY.c_str(),Notaries_elected1[i][1]) == 0 ) + if ( strcmp(NOTARY_PUBKEY.c_str(),notaries_elected[kmd_season][NUM_KMD_NOTARIES][1]) == 0 ) { IS_KOMODO_NOTARY = 1; KOMODO_MININGTHREADS = 1; mapArgs ["-genproclimit"] = itostr(KOMODO_MININGTHREADS); IS_STAKED_NOTARY = -1; - fprintf(stderr,"running as notary.%d %s\n",i,Notaries_elected1[i][0]); + fprintf(stderr,"running as notary.%d %s\n",i,notaries_elected[kmd_season][NUM_KMD_NOTARIES][0]); break; } } + } + if ( IS_STAKED_NOTARY != -1 && IS_KOMODO_NOTARY == true ) { + fprintf(stderr, "Cannot be STAKED and KMD notary at the same time!\n"); + StartShutdown(); } name = GetArg("-ac_name",""); if ( argv0 != 0 ) @@ -1760,7 +1763,6 @@ void komodo_args(char *argv0) } KOMODO_EARLYTXID = Parseuint256(GetArg("-earlytxid","0").c_str()); ASSETCHAINS_EARLYTXIDCONTRACT = GetArg("-ac_earlytxidcontract",0); - fprintf(stderr, "ASSETCHAINS_EARLYTXIDCONTRACT.%i\n", ASSETCHAINS_EARLYTXIDCONTRACT); if ( name.c_str()[0] != 0 ) { std::string selectedAlgo = GetArg("-ac_algo", std::string(ASSETCHAINS_ALGORITHMS[0])); diff --git a/src/main.cpp b/src/main.cpp index 609203562..c14e4351d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1373,26 +1373,26 @@ bool CheckTransaction(uint32_t tiptime,const CTransaction& tx, CValidationState } } +extern int32_t getacseason(int32_t timestamp); + int32_t komodo_isnotaryvout(char *coinaddr,uint32_t tiptime) // from ac_private chains only { - static int32_t didinit; static char notaryaddrs[sizeof(Notaries_elected1)/sizeof(*Notaries_elected1) + 1][64]; - //use normal notary functions - int32_t i; - if ( didinit == 0 ) + int32_t season = getacseason(tiptime); + if ( NOTARY_ADDRESSES[season-1][0][0] == 0 ) { - uint8_t pubkey33[33]; - for (i=0; i<=sizeof(Notaries_elected1)/sizeof(*Notaries_elected1); i++) - { - if ( i < sizeof(Notaries_elected1)/sizeof(*Notaries_elected1) ) - decode_hex(pubkey33,33,(char *)Notaries_elected1[i][1]); - else decode_hex(pubkey33,33,(char *)CRYPTO777_PUBSECPSTR); - pubkey2addr((char *)notaryaddrs[i],(uint8_t *)pubkey33); - } - didinit = 1; + uint8_t pubkeys[64][33]; + komodo_notaries(pubkeys,0,tiptime); } - for (i=0; i<=sizeof(Notaries_elected1)/sizeof(*Notaries_elected1); i++) - if ( strcmp(coinaddr,notaryaddrs[i]) == 0 ) + if ( strcmp(coinaddr,CRYPTO777_KMDADDR) == 0 ) return(1); + for (int32_t i = 0; i < NUM_KMD_NOTARIES; i++) + { + if ( strcmp(coinaddr,NOTARY_ADDRESSES[season-1][i]) == 0 ) + { + //fprintf(stderr, "coinaddr.%s notaryaddress[%i].%s\n",coinaddr,i,NOTARY_ADDRESSES[season-1][i]); + return(1); + } + } return(0); } @@ -3104,7 +3104,7 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex *pfClean = false; bool fClean = true; - komodo_disconnect(pindex,block); + //komodo_disconnect(pindex,block); does nothing? CBlockUndo blockUndo; CDiskBlockPos pos = pindex->GetUndoPos(); if (pos.IsNull()) @@ -4085,7 +4085,8 @@ bool static DisconnectTip(CValidationState &state, bool fBare = false) { if ((i == (block.vtx.size() - 1)) && (ASSETCHAINS_STAKED != 0 && (komodo_isPoS((CBlock *)&block,pindexDelete->GetHeight(),true) != 0))) { #ifdef ENABLE_WALLET - pwalletMain->EraseFromWallet(tx.GetHash()); + if ( !GetBoolArg("-disablewallet", false) ) + pwalletMain->EraseFromWallet(tx.GetHash()); #endif } else @@ -4266,7 +4267,10 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * { uint64_t start = time(NULL); if ( !komodo_dailysnapshot(pindexNew->GetHeight()) ) - fprintf(stderr, "daily snapshot failed, please reindex your chain\n"); // maybe force shutdown here? + { + fprintf(stderr, "daily snapshot failed, please reindex your chain\n"); + StartShutdown(); + } fprintf(stderr, "snapshot completed in: %lu seconds\n", time(NULL)-start); } return true; @@ -6500,15 +6504,15 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) } try { // read block + CBlock block; uint64_t nBlockPos = blkdat.GetPos(); if (dbp) dbp->nPos = nBlockPos; blkdat.SetLimit(nBlockPos + nSize); blkdat.SetPos(nBlockPos); - CBlock block; blkdat >> block; - nRewind = blkdat.GetPos(); - + + nRewind = blkdat.GetPos(); // detect out of order blocks, and store them for later uint256 hash = block.GetHash(); if (hash != chainparams.GetConsensus().hashGenesisBlock && mapBlockIndex.find(block.hashPrevBlock) == mapBlockIndex.end()) { @@ -6539,6 +6543,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) std::pair::iterator, std::multimap::iterator> range = mapBlocksUnknownParent.equal_range(head); while (range.first != range.second) { std::multimap::iterator it = range.first; + if (ReadBlockFromDisk(mapBlockIndex.count(hash)!=0?mapBlockIndex[hash]->GetHeight():0,block, it->second,1)) { LogPrintf("%s: Processing out of order child %s of %s\n", __func__, block.GetHash().ToString(), diff --git a/src/miner.cpp b/src/miner.cpp index 8fc658fa9..67e61b4a4 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -810,12 +810,17 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 //fprintf(stderr,"check validity\n"); if ( !TestBlockValidity(state, *pblock, pindexPrev, false, false)) // invokes CC checks { + if ( ASSETCHAINS_SYMBOL[0] == 0 || (ASSETCHAINS_SYMBOL[0] != 0 && !isStake) ) + { + LEAVE_CRITICAL_SECTION(cs_main); + LEAVE_CRITICAL_SECTION(mempool.cs); + } throw std::runtime_error("CreateNewBlock(): TestBlockValidity failed"); } //fprintf(stderr,"valid\n"); } } - if ( ASSETCHAINS_SYMBOL[0] == 0 || (ASSETCHAINS_SYMBOL[0] != 0 && !isStake) ) + if ( ASSETCHAINS_SYMBOL[0] == 0 || (ASSETCHAINS_SYMBOL[0] != 0 && !isStake) ) { LEAVE_CRITICAL_SECTION(cs_main); LEAVE_CRITICAL_SECTION(mempool.cs); diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index cb2cfce92..76d35ff61 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -48,6 +48,7 @@ using namespace std; +extern int32_t KOMODO_INSYNC; extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry); void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); #include "komodo_defs.h" @@ -1453,6 +1454,23 @@ UniValue pricesgetorderbook(const UniValue& params, bool fHelp) return PricesGetOrderbook(); } +// pricesrekt rpc implementation +UniValue pricesrefillfund(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error("pricesrefillfund amount\n"); + LOCK(cs_main); + UniValue ret(UniValue::VOBJ); + + if (ASSETCHAINS_CBOPRET == 0) + throw JSONRPCError(RPC_INVALID_PARAMETER, "only -ac_cbopret chains have prices"); + + CAmount amount = atof(params[0].get_str().c_str()) * COIN; + + return PricesRefillFund(amount); +} + + UniValue gettxout(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 2 || params.size() > 3) @@ -1689,6 +1707,7 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) UniValue obj(UniValue::VOBJ); obj.push_back(Pair("chain", Params().NetworkIDString())); obj.push_back(Pair("blocks", (int)chainActive.Height())); + obj.push_back(Pair("synced", KOMODO_INSYNC!=0)); obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->GetHeight() : -1)); obj.push_back(Pair("bestblockhash", chainActive.LastTip()->GetBlockHash().GetHex())); obj.push_back(Pair("difficulty", (double)GetNetworkDifficulty())); @@ -2082,4 +2101,4 @@ void RegisterBlockchainRPCCommands(CRPCTable &tableRPC) { for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]); -} \ No newline at end of file +} diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 5a495c005..eca4abb36 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -69,7 +69,7 @@ bool komodo_txnotarizedconfirmed(uint256 txid); uint32_t komodo_chainactive_timestamp(); int32_t komodo_whoami(char *pubkeystr,int32_t height,uint32_t timestamp); extern uint64_t KOMODO_INTERESTSUM,KOMODO_WALLETBALANCE; -extern int32_t KOMODO_LASTMINED,JUMBLR_PAUSE,KOMODO_LONGESTCHAIN,IS_STAKED_NOTARY,IS_KOMODO_NOTARY,STAKED_ERA; +extern int32_t KOMODO_LASTMINED,JUMBLR_PAUSE,KOMODO_LONGESTCHAIN,IS_STAKED_NOTARY,IS_KOMODO_NOTARY,STAKED_ERA,KOMODO_INSYNC; extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; uint32_t komodo_segid32(char *coinaddr); int64_t komodo_coinsupply(int64_t *zfundsp,int64_t *sproutfundsp,int32_t height); @@ -237,6 +237,7 @@ UniValue getinfo(const UniValue& params, bool fHelp) obj.push_back(Pair("version", CLIENT_VERSION)); obj.push_back(Pair("protocolversion", PROTOCOL_VERSION)); obj.push_back(Pair("KMDversion", KOMODO_VERSION)); + obj.push_back(Pair("synced", KOMODO_INSYNC!=0)); //obj.push_back(Pair("VRSCversion", VERUS_VERSION)); obj.push_back(Pair("notarized", notarized_height)); obj.push_back(Pair("prevMoMheight", prevMoMheight)); diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index e280b1a0b..56f221a37 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -219,7 +219,6 @@ int32_t komodo_longestchain() depth--; if ( num > (n >> 1) ) { - extern char ASSETCHAINS_SYMBOL[]; if ( 0 && height != KOMODO_LONGESTCHAIN ) fprintf(stderr,"set %s KOMODO_LONGESTCHAIN <- %d\n",ASSETCHAINS_SYMBOL,height); KOMODO_LONGESTCHAIN = height; diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index c35647f8c..500d175e0 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -471,7 +471,7 @@ static const CRPCCommand vRPCCommands[] = { "prices", "pricesrekt", &pricesrekt, true }, { "prices", "pricesaddfunding", &pricesaddfunding, true }, { "prices", "pricesgetorderbook", &pricesgetorderbook, true }, - + { "prices", "pricesrefillfund", &pricesrefillfund, true }, // Pegs { "pegs", "pegsaddress", &pegsaddress, true }, diff --git a/src/rpc/server.h b/src/rpc/server.h index c61f62dc3..b9fb33198 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -510,6 +510,7 @@ extern UniValue pricescashout(const UniValue& params, bool fHelp); extern UniValue pricesrekt(const UniValue& params, bool fHelp); extern UniValue pricesaddfunding(const UniValue& params, bool fHelp); extern UniValue pricesgetorderbook(const UniValue& params, bool fHelp); +extern UniValue pricesrefillfund(const UniValue& params, bool fHelp); diff --git a/src/wallet/db.h b/src/wallet/db.h index 604ae1633..e1ae52909 100644 --- a/src/wallet/db.h +++ b/src/wallet/db.h @@ -34,8 +34,8 @@ #include // If CCLIB fails to compile with this, use the one below. -//include -#include "../depends/x86_64-unknown-linux-gnu/include/db_cxx.h" +#include +//#include "../depends/x86_64-unknown-linux-gnu/include/db_cxx.h" extern unsigned int nWalletDBUpdated; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index d2d994896..d63a387b2 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -70,6 +70,7 @@ extern std::string ASSETCHAINS_OVERRIDE_PUBKEY; const std::string ADDR_TYPE_SPROUT = "sprout"; const std::string ADDR_TYPE_SAPLING = "sapling"; extern UniValue TxJoinSplitToJSON(const CTransaction& tx); +extern int32_t KOMODO_INSYNC; uint32_t komodo_segid32(char *coinaddr); int32_t komodo_dpowconfs(int32_t height,int32_t numconfs); int32_t komodo_isnotaryvout(char *coinaddr,uint32_t tiptime); // from ac_private chains only @@ -84,6 +85,7 @@ UniValue z_getoperationstatus_IMPL(const UniValue&, bool); #define PLAN_NAME_MAX 8 #define VALID_PLAN_NAME(x) (strlen(x) <= PLAN_NAME_MAX) +#define THROW_IF_SYNCING(INSYNC) if (INSYNC == 0) { throw runtime_error(strprintf("%s: Chain still syncing at height %d, aborting to prevent linkability analysis!",__FUNCTION__,chainActive.Tip()->GetHeight())); } int tx_height( const uint256 &hash ); @@ -4249,6 +4251,8 @@ UniValue z_sendmany(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); + THROW_IF_SYNCING(KOMODO_INSYNC); + // Check that the from address is valid. auto fromaddress = params[0].get_str(); bool fromTaddr = false; @@ -4558,6 +4562,8 @@ UniValue z_shieldcoinbase(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); + THROW_IF_SYNCING(KOMODO_INSYNC); + // Validate the from address auto fromaddress = params[0].get_str(); bool isFromWildcard = fromaddress == "*"; @@ -4818,6 +4824,8 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); + THROW_IF_SYNCING(KOMODO_INSYNC); + bool useAnyUTXO = false; bool useAnySprout = false; bool useAnySapling = false; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index fa39d204a..4d834ccee 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2874,21 +2874,18 @@ void CWallet::ReacceptWalletTransactions() bool invalid = state.IsInvalid(nDoS); // log rejection and deletion - // printf("ERROR reaccepting wallet transaction %s to mempool, reason: %s, DoS: %d\n", wtx.GetHash().ToString().c_str(), state.GetRejectReason().c_str(), nDoS); + //printf("ERROR reaccepting wallet transaction %s to mempool, reason: %s, DoS: %d\n", wtx.GetHash().ToString().c_str(), state.GetRejectReason().c_str(), nDoS); - if (!wtx.IsCoinBase() && invalid && nDoS > 0) + if (!wtx.IsCoinBase() && invalid && nDoS > 0 && state.GetRejectReason() != "tx-overwinter-expired") { LogPrintf("erasing transaction %s\n", wtx.GetHash().GetHex().c_str()); vwtxh.push_back(wtx.GetHash()); } } } - if ( IsInitialBlockDownload() == 0 ) + for (auto hash : vwtxh) { - for (auto hash : vwtxh) - { - EraseFromWallet(hash); - } + EraseFromWallet(hash); } } @@ -2896,7 +2893,7 @@ bool CWalletTx::RelayWalletTransaction() { if ( pwallet == 0 ) { - fprintf(stderr,"unexpected null pwallet in RelayWalletTransaction\n"); + //fprintf(stderr,"unexpected null pwallet in RelayWalletTransaction\n"); return(false); } assert(pwallet->GetBroadcastTransactions()); diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index efba38d9e..e81eba03d 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -41,6 +41,7 @@ using namespace std; static uint64_t nAccountingEntryNumber = 0; static list deadTxns; +extern CBlockIndex *komodo_blockindex(uint256 hash); // // CWalletDB @@ -964,21 +965,20 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet) // staking chains with vin-empty error is a failed staking tx. // we remove then re add the tx here to stop needing a full rescan, which does not actually fix the problem. int32_t reAdded = 0; - CWalletDB walletdb(pwallet->strWalletFile, "r+", false); BOOST_FOREACH (uint256& hash, deadTxns) { - fprintf(stderr, "Removing corrupt tx from wallet.%s\n", hash.ToString().c_str()); + fprintf(stderr, "Removing possible orphaned staking transaction from wallet.%s\n", hash.ToString().c_str()); if (!EraseTx(hash)) fprintf(stderr, "could not delete tx.%s\n",hash.ToString().c_str()); - uint256 blockhash; CTransaction tx; - if (GetTransaction(hash,tx,blockhash,true)) + uint256 blockhash; CTransaction tx; CBlockIndex* pindex; + if ( GetTransaction(hash,tx,blockhash,false) && (pindex= komodo_blockindex(blockhash)) != 0 && chainActive.Contains(pindex) ) { CWalletTx wtx(pwallet,tx); - pwallet->AddToWallet(wtx, false, &walletdb); + pwallet->AddToWallet(wtx, true, NULL); reAdded++; } } - fprintf(stderr, "Cleared %li corrupted transactions from wallet. Readded %i known transactions.\n",deadTxns.size(),reAdded); + fprintf(stderr, "Cleared %li orphaned staking transactions from wallet. Readded %i real transactions.\n",deadTxns.size(),reAdded); fNoncriticalErrors = false; deadTxns.clear(); }