From ab7558ab9db8c38d9bb6a84fd3ac3f5d4cd76aab Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Wed, 17 Apr 2019 17:42:24 +0800 Subject: [PATCH 001/242] inital commit for notarypay 0BR --- src/chain.h | 10 ++++- src/komodo_utils.h | 7 ++- src/main.cpp | 11 ++++- src/rpc/misc.cpp | 104 ++++++++++++++++++++++++++++++++++++++++++++- src/rpc/server.cpp | 2 + src/rpc/server.h | 2 + src/txdb.cpp | 2 + 7 files changed, 131 insertions(+), 7 deletions(-) diff --git a/src/chain.h b/src/chain.h index d810ed4cb..7ed6c4b4d 100644 --- a/src/chain.h +++ b/src/chain.h @@ -118,7 +118,7 @@ enum BlockStatus: uint32_t { BLOCK_FAILED_MASK = BLOCK_FAILED_VALID | BLOCK_FAILED_CHILD, BLOCK_ACTIVATES_UPGRADE = 128, //! block activates a network upgrade - BLOCK_IN_TMPFILE = 256 + BLOCK_IN_TMPFILE = 256 }; //! Short-hand for the highest consensus validity we implement. @@ -238,7 +238,7 @@ public: CBlockIndex* pskip; //! height of the entry in the chain. The genesis block has height 0 - int64_t newcoins,zfunds,sproutfunds; int8_t segid; // jl777 fields + int64_t newcoins,zfunds,sproutfunds,nNotaryPay; int8_t segid; // jl777 fields //! Which # file this block is stored in (blk?????.dat) int nFile; @@ -309,6 +309,7 @@ public: phashBlock = NULL; newcoins = zfunds = 0; segid = -2; + nNotaryPay = 0; pprev = NULL; pskip = NULL; nFile = 0; @@ -531,6 +532,11 @@ public: READWRITE(nBits); READWRITE(nNonce); READWRITE(nSolution); + + // LABS extra blockindex stuff. + // only read/write nNotaryPay if it has a value. This should be backwards compatible with all existing chains. + if ( nNotaryPay != 0 ) + READWRITE(nNotaryPay); // Only read/write nSproutValue if the client version used to create // this index was storing them. diff --git a/src/komodo_utils.h b/src/komodo_utils.h index d87b50716..a5c7a6a0d 100644 --- a/src/komodo_utils.h +++ b/src/komodo_utils.h @@ -1539,7 +1539,7 @@ uint16_t komodo_port(char *symbol,uint64_t supply,uint32_t *magicp,uint8_t *extr printf("ports\n"); }*/ -char *iguanafmtstr = (char *)"curl --url \"http://127.0.0.1:7776\" --data \"{\\\"conf\\\":\\\"%s.conf\\\",\\\"path\\\":\\\"${HOME#\"/\"}/.komodo/%s\\\",\\\"unitval\\\":\\\"20\\\",\\\"zcash\\\":1,\\\"RELAY\\\":-1,\\\"VALIDATE\\\":0,\\\"prefetchlag\\\":-1,\\\"poll\\\":100,\\\"active\\\":1,\\\"agent\\\":\\\"iguana\\\",\\\"method\\\":\\\"addcoin\\\",\\\"startpend\\\":4,\\\"endpend\\\":4,\\\"services\\\":129,\\\"maxpeers\\\":8,\\\"newcoin\\\":\\\"%s\\\",\\\"name\\\":\\\"%s\\\",\\\"hasheaders\\\":1,\\\"useaddmultisig\\\":0,\\\"netmagic\\\":\\\"%s\\\",\\\"p2p\\\":%u,\\\"rpc\\\":%u,\\\"pubval\\\":60,\\\"p2shval\\\":85,\\\"wifval\\\":188,\\\"txfee_satoshis\\\":\\\"10000\\\",\\\"isPoS\\\":0,\\\"minoutput\\\":10000,\\\"minconfirms\\\":2,\\\"genesishash\\\":\\\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\\\",\\\"protover\\\":170002,\\\"genesisblock\\\":\\\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\\\",\\\"debug\\\":0,\\\"seedipaddr\\\":\\\"%s\\\",\\\"sapling\\\":1}\""; +char *iguanafmtstr = (char *)"curl --url \"http://127.0.0.1:7776\" --data \"{\\\"conf\\\":\\\"%s.conf\\\",\\\"path\\\":\\\"${HOME#\"/\"}/.komodo/%s\\\",\\\"unitval\\\":\\\"20\\\",\\\"zcash\\\":1,\\\"RELAY\\\":-1,\\\"VALIDATE\\\":0,\\\"prefetchlag\\\":-1,\\\"poll\\\":100,\\\"active\\\":1,\\\"agent\\\":\\\"iguana\\\",\\\"method\\\":\\\"addcoin\\\",\\\"startpend\\\":4,\\\"endpend\\\":4,\\\"services\\\":129,\\\"maxpeers\\\":8,\\\"newcoin\\\":\\\"%s\\\",\\\"name\\\":\\\"%s\\\",\\\"hasheaders\\\":1,\\\"useaddmultisig\\\":0,\\\"netmagic\\\":\\\"%s\\\",\\\"p2p\\\":%u,\\\"rpc\\\":%u,\\\"pubval\\\":60,\\\"p2shval\\\":85,\\\"wifval\\\":188,\\\"txfee_satoshis\\\":\\\"10000\\\",\\\"isPoS\\\":0,\\\"minoutput\\\":10000,\\\"minconfirms\\\":2,\\\"genesishash\\\":\\\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\\\",\\\"protover\\\":170002,\\\"genesisblock\\\":\\\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\\\",\\\"debug\\\":0,\\\"seedipaddr\\\":\\\"%s\\\",\\\"sapling\\\":1,\\\"notarypay\\\":%i}\""; @@ -2207,7 +2207,10 @@ void komodo_args(char *argv0) sprintf(fname,"%s_7776",ASSETCHAINS_SYMBOL); if ( (fp= fopen(fname,"wb")) != 0 ) { - fprintf(fp,iguanafmtstr,name.c_str(),name.c_str(),name.c_str(),name.c_str(),magicstr,ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT,"78.47.196.146"); + int8_t notarypay = 0; + if ( ASSETCHAINS_NOTARY_PAY[0] != 0 ) + notarypay = 1; + fprintf(fp,iguanafmtstr,name.c_str(),name.c_str(),name.c_str(),name.c_str(),magicstr,ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT,"78.47.196.146",notarypay); fclose(fp); //printf("created (%s)\n",fname); } else printf("error creating (%s)\n",fname); diff --git a/src/main.cpp b/src/main.cpp index 40da1b855..b8861bf9a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3269,7 +3269,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin auto verifier = libzcash::ProofVerifier::Strict(); auto disabledVerifier = libzcash::ProofVerifier::Disabled(); int32_t futureblock; - CAmount blockReward = 0; + CAmount blockReward = 0; uint64_t notarypaycheque = 0; // Check it again to verify JoinSplit proofs, and in case a previous version let a bad block in if (!CheckBlock(&futureblock,pindex->GetHeight(),pindex,block, state, fExpensiveChecks ? verifier : disabledVerifier, fCheckPOW, !fJustCheck) || futureblock != 0 ) { @@ -3307,7 +3307,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin return state.DoS(100, error("ConnectBlock(): Notaries have not been paid!"), REJECT_INVALID, "bad-cb-amount"); // calculate the notaries compensation and validate the amounts and pubkeys are correct. - uint64_t notarypaycheque = komodo_checknotarypay((CBlock *)&block,(int32_t)pindex->GetHeight()); + notarypaycheque = komodo_checknotarypay((CBlock *)&block,(int32_t)pindex->GetHeight()); //fprintf(stderr, "notarypaycheque.%lu\n", notarypaycheque); if ( notarypaycheque > 0 ) blockReward += notarypaycheque; @@ -3714,6 +3714,12 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin //FlushStateToDisk(); komodo_connectblock(false,pindex,*(CBlock *)&block); // dPoW state update. + if ( ASSETCHAINS_NOTARY_PAY[0] != 0 && pindex->GetHeight() > 10 ) + { + // Update the notary pay with the latest payment. + pindex->nNotaryPay = pindex->pprev->nNotaryPay + notarypaycheque; + fprintf(stderr, "total notary pay.%li\n", pindex->nNotaryPay); + } return true; } @@ -3923,6 +3929,7 @@ bool static DisconnectTip(CValidationState &state, bool fBare = false) { DisconnectNotarisations(block); } pindexDelete->segid = -2; + pindexDelete->nNotaryPay = 0; pindexDelete->newcoins = 0; pindexDelete->zfunds = 0; diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 4e21ab9e9..c2ba9d702 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -75,6 +75,8 @@ uint32_t komodo_segid32(char *coinaddr); int64_t komodo_coinsupply(int64_t *zfundsp,int64_t *sproutfundsp,int32_t height); int32_t notarizedtxid_height(char *dest,char *txidstr,int32_t *kmdnotarized_heightp); int8_t StakedNotaryID(std::string ¬aryname, char *Raddress); +uint64_t komodo_notarypayamount(int32_t nHeight, int64_t notarycount); +int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp); #define KOMODO_VERSION "0.3.3b" #define VERUS_VERSION "0.4.0g" @@ -168,7 +170,7 @@ UniValue geterablockheights(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( - "getnotarysendmany\n" + "geterablockheights\n" "Returns a JSON object with the first block in each era.\n" ); @@ -1216,6 +1218,106 @@ UniValue getaddressdeltas(const UniValue& params, bool fHelp) } } +CAmount checkburnaddress(CAmount &received, int64_t &nNotaryPay, int32_t &height, std::string sAddress) +{ + CBitcoinAddress address(sAddress); + uint160 hashBytes; int type = 0; CAmount balance = 0; + if (address.GetIndexKey(hashBytes, type, false)) + { + std::vector > addressIndex; + if (GetAddressIndex(hashBytes, type, addressIndex)) + { + for (std::vector >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++) + { + if (it->second > 0) + received += it->second; + balance += it->second; + } + // Get notary pay from current chain tip + CBlockIndex* pindex = chainActive.LastTip(); + nNotaryPay = pindex->nNotaryPay; + height = pindex->GetHeight(); + } + } + return balance; +} + +UniValue checknotarization(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "checknotarization\n" + "\nReturns true if burn address balance is greater than total notary pay. (requires addressindex to be enabled).\n" + ); + + UniValue result(UniValue::VOBJ); CAmount balance = 0, received = 0; int64_t nNotaryPay = 0; int32_t height; + + // helper to test burn address's + /*uint8_t priv[32] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + uint8_t pub[33] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + char coinaddr[64]; uint8_t buf33[33]; + //pubkey2addr(coinaddr, pub); + priv2addr(coinaddr,buf33,priv); + fprintf(stderr, "what.%s\n", coinaddr); + result.push_back(Pair("address", coinaddr)); + return result; + */ + + if ( ASSETCHAINS_NOTARY_PAY[0] == 0 ) + throw runtime_error("only works for ac_notarypay chains"); + // pubkey 020000000000000000000000000000000 + balance = checkburnaddress(received, nNotaryPay, height, "REDVp3ox1pbcWYCzySadfHhk8UU3HM4k5x"); + if ( nNotaryPay >= balance || received != balance ) + return false; + return true; +} + +UniValue getnotarypayinfo(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getnotarypayinfo\n" + "\nReturns infomation about ac_notaypay status (requires addressindex to be enabled).\n" + "\nResult:\n" + "{\n" + " \"height\" (number) The current block height\n" + " \"balance\" (number) The current balance of the burn address\n" + " \"spent\" (bool) true if coins have been spent from the burn address\n" + " \"Total_NotaryPay\" (number) Total amount paid to notaries\n" + " \"Estimated_Notarizations_Left\" (number) the estimated amount of notarizations left before the balance is consumed\n" + " \"Estimated_Days_Left\" (number) the estimated amount of days the current balance will last\n" + " \"Estimated_Height\" (number) the estimated block height funds will run out\n" + "}\n" + ); + + if ( ASSETCHAINS_NOTARY_PAY[0] == 0 ) + throw runtime_error("only works for ac_notarypay chains"); + + UniValue result(UniValue::VOBJ); CAmount balance = 0, received = 0; int64_t TotalNotaryPay = 0, NotaryPay, notaleft = 0, daysleft = 0, notarycount; int32_t height, endheight = 0; uint8_t notarypubkeys[64][33] = {0}; + + // pubkey 020000000000000000000000000000000 + balance = checkburnaddress(received, TotalNotaryPay, height, "REDVp3ox1pbcWYCzySadfHhk8UU3HM4k5x"); + + notarycount = komodo_notaries(notarypubkeys, height, chainActive[height]->GetBlockTime()); + NotaryPay = komodo_notarypayamount(height, notarycount); + bool spent = (received != balance); + if ( !spent ) + { + notaleft = (balance - TotalNotaryPay) / NotaryPay; + daysleft = (((ASSETCHAINS_BLOCKTIME * 5) * notaleft) / 3600) / 24; + endheight = (notaleft * 5) + height; + } + + result.push_back(Pair("height", height)); + result.push_back(Pair("balance", ValueFromAmount(balance))); + result.push_back(Pair("spent", spent)); + result.push_back(Pair("Total_NotaryPay", ValueFromAmount(TotalNotaryPay))); + result.push_back(Pair("Estimated_Notarizations_Left", notaleft)); + result.push_back(Pair("Estimated_Days_Left", daysleft)); + result.push_back(Pair("Estimated_Height", endheight)); + return result; +} + UniValue getaddressbalance(const UniValue& params, bool fHelp) { if (fHelp ||params.size() > 2 || params.size() == 0) diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index fc34a2a3f..969f937cf 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -538,6 +538,8 @@ static const CRPCCommand vRPCCommands[] = /* Address index */ { "addressindex", "getaddressmempool", &getaddressmempool, true }, { "addressindex", "getaddressutxos", &getaddressutxos, false }, + { "addressindex", "checknotarization", &checknotarization, false }, + { "addressindex", "getnotarypayinfo", &getnotarypayinfo, false }, { "addressindex", "getaddressdeltas", &getaddressdeltas, false }, { "addressindex", "getaddresstxids", &getaddresstxids, false }, { "addressindex", "getaddressbalance", &getaddressbalance, false }, diff --git a/src/rpc/server.h b/src/rpc/server.h index d8fd0e736..87f391dfa 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -210,6 +210,8 @@ extern UniValue getaddresstxids(const UniValue& params, bool fHelp); extern UniValue getsnapshot(const UniValue& params, bool fHelp); extern UniValue getaddressbalance(const UniValue& params, bool fHelp); extern UniValue getpeerinfo(const UniValue& params, bool fHelp); +extern UniValue checknotarization(const UniValue& params, bool fHelp); +extern UniValue getnotarypayinfo(const UniValue& params, bool fHelp); extern UniValue ping(const UniValue& params, bool fHelp); extern UniValue addnode(const UniValue& params, bool fHelp); extern UniValue disconnectnode(const UniValue& params, bool fHelp); diff --git a/src/txdb.cpp b/src/txdb.cpp index 4c9ea31ca..e6b4970db 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -712,6 +712,8 @@ bool CBlockTreeDB::LoadBlockIndexGuts() pindexNew->nTx = diskindex.nTx; pindexNew->nSproutValue = diskindex.nSproutValue; pindexNew->nSaplingValue = diskindex.nSaplingValue; + pindexNew->segid = diskindex.segid; + pindexNew->nNotaryPay = diskindex.nNotaryPay; //fprintf(stderr,"loadguts ht.%d\n",pindexNew->GetHeight()); // Consistency checks auto header = pindexNew->GetBlockHeader(); From 25bf471dddfa5efda2ad024ee4824d25619b0aee Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Wed, 17 Apr 2019 18:36:00 +0800 Subject: [PATCH 002/242] add notary pay stuff without breaking blockindex. --- src/chain.h | 13 ++++++++----- src/komodo_nk.h | 4 ++-- src/main.cpp | 4 ++-- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/chain.h b/src/chain.h index 7ed6c4b4d..4e5d7e48d 100644 --- a/src/chain.h +++ b/src/chain.h @@ -28,6 +28,7 @@ class CChainPower; #include "pow.h" #include "tinyformat.h" #include "uint256.h" +extern int8_t is_STAKED(const char *chain_name); #include @@ -36,6 +37,8 @@ class CChainPower; static const int SPROUT_VALUE_VERSION = 1001400; static const int SAPLING_VALUE_VERSION = 1010100; extern int32_t ASSETCHAINS_LWMAPOS; +extern char ASSETCHAINS_SYMBOL[65]; +//extern uint64_t ASSETCHAINS_NOTARY_PAY; struct CDiskBlockPos { @@ -532,11 +535,6 @@ public: READWRITE(nBits); READWRITE(nNonce); READWRITE(nSolution); - - // LABS extra blockindex stuff. - // only read/write nNotaryPay if it has a value. This should be backwards compatible with all existing chains. - if ( nNotaryPay != 0 ) - READWRITE(nNotaryPay); // Only read/write nSproutValue if the client version used to create // this index was storing them. @@ -549,6 +547,11 @@ public: if ((s.GetType() & SER_DISK) && (nVersion >= SAPLING_VALUE_VERSION)) { READWRITE(nSaplingValue); } + if ( (s.GetType() & SER_DISK) && (is_STAKED(ASSETCHAINS_SYMBOL) != 0) ) + { + READWRITE(nNotaryPay); + READWRITE(segid); + } } uint256 GetBlockHash() const diff --git a/src/komodo_nk.h b/src/komodo_nk.h index 3c9034dde..ed994c13f 100644 --- a/src/komodo_nk.h +++ b/src/komodo_nk.h @@ -1,7 +1,7 @@ #ifndef KOMODO_NK_H #define KOMODO_NK_H -#define ASSETCHAINS_N 96 -#define ASSETCHAINS_K 5 +#define ASSETCHAINS_N 77 +#define ASSETCHAINS_K 3 #endif diff --git a/src/main.cpp b/src/main.cpp index b8861bf9a..f5b57b364 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3714,11 +3714,11 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin //FlushStateToDisk(); komodo_connectblock(false,pindex,*(CBlock *)&block); // dPoW state update. - if ( ASSETCHAINS_NOTARY_PAY[0] != 0 && pindex->GetHeight() > 10 ) + if ( ASSETCHAINS_NOTARY_PAY[0] != 0 ) { // Update the notary pay with the latest payment. pindex->nNotaryPay = pindex->pprev->nNotaryPay + notarypaycheque; - fprintf(stderr, "total notary pay.%li\n", pindex->nNotaryPay); + //fprintf(stderr, "total notary pay.%li\n", pindex->nNotaryPay); } return true; } From 451773dcc13387036aac90daf52080dfc245395a Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Mon, 22 Apr 2019 00:00:01 +0800 Subject: [PATCH 003/242] initial commit for -earlytxid use with ac_script and ccvout_opret --- src/cc/CCutils.cpp | 4 +-- src/cc/payments.cpp | 62 ++++++++++++++++++++++++++++++++++------ src/komodo_bitcoind.h | 44 +++++++++++++++++++++++++--- src/komodo_defs.h | 2 +- src/komodo_utils.h | 1 + src/miner.cpp | 11 +++++-- src/rpc/server.cpp | 1 + src/rpc/server.h | 1 + src/wallet/rpcwallet.cpp | 36 ++++++++++++++++++++++- 9 files changed, 143 insertions(+), 19 deletions(-) diff --git a/src/cc/CCutils.cpp b/src/cc/CCutils.cpp index 3c4c6c67c..1610e2426 100644 --- a/src/cc/CCutils.cpp +++ b/src/cc/CCutils.cpp @@ -76,11 +76,9 @@ CScript getCCopret(const CScript &scriptPubKey) CScript dummy; CScript opret; if ( scriptPubKey.IsPayToCryptoCondition(&dummy, vParams) ) { - //opret << E_MARSHAL(ss << vParams[0]); + //fprintf(stderr, "vparams.%s\n", HexStr(vParams[0].begin(), vParams[0].end()).c_str()); opret = CScript(vParams[0].begin()+6, vParams[0].end()); } - //fprintf(stderr, "params_size.%li parmas_hexstr.%s\n", vParams.size(), HexStr(vParams[0].begin(),vParams[0].end()).c_str()); - //opret = CScript(vParams[0].begin(), vParams[0].end()); return opret; } diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index 526fea52f..7d6fcba32 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -16,11 +16,59 @@ #include "CCPayments.h" /* +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ac_script + -earlytxid instructions with payments cc + rewards CC as an example. +How this works: + - earlytxid must be a transaction included in the chain before block 100. The chain MUST not have any other of these type of tx before block 100, or someone may be able to change it and mess things up. + - When it gets to block 100, it takes the txid specified by the -earlytxid param (does not affect magic) + - Looks up the transaction searches for the opreturn, then permenantly appends it to the end of ac_script in RAM. + - After every daemon restart, the first time the daemon mines a block, or receives a block that pays ac_script it will look up the op_return and save it again. + - this enables it to always reach consensus but doesnt need to constantly keep looking up the tx in the chain. + - The trick is to use ac_founders=101 or higher so that nothing is ever paid to the unspendable CC address. Although it should still work without this it burns coins. + +-ac_script can be any Global CC address you can spend to with an OP_RETURN. Here we use example of paymentsCC being used to fund a rewards plan, and a set of founders address's. + you can get the ac_script from another chain, but the op_return payload must generated on the chain itself. this command gives you the needed info to get the scripPubKey Hex: + ./komodo-cli -ac_name=TEST paymentsfund '["5d536f54332db09f2be04593c54f764cf569e225f4d8df5155658c679e663682",1000]' + append: b8, to the end of ac_script, this changes magic value for -earlytxid chains vs normal ac_script and allows bypass of ac_supply paid to the scritpt as it would be unspendable and you would be unable to create the needed plans with no coins. + -ac_script=2ea22c8020987fad30df055db6fd922c3a57e55d76601229ed3da3b31340112e773df3d0d28103120c008203000401ccb8 --earlytxid is not an -ac_param, so it doesnt affect the chain magics -extra data after the normal CCvout is whatever data we want and can represent whatever we want -so -ac_script= -in the validation if you see the useearlytxid in the opreturn data or extra data, you use the earlytxid as the txid that specifies the payment +start chain and make sure to do the following steps before block 100 (set generate false/true is a good idea between steps) +create rewards plan and fund it with all or a % of the premine. Must be some amount. eg. + ./komodo-cli -ac_name=TEST rewardscreatefunding test 1000 10 0 10 10 + +do rewards add funding and get the script pubkey and op_return from this tx (no need to send it) eg. + scriptPubKey: 2ea22c802065686d47a4049c2c845a71895a915eb84c04445896eec5dc0be40df0b31372da8103120c008203000401cc + OP_RETURN: 6a2ae541746573740000000061e7063fa8f99ef92a47e4aebf7ea28c59aeadaf3c1784312de64e4bcb3666f1 + +create txidopreturn for this payment: + ./komodo-cli -ac_name=TEST paymentstxidopret '[50,"2ea22c802065686d47a4049c2c845a71895a915eb84c04445896eec5dc0be40df0b31372da8103120c008203000401cc","6a2ae541746573740000000061e7063fa8f99ef92a47e4aebf7ea28c59aeadaf3c1784312de64e4bcb3666f1"]' + +create the txidopret for the founders reward(s) pubkeys: should be able to be a few here, not sure of max number yet. These can pay anything that does not need an opreturn. allocation and scriptpubkey hex. + ./komodo-cli -ac_name=TEST paymentstxidopret '[50,"76a9146bf5dd9f679c87a3f83ea176f82148d26653c04388ac"]' + +create payments plan: + ./komodo-cli -ac_name=TEST paymentscreate '[0,0,"273d193e5d09928e471926827dcac1f06c4801bdaa5524a84b17a00f4eaf8d38","81264daf7874b2041802ac681e49618413313cc2f29b47d47bd8e63dc2a06cad"]' +gives plan txid eg. 5d536f54332db09f2be04593c54f764cf569e225f4d8df5155658c679e663682 + +paymentsfund: + send some of the premine to this payments fund to get the rest of the scriptpubkey payload. (could skip send and just gen/decode the tx if required.) + send opret path this time to get the required script pubkey. For payments this mode is enabled by default rather than a traditional OP_RETURN, + for other CC we would need to modify daemon to get the correct info. + ./komodo-cli -ac_name=TEST paymentsfund '["5d536f54332db09f2be04593c54f764cf569e225f4d8df5155658c679e663682",1000,1]' + +get the payment fund script pubkey: (the split it at OP_CHECKCRYPTOCONDITION or 'cc' ) + 2ea22c8020987fad30df055db6fd922c3a57e55d76601229ed3da3b31340112e773df3d0d28103120c008203000401cc 2a0401f00101246a22f0466b75e35aa4d8ea6c3dd1b76141a0acbd06dfb4897288a62b8a8ec31b75a5b6cb75 + + put the second half into an OP_RETURN: (the remaining part of the the above scriptpubkey) eg. + ./komodo-cli -ac_name=TEST opreturn_burn 1 2a0401f00101246a22f0466b75e35aa4d8ea6c3dd1b76141a0acbd06dfb4897288a62b8a8ec31b75a5b6cb75 + opret_burn takes any burn amount and arbitrary hex string. (RPC works, but may have bugs, likely use this for LABS too with some fixes) + this gives a txid to locate it in the chain eg: + -earlytxid=1acd0b9b728feaea37a3f52d4106c35b0f8cfd19f9f3e64815d23ace0721d69d + restart the chain with earlytxid param before height 100 on BOTH NODES! + +once the payments plan has been funded with the mined coinbase you can issue payments release when conditions of the plan are met to fund founders reward/rewards plan. eg. + ./komodo-cli -ac_name=TEST paymentsrelease '["5d536f54332db09f2be04593c54f764cf569e225f4d8df5155658c679e663682",500]' +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 0) txidopret <- allocation, scriptPubKey, opret 1) create <- locked_blocks, minrelease, list of txidopret @@ -643,13 +691,11 @@ UniValue PaymentsFund(struct CCcontract_info *cp,char *jsonstr) else { opret = EncodePaymentsFundOpRet(txid); - fprintf(stderr, "opret.%s\n", HexStr(opret.begin(), opret.end()).c_str()); std::vector> vData = std::vector>(); if ( makeCCopret(opret, vData) ) - { mtx.vout.push_back(MakeCC1vout(EVAL_PAYMENTS,amount,Paymentspk,&vData)); - fprintf(stderr, "params_size.%li parmas_hexstr.%s\n", vData.size(), HexStr(vData[0].begin(),vData[0].end()).c_str()); - } + //fprintf(stderr, "scriptpubkey.%s\n", mtx.vout.back().scriptPubKey.ToString().c_str()); + //fprintf(stderr, "hex.%s\n", HexStr(mtx.vout.back().scriptPubKey.begin(), mtx.vout.back().scriptPubKey.end()).c_str()); } rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,CScript()); if ( params != 0 ) diff --git a/src/komodo_bitcoind.h b/src/komodo_bitcoind.h index bb5a093d3..3dd590417 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -2030,9 +2030,39 @@ uint64_t komodo_checknotarypay(CBlock *pblock,int32_t height) return(0); } +bool komodo_appendACscriptpub() +{ + static bool didinit = false; + if ( didinit ) + return didinit; + if ( ASSETCHAINS_SCRIPTPUB[ASSETCHAINS_SCRIPTPUB.back()] == 49 && ASSETCHAINS_SCRIPTPUB[ASSETCHAINS_SCRIPTPUB.back()-1] == 51 ) + { + CTransaction tx; uint256 blockhash; + // get transaction and check that it occured before height 100. + if ( myGetTransaction(KOMODO_EARLYTXID,tx,blockhash) && mapBlockIndex[blockhash]->GetHeight() < 100 ) + { + for (int i = 0; i < tx.vout.size(); i++) + { + if ( tx.vout[i].scriptPubKey[0] == OP_RETURN ) + { + ASSETCHAINS_SCRIPTPUB.pop_back(); ASSETCHAINS_SCRIPTPUB.pop_back(); // remove last 2 chars. + // get OP_RETURN from txid and append the HexStr of it to scriptpub + ASSETCHAINS_SCRIPTPUB.append(HexStr(tx.vout[i].scriptPubKey.begin()+3, tx.vout[i].scriptPubKey.end())); + //fprintf(stderr, "ac_script.%s\n",ASSETCHAINS_SCRIPTPUB.c_str()); + didinit = true; + return true; + } + } + } + fprintf(stderr, "could not get KOMODO_EARLYTXID.%s OP_RETURN data. Restart with correct txid!\n", KOMODO_EARLYTXID.GetHex().c_str()); + StartShutdown(); + } + return false; +} + int64_t komodo_checkcommission(CBlock *pblock,int32_t height) { - int64_t checktoshis=0; uint8_t *script,scripthex[8192]; int32_t scriptlen,matched = 0; + int64_t checktoshis=0; uint8_t *script,scripthex[8192]; int32_t scriptlen,matched = 0; static bool didinit = false; if ( ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_FOUNDERS_REWARD != 0 ) { checktoshis = komodo_commission(pblock,height); @@ -2054,6 +2084,12 @@ int64_t komodo_checkcommission(CBlock *pblock,int32_t height) } if ( ASSETCHAINS_SCRIPTPUB.size() > 1 ) { + static bool didinit = false; + if ( !didinit && height > 100 && KOMODO_EARLYTXID != zeroid && komodo_appendACscriptpub() ) + { + fprintf(stderr, "appended CC_op_return to ASSETCHAINS_SCRIPTPUB.%s\n", ASSETCHAINS_SCRIPTPUB.c_str()); + didinit = true; + } if ( ASSETCHAINS_SCRIPTPUB.size()/2 == scriptlen && scriptlen < sizeof(scripthex) ) { decode_hex(scripthex,scriptlen,(char *)ASSETCHAINS_SCRIPTPUB.c_str()); @@ -2190,11 +2226,11 @@ int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height) else if ( ASSETCHAINS_STAKED != 0 ) failed = 0; } - if ( failed == 0 && ASSETCHAINS_COMMISSION != 0 ) //ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 ) + if ( failed == 0 && ASSETCHAINS_COMMISSION != 0 ) { if ( height == 1 ) { - if ( ASSETCHAINS_SCRIPTPUB.size() > 1 ) + if ( ASSETCHAINS_SCRIPTPUB.size() > 1 && ASSETCHAINS_SCRIPTPUB[ASSETCHAINS_SCRIPTPUB.back()] != 49 && ASSETCHAINS_SCRIPTPUB[ASSETCHAINS_SCRIPTPUB.back()-1] != 51 ) { int32_t scriptlen; uint8_t scripthex[10000]; script = (uint8_t *)&pblock->vtx[0].vout[0].scriptPubKey[0]; @@ -2206,7 +2242,7 @@ int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height) return(-1); } else return(-1); } - else + else if ( ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 ) { script = (uint8_t *)&pblock->vtx[0].vout[0].scriptPubKey[0]; scriptlen = (int32_t)pblock->vtx[0].vout[0].scriptPubKey.size(); diff --git a/src/komodo_defs.h b/src/komodo_defs.h index ecaf7339a..ecb503be9 100644 --- a/src/komodo_defs.h +++ b/src/komodo_defs.h @@ -63,7 +63,7 @@ extern uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33],ASSETCHAINS extern std::vector ASSETCHAINS_PRICES,ASSETCHAINS_STOCKS; extern int32_t VERUS_BLOCK_POSUNITS, VERUS_CONSECUTIVE_POS_THRESHOLD, VERUS_NOPOS_THRESHHOLD; - +extern uint256 KOMODO_EARLYTXID; extern int32_t KOMODO_CONNECTING,KOMODO_CCACTIVATE,KOMODO_DEALERNODE; extern uint32_t ASSETCHAINS_CC; diff --git a/src/komodo_utils.h b/src/komodo_utils.h index 88efb0264..cfb133a9d 100644 --- a/src/komodo_utils.h +++ b/src/komodo_utils.h @@ -2072,6 +2072,7 @@ void komodo_args(char *argv0) extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_FOUNDERS),(void *)&ASSETCHAINS_FOUNDERS); if ( ASSETCHAINS_FOUNDERS_REWARD != 0 ) { + fprintf(stderr, "set founders reward.%li\n",ASSETCHAINS_FOUNDERS_REWARD); extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_FOUNDERS_REWARD),(void *)&ASSETCHAINS_FOUNDERS_REWARD); } } diff --git a/src/miner.cpp b/src/miner.cpp index e199acccd..a2ff8c933 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -156,6 +156,7 @@ uint64_t komodo_notarypay(CMutableTransaction &txNew, std::vector &Notar int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp); int32_t komodo_getnotarizedheight(uint32_t timestamp,int32_t height, uint8_t *script, int32_t len); CScript komodo_mineropret(int32_t nHeight); +bool komodo_appendACscriptpub(); CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32_t gpucount, bool isStake) { @@ -652,6 +653,12 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 txNew.vout[1].nValue = commission; if ( ASSETCHAINS_SCRIPTPUB.size() > 1 ) { + static bool didinit = false; + if ( !didinit && nHeight > 100 && KOMODO_EARLYTXID != zeroid && komodo_appendACscriptpub() ) + { + fprintf(stderr, "appended ccopreturn to ASSETCHAINS_SCRIPTPUB.%s\n", ASSETCHAINS_SCRIPTPUB.c_str()); + didinit = true; + } //fprintf(stderr,"mine to -ac_script\n"); //txNew.vout[1].scriptPubKey = CScript() << ParseHex(); int32_t len = strlen(ASSETCHAINS_SCRIPTPUB.c_str()); @@ -895,14 +902,14 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey, int32_t nHeight, int32_t gpucount, bool isStake) { CPubKey pubkey; CScript scriptPubKey; uint8_t *script,*ptr; int32_t i,len; - if ( nHeight == 1 && ASSETCHAINS_COMMISSION != 0 ) + if ( nHeight == 1 && ASSETCHAINS_COMMISSION != 0 && ASSETCHAINS_SCRIPTPUB[ASSETCHAINS_SCRIPTPUB.back()] != 49 && ASSETCHAINS_SCRIPTPUB[ASSETCHAINS_SCRIPTPUB.back()-1] != 51 ) { if ( ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 ) { pubkey = ParseHex(ASSETCHAINS_OVERRIDE_PUBKEY); scriptPubKey = CScript() << ParseHex(HexStr(pubkey)) << OP_CHECKSIG; } - else + else { len = strlen(ASSETCHAINS_SCRIPTPUB.c_str()); len >>= 1; diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 3ed082455..79a782c35 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -639,6 +639,7 @@ static const CRPCCommand vRPCCommands[] = { "wallet", "z_importviewingkey", &z_importviewingkey, true }, { "wallet", "z_exportwallet", &z_exportwallet, true }, { "wallet", "z_importwallet", &z_importwallet, true }, + { "wallet", "opreturn_burn", &opreturn_burn, true }, // TODO: rearrange into another category { "disclosure", "z_getpaymentdisclosure", &z_getpaymentdisclosure, true }, diff --git a/src/rpc/server.h b/src/rpc/server.h index 8e0054e6f..bcbe644a3 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -466,6 +466,7 @@ extern UniValue z_shieldcoinbase(const UniValue& params, bool fHelp); // in rpcw extern UniValue z_getoperationstatus(const UniValue& params, bool fHelp); // in rpcwallet.cpp extern UniValue z_getoperationresult(const UniValue& params, bool fHelp); // in rpcwallet.cpp extern UniValue z_listoperationids(const UniValue& params, bool fHelp); // in rpcwallet.cpp +extern UniValue opreturn_burn(const UniValue& params, bool fHelp); // in rpcwallet.cpp extern UniValue z_validateaddress(const UniValue& params, bool fHelp); // in rpcmisc.cpp extern UniValue z_getpaymentdisclosure(const UniValue& params, bool fHelp); // in rpcdisclosure.cpp extern UniValue z_validatepaymentdisclosure(const UniValue ¶ms, bool fHelp); // in rpcdisclosure.cpp diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 847205ec1..de446390e 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -7979,9 +7979,11 @@ UniValue test_ac(const UniValue& params, bool fHelp) return(FinalizeCCTx(0, cp, mtx, myPubkey, txfee, opret)); } +extern bool komodo_appendACscriptpub(); + UniValue test_heirmarker(const UniValue& params, bool fHelp) { - // make fake token tx: + //make fake token tx: struct CCcontract_info *cp, C; if (fHelp || (params.size() != 1)) @@ -8010,6 +8012,38 @@ UniValue test_heirmarker(const UniValue& params, bool fHelp) return(FinalizeCCTx(0, cp, mtx, myPubkey, 10000, opret)); } +UniValue opreturn_burn(const UniValue& params, bool fHelp) +{ + struct CCcontract_info *cp, C; UniValue ret(UniValue::VOBJ); + if (ensure_CCrequirements(EVAL_PAYMENTS) < 0) + throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + cp = CCinit(&C, EVAL_PAYMENTS); + if (fHelp || (params.size() != 2)) + throw runtime_error("amount to burn, hexstring to send\n"); + + CAmount nAmount = AmountFromValue(params[0]); + if (nAmount <= 10000) + throw JSONRPCError(RPC_TYPE_ERROR, "must send at least 10000 sat"); + std::string strHex = params[1].get_str(); + CPubKey myPubkey = pubkey2pk(Mypubkey()); + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + + int64_t normalInputs = AddNormalinputs(mtx, myPubkey, nAmount, 60); + if (normalInputs < nAmount) + throw runtime_error("not enough normals\n"); + + CScript opret; uint8_t scripthex[8192]; + + decode_hex(scripthex,strHex.size()/2,(char *)strHex.c_str()); + std::string test; + test.append((char*)scripthex); + std::vector opretdata(test.begin(), test.end()); + opret << OP_RETURN << E_MARSHAL(ss << opretdata); + mtx.vout.push_back(CTxOut(nAmount,opret)); + ret.push_back(Pair("hex",FinalizeCCTx(0, cp, mtx, myPubkey, 10000, CScript()))); + return(ret); +} + UniValue test_burntx(const UniValue& params, bool fHelp) { // make fake token tx: From 489485252b68597bc9173328ed21674b58f90b8b Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Mon, 22 Apr 2019 18:02:19 +0800 Subject: [PATCH 004/242] fixes for TESTHC chain and add notes for others to make similar chains. --- src/cc/hempcoin_notes.txt | 65 +++++++++++++++++++++++++++++++ src/cc/payments.cpp | 80 +++++++-------------------------------- src/komodo_bitcoind.h | 3 +- src/wallet/rpcwallet.cpp | 20 +++++----- 4 files changed, 91 insertions(+), 77 deletions(-) create mode 100644 src/cc/hempcoin_notes.txt diff --git a/src/cc/hempcoin_notes.txt b/src/cc/hempcoin_notes.txt new file mode 100644 index 000000000..f8003ac95 --- /dev/null +++ b/src/cc/hempcoin_notes.txt @@ -0,0 +1,65 @@ +How this works: + - earlytxid must be a transaction included in the chain before block 100. The chain MUST not have any other of these type of tx before block 100, or someone may be able to change it and mess things up. + - When it gets to block 100, it takes the txid specified by the -earlytxid param (does not affect magic) + - Looks up the transaction searches for the opreturn, then permenantly appends it to the end of ac_script in RAM. + - After every daemon restart, the first time the daemon mines a block, or receives a block that pays ac_script it will look up the op_return and save it again. + - this enables it to always reach consensus but doesnt need to constantly keep looking up the tx in the chain. + - The trick is to use ac_founders=101 or higher so that nothing is ever paid to the unspendable CC address. Although it should still work without this it burns coins. + +-ac_script can be any Global CC address you can spend to with an OP_RETURN. Here we use example of paymentsCC being used to fund a rewards plan, and a set of founders address's. + you can get the ac_script from another chain, but the op_return payload must generated on the chain itself. this command gives you the needed info to get the scripPubKey Hex: + ./komodo-cli -ac_name=TEST paymentsfund '["5d536f54332db09f2be04593c54f764cf569e225f4d8df5155658c679e663682",1000]' + append: b8, to the end of ac_script, this changes magic value for -earlytxid chains vs normal ac_script and allows bypass of ac_supply paid to the scritpt as it would be unspendable and you would be unable to create the needed plans with no coins. + -ac_script=2ea22c8020987fad30df055db6fd922c3a57e55d76601229ed3da3b31340112e773df3d0d28103120c008203000401ccb8 + +-testnode=1 is not affecting magic and allows mining on a single node, we can use this to bootstrap the chain before syncing a second node to save time. + +start chain and make sure to do the following steps before block 100 (set generate false/true is a good idea between steps) + ./komodod -ac_name=TESTHC -ac_supply=1000000 -ac_reward=100000000000 -ac_cc=2 -ac_script=2ea22c8020987fad30df055db6fd922c3a57e55d76601229ed3da3b31340112e773df3d0d28103120c008203000401ccb8 -ac_founders=150 -ac_blocktime=20 -ac_nk=96,5 -testnode=1 + +create rewards plan and fund it with all or a % of the premine. Must be some amount. eg. + ./komodo-cli -ac_name=TESTHC rewardscreatefunding test 50000 25 0 2 500 + +do rewards add funding: + ./komodo-cli -ac_name=TESTHC rewardsaddfunding test 47a3150150bd196bd2086cae5e0c6b01a23785a04139fa660d169121a534b38e 1000 + +and get the script pubkey and op_return from this tx (no need to send it) +./komodo-cli -ac_name=TESTHC decoderawtransaction 010000000204ca4c7aaae62bb8fc9412ac010e047fa8d33c3f87d2adeb3e02170642ddfe370000000049483045022100d7b9a +4f28ca3a35f34dcdb6075e905cde1eaa962bd0619d0a8ed8e17e952bc99022077308e12325fc2a02c752ec3df9aeee1fc219ea54a4d3884834582b75c89815e01ffffffff08800132da3233d80c65e87b6db6a76dcf +188e4fdfa23198d69f647e67754cfb0000000049483045022100d6a8f7a1c4f6013f5897768ae0117fe61dfb72352d3e6652e64a6588db3ffcb102202aa1d041b24f9cbbf7028295b7c5e7f18b4f95ae39c13031dab +7f06634438e6801ffffffff0300e8764817000000302ea22c802065686d47a4049c2c845a71895a915eb84c04445896eec5dc0be40df0b31372da8103120c008203000401ccf0c0764817000000232103bbec93af84 +0933ae2d35fc56eff24f34dbe26871402552f84c44f690945ccd79ac00000000000000002c6a2ae54174657374000000008eb334a52191160d66fa3941a08537a2016b0c5eae6c08d26b19bd500115a34700000000 + +From the return of this you need the scriptpubkey hex of vout 0: + scriptPubKey: 2ea22c802065686d47a4049c2c845a71895a915eb84c04445896eec5dc0be40df0b31372da8103120c008203000401cc +and the scriptpubkey hex of the OP_RETURN in vout 2. + OP_RETURN: 6a2ae54174657374000000008eb334a52191160d66fa3941a08537a2016b0c5eae6c08d26b19bd500115a347 + +create txidopreturn for this payment: + ./komodo-cli -ac_name=TESTHC paymentstxidopret '[50,"2ea22c802065686d47a4049c2c845a71895a915eb84c04445896eec5dc0be40df0b31372da8103120c008203000401cc","6a2ae54174657374000000008eb334a52191160d66fa3941a08537a2016b0c5eae6c08d26b19bd500115a347"]' + +create the txidopret for the founders reward(s) pubkeys: should be able to be a few here, not sure of max number yet. These can pay anything that does not need an opreturn. allocation and scriptpubkey hex. + ./komodo-cli -ac_name=TESTHC paymentstxidopret '[50,"76a9146bf5dd9f679c87a3f83ea176f82148d26653c04388ac"]' + +create payments plan: + ./komodo-cli -ac_name=TESTHC paymentscreate '[0,0,"61f55f2f87dad3a37d42731a8cb73b3ebea1817abfa176218162c360a8bd7145","0550014823ffa0aa99d7dd7ca5292f4dd0a1b9156eddec03412c953f095181bc"]' +gives plan txid: ee7765be874fb084c00538b1b0488e8ecb857de253f09a9ba6ea8d3579b77d33 + +paymentsfund: + To do this you first need to change the type of tx generated by paymentsfund RPC. in payments.cpp go to line: 639 and comment it out, then uncomment the block of code under this. + change the line 646 to line 647 with comments, and line 650/651 aswell. This enables the RPC to generate the ccvout opreturn payload you need without sending the payment on the chain. Just decode the raw hex. + ./komodo-cli -ac_name=TESTHC paymentsfund '["ee7765be874fb084c00538b1b0488e8ecb857de253f09a9ba6ea8d3579b77d33",1000,1]' + +get the payment fund scriptpubkey hex from vout 0: (the split it at OP_CHECKCRYPTOCONDITION or 'cc' ) + 2ea22c8020987fad30df055db6fd922c3a57e55d76601229ed3da3b31340112e773df3d0d28103120c008203000401cc 2a0401f00101246a22f046337db779358deaa69b9af053e27d85cb8e8e48b0b13805c084b04f87be6577ee75 + + put the second half into an OP_RETURN: (the remaining part of the the above scriptpubkey) eg. + ./komodo-cli -ac_name=TESTHC opreturn_burn 1 2a0401f00101246a22f046337db779358deaa69b9af053e27d85cb8e8e48b0b13805c084b04f87be6577ee75 + opret_burn takes any burn amount and arbitrary hex string. (RPC works, but may have bugs, likely use this for LABS too with some fixes) + this gives a raw hex. Decode it and check the OP_RETURN is right before sending (using this RPC currently adds 3 extra bytes to the front (6a2d2c), which is truncated later on, this should be fixed if possible before making any real chains as its consensus code. Need to try diffrent methods to decode the hex correctly.) + -earlytxid=810bd62fb8353fad20267ff2050684b8829affa3edf6b366633931530791dfce + restart the chain with earlytxid param before height 100 on all nodes (if not using -testnode=1) + ./komodod -ac_name=TESTHC -ac_supply=1000000 -ac_reward=100000000000 -ac_cc=2 -ac_script=2ea22c8020987fad30df055db6fd922c3a57e55d76601229ed3da3b31340112e773df3d0d28103120c008203000401ccb8 -ac_founders=150 -ac_blocktime=20 -ac_nk=96,5 -earlytxid=810bd62fb8353fad20267ff2050684b8829affa3edf6b366633931530791dfce + +once the payments plan has been funded with the mined coinbase you can issue payments release when conditions of the plan are met to fund founders reward/rewards plan. eg. + ./komodo-cli -ac_name=TESTHC paymentsrelease '["ee7765be874fb084c00538b1b0488e8ecb857de253f09a9ba6ea8d3579b77d33",500]' diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index 7d6fcba32..ba915e586 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -16,60 +16,6 @@ #include "CCPayments.h" /* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -ac_script + -earlytxid instructions with payments cc + rewards CC as an example. -How this works: - - earlytxid must be a transaction included in the chain before block 100. The chain MUST not have any other of these type of tx before block 100, or someone may be able to change it and mess things up. - - When it gets to block 100, it takes the txid specified by the -earlytxid param (does not affect magic) - - Looks up the transaction searches for the opreturn, then permenantly appends it to the end of ac_script in RAM. - - After every daemon restart, the first time the daemon mines a block, or receives a block that pays ac_script it will look up the op_return and save it again. - - this enables it to always reach consensus but doesnt need to constantly keep looking up the tx in the chain. - - The trick is to use ac_founders=101 or higher so that nothing is ever paid to the unspendable CC address. Although it should still work without this it burns coins. - --ac_script can be any Global CC address you can spend to with an OP_RETURN. Here we use example of paymentsCC being used to fund a rewards plan, and a set of founders address's. - you can get the ac_script from another chain, but the op_return payload must generated on the chain itself. this command gives you the needed info to get the scripPubKey Hex: - ./komodo-cli -ac_name=TEST paymentsfund '["5d536f54332db09f2be04593c54f764cf569e225f4d8df5155658c679e663682",1000]' - append: b8, to the end of ac_script, this changes magic value for -earlytxid chains vs normal ac_script and allows bypass of ac_supply paid to the scritpt as it would be unspendable and you would be unable to create the needed plans with no coins. - -ac_script=2ea22c8020987fad30df055db6fd922c3a57e55d76601229ed3da3b31340112e773df3d0d28103120c008203000401ccb8 - -start chain and make sure to do the following steps before block 100 (set generate false/true is a good idea between steps) -create rewards plan and fund it with all or a % of the premine. Must be some amount. eg. - ./komodo-cli -ac_name=TEST rewardscreatefunding test 1000 10 0 10 10 - -do rewards add funding and get the script pubkey and op_return from this tx (no need to send it) eg. - scriptPubKey: 2ea22c802065686d47a4049c2c845a71895a915eb84c04445896eec5dc0be40df0b31372da8103120c008203000401cc - OP_RETURN: 6a2ae541746573740000000061e7063fa8f99ef92a47e4aebf7ea28c59aeadaf3c1784312de64e4bcb3666f1 - -create txidopreturn for this payment: - ./komodo-cli -ac_name=TEST paymentstxidopret '[50,"2ea22c802065686d47a4049c2c845a71895a915eb84c04445896eec5dc0be40df0b31372da8103120c008203000401cc","6a2ae541746573740000000061e7063fa8f99ef92a47e4aebf7ea28c59aeadaf3c1784312de64e4bcb3666f1"]' - -create the txidopret for the founders reward(s) pubkeys: should be able to be a few here, not sure of max number yet. These can pay anything that does not need an opreturn. allocation and scriptpubkey hex. - ./komodo-cli -ac_name=TEST paymentstxidopret '[50,"76a9146bf5dd9f679c87a3f83ea176f82148d26653c04388ac"]' - -create payments plan: - ./komodo-cli -ac_name=TEST paymentscreate '[0,0,"273d193e5d09928e471926827dcac1f06c4801bdaa5524a84b17a00f4eaf8d38","81264daf7874b2041802ac681e49618413313cc2f29b47d47bd8e63dc2a06cad"]' -gives plan txid eg. 5d536f54332db09f2be04593c54f764cf569e225f4d8df5155658c679e663682 - -paymentsfund: - send some of the premine to this payments fund to get the rest of the scriptpubkey payload. (could skip send and just gen/decode the tx if required.) - send opret path this time to get the required script pubkey. For payments this mode is enabled by default rather than a traditional OP_RETURN, - for other CC we would need to modify daemon to get the correct info. - ./komodo-cli -ac_name=TEST paymentsfund '["5d536f54332db09f2be04593c54f764cf569e225f4d8df5155658c679e663682",1000,1]' - -get the payment fund script pubkey: (the split it at OP_CHECKCRYPTOCONDITION or 'cc' ) - 2ea22c8020987fad30df055db6fd922c3a57e55d76601229ed3da3b31340112e773df3d0d28103120c008203000401cc 2a0401f00101246a22f0466b75e35aa4d8ea6c3dd1b76141a0acbd06dfb4897288a62b8a8ec31b75a5b6cb75 - - put the second half into an OP_RETURN: (the remaining part of the the above scriptpubkey) eg. - ./komodo-cli -ac_name=TEST opreturn_burn 1 2a0401f00101246a22f0466b75e35aa4d8ea6c3dd1b76141a0acbd06dfb4897288a62b8a8ec31b75a5b6cb75 - opret_burn takes any burn amount and arbitrary hex string. (RPC works, but may have bugs, likely use this for LABS too with some fixes) - this gives a txid to locate it in the chain eg: - -earlytxid=1acd0b9b728feaea37a3f52d4106c35b0f8cfd19f9f3e64815d23ace0721d69d - restart the chain with earlytxid param before height 100 on BOTH NODES! - -once the payments plan has been funded with the mined coinbase you can issue payments release when conditions of the plan are met to fund founders reward/rewards plan. eg. - ./komodo-cli -ac_name=TEST paymentsrelease '["5d536f54332db09f2be04593c54f764cf569e225f4d8df5155658c679e663682",500]' ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 0) txidopret <- allocation, scriptPubKey, opret 1) create <- locked_blocks, minrelease, list of txidopret @@ -347,14 +293,14 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & CScript opret; uint256 checktxid; int32_t opret_ind; if ( (opret_ind= has_opret(txin, EVAL_PAYMENTS)) == 0 ) { - // get op_return from CCvout - opret = getCCopret(txin.vout[0].scriptPubKey); + // get op_return from CCvout, + opret = getCCopret(txin.vout[vin.prevout.n].scriptPubKey); } else { // get op_return from the op_return opret = txin.vout[opret_ind].scriptPubKey; - } // else return(eval->Invalid("vin has wrong amount of vouts")); // dont think this is needed? + } if ( DecodePaymentsFundOpRet(opret,checktxid) != 'F' || checktxid != createtxid ) { fprintf(stderr, "vin.%i is not a payments CC vout: txid.%s\n", i, txin.GetHash().ToString().c_str()); @@ -381,7 +327,7 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & int64_t AddPaymentsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey txidpk,int64_t total,int32_t maxinputs,uint256 createtxid,int32_t latestheight) { - char coinaddr[64]; CPubKey Paymentspk; int64_t nValue,threshold,price,totalinputs = 0; uint256 txid,checktxid,hashBlock; std::vector origpubkey; CTransaction vintx,tx; int32_t iter,vout,ht,n = 0; + char coinaddr[64]; CPubKey Paymentspk; int64_t nValue,threshold,price,totalinputs = 0; uint256 txid,checktxid,hashBlock; std::vector origpubkey; CTransaction vintx; int32_t iter,vout,ht,n = 0; std::vector > unspentOutputs; if ( maxinputs > CC_MAXVINS ) maxinputs = CC_MAXVINS; @@ -400,7 +346,7 @@ int64_t AddPaymentsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CP txid = it->first.txhash; vout = (int32_t)it->first.index; //fprintf(stderr,"iter.%d %s/v%d %s\n",iter,txid.GetHex().c_str(),vout,coinaddr); - if ( vout == 0 && GetTransaction(txid,vintx,hashBlock,false) != 0 ) + if ( (vout == 0 || vout == 1) && GetTransaction(txid,vintx,hashBlock,false) != 0 ) { if ( latestheight != 0 ) { @@ -421,14 +367,14 @@ int64_t AddPaymentsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CP if ( (opret_ind= has_opret(vintx, EVAL_PAYMENTS)) == 0 ) { // get op_return from CCvout - opret = getCCopret(vintx.vout[0].scriptPubKey); + opret = getCCopret(vintx.vout[vout].scriptPubKey); } else { // get op_return from the op_return opret = vintx.vout[opret_ind].scriptPubKey; } - if ( myGetTransaction(txid,tx,hashBlock) == 0 || DecodePaymentsFundOpRet(opret,checktxid) != 'F' || checktxid != createtxid ) + if ( DecodePaymentsFundOpRet(opret,checktxid) != 'F' || checktxid != createtxid ) { fprintf(stderr,"bad opret %s vs %s\n",checktxid.GetHex().c_str(),createtxid.GetHex().c_str()); continue; @@ -690,16 +636,18 @@ UniValue PaymentsFund(struct CCcontract_info *cp,char *jsonstr) } else { - opret = EncodePaymentsFundOpRet(txid); + mtx.vout.push_back(MakeCC1vout(EVAL_PAYMENTS,amount,Paymentspk)); + // Use the below one along with other FinalizeCCTx/return, to get the ccvout scriptpubkey + /*opret = EncodePaymentsFundOpRet(txid); std::vector> vData = std::vector>(); if ( makeCCopret(opret, vData) ) - mtx.vout.push_back(MakeCC1vout(EVAL_PAYMENTS,amount,Paymentspk,&vData)); - //fprintf(stderr, "scriptpubkey.%s\n", mtx.vout.back().scriptPubKey.ToString().c_str()); - //fprintf(stderr, "hex.%s\n", HexStr(mtx.vout.back().scriptPubKey.begin(), mtx.vout.back().scriptPubKey.end()).c_str()); + mtx.vout.push_back(MakeCC1vout(EVAL_PAYMENTS,amount,Paymentspk,&vData)); */ } - rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,CScript()); + rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,EncodePaymentsFundOpRet(txid)); + //rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,CScript()); // use this one to get ccvout scriptpubkey. if ( params != 0 ) free_json(params); + //return(payments_rawtxresult(result,rawtx,0)); // disable sending for CCvout, as we only need to decode the tx. return(payments_rawtxresult(result,rawtx,1)); } else diff --git a/src/komodo_bitcoind.h b/src/komodo_bitcoind.h index 3dd590417..788f3795a 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -2047,7 +2047,8 @@ bool komodo_appendACscriptpub() { ASSETCHAINS_SCRIPTPUB.pop_back(); ASSETCHAINS_SCRIPTPUB.pop_back(); // remove last 2 chars. // get OP_RETURN from txid and append the HexStr of it to scriptpub - ASSETCHAINS_SCRIPTPUB.append(HexStr(tx.vout[i].scriptPubKey.begin()+3, tx.vout[i].scriptPubKey.end())); + // encoded opreturn incorrectly on TESTHC chain, once we no longer need this it can be changed to a straight +1 to drop OP_RETURN opcode. + ASSETCHAINS_SCRIPTPUB.append(HexStr(tx.vout[i].scriptPubKey.begin()+(strcmp("TESTHC",ASSETCHAINS_SYMBOL) == 0 ? 3 : 1), tx.vout[i].scriptPubKey.end())); //fprintf(stderr, "ac_script.%s\n",ASSETCHAINS_SCRIPTPUB.c_str()); didinit = true; return true; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index de446390e..8152e22b8 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -8014,13 +8014,13 @@ UniValue test_heirmarker(const UniValue& params, bool fHelp) UniValue opreturn_burn(const UniValue& params, bool fHelp) { + if (fHelp || (params.size() != 2)) + throw runtime_error("amount to burn, hexstring to send\n"); struct CCcontract_info *cp, C; UniValue ret(UniValue::VOBJ); if (ensure_CCrequirements(EVAL_PAYMENTS) < 0) throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); cp = CCinit(&C, EVAL_PAYMENTS); - if (fHelp || (params.size() != 2)) - throw runtime_error("amount to burn, hexstring to send\n"); - + CAmount nAmount = AmountFromValue(params[0]); if (nAmount <= 10000) throw JSONRPCError(RPC_TYPE_ERROR, "must send at least 10000 sat"); @@ -8032,13 +8032,13 @@ UniValue opreturn_burn(const UniValue& params, bool fHelp) if (normalInputs < nAmount) throw runtime_error("not enough normals\n"); - CScript opret; uint8_t scripthex[8192]; - - decode_hex(scripthex,strHex.size()/2,(char *)strHex.c_str()); - std::string test; - test.append((char*)scripthex); - std::vector opretdata(test.begin(), test.end()); - opret << OP_RETURN << E_MARSHAL(ss << opretdata); + CScript opret; uint8_t *ptr; + opret << OP_RETURN; + int32_t len = strlen(strHex.c_str()); + len >>=1; + opret.resize(len+1); + ptr = (uint8_t *)&opret[1]; + decode_hex(ptr,len,(char *)strHex.c_str()); mtx.vout.push_back(CTxOut(nAmount,opret)); ret.push_back(Pair("hex",FinalizeCCTx(0, cp, mtx, myPubkey, 10000, CScript()))); return(ret); From 1a9ed2ac488b3788610176d0e3d1d1be72d626eb Mon Sep 17 00:00:00 2001 From: dimxy Date: Sun, 7 Apr 2019 22:42:54 +0500 Subject: [PATCH 005/242] univalue ptr test --- src/wallet/rpcwallet.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 6fe061727..3a4331b25 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5848,8 +5848,26 @@ UniValue assetsaddress(const UniValue& params, bool fHelp) return(CCaddress(cp, (char *)"Assets", pubkey)); } +void f(UniValue *p1, UniValue *p2) { + + if (p1) + p1->push_back(make_pair("x", "y")); + + // or... + if (p2) + (*p2).push_back(make_pair("a", "b")); + +} + UniValue tokenaddress(const UniValue& params, bool fHelp) { + UniValue v1, v2; + f(&v1, &v2); + + std::cerr << v1.getValues()[0].get_str() << std::endl; + std::cerr << v2.getValues()[0].get_str() << std::endl; + + struct CCcontract_info *cp,C; std::vector pubkey; cp = CCinit(&C,EVAL_TOKENS); if ( fHelp || params.size() > 1 ) @@ -8102,3 +8120,14 @@ UniValue test_proof(const UniValue& params, bool fHelp) return result; } + +void f(UniValue *p) { + + if (p) + p->push_back(make_pair("x", "y")); + + // or... + if (p) + (*p).push_back(make_pair("x", "y")); + +} \ No newline at end of file From b4b55290a2f85f41e4a7d714e79a5894d5ae1ae1 Mon Sep 17 00:00:00 2001 From: dimxy Date: Sun, 7 Apr 2019 23:02:28 +0500 Subject: [PATCH 006/242] corr univalue init --- src/wallet/rpcwallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 3a4331b25..64c32fa05 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5861,7 +5861,7 @@ void f(UniValue *p1, UniValue *p2) { UniValue tokenaddress(const UniValue& params, bool fHelp) { - UniValue v1, v2; + UniValue v1(UniValue::VARR), v2(UniValue::VARR); f(&v1, &v2); std::cerr << v1.getValues()[0].get_str() << std::endl; From 161b75b7f8ee0fbbc8ee6b02db95ad35a67a759d Mon Sep 17 00:00:00 2001 From: dimxy Date: Sun, 7 Apr 2019 23:10:46 +0500 Subject: [PATCH 007/242] more init corr --- src/wallet/rpcwallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 64c32fa05..1f0d1c5ca 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5861,7 +5861,7 @@ void f(UniValue *p1, UniValue *p2) { UniValue tokenaddress(const UniValue& params, bool fHelp) { - UniValue v1(UniValue::VARR), v2(UniValue::VARR); + UniValue v1(UniValue::VOBJ), v2(UniValue::VOBJ); f(&v1, &v2); std::cerr << v1.getValues()[0].get_str() << std::endl; From f0eeb7efe1cb812a0c11be05d7567cd0c2d5ef25 Mon Sep 17 00:00:00 2001 From: dimxy Date: Mon, 8 Apr 2019 00:23:42 +0500 Subject: [PATCH 008/242] added pricesbet rpc --- src/rpc/server.cpp | 1 + src/rpc/server.h | 1 + src/wallet/rpcwallet.cpp | 18 ------------------ 3 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 3ed082455..581676763 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -464,6 +464,7 @@ static const CRPCCommand vRPCCommands[] = { "prices", "pricesaddress", &pricesaddress, true }, { "prices", "priceslist", &priceslist, true }, { "prices", "pricesinfo", &pricesinfo, true }, + { "prices", "pricesbet", &pricesbet, true }, // Pegs { "pegs", "pegsaddress", &pegsaddress, true }, diff --git a/src/rpc/server.h b/src/rpc/server.h index 8e0054e6f..3df78de9f 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -497,6 +497,7 @@ extern UniValue paxdeposit(const UniValue& params, bool fHelp); extern UniValue paxwithdraw(const UniValue& params, bool fHelp); extern UniValue prices(const UniValue& params, bool fHelp); +extern UniValue pricesbet(const UniValue& params, bool fHelp); // test rpc: extern UniValue test_ac(const UniValue& params, bool fHelp); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 1f0d1c5ca..96e201bc3 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5848,26 +5848,8 @@ UniValue assetsaddress(const UniValue& params, bool fHelp) return(CCaddress(cp, (char *)"Assets", pubkey)); } -void f(UniValue *p1, UniValue *p2) { - - if (p1) - p1->push_back(make_pair("x", "y")); - - // or... - if (p2) - (*p2).push_back(make_pair("a", "b")); - -} - UniValue tokenaddress(const UniValue& params, bool fHelp) { - UniValue v1(UniValue::VOBJ), v2(UniValue::VOBJ); - f(&v1, &v2); - - std::cerr << v1.getValues()[0].get_str() << std::endl; - std::cerr << v2.getValues()[0].get_str() << std::endl; - - struct CCcontract_info *cp,C; std::vector pubkey; cp = CCinit(&C,EVAL_TOKENS); if ( fHelp || params.size() > 1 ) From ffb14229e55884e71d459efc4d706a6356c39697 Mon Sep 17 00:00:00 2001 From: dimxy Date: Mon, 8 Apr 2019 01:22:48 +0500 Subject: [PATCH 009/242] logging added --- src/cc/prices.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 407cd81fa..acf2fce4d 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -274,8 +274,10 @@ UniValue prices_rawtxresult(UniValue &result,std::string rawtx,int32_t broadcast int32_t prices_syntheticvec(std::vector &vec,std::vector synthetic) { int32_t i,need,ind,depth = 0; std::string opstr; uint16_t opcode,weight; - if ( synthetic.size() == 0 ) + if (synthetic.size() == 0) { + std::cerr << "synthetic expression is empty" << std::endl; return(-1); + } for (i=0; i &vec,std::vector { opcode = PRICES_WEIGHT | weight; need = 1; - } else return(-2); - if ( depth < need ) + } + else { + std::cerr << "incorrect opcode=" << opstr << std::endl; + return(-2); + } + if (depth < need) { + std::cerr << "incorrect not enough operands for opcode=" << opstr << std::endl; return(-3); + } depth -= need; if ( (opcode & KOMODO_PRICEMASK) != PRICES_WEIGHT ) // weight depth++; - if ( depth > 3 ) + if (depth > 3) { + std::cerr << "to many operands, last=" << opstr << std::endl; return(-4); + } vec.push_back(opcode); } if ( depth != 0 ) From 0b1ab063e096919f4f11b758795ac90e42c09037 Mon Sep 17 00:00:00 2001 From: dimxy Date: Mon, 8 Apr 2019 14:02:45 +0500 Subject: [PATCH 010/242] deb logging added --- src/komodo_gateway.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/komodo_gateway.h b/src/komodo_gateway.h index 0ff1c0b66..d12d2467f 100644 --- a/src/komodo_gateway.h +++ b/src/komodo_gateway.h @@ -2337,6 +2337,7 @@ int64_t komodo_pricemult(int32_t ind) return(0); } +// returns index name for ind value char *komodo_pricename(char *name,int32_t ind) { strcpy(name,"error"); @@ -2401,14 +2402,18 @@ char *komodo_pricename(char *name,int32_t ind) return(0); } +// finds index value for its char* name int32_t komodo_priceind(char *symbol) { char name[65]; int32_t i,n = (int32_t)(komodo_cbopretsize(ASSETCHAINS_CBOPRET) / sizeof(uint32_t)); for (i=1; i s uint32_t get_dailyfx(uint32_t *prices) { //{"base":"USD","rates":{"BGN":1.74344803,"NZD":1.471652701,"ILS":3.6329113924,"RUB":65.1997682296,"CAD":1.3430201462,"USD":1.0,"PHP":52.8641469068,"CHF":0.9970582992,"AUD":1.4129078267,"JPY":110.6792654662,"TRY":5.6523444464,"HKD":7.8499732573,"MYR":4.0824567659,"HRK":6.6232840078,"CZK":22.9862720628,"IDR":14267.4986628633,"DKK":6.6551078624,"NOK":8.6806917454,"HUF":285.131039401,"GBP":0.7626582278,"MXN":19.4183455161,"THB":31.8702085933,"ISK":122.5708682475,"ZAR":14.7033339276,"BRL":3.9750401141,"SGD":1.3573720806,"PLN":3.8286682118,"INR":69.33187734,"KRW":1139.1602781244,"RON":4.2423783206,"CNY":6.7387234801,"SEK":9.3385630237,"EUR":0.8914244963},"date":"2019-03-28"} + char url[512],*datestr; cJSON *json,*rates; int32_t i; uint32_t datenum=0,price = 0; + sprintf(url,"https://api.openrates.io/latest?base=USD"); if ( (json= get_urljson(url)) != 0 ) //if ( (json= send_curl(url,(char *)"dailyfx")) != 0 ) { + std::cerr << "Forex rates:" << std::endl; if ( (rates= jobj(json,(char *)"rates")) != 0 ) { for (i=0; i strvec) { int32_t i,errs=0; uint32_t price; char *symbol; + std::cerr << "Crypto rates:" << std::endl; + for (i=0; i Date: Mon, 8 Apr 2019 14:57:49 +0500 Subject: [PATCH 013/242] logging --- src/komodo_gateway.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/komodo_gateway.h b/src/komodo_gateway.h index 99759d043..9418f7333 100644 --- a/src/komodo_gateway.h +++ b/src/komodo_gateway.h @@ -2102,7 +2102,6 @@ uint32_t get_binanceprice(const char *symbol) if ( (json= get_urljson(url)) != 0 ) //if ( (json= send_curl(url,(char *)"bnbprice")) != 0 ) { price = jdouble(json,(char *)"price")*SATOSHIDEN + 0.0000000049; - std::cerr << price << std::endl; free_json(json); } usleep(100000); From 4cd2814aa83d235cf35882e31409ac521f86ed40 Mon Sep 17 00:00:00 2001 From: dimxy Date: Mon, 8 Apr 2019 15:59:48 +0500 Subject: [PATCH 014/242] logging --- src/cc/prices.cpp | 24 ++++++++++++++++++++---- src/komodo_gateway.h | 8 ++++---- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index acf2fce4d..a2a78c9ed 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -144,6 +144,16 @@ CBOPRET creates trustless oracles, which can be used for making a synthetic cash */ +// helpers: + +// returns true if there are only digits and no alphas in 's' +inline bool is_weight(std::string s) { + return + std::count_if(s.begin(), s.end(), [](unsigned char c) { return std::isdigit(c); } ) > 0 && + std::count_if(s.begin(), s.end(), [](unsigned char c) { return std::isalpha(c); } ) == 0; +} + + // start of consensus code CScript prices_betopret(CPubKey mypk,int32_t height,int64_t amount,int16_t leverage,int64_t firstprice,std::vector vec,uint256 tokenid) @@ -296,7 +306,7 @@ int32_t prices_syntheticvec(std::vector &vec,std::vector opcode = PRICES_MMM, need = 3; else if ( opstr == "///" ) opcode = PRICES_DDD, need = 3; - else if ( (ind= komodo_priceind((char *)opstr.c_str())) >= 0 ) + else if (!is_weight(opstr) && (ind= komodo_priceind(opstr.c_str())) >= 0 ) opcode = ind, need = 0; else if ( (weight= atoi(opstr.c_str())) > 0 && weight < KOMODO_MAXPRICES ) { @@ -429,12 +439,18 @@ int64_t prices_syntheticprice(std::vector vec,int32_t height,int32_t m if ( errcode != 0 ) break; } - if ( den == 0 ) + if (den == 0) { + std::cerr << "prices_syntheticprice den==0 return err=-11" << std::endl; return(-11); - else if ( depth != 0 ) + } + else if (depth != 0) { + std::cerr << "prices_syntheticprice depth!=0 err=-12" << std::endl; return(-12); - else if ( errcode != 0 ) + } + else if (errcode != 0) { + std::cerr << "prices_syntheticprice err=" << errcode << std::endl; return(errcode); + } return(price / den); } diff --git a/src/komodo_gateway.h b/src/komodo_gateway.h index 9418f7333..204960693 100644 --- a/src/komodo_gateway.h +++ b/src/komodo_gateway.h @@ -2111,7 +2111,7 @@ uint32_t get_binanceprice(const char *symbol) int32_t get_cryptoprices(uint32_t *prices,const char *list[],int32_t n,std::vector strvec) { int32_t i,errs=0; uint32_t price; char *symbol; - std::cerr << "Crypto rates:" << std::endl; + std::cerr << "Crypto binance rates:" << std::endl; for (i=0; i &vec,std::vector opcode = PRICES_MMM, need = 3; else if ( opstr == "///" ) opcode = PRICES_DDD, need = 3; - else if (!is_weight(opstr) && (ind= komodo_priceind(opstr.c_str())) >= 0 ) + else if (!is_weight_str(opstr) && (ind= komodo_priceind(opstr.c_str())) >= 0 ) opcode = ind, need = 0; else if ( (weight= atoi(opstr.c_str())) > 0 && weight < KOMODO_MAXPRICES ) { @@ -314,30 +314,34 @@ int32_t prices_syntheticvec(std::vector &vec,std::vector need = 1; } else { - std::cerr << "incorrect opcode=" << opstr << std::endl; + std::cerr << "prices_syntheticvec() incorrect opcode=" << opstr << std::endl; return(-2); } if (depth < need) { - std::cerr << "incorrect not enough operands for opcode=" << opstr << std::endl; + std::cerr << "prices_syntheticvec() incorrect not enough operands for opcode=" << opstr << std::endl; return(-3); } depth -= need; - if ( (opcode & KOMODO_PRICEMASK) != PRICES_WEIGHT ) // weight - depth++; + std::cerr << "opcode=" << opcode << " opstr=" << opstr << " depth-=need=" << depth << std::endl; + if ((opcode & KOMODO_PRICEMASK) != PRICES_WEIGHT) { // skip weight + depth++; // increase operands count + std::cerr << "depth++=" << depth << std::endl; + } if (depth > 3) { - std::cerr << "to many operands, last=" << opstr << std::endl; + std::cerr << "prices_syntheticvec() to many operands, last=" << opstr << std::endl; return(-4); } vec.push_back(opcode); } if ( depth != 0 ) { - fprintf(stderr,"depth.%d not empty\n",depth); + fprintf(stderr,"prices_syntheticvec() depth.%d not empty\n",depth); return(-5); } return(0); } +// calculate price for synthetic expression int64_t prices_syntheticprice(std::vector vec,int32_t height,int32_t minmax,int16_t leverage) { int32_t i,ind,errcode,depth,retval = -1; uint16_t opcode; int64_t pricedata[PRICES_MAXDATAPOINTS],pricestack[4],price,den,a,b,c; @@ -345,7 +349,7 @@ int64_t prices_syntheticprice(std::vector vec,int32_t height,int32_t m for (i=0; i vec,int32_t height,int32_t m { if ( leverage > 0 ) pricestack[depth] = (pricedata[1] > pricedata[2]) ? pricedata[1] : pricedata[2]; // MAX - else pricestack[depth] = (pricedata[1] < pricedata[2]) ? pricedata[1] : pricedata[2]; // MIN + else + pricestack[depth] = (pricedata[1] < pricedata[2]) ? pricedata[1] : pricedata[2]; // MIN } } if ( pricestack[depth] == 0 ) diff --git a/src/komodo_gateway.h b/src/komodo_gateway.h index 204960693..c9e3d0470 100644 --- a/src/komodo_gateway.h +++ b/src/komodo_gateway.h @@ -2077,7 +2077,7 @@ uint32_t get_dailyfx(uint32_t *prices) sprintf(url,"https://api.openrates.io/latest?base=USD"); if ( (json= get_urljson(url)) != 0 ) //if ( (json= send_curl(url,(char *)"dailyfx")) != 0 ) { - std::cerr << "Forex rates:" << std::endl; + std::cerr << "Forex USD rates:" << std::endl; if ( (rates= jobj(json,(char *)"rates")) != 0 ) { for (i=0; i strvec) { int32_t i,errs=0; uint32_t price; char *symbol; - std::cerr << "Crypto binance rates:" << std::endl; + std::cerr << "Crypto binance BTC rates:" << std::endl; for (i=0; i Date: Mon, 8 Apr 2019 17:54:49 +0500 Subject: [PATCH 016/242] logging --- src/cc/prices.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index d1fc1aba9..bb77c8f30 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -322,7 +322,7 @@ int32_t prices_syntheticvec(std::vector &vec,std::vector return(-3); } depth -= need; - std::cerr << "opcode=" << opcode << " opstr=" << opstr << " depth-=need=" << depth << std::endl; + std::cerr << "opcode=" << opcode << " opstr=" << opstr << " need=" << need << " depth-=need=" << depth << std::endl; if ((opcode & KOMODO_PRICEMASK) != PRICES_WEIGHT) { // skip weight depth++; // increase operands count std::cerr << "depth++=" << depth << std::endl; From fce9b0581a813cfbff8c2f0bedef6fcc5817ba4a Mon Sep 17 00:00:00 2001 From: dimxy Date: Mon, 8 Apr 2019 18:24:36 +0500 Subject: [PATCH 017/242] logging --- src/cc/prices.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index bb77c8f30..6cdfb1e8a 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -352,7 +352,7 @@ int64_t prices_syntheticprice(std::vector vec,int32_t height,int32_t m ind = (opcode & (KOMODO_MAXPRICES-1)); // weight value switch ( opcode & KOMODO_PRICEMASK ) { - case 0: + case 0: // indices pricestack[depth] = 0; if ( komodo_priceget(pricedata,ind,height,1) > 0 ) { @@ -375,7 +375,7 @@ int64_t prices_syntheticprice(std::vector vec,int32_t height,int32_t m { depth--; price += pricestack[0] * ind; - den += ind; + den += ind; // acc weight values } else errcode = -2; break; case PRICES_MULT: @@ -444,6 +444,10 @@ int64_t prices_syntheticprice(std::vector vec,int32_t height,int32_t m if ( errcode != 0 ) break; } + + if (errcode != 0) + std::cerr << "prices_syntheticprice warning: errcode in switch=" << errcode << std::endl; + if (den == 0) { std::cerr << "prices_syntheticprice den==0 return err=-11" << std::endl; return(-11); From 9e4ef902f864660126371de3eb43c4938d4b0e35 Mon Sep 17 00:00:00 2001 From: dimxy Date: Mon, 8 Apr 2019 19:21:36 +0500 Subject: [PATCH 018/242] loggin --- src/cc/prices.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 6cdfb1e8a..e5922cfa7 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -349,7 +349,7 @@ int64_t prices_syntheticprice(std::vector vec,int32_t height,int32_t m for (i=0; i vec,int32_t height,int32_t m errcode = -1; depth++; break; + case PRICES_WEIGHT: // multiply by weight and consume top of stack by updating price if ( depth == 1 ) { @@ -378,6 +379,7 @@ int64_t prices_syntheticprice(std::vector vec,int32_t height,int32_t m den += ind; // acc weight values } else errcode = -2; break; + case PRICES_MULT: if ( depth >= 2 ) { @@ -386,6 +388,7 @@ int64_t prices_syntheticprice(std::vector vec,int32_t height,int32_t m pricestack[depth++] = (a * b) / SATOSHIDEN; } else errcode = -3; break; + case PRICES_DIV: if ( depth >= 2 ) { @@ -394,6 +397,7 @@ int64_t prices_syntheticprice(std::vector vec,int32_t height,int32_t m pricestack[depth++] = (a * SATOSHIDEN) / b; } else errcode = -4; break; + case PRICES_INV: if ( depth >= 1 ) { @@ -401,6 +405,7 @@ int64_t prices_syntheticprice(std::vector vec,int32_t height,int32_t m pricestack[depth++] = (SATOSHIDEN * SATOSHIDEN) / a; } else errcode = -5; break; + case PRICES_MDD: if ( depth >= 3 ) { @@ -410,6 +415,7 @@ int64_t prices_syntheticprice(std::vector vec,int32_t height,int32_t m pricestack[depth++] = (((a * SATOSHIDEN) / b) * SATOSHIDEN) / c; } else errcode = -6; break; + case PRICES_MMD: if ( depth >= 3 ) { @@ -419,6 +425,7 @@ int64_t prices_syntheticprice(std::vector vec,int32_t height,int32_t m pricestack[depth++] = (a * b) / c; } else errcode = -7; break; + case PRICES_MMM: if ( depth >= 3 ) { @@ -428,6 +435,7 @@ int64_t prices_syntheticprice(std::vector vec,int32_t height,int32_t m pricestack[depth++] = ((a * b) / SATOSHIDEN) * c; } else errcode = -8; break; + case PRICES_DDD: if ( depth >= 3 ) { @@ -437,6 +445,7 @@ int64_t prices_syntheticprice(std::vector vec,int32_t height,int32_t m pricestack[depth++] = (((((SATOSHIDEN * SATOSHIDEN) / a) * SATOSHIDEN) / b) * SATOSHIDEN) / c; } else errcode = -9; break; + default: errcode = -10; break; From 0c017ca582fc547fc4ef6beebe275c2dc0e67543 Mon Sep 17 00:00:00 2001 From: dimxy Date: Mon, 8 Apr 2019 23:38:37 +0500 Subject: [PATCH 019/242] loggin in correlation --- src/komodo_gateway.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/komodo_gateway.h b/src/komodo_gateway.h index c9e3d0470..1ae6440d3 100644 --- a/src/komodo_gateway.h +++ b/src/komodo_gateway.h @@ -2471,7 +2471,7 @@ int64_t komodo_pricecorrelated(uint64_t seed,int32_t ind,uint32_t *rawprices,int if ( lowprice == refprice ) lowprice--; sum = 0; - //fprintf(stderr,"firsti.%d: ",i); + fprintf(stderr,"firsti.%d: ",i); for (j=0; j= PRICES_DAYWINDOW ) @@ -2483,14 +2483,14 @@ int64_t komodo_pricecorrelated(uint64_t seed,int32_t ind,uint32_t *rawprices,int } if ( price >= lowprice && price <= highprice ) { - //fprintf(stderr,"%.1f ",(double)price/10000); + fprintf(stderr,"%.1f ",(double)price/10000); sum += price; correlation++; if ( correlation > (PRICES_DAYWINDOW>>1) ) { if ( nonzprices == 0 ) return(refprice * mult); - //fprintf(stderr,"-> %.4f\n",(double)sum*mult/correlation); + fprintf(stderr,"-> %.4f\n",(double)sum*mult/correlation); //return(sum*mult/correlation); n = 0; i = (iter + seed) % PRICES_DAYWINDOW; @@ -2508,12 +2508,12 @@ int64_t komodo_pricecorrelated(uint64_t seed,int32_t ind,uint32_t *rawprices,int else { nonzprices[i] = price; - //fprintf(stderr,"(%d %u) ",i,rawprices[i*rawskip]); + fprintf(stderr,"(%d %u) ",i,rawprices[i*rawskip]); n++; } } } - //fprintf(stderr,"ind.%d iter.%d j.%d i.%d n.%d correlation.%d ref %llu -> %llu\n",ind,iter,j,i,n,correlation,(long long)refprice,(long long)sum/correlation); + fprintf(stderr,"ind.%d iter.%d j.%d i.%d n.%d correlation.%d ref %llu -> %llu\n",ind,iter,j,i,n,correlation,(long long)refprice,(long long)sum/correlation); if ( n != correlation ) return(-1); sum = den = n = 0; @@ -2521,7 +2521,7 @@ int64_t komodo_pricecorrelated(uint64_t seed,int32_t ind,uint32_t *rawprices,int if ( nonzprices[i] != 0 ) break; firstprice = nonzprices[i]; - //fprintf(stderr,"firsti.%d: ",i); + fprintf(stderr,"firsti.%d: ",i); for (i=0; i %.8f\n",(long long)firstprice,((double)(sum*mult) / den) / COIN); + std::cerr << "sum=" << sum << " mul=" << mul << " den=" << den << std::endl; + fprintf(stderr,"firstprice.%llu weighted -> %.8f\n",(long long)firstprice,((double)(sum*mult) / den) / COIN); return((sum * mult) / den); } } From e92c6c4c1bfc10a3971ea4ef39cfe57ed61708d6 Mon Sep 17 00:00:00 2001 From: dimxy Date: Mon, 8 Apr 2019 23:42:17 +0500 Subject: [PATCH 020/242] mult --- src/komodo_gateway.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/komodo_gateway.h b/src/komodo_gateway.h index 1ae6440d3..a18723338 100644 --- a/src/komodo_gateway.h +++ b/src/komodo_gateway.h @@ -2536,7 +2536,7 @@ int64_t komodo_pricecorrelated(uint64_t seed,int32_t ind,uint32_t *rawprices,int fprintf(stderr,"seed.%llu n.%d vs correlation.%d sum %llu, den %llu\n",(long long)seed,n,correlation,(long long)sum,(long long)den); return(-1); } - std::cerr << "sum=" << sum << " mul=" << mul << " den=" << den << std::endl; + std::cerr << "sum=" << sum << " mult=" << mult << " den=" << den << std::endl; fprintf(stderr,"firstprice.%llu weighted -> %.8f\n",(long long)firstprice,((double)(sum*mult) / den) / COIN); return((sum * mult) / den); } From dc1257a85db65510ffa782e2744a773421bb73c2 Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 9 Apr 2019 01:00:37 +0500 Subject: [PATCH 021/242] changed to SplitStr --- src/util.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/util.h b/src/util.h index dc421092a..9cdbabf70 100644 --- a/src/util.h +++ b/src/util.h @@ -287,6 +287,8 @@ template void TraceThread(const char* name, Callable func) } } +void SplitStr(const std::string& strVal, std::vector &outVals); + #define KOMODO_ASSETCHAIN_MAXLEN 65 From dee17205d2f9cffd63b5f633201473f49fb53d56 Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 9 Apr 2019 12:40:44 +0500 Subject: [PATCH 022/242] SplitStr add support for comma and space delims --- src/util.cpp | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/util.cpp b/src/util.cpp index 980d82ac9..e1d37b4a9 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -394,27 +394,25 @@ void ParseParameters(int argc, const char* const argv[]) } } +// split string using by space or comma as delimiter char void SplitStr(const std::string& strVal, std::vector &outVals) { stringstream ss(strVal); - std::string str; - while ( ss.peek() == ' ' ) - ss.ignore(); - - while ( ss >> str ) - { - if ( str.size() == 0 ) - continue; - if ( str[str.size()-1] == ',' ) - str.resize(str.size()-1); - outVals.push_back(str); - while ( ss.peek() == ' ' ) - ss.ignore(); - if ( ss.peek() == ',' ) - ss.ignore(); - while ( ss.peek() == ' ' ) + while (true) { + int c; + std::string str; + + while (std::isspace(ss.peek())) ss.ignore(); + + while (!ss.eofbit && !std::isspace(c = ss.get() && c != ',')) + str += c; + + if (!str.empty()) + outVals.push_back(str); + else + break; } } From e85fbb10c9d39e7b8b96afd80227979d1c7c3f62 Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 9 Apr 2019 12:48:41 +0500 Subject: [PATCH 023/242] corr SplitStr --- src/util.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util.cpp b/src/util.cpp index e1d37b4a9..163e4aad3 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -406,7 +406,7 @@ void SplitStr(const std::string& strVal, std::vector &outVals) while (std::isspace(ss.peek())) ss.ignore(); - while (!ss.eofbit && !std::isspace(c = ss.get() && c != ',')) + while (!ss.eofbit && !std::isspace(c = ss.get()) && c != ',') str += c; if (!str.empty()) From 2f24cf602f4410ce67416bfa57075a8d279cfe61 Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 9 Apr 2019 12:58:55 +0500 Subject: [PATCH 024/242] corr SplitStr --- src/util.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util.cpp b/src/util.cpp index 163e4aad3..7d0b9cc3d 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -406,7 +406,7 @@ void SplitStr(const std::string& strVal, std::vector &outVals) while (std::isspace(ss.peek())) ss.ignore(); - while (!ss.eofbit && !std::isspace(c = ss.get()) && c != ',') + while (!ss.eof() && !std::isspace(c = ss.get()) && c != ',') str += c; if (!str.empty()) From 8231a83db8f3603d2155760829e9c4591706405e Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 9 Apr 2019 13:28:02 +0500 Subject: [PATCH 025/242] corr eof state SplitStr --- src/util.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/util.cpp b/src/util.cpp index 7d0b9cc3d..fe28acf75 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -399,20 +399,18 @@ void SplitStr(const std::string& strVal, std::vector &outVals) { stringstream ss(strVal); - while (true) { + while (!ss.eof()) { int c; std::string str; while (std::isspace(ss.peek())) ss.ignore(); - while (!ss.eof() && !std::isspace(c = ss.get()) && c != ',') + while ((c = ss.get()) != EOF && !std::isspace(c = ss.get()) && c != ',') str += c; if (!str.empty()) outVals.push_back(str); - else - break; } } From 124983720d06ecdf194d7cffb2feea5097021af5 Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 9 Apr 2019 13:33:28 +0500 Subject: [PATCH 026/242] corr SplitStr c --- src/util.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util.cpp b/src/util.cpp index fe28acf75..70f638f93 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -406,7 +406,7 @@ void SplitStr(const std::string& strVal, std::vector &outVals) while (std::isspace(ss.peek())) ss.ignore(); - while ((c = ss.get()) != EOF && !std::isspace(c = ss.get()) && c != ',') + while ((c = ss.get()) != EOF && !std::isspace(c) && c != ',') str += c; if (!str.empty()) From 78a9a071067da35eae46bae077ab5dcd52fe25f9 Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 9 Apr 2019 14:13:14 +0500 Subject: [PATCH 027/242] commented logging --- src/util.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util.cpp b/src/util.cpp index 70f638f93..1aa079085 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -394,7 +394,7 @@ void ParseParameters(int argc, const char* const argv[]) } } -// split string using by space or comma as delimiter char +// split string using by space or comma as a delimiter char void SplitStr(const std::string& strVal, std::vector &outVals) { stringstream ss(strVal); From a3da9aa68ca4f49b7d2542123fdd5dbb2ae46d6b Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 9 Apr 2019 14:19:17 +0500 Subject: [PATCH 028/242] more logging commented out --- src/komodo_gateway.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/komodo_gateway.h b/src/komodo_gateway.h index a18723338..3f1d5ec5e 100644 --- a/src/komodo_gateway.h +++ b/src/komodo_gateway.h @@ -2483,7 +2483,7 @@ int64_t komodo_pricecorrelated(uint64_t seed,int32_t ind,uint32_t *rawprices,int } if ( price >= lowprice && price <= highprice ) { - fprintf(stderr,"%.1f ",(double)price/10000); + //fprintf(stderr,"%.1f ",(double)price/10000); sum += price; correlation++; if ( correlation > (PRICES_DAYWINDOW>>1) ) @@ -2521,7 +2521,7 @@ int64_t komodo_pricecorrelated(uint64_t seed,int32_t ind,uint32_t *rawprices,int if ( nonzprices[i] != 0 ) break; firstprice = nonzprices[i]; - fprintf(stderr,"firsti.%d: ",i); + //fprintf(stderr,"firsti.%d: ",i); for (i=0; i Date: Tue, 9 Apr 2019 14:37:31 +0500 Subject: [PATCH 029/242] more logging --- src/cc/prices.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index e5922cfa7..0a4ce90ae 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -469,6 +469,7 @@ int64_t prices_syntheticprice(std::vector vec,int32_t height,int32_t m std::cerr << "prices_syntheticprice err=" << errcode << std::endl; return(errcode); } + std::cerr << "prices_syntheticprice price=" << price << " den=" << den << std::endl; return(price / den); } From ca97519ccda161e30d8efcca3852da79eb1e4bde Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 9 Apr 2019 18:35:53 +0500 Subject: [PATCH 030/242] loggin --- src/cc/prices.cpp | 54 ++++++++++++++++++++++++++++++++++------------- src/util.h | 1 + 2 files changed, 40 insertions(+), 15 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 0a4ce90ae..058bd314d 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -344,18 +344,25 @@ int32_t prices_syntheticvec(std::vector &vec,std::vector // calculate price for synthetic expression int64_t prices_syntheticprice(std::vector vec,int32_t height,int32_t minmax,int16_t leverage) { - int32_t i,ind,errcode,depth,retval = -1; uint16_t opcode; int64_t pricedata[PRICES_MAXDATAPOINTS],pricestack[4],price,den,a,b,c; + int32_t i,value,errcode,depth,retval = -1; + uint16_t opcode; + int64_t *pricedata,pricestack[4],price,den,a,b,c; + + pricedata = (int64_t *)calloc(sizeof(*pricedata)*3,1 + PRICES_DAYWINDOW*2 + PRICES_SMOOTHWIDTH); price = den = depth = errcode = 0; + for (i=0; i= amount+4*txfee ) + if ( AddNormalinputs(mtx,mypk,amount+5*txfee,64) >= amount+5*txfee ) { betamount = (amount * 199) / 200; + mtx.vout.push_back(CTxOut(txfee, CScript() << std::vector(pricespk.begin(), pricespk.end()))); // marker mtx.vout.push_back(MakeCC1vout(cp->evalcode,txfee,mypk)); // baton for total funding mtx.vout.push_back(MakeCC1vout(cp->evalcode,(amount-betamount)+2*txfee,pricespk)); mtx.vout.push_back(MakeCC1of2vout(cp->evalcode,betamount,pricespk,mypk)); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 96e201bc3..a5ff4fdc4 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -6931,7 +6931,7 @@ UniValue priceslist(const UniValue& params, bool fHelp) UniValue pricesinfo(const UniValue& params, bool fHelp) { uint256 bettxid; int32_t height; - if ( fHelp || params.size() != 2 ) + if ( fHelp || params.size() != 1 ) throw runtime_error("pricesinfo fundingtxid\n"); if ( ensure_CCrequirements(EVAL_PRICES) < 0 ) throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); From 7c4b7eb7d4c3f82c29fd54bbbe53b6a8b26173ae Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 9 Apr 2019 21:13:48 +0500 Subject: [PATCH 036/242] corr marker --- src/cc/prices.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 0e7b06197..fe9d47a89 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -567,7 +567,7 @@ UniValue PricesBet(uint64_t txfee,int64_t amount,int16_t leverage,std::vector= amount+5*txfee ) { betamount = (amount * 199) / 200; - mtx.vout.push_back(CTxOut(txfee, CScript() << std::vector(pricespk.begin(), pricespk.end()))); // marker + mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(HexStr(pricespk)))); // marker mtx.vout.push_back(MakeCC1vout(cp->evalcode,txfee,mypk)); // baton for total funding mtx.vout.push_back(MakeCC1vout(cp->evalcode,(amount-betamount)+2*txfee,pricespk)); mtx.vout.push_back(MakeCC1of2vout(cp->evalcode,betamount,pricespk,mypk)); From e6474a62af89e7a4a02c11b8e8e44f100832c5b6 Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 9 Apr 2019 21:26:07 +0500 Subject: [PATCH 037/242] corr marker --- src/cc/prices.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index fe9d47a89..3d4603c7a 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -567,7 +567,7 @@ UniValue PricesBet(uint64_t txfee,int64_t amount,int16_t leverage,std::vector= amount+5*txfee ) { betamount = (amount * 199) / 200; - mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(HexStr(pricespk)))); // marker + mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(HexStr(pricespk)) << OP_CHECKSIG)); // marker mtx.vout.push_back(MakeCC1vout(cp->evalcode,txfee,mypk)); // baton for total funding mtx.vout.push_back(MakeCC1vout(cp->evalcode,(amount-betamount)+2*txfee,pricespk)); mtx.vout.push_back(MakeCC1of2vout(cp->evalcode,betamount,pricespk,mypk)); From 0aba8374f1e7096ac672bb0e0d50ae185e40bc94 Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 9 Apr 2019 21:40:23 +0500 Subject: [PATCH 038/242] rpc height added --- src/wallet/rpcwallet.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index a5ff4fdc4..05283c0b9 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -6931,8 +6931,8 @@ UniValue priceslist(const UniValue& params, bool fHelp) UniValue pricesinfo(const UniValue& params, bool fHelp) { uint256 bettxid; int32_t height; - if ( fHelp || params.size() != 1 ) - throw runtime_error("pricesinfo fundingtxid\n"); + if ( fHelp || params.size() != 2 ) + throw runtime_error("pricesinfo fundingtxid height\n"); if ( ensure_CCrequirements(EVAL_PRICES) < 0 ) throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); bettxid = Parseuint256((char *)params[0].get_str().c_str()); From 2e576d596749e1473c2fdb1546578d12c0a8530c Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 9 Apr 2019 22:28:45 +0500 Subject: [PATCH 039/242] costbasis == 0 --- src/cc/prices.cpp | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 3d4603c7a..a8542df6b 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -509,7 +509,7 @@ int64_t prices_syntheticprofits(int64_t &costbasis,int32_t firstheight,int32_t h else if ( leverage < 0 && (costbasis == 0 || price < costbasis) ) costbasis = price; } - profits = ((price * SATOSHIDEN) / costbasis) - SATOSHIDEN; + profits = costbasis > 0 ? ((price * SATOSHIDEN) / costbasis) - SATOSHIDEN : 0; profits *= leverage * positionsize; return(positionsize + addedbets + profits); } @@ -747,18 +747,29 @@ UniValue PricesCashout(uint64_t txfee,uint256 bettxid) UniValue PricesInfo(uint256 bettxid,int32_t refheight) { - UniValue result(UniValue::VOBJ); CTransaction bettx; uint256 hashBlock,batontxid,tokenid; int64_t myfee,ignore,positionsize=0,addedbets=0,firstprice=0,profits=0,costbasis=0; int32_t i,firstheight=0,height,numvouts; int16_t leverage=0; std::vector vec; CPubKey pk,mypk,pricespk; std::string rawtx; - if ( myGetTransaction(bettxid,bettx,hashBlock) != 0 && (numvouts= bettx.vout.size()) > 3 ) + UniValue result(UniValue::VOBJ); + CTransaction bettx; + uint256 hashBlock,batontxid,tokenid; + int64_t myfee,ignore=0,positionsize=0,addedbets=0,firstprice=0,profits=0,costbasis=0; + int32_t i,firstheight=0,height,numvouts; + int16_t leverage=0; + std::vector vec; + CPubKey pk,mypk,pricespk; + std::string rawtx; + + if( myGetTransaction(bettxid,bettx,hashBlock) != 0 && (numvouts= bettx.vout.size()) > 3 ) { - if ( prices_betopretdecode(bettx.vout[numvouts-1].scriptPubKey,pk,firstheight,positionsize,leverage,firstprice,vec,tokenid) == 'B' ) + if( prices_betopretdecode(bettx.vout[numvouts-1].scriptPubKey,pk,firstheight,positionsize,leverage,firstprice,vec,tokenid) == 'B' ) { costbasis = prices_costbasis(bettx); addedbets = prices_batontxid(batontxid,bettx,bettxid); - if ( (profits= prices_syntheticprofits(ignore,firstheight,refheight,leverage,vec,positionsize,addedbets)) < 0 ) + if ((profits= prices_syntheticprofits(ignore,firstheight,refheight,leverage,vec,positionsize,addedbets)) < 0) { result.push_back(Pair("rekt",1)); result.push_back(Pair("rektfee",(positionsize + addedbets) / 500)); - } else result.push_back(Pair("rekt",0)); + } + else + result.push_back(Pair("rekt",0)); result.push_back(Pair("batontxid",batontxid.GetHex())); prices_betjson(result,profits,costbasis,positionsize,addedbets,leverage,firstheight,firstprice); result.push_back(Pair("height",(int64_t)refheight)); From cf059070245b7d621ef5d5889b939a0dcdf4d226 Mon Sep 17 00:00:00 2001 From: dimxy Date: Thu, 11 Apr 2019 19:09:46 +0500 Subject: [PATCH 040/242] pricessetcostbasis added --- src/cc/CCPrices.h | 2 +- src/cc/prices.cpp | 57 +++++++++++++++++++++++++++------------------- src/rpc/server.cpp | 1 + src/rpc/server.h | 1 + 4 files changed, 37 insertions(+), 24 deletions(-) diff --git a/src/cc/CCPrices.h b/src/cc/CCPrices.h index f88a5fe55..a32264a88 100644 --- a/src/cc/CCPrices.h +++ b/src/cc/CCPrices.h @@ -40,7 +40,7 @@ bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx // CCcustom UniValue PricesBet(uint64_t txfee,int64_t amount,int16_t leverage,std::vector synthetic); UniValue PricesAddFunding(uint64_t txfee,uint256 bettxid,int64_t amount); -UniValue PricesSetcostbasis(uint64_t txfee,uint256 bettxid); +UniValue PricesSetcostbasis(int64_t txfee,uint256 bettxid); UniValue PricesRekt(uint64_t txfee,uint256 bettxid,int32_t rektheight); UniValue PricesCashout(uint64_t txfee,uint256 bettxid); UniValue PricesInfo(uint256 bettxid,int32_t refheight); diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index a8542df6b..525a42cda 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -362,12 +362,13 @@ int64_t prices_syntheticprice(std::vector vec,int32_t height,int32_t m pricestack[depth] = 0; if ( prices_extract(pricedata,height,1,value) == 0 ) { - // push to the prices stack + // push price to the prices stack if ( minmax == 0 ) - pricestack[depth] = pricedata[2]; + pricestack[depth] = pricedata[2]; // use smoothed value if we are over 24h else { - if ( leverage > 0 ) + // if we are within 24h use min or max price + if ( leverage > 0 ) pricestack[depth] = (pricedata[1] > pricedata[2]) ? pricedata[1] : pricedata[2]; // MAX else pricestack[depth] = (pricedata[1] < pricedata[2]) ? pricedata[1] : pricedata[2]; // MIN @@ -495,20 +496,29 @@ int64_t prices_syntheticprice(std::vector vec,int32_t height,int32_t m int64_t prices_syntheticprofits(int64_t &costbasis,int32_t firstheight,int32_t height,int16_t leverage,std::vector vec,int64_t positionsize,int64_t addedbets) { - int64_t price,profits = 0; int32_t minmax; - minmax = (height > firstheight+PRICES_DAYWINDOW); - if ( (price= prices_syntheticprice(vec,height,minmax,leverage)) < 0 ) - { - fprintf(stderr,"unexpected zero synthetic price at height.%d\n",height); - return(0); - } - if ( minmax != 0 ) - { - if ( leverage > 0 && price > costbasis ) - costbasis = price; - else if ( leverage < 0 && (costbasis == 0 || price < costbasis) ) - costbasis = price; + int64_t price, profits = 0; + + if (firstheight >= 0) { // >=0 means request to find costbase + int32_t minmax = (height < firstheight + PRICES_DAYWINDOW); // use minmax value if we are within 24h + + if ((price = prices_syntheticprice(vec, height, minmax, leverage)) < 0) + { + fprintf(stderr, "unexpected zero synthetic price at height.%d\n", height); + return(0); + } + if (minmax /*!= 0*/) // if we are within day window, use bigger or lesser value + { + if (leverage > 0 && price > costbasis) + costbasis = price; // set costbasis + else if (leverage < 0 && (costbasis == 0 || price < costbasis)) + costbasis = price; + // else -> use the previous value + } + else + costbasis = price; //?? } + // else < 0 then use the passed costbase + profits = costbasis > 0 ? ((price * SATOSHIDEN) / costbasis) - SATOSHIDEN : 0; profits *= leverage * positionsize; return(positionsize + addedbets + profits); @@ -567,10 +577,10 @@ UniValue PricesBet(uint64_t txfee,int64_t amount,int16_t leverage,std::vector= amount+5*txfee ) { betamount = (amount * 199) / 200; - mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(HexStr(pricespk)) << OP_CHECKSIG)); // marker mtx.vout.push_back(MakeCC1vout(cp->evalcode,txfee,mypk)); // baton for total funding mtx.vout.push_back(MakeCC1vout(cp->evalcode,(amount-betamount)+2*txfee,pricespk)); mtx.vout.push_back(MakeCC1of2vout(cp->evalcode,betamount,pricespk,mypk)); + mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(HexStr(pricespk)) << OP_CHECKSIG)); // marker rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,prices_betopret(mypk,nextheight-1,amount,leverage,firstprice,vec,zeroid)); return(prices_rawtxresult(result,rawtx,0)); } @@ -612,7 +622,7 @@ UniValue PricesAddFunding(uint64_t txfee,uint256 bettxid,int64_t amount) return(result); } -UniValue PricesSetcostbasis(uint64_t txfee,uint256 bettxid) +UniValue PricesSetcostbasis(int64_t txfee,uint256 bettxid) { int32_t nextheight = komodo_nextheight(); CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(),nextheight); UniValue result(UniValue::VOBJ); @@ -626,12 +636,12 @@ UniValue PricesSetcostbasis(uint64_t txfee,uint256 bettxid) { if ( prices_betopretdecode(bettx.vout[numvouts-1].scriptPubKey,pk,firstheight,positionsize,leverage,firstprice,vec,tokenid) == 'B' ) { - addedbets = prices_batontxid(batontxid,bettx,bettxid); + addedbets = prices_batontxid(batontxid, bettx, bettxid); mtx.vin.push_back(CTxIn(bettxid,1,CScript())); - for (i=0; ievalcode,bettx.vout[1].nValue-myfee-txfee,pricespk)); @@ -669,7 +680,7 @@ UniValue PricesRekt(uint64_t txfee,uint256 bettxid,int32_t rektheight) { costbasis = prices_costbasis(bettx); addedbets = prices_batontxid(batontxid,bettx,bettxid); - if ( (profits= prices_syntheticprofits(ignore,firstheight,rektheight,leverage,vec,positionsize,addedbets)) < 0 ) + if ( (profits= prices_syntheticprofits(costbasis /*ignore*/, -1, rektheight, leverage, vec, positionsize, addedbets)) < 0 ) { myfee = (positionsize + addedbets) / 500; } diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 581676763..d132dabd5 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -465,6 +465,7 @@ static const CRPCCommand vRPCCommands[] = { "prices", "priceslist", &priceslist, true }, { "prices", "pricesinfo", &pricesinfo, true }, { "prices", "pricesbet", &pricesbet, true }, + { "prices", "pricesbet", &pricessetcostbasis, true }, // Pegs { "pegs", "pegsaddress", &pegsaddress, true }, diff --git a/src/rpc/server.h b/src/rpc/server.h index 3df78de9f..94d16ecdc 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -498,6 +498,7 @@ extern UniValue paxwithdraw(const UniValue& params, bool fHelp); extern UniValue prices(const UniValue& params, bool fHelp); extern UniValue pricesbet(const UniValue& params, bool fHelp); +extern UniValue pricessetcostbasis(const UniValue& params, bool fHelp); // test rpc: extern UniValue test_ac(const UniValue& params, bool fHelp); From 3cc12f4a023c8fb62c004a11be60b371bc9674aa Mon Sep 17 00:00:00 2001 From: dimxy Date: Thu, 11 Apr 2019 19:11:18 +0500 Subject: [PATCH 041/242] pricessetcostbasis + --- src/rpc/server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index d132dabd5..c2cead4a4 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -465,7 +465,7 @@ static const CRPCCommand vRPCCommands[] = { "prices", "priceslist", &priceslist, true }, { "prices", "pricesinfo", &pricesinfo, true }, { "prices", "pricesbet", &pricesbet, true }, - { "prices", "pricesbet", &pricessetcostbasis, true }, + { "prices", "pricesbetsetcostbasis", &pricessetcostbasis, true }, // Pegs { "pegs", "pegsaddress", &pegsaddress, true }, From f0c14e77d5f5c20775f9ff8bb155cdca31dc7a69 Mon Sep 17 00:00:00 2001 From: dimxy Date: Sat, 13 Apr 2019 20:45:42 +0500 Subject: [PATCH 042/242] rpc rekt cashout logging, formatting --- src/cc/prices.cpp | 420 ++++++++++++++++++++------------------------- src/rpc/server.cpp | 4 +- src/rpc/server.h | 3 + 3 files changed, 195 insertions(+), 232 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 525a42cda..ec099e7e1 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -22,127 +22,25 @@ CBOPRET creates trustless oracles, which can be used for making a synthetic cash 0.5% fee based on betamount, NOT leveraged betamount!! 0.1% collected by price basis determinant 0.2% collected by rekt tx - - At the simplest, prices CC allows to make leveraged cash settled bets on long and short BTCUSD: - BTCUSD, 1 with positive leverage parameter up to 777 - BTCUSD, 1 with negative leverage parameter up to -777 - These specific limits of 0.5%, 0.1%, 0.2%, 777 should be able to be changed based on #define + 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 - Another configuration is to send the 0.4% (or 0.2%) fees to a fee collection address (this is not currently implemented, but would be needed for systems that dont use -ac_perc to collect a global override) + PricesRekt -> bettxid height -> 0.1% to miner, rest to global CC - The definition of the synthetic instrument that is being tracked is actually defined with a forth type of syntax and is quite flexible to allow unlimited combinations and weights, but that is an independent aspect and will be covered later. + PricesClose -> bettxid returns (synthetic value + amount) - Let us discuss the simplest synthetic case of a long or short of BTCUSD (or any other direct pricepoint from the trustless oracle). If you look at the charts, you will see the blue line that is direct from the miners (and therefore cant be directly used). The orange line is the 51% correlated price that is deterministically random selected from the prior 24 hours. And finally the green line which is simply the average value from the priot 24 hours. - - We will assume that the orange and green prices are able to be deterministically calculated from the raw coinbase data (blue). The prices rpc is currently working reasonably well and appears to return deterministic prices, however for use in the prices CC, it is often needed to find just a single data point. To that effect there is the temporary function prices_syntheticprice, which uses a bruteforce and totally inefficient way to calculate the correlated and smoothed prices. This inefficient process will need to be changed to a permanent storage of correlated and smoothed prices for each trustless oracle that is updated each block. This will then allow to directly lookup each value for any of the trustless prices. Such speed will indeed be needed to scale up usage of a REKT chain. - - Since the mined prices can be manipulated by any miner, combined with the +/-1% tolerance, it would be possible for an external miner to obtain a large hashrate and skew the price +1%, then to -1% to create a 2% price difference, which under high leverage might be able to generate a large profit. - - To avoid this precisely controllable biasing, the 51% correlation of past day is used (orange), which makes the price jump around a lot. The green line that sums the prior day is needed to remove this jitter back to the average value. However, this creates a 1.5 day delay to the price movement of the smoothed price compared to the current price. What this means is that if we want to use the green line to settle prices automatically, a trivial way to make money is to bet in the direct that the mined prices are relative to the smoothed prices. Given 1.5 day head start, it wont be any mystery which direction the smoothed line will move in the next 24 hours. - - So this makes the smoothed price unusable for settling the bets with. However, we cant use the correlated price either, as it would also allow to make bets when the correlated price picked a significantly lower/higher price than the raw price. The solution is to have a floating basis for the costbasis of the bet. In order to allow finding the right costbasis, for long bets the maximum price between the correlated and smoothed price is needed over the first day after the bet. For short bets, the minimum price is needed. - - What this means is that the actual starting price for a bet wont be known for sure when the bet is made, but if the price is relatively stable, there wont be much of a change. If there is a lot of recent volatility, then the starting price will have a high variability. In order to calculate the costbasis, it currently requires many calculations to find the MAX (or MIN) for the first day. Even when this is made to be a lookup, it still requires to issue a transaction to change the state of a bet from a "starting" state to a "in effect" state and this state change is indicated by whether the bettx vout that contains the costbasis utxo is spent or not. - - Once a bet goes into effect, then block by block, it is checked by the decentralized set of rekt scanners if it is rekt or not, in this case for double the reward for calculating the cost basis. This fully decentralized mechanism ensures that some node will decide to collect the free money and ensures that the bankroll is growing. To miss a rekt bet and not close it out when it can be is to allow it to survive for another block, which can change it profitability from negative to positive. - - Which comes to how profits are calculated. Once the costbasis is locked, then the profit calculation can be made based on the ratio between the costbasis and the current price, multiplied by the leverage. So, if a long position gains 10% at a 10x leverage, then approximately the entire bet amount will be made, ie. a double. Similarily with a short position, a 10% drop in price at 10x leverage will double the bet amount. Since it takes a full day to establish the costbasis, it is not possible to allow changing the costbasis for an existing bet, however it is possible to add funds so that it is less likely to be rekt. The sum of the initial bet and all added funds must be greater than the loss at every block to prevent a position from being rekt. To make it simple to calculate the amount of funds added, another bettx vout is used as a baton. Techniques similar to rogue CC to find where the bettx vout was spent and looking at each such transaction to find the total funds added can be used. - - The once that makes the bet is able to add funds or cashout at any block, as long as it isnt rekt. If it is rekt, the bettor is able to collect the rekt fee, so at least that is some consolation, but it is advised to increase the total funding to avoid being rekt. On a cashout all the funds that were bet adjusted by the profits can be collected. - - Hopefully the above description makes it clear what the following rpc calls should be doing: - - UniValue PricesBet(uint64_t txfee,int64_t amount,int16_t leverage,std::vector synthetic) - 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 - - UniValue PricesAddFunding(uint64_t txfee,uint256 bettxid,int64_t amount) - add funding to an existing bet, doesnt change the profit calcs but does make the bet less likely to be rekt - - UniValue PricesSetcostbasis(uint64_t txfee,uint256 bettxid) - in the first day from the bet, the costbasis can (and usually does) change based on the MAX(correlated,smoothed) for long and MIN() for shorts - to calculate this requires a bit of work, so whatever node is first to get the proper calculation confirmed, gets a 0.1% costbasis fee - - UniValue PricesRekt(uint64_t txfee,uint256 bettxid,int32_t rektheight) - similarily, any node can submit a rekt tx and cash in on 0.2% fee if their claim is confirmed - - UniValue PricesCashout(uint64_t txfee,uint256 bettxid) - only the actually creator of bet is able to cashout and only if it isnt rekt at that moment - - UniValue PricesInfo(uint256 bettxid,int32_t refheight) - all relevant info about a bet - - UniValue PricesList() - a list of all pending and completed bets in different lists + PricesList -> all bettxid -> list [bettxid, netgain] - Appendix Synthetic position definition language: - - Let us start from the familiar BTCUSD nomenclature. this is similar (identical) to forex EURUSD and the equivalent. Notice the price needs two things as it is actually a ratio, ie. BTCUSD is how many USD does 1 BTC get converted to. It can be thought of as the value of BTC/USD, in other words a ratio. - - The value of BTC alone, or USD alone, it is actually quite an abstract issue and it can only be approximated. Specific ways of how to do this can be discussed later, for now it is only important to understand that all prices are actually ratios. - - And these ratios work as normal algebra does. So a/b * b/c == a/c! You can try this out with BTCUSD and USDJPY -> BTC/USD * USD/JPY -> BTC/JPY or the BTCJPY price - - division is the reciprocal, so BTCUSD reciprocated is USDBTC - - Without getting into all the possible combinations of things, let us first understand what the language allows. It uses a stack based language, where individual tokens update the state. The final state needs to have an empty stack and it will have a calculated price. - - The most important is pushing a specific price onto the stack. All the correlated and smoothed prices are normalized so it has each integer unit equal to 0.00000001, amounts above 100 million are above one, amounts less are below one. 100 million is the unit constant. - - In the prices CC synthetic definition language, the symbol that is returned pushes the adjusted price to the stack. The adjustment is selecting between the correlated and smoothed if within a day from the bet creation, or just the smoothed if after a day. You can have a maximum depth of 3, any more than that and it should return an error. - - This means there are operations that are possible on 1, 2 and 3 symbols. For 1 symbol, it is easy, the only direct operation is the inverse, which is represented by "!". All items in the language are separated by "," - - "BTCUSD, !" - - The above is the inverse or USD/BTC, which is another way to short BTCUSD. It is also possible to short the entire synthetic with a negative leverage. The exact results of a -1 leverage and inverse, might not be exact due to the math involved with calculating the profit, but it should generally be similar. - - For two symbols, there is a bit more we can do, namely multiply and divide, combined with inverting, however to simplify the language any inverting is required to be done by the ordering of the symbols and usage of multiply or divide. multiply is "*" and divide is "/" the top of the stack (last to be pushed) is the divisor, the one right before the divisor is the numerator. - - "BTCUSD, USDJPY, *" <- That will create a BTCJPY synthetic - - "BTCEUR, BTCUSD, /" <- That will create a USDEUR synthetic - - If you experiment around with this, you will see that given two symbols and the proper order and * or /, you can always create the synthetic that you want, assuming what you want is the cancelling out of the term in common with the two symbols and the resulting ratio is between the two unique terms. - */ - -// Now we get to the three symbol operations, which there are 4 of *//, **/, *** and /// - -/* - these four operators work on the top of the stack in left to right order as the syntax of the definition lists it, though it is even possible to have the value from an earlier computation on the top of the stack. Ultimately all three will be multiplied together, so a * in a spot means it us used without changing. A / means its inverse will be used. - - "KMDBTC, BTCUSD, USDJPY, ***" <- this would create a KMDJPY synthetic. The various location of the / to make an inverse is to orient the raw symbol into the right orientation as the pricefeed is only getting one orientation of the ratio. - - So now we have covered all ways to map 1, 2 and 3 values on the top of the stack. A value can be on the top of the stack directly from a symbol, or as the result of some 1, 2 or 3 symbol operation. With a maximum stack depth of 3, it might require some experimentation to get a very complex synthetic to compile. Alternately, a stack deeper than 3 might be the acceptable solution if there are a family of synthetics that need it. - - At this point, it is time to describe the weights. It turns out that all above examples are incomplete and the synthetic descriptions are all insufficient and should generate an error. The reason is that the actual synthetic price is the value of the accumulator, which adds up all the weighted prices. In order to assign a weight to a price value on the stack, you simply use a number that is less than 2048. - - What such a weight number does, is consume the top of the stack, which also must be at depth of 1 and adds it to the accumulator. This allows combining multiple different synthetics into a meta synthetic, like for an aggregated index that is weighted by marketcap, or whatever other type of ratio trade that is desired. - - "BTCUSD, 1000, ETHBTC, BTCUSD, *, 300" -> that creates a dual index of BTCUSD and ETHUSD with a 30% ETH weight - - all weight operations consumes the one and only stack element and adds its weight to the accumulator, using this a very large number of terms can be all added together. Using inverses, allows to get the short direction into the equation mixed with longs, but all terms must be positive. If you want to create a spread between two synthetics, you need to create two different synthetics and go long with one and short with another. - - "BTCUSD, 1" with leverage -2 and "KMDBTC, BTCUSD, *, 1" with leverage 1 this will setup a +KMDUSD -2 BTCUSD spread when the two are combined, and would be at breakeven when KMDUSD gains 2x more percentage wise than BTC does. anytime KMD gains more, will be positive, if the gains are less, would be negative. - - Believe it or not, the string to binary compiler for synthetic description and interpretation of it is less than 200 lines of code. - - todo: complete all the above, bet tokens, cross chain prices within cluster These specific limits of 0.5%, 0.1%, 0.2%, 777 should be able to be changed based on #define - - Another configuration is to send the 0.4% (or 0.2%) fees to a fee collection scriptPubKey (this is not currently implemented, but would be needed for systems that dont use -ac_perc to collect a global override) this requires adding new vouts - - Modification: in the event there is one price in the accumulator and one price on the stack at the end, then it is a (A - B) spread - - Monetizations should be sent to: RGsWqwFviaNJSbmgWi6338NL2tKkY7ZqKL - - */ - +*/ // helpers: @@ -240,7 +138,7 @@ int64_t AddPricesInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,char { int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector origpubkey; CTransaction vintx; int32_t vout,n = 0; std::vector > unspentOutputs; - SetCCunspents(unspentOutputs,destaddr,true); + SetCCunspents(unspentOutputs,destaddr); for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) { txid = it->first.txhash; @@ -494,19 +392,19 @@ int64_t prices_syntheticprice(std::vector vec,int32_t height,int32_t m return(price / den); } -int64_t prices_syntheticprofits(int64_t &costbasis,int32_t firstheight,int32_t height,int16_t leverage,std::vector vec,int64_t positionsize,int64_t addedbets) +int64_t prices_syntheticprofits(bool isCalcCostBasis, int64_t &costbasis,int32_t firstheight,int32_t height,int16_t leverage,std::vector vec,int64_t positionsize,int64_t addedbets) { int64_t price, profits = 0; - if (firstheight >= 0) { // >=0 means request to find costbase - int32_t minmax = (height < firstheight + PRICES_DAYWINDOW); // use minmax value if we are within 24h + int32_t minmax = (height < firstheight + PRICES_DAYWINDOW); // if we are within 24h then use min or max value - if ((price = prices_syntheticprice(vec, height, minmax, leverage)) < 0) - { - fprintf(stderr, "unexpected zero synthetic price at height.%d\n", height); - return(0); - } - if (minmax /*!= 0*/) // if we are within day window, use bigger or lesser value + if ((price = prices_syntheticprice(vec, height, minmax, leverage)) < 0) + { + fprintf(stderr, "unexpected zero synthetic price at height.%d\n", height); + return(0); + } + if (isCalcCostBasis) { + if (minmax) // if we are within day window, set costbasis to max or min value { if (leverage > 0 && price > costbasis) costbasis = price; // set costbasis @@ -514,10 +412,7 @@ int64_t prices_syntheticprofits(int64_t &costbasis,int32_t firstheight,int32_t h costbasis = price; // else -> use the previous value } - else - costbasis = price; //?? } - // else < 0 then use the passed costbase profits = costbasis > 0 ? ((price * SATOSHIDEN) / costbasis) - SATOSHIDEN : 0; profits *= leverage * positionsize; @@ -540,8 +435,29 @@ int64_t prices_costbasis(CTransaction bettx) int64_t costbasis = 0; // if vout1 is spent, follow and extract costbasis from opreturn //uint8_t prices_costbasisopretdecode(CScript scriptPubKey,uint256 &bettxid,CPubKey &pk,int32_t &height,int64_t &costbasis) + uint256 txidCostbasis; + int32_t vini; + int32_t height; + if (CCgetspenttxid(txidCostbasis, vini, height, bettx.GetHash(), 1) < 0) { + std::cerr << "prices_costbasis() no costbasis txid found" << std::endl; + return 0; + } - return(costbasis); + CTransaction txCostbasis; + uint256 hashBlock; + uint256 bettxid; + CPubKey pk; + bool isLoaded = false; + uint8_t funcId = 0; + + if ((isLoaded = myGetTransaction(txidCostbasis, txCostbasis, hashBlock)) && + txCostbasis.vout.size() > 0 && + (funcId = prices_costbasisopretdecode(txCostbasis.vout.back().scriptPubKey, bettxid, pk, height, costbasis)) != 0) { + return costbasis; + } + + std::cerr << "prices_costbasis() cannot load costbasis tx or decode opret" << " isLoaded=" << isLoaded << " funcId=" << funcId << std::endl; + return 0; } int64_t prices_batontxid(uint256 &batontxid,CTransaction bettx,uint256 bettxid) @@ -622,190 +538,232 @@ UniValue PricesAddFunding(uint64_t txfee,uint256 bettxid,int64_t amount) return(result); } -UniValue PricesSetcostbasis(int64_t txfee,uint256 bettxid) +UniValue PricesSetcostbasis(int64_t txfee, uint256 bettxid) { int32_t nextheight = komodo_nextheight(); - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(),nextheight); UniValue result(UniValue::VOBJ); - struct CCcontract_info *cp,C; CTransaction bettx; uint256 hashBlock,batontxid,tokenid; int64_t myfee,positionsize=0,addedbets,firstprice=0,profits=0,costbasis=0; int32_t i,firstheight=0,height,numvouts; int16_t leverage=0; std::vector vec; CPubKey pk,mypk,pricespk; std::string rawtx; - cp = CCinit(&C,EVAL_PRICES); - if ( txfee == 0 ) + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nextheight); + UniValue result(UniValue::VOBJ); + struct CCcontract_info *cp, C; CTransaction bettx; uint256 hashBlock, batontxid, tokenid; + int64_t myfee, positionsize = 0, addedbets, firstprice = 0, profits = 0, costbasis = 0; + int32_t i, firstheight = 0, height, numvouts; int16_t leverage = 0; + std::vector vec; + CPubKey pk, mypk, pricespk; std::string rawtx; + + cp = CCinit(&C, EVAL_PRICES); + if (txfee == 0) txfee = PRICES_TXFEE; + mypk = pubkey2pk(Mypubkey()); - pricespk = GetUnspendable(cp,0); - if ( myGetTransaction(bettxid,bettx,hashBlock) != 0 && (numvouts= bettx.vout.size()) > 3 ) + pricespk = GetUnspendable(cp, 0); + if (myGetTransaction(bettxid, bettx, hashBlock) != 0 && (numvouts = bettx.vout.size()) > 3) { - if ( prices_betopretdecode(bettx.vout[numvouts-1].scriptPubKey,pk,firstheight,positionsize,leverage,firstprice,vec,tokenid) == 'B' ) + if (prices_betopretdecode(bettx.vout[numvouts - 1].scriptPubKey, pk, firstheight, positionsize, leverage, firstprice, vec, tokenid) == 'B') { + if (nextheight < firstheight + PRICES_DAYWINDOW) { + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "cannot calculate costbasis yet")); + return(result); + } + addedbets = prices_batontxid(batontxid, bettx, bettxid); - mtx.vin.push_back(CTxIn(bettxid,1,CScript())); - for (i=0; ievalcode,bettx.vout[1].nValue-myfee-txfee,pricespk)); - rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,prices_costbasisopret(bettxid,mypk,firstheight+PRICES_DAYWINDOW-1,costbasis)); - return(prices_rawtxresult(result,rawtx,0)); + result.push_back(Pair("myfee", myfee)); + mtx.vout.push_back(CTxOut(myfee, CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); + mtx.vout.push_back(MakeCC1vout(cp->evalcode, bettx.vout[1].nValue - myfee - txfee, pricespk)); + rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_costbasisopret(bettxid, mypk, firstheight + PRICES_DAYWINDOW - 1, costbasis)); + return(prices_rawtxresult(result, rawtx, 0)); } } - result.push_back(Pair("result","error")); - result.push_back(Pair("error","cant find bettxid")); + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "cant find bettxid")); return(result); } -UniValue PricesRekt(uint64_t txfee,uint256 bettxid,int32_t rektheight) +UniValue PricesRekt(uint64_t txfee, uint256 bettxid, int32_t rektheight) { int32_t nextheight = komodo_nextheight(); - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(),nextheight); UniValue result(UniValue::VOBJ); - struct CCcontract_info *cp,C; CTransaction bettx; uint256 hashBlock,tokenid,batontxid; int64_t myfee=0,positionsize,addedbets,firstprice,profits,ignore,costbasis=0; int32_t firstheight,numvouts; int16_t leverage; std::vector vec; CPubKey pk,mypk,pricespk; std::string rawtx; - cp = CCinit(&C,EVAL_PRICES); - if ( txfee == 0 ) + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nextheight); UniValue result(UniValue::VOBJ); + struct CCcontract_info *cp, C; CTransaction bettx; uint256 hashBlock, tokenid, batontxid; int64_t myfee = 0, positionsize, addedbets, firstprice, profits, ignore, costbasis = 0; int32_t firstheight, numvouts; int16_t leverage; std::vector vec; CPubKey pk, mypk, pricespk; std::string rawtx; + cp = CCinit(&C, EVAL_PRICES); + if (txfee == 0) txfee = PRICES_TXFEE; mypk = pubkey2pk(Mypubkey()); - pricespk = GetUnspendable(cp,0); - if ( myGetTransaction(bettxid,bettx,hashBlock) != 0 && (numvouts= bettx.vout.size()) > 3 ) + pricespk = GetUnspendable(cp, 0); + if (myGetTransaction(bettxid, bettx, hashBlock) != 0 && (numvouts = bettx.vout.size()) > 3) { - if ( prices_betopretdecode(bettx.vout[numvouts-1].scriptPubKey,pk,firstheight,positionsize,leverage,firstprice,vec,tokenid) == 'B' ) + if (prices_betopretdecode(bettx.vout[numvouts - 1].scriptPubKey, pk, firstheight, positionsize, leverage, firstprice, vec, tokenid) == 'B') { costbasis = prices_costbasis(bettx); - addedbets = prices_batontxid(batontxid,bettx,bettxid); - if ( (profits= prices_syntheticprofits(costbasis /*ignore*/, -1, rektheight, leverage, vec, positionsize, addedbets)) < 0 ) + if (costbasis == 0) { + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "costbasis not defined yet")); + return(result); + } + + addedbets = prices_batontxid(batontxid, bettx, bettxid); + if ((profits = prices_syntheticprofits(false, costbasis /*ignore*/, firstheight, rektheight, leverage, vec, positionsize, addedbets)) < 0) { myfee = (positionsize + addedbets) / 500; } - prices_betjson(result,profits,costbasis,positionsize,addedbets,leverage,firstheight,firstprice); - if ( myfee != 0 ) + prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice); + if (myfee != 0) { - mtx.vin.push_back(CTxIn(bettxid,2,CScript())); - mtx.vout.push_back(CTxOut(myfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); - mtx.vout.push_back(MakeCC1vout(cp->evalcode,bettx.vout[2].nValue-myfee-txfee,pricespk)); - rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,prices_finalopret(bettxid,profits,rektheight,mypk,firstprice,costbasis,addedbets,positionsize,leverage)); - return(prices_rawtxresult(result,rawtx,0)); + mtx.vin.push_back(CTxIn(bettxid, 2, CScript())); + mtx.vout.push_back(CTxOut(myfee, CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); + mtx.vout.push_back(MakeCC1vout(cp->evalcode, bettx.vout[2].nValue - myfee - txfee, pricespk)); + rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_finalopret(bettxid, profits, rektheight, mypk, firstprice, costbasis, addedbets, positionsize, leverage)); + return(prices_rawtxresult(result, rawtx, 0)); } else { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","position not rekt")); + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "position not rekt")); return(result); } } else { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","cant decode opret")); + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "cant decode opret")); return(result); } } - result.push_back(Pair("result","error")); - result.push_back(Pair("error","cant find bettxid")); + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "cant find bettxid")); return(result); } -UniValue PricesCashout(uint64_t txfee,uint256 bettxid) +UniValue PricesCashout(uint64_t txfee, uint256 bettxid) { int32_t nextheight = komodo_nextheight(); - 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 CCchange=0,positionsize,inputsum,ignore,addedbets,firstprice,profits,costbasis=0; int32_t i,firstheight,height,numvouts; int16_t leverage; std::vector vec; CPubKey pk,mypk,pricespk; std::string rawtx; - cp = CCinit(&C,EVAL_PRICES); - if ( txfee == 0 ) + 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 CCchange = 0, positionsize, inputsum, ignore, addedbets, firstprice, profits, costbasis = 0; + int32_t i, firstheight, height, numvouts; + int16_t leverage; + std::vector vec; + CPubKey pk, mypk, pricespk; + std::string rawtx; + + cp = CCinit(&C, EVAL_PRICES); + if (txfee == 0) txfee = PRICES_TXFEE; + mypk = pubkey2pk(Mypubkey()); - pricespk = GetUnspendable(cp,0); - GetCCaddress(cp,destaddr,pricespk); - if ( myGetTransaction(bettxid,bettx,hashBlock) != 0 && (numvouts= bettx.vout.size()) > 3 ) + pricespk = GetUnspendable(cp, 0); + GetCCaddress(cp, destaddr, pricespk); + if (myGetTransaction(bettxid, bettx, hashBlock) != 0 && (numvouts = bettx.vout.size()) > 3) { - if ( prices_betopretdecode(bettx.vout[numvouts-1].scriptPubKey,pk,firstheight,positionsize,leverage,firstprice,vec,tokenid) == 'B' ) + if (prices_betopretdecode(bettx.vout[numvouts - 1].scriptPubKey, pk, firstheight, positionsize, leverage, firstprice, vec, tokenid) == 'B') { costbasis = prices_costbasis(bettx); - addedbets = prices_batontxid(batontxid,bettx,bettxid); - if ( (profits= prices_syntheticprofits(ignore,firstheight,nextheight-1,leverage,vec,positionsize,addedbets)) < 0 ) - { - prices_betjson(result,profits,costbasis,positionsize,addedbets,leverage,firstheight,firstprice); - result.push_back(Pair("result","error")); - result.push_back(Pair("error","position rekt")); + if (costbasis == 0) { + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "costbasis not defined yet")); return(result); } - prices_betjson(result,profits,costbasis,positionsize,addedbets,leverage,firstheight,firstprice); - mtx.vin.push_back(CTxIn(bettxid,2,CScript())); - if ( (inputsum= AddPricesInputs(cp,mtx,destaddr,profits+txfee,64,bettxid,2)) > profits+txfee ) + + addedbets = prices_batontxid(batontxid, bettx, bettxid); + if ((profits = prices_syntheticprofits(false, costbasis, firstheight, nextheight - 1, leverage, vec, positionsize, addedbets)) < 0) + { + prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice); + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "position rekt")); + return(result); + } + prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice); + mtx.vin.push_back(CTxIn(bettxid, 2, CScript())); + if ((inputsum = AddPricesInputs(cp, mtx, destaddr, profits + txfee, 64, bettxid, 2)) > profits + txfee) CCchange = (inputsum - profits); - mtx.vout.push_back(CTxOut(bettx.vout[2].nValue + profits,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); - if ( CCchange >= txfee ) - mtx.vout.push_back(MakeCC1vout(cp->evalcode,CCchange,pricespk)); - rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,prices_finalopret(bettxid,profits,nextheight-1,mypk,firstprice,costbasis,addedbets,positionsize,leverage)); - return(prices_rawtxresult(result,rawtx,0)); + mtx.vout.push_back(CTxOut(bettx.vout[2].nValue + profits, CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); + if (CCchange >= txfee) + mtx.vout.push_back(MakeCC1vout(cp->evalcode, CCchange, pricespk)); + rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_finalopret(bettxid, profits, nextheight - 1, mypk, firstprice, costbasis, addedbets, positionsize, leverage)); + return(prices_rawtxresult(result, rawtx, 0)); } else { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","cant decode opret")); + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "cant decode opret")); return(result); } } return(result); } -UniValue PricesInfo(uint256 bettxid,int32_t refheight) +UniValue PricesInfo(uint256 bettxid, int32_t refheight) { - UniValue result(UniValue::VOBJ); - CTransaction bettx; - uint256 hashBlock,batontxid,tokenid; - int64_t myfee,ignore=0,positionsize=0,addedbets=0,firstprice=0,profits=0,costbasis=0; - int32_t i,firstheight=0,height,numvouts; - int16_t leverage=0; - std::vector vec; - CPubKey pk,mypk,pricespk; + UniValue result(UniValue::VOBJ); + CTransaction bettx; + uint256 hashBlock, batontxid, tokenid; + int64_t myfee, ignore = 0, positionsize = 0, addedbets = 0, firstprice = 0, profits = 0, costbasis = 0; + int32_t i, firstheight = 0, height, numvouts; + int16_t leverage = 0; + std::vector vec; + CPubKey pk, mypk, pricespk; std::string rawtx; - if( myGetTransaction(bettxid,bettx,hashBlock) != 0 && (numvouts= bettx.vout.size()) > 3 ) + if (myGetTransaction(bettxid, bettx, hashBlock) != 0 && (numvouts = bettx.vout.size()) > 3) { - if( prices_betopretdecode(bettx.vout[numvouts-1].scriptPubKey,pk,firstheight,positionsize,leverage,firstprice,vec,tokenid) == 'B' ) + if (prices_betopretdecode(bettx.vout[numvouts - 1].scriptPubKey, pk, firstheight, positionsize, leverage, firstprice, vec, tokenid) == 'B') { costbasis = prices_costbasis(bettx); - addedbets = prices_batontxid(batontxid,bettx,bettxid); - if ((profits= prices_syntheticprofits(ignore,firstheight,refheight,leverage,vec,positionsize,addedbets)) < 0) + addedbets = prices_batontxid(batontxid, bettx, bettxid); + if ((profits = prices_syntheticprofits(false, costbasis, firstheight, refheight, leverage, vec, positionsize, addedbets)) < 0) { - result.push_back(Pair("rekt",1)); - result.push_back(Pair("rektfee",(positionsize + addedbets) / 500)); - } - else - result.push_back(Pair("rekt",0)); - result.push_back(Pair("batontxid",batontxid.GetHex())); - prices_betjson(result,profits,costbasis,positionsize,addedbets,leverage,firstheight,firstprice); - result.push_back(Pair("height",(int64_t)refheight)); + result.push_back(Pair("rekt", 1)); + result.push_back(Pair("rektfee", (positionsize + addedbets) / 500)); + } + else + result.push_back(Pair("rekt", 0)); + result.push_back(Pair("batontxid", batontxid.GetHex())); + prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice); + result.push_back(Pair("height", (int64_t)refheight)); return(result); } } - result.push_back(Pair("result","error")); - result.push_back(Pair("error","cant find bettxid")); + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "cant find bettxid")); return(result); } UniValue PricesList() { - UniValue result(UniValue::VARR); std::vector > addressIndex; struct CCcontract_info *cp,C; int64_t amount,firstprice; int32_t height; int16_t leverage; uint256 txid,hashBlock,tokenid; CPubKey pk,pricespk; std::vector vec; CTransaction vintx; char str[65]; - cp = CCinit(&C,EVAL_PRICES); - pricespk = GetUnspendable(cp,0); - SetCCtxids(addressIndex,cp->normaladdr,false); - for (std::vector >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++) + UniValue result(UniValue::VARR); std::vector > addressIndex; + struct CCcontract_info *cp, C; + int64_t amount, firstprice; int32_t height; int16_t leverage; uint256 txid, hashBlock, tokenid; + CPubKey pk, pricespk; + std::vector vec; + CTransaction vintx; + char str[65]; + + cp = CCinit(&C, EVAL_PRICES); + pricespk = GetUnspendable(cp, 0); + SetCCtxids(addressIndex, cp->normaladdr); + for (std::vector >::const_iterator it = addressIndex.begin(); it != addressIndex.end(); it++) { txid = it->first.txhash; - if ( GetTransaction(txid,vintx,hashBlock,false) != 0 ) + if (GetTransaction(txid, vintx, hashBlock, false) != 0) { - if ( vintx.vout.size() > 0 && prices_betopretdecode(vintx.vout[vintx.vout.size()-1].scriptPubKey,pk,height,amount,leverage,firstprice,vec,tokenid) == 'B' ) + if (vintx.vout.size() > 0 && prices_betopretdecode(vintx.vout[vintx.vout.size() - 1].scriptPubKey, pk, height, amount, leverage, firstprice, vec, tokenid) == 'B') { - result.push_back(uint256_str(str,txid)); + result.push_back(uint256_str(str, txid)); } } } diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index c2cead4a4..3cc23a4fd 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -465,7 +465,9 @@ static const CRPCCommand vRPCCommands[] = { "prices", "priceslist", &priceslist, true }, { "prices", "pricesinfo", &pricesinfo, true }, { "prices", "pricesbet", &pricesbet, true }, - { "prices", "pricesbetsetcostbasis", &pricessetcostbasis, true }, + { "prices", "pricessetcostbasis", &pricessetcostbasis, true }, + { "prices", "pricescashout", &pricescashout, true }, + { "prices", "pricesrekt", &pricesrekt, true }, // Pegs { "pegs", "pegsaddress", &pegsaddress, true }, diff --git a/src/rpc/server.h b/src/rpc/server.h index 94d16ecdc..aef17d931 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -499,6 +499,9 @@ extern UniValue paxwithdraw(const UniValue& params, bool fHelp); extern UniValue prices(const UniValue& params, bool fHelp); extern UniValue pricesbet(const UniValue& params, bool fHelp); extern UniValue pricessetcostbasis(const UniValue& params, bool fHelp); +extern UniValue pricescashout(const UniValue& params, bool fHelp); +extern UniValue pricesrekt(const UniValue& params, bool fHelp); + // test rpc: extern UniValue test_ac(const UniValue& params, bool fHelp); From 829fb4d0cd33f5fdc052f2bc53fdcbe9c0b2953b Mon Sep 17 00:00:00 2001 From: dimxy Date: Mon, 15 Apr 2019 20:57:05 +0500 Subject: [PATCH 043/242] added 'add bet funds' added comments --- src/cc/prices.cpp | 89 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 60 insertions(+), 29 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index ec099e7e1..fe3ae9c3a 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -239,7 +239,7 @@ int32_t prices_syntheticvec(std::vector &vec,std::vector return(0); } -// calculate price for synthetic expression +// calculates price for synthetic expression int64_t prices_syntheticprice(std::vector vec,int32_t height,int32_t minmax,int16_t leverage) { int32_t i,value,errcode,depth,retval = -1; @@ -261,7 +261,7 @@ int64_t prices_syntheticprice(std::vector vec,int32_t height,int32_t m if ( prices_extract(pricedata,height,1,value) == 0 ) { // push price to the prices stack - if ( minmax == 0 ) + if ( !minmax ) pricestack[depth] = pricedata[2]; // use smoothed value if we are over 24h else { @@ -392,7 +392,8 @@ int64_t prices_syntheticprice(std::vector vec,int32_t height,int32_t m return(price / den); } -int64_t prices_syntheticprofits(bool isCalcCostBasis, int64_t &costbasis,int32_t firstheight,int32_t height,int16_t leverage,std::vector vec,int64_t positionsize,int64_t addedbets) +// calculates profit/loss for the bet +int64_t prices_syntheticprofits(bool calcCostbasis, int64_t &costbasis, int32_t firstheight, int32_t height, int16_t leverage, std::vector vec, int64_t positionsize, int64_t addedbets) { int64_t price, profits = 0; @@ -403,15 +404,17 @@ int64_t prices_syntheticprofits(bool isCalcCostBasis, int64_t &costbasis,int32_t fprintf(stderr, "unexpected zero synthetic price at height.%d\n", height); return(0); } - if (isCalcCostBasis) { - if (minmax) // if we are within day window, set costbasis to max or min value - { + if (calcCostbasis) { + if (minmax) { // if we are within day window, set costbasis to max or min price value if (leverage > 0 && price > costbasis) costbasis = price; // set costbasis else if (leverage < 0 && (costbasis == 0 || price < costbasis)) costbasis = price; // else -> use the previous value } + else { + costbasis = price; // smoothed value + } } profits = costbasis > 0 ? ((price * SATOSHIDEN) / costbasis) - SATOSHIDEN : 0; @@ -456,14 +459,41 @@ int64_t prices_costbasis(CTransaction bettx) return costbasis; } - std::cerr << "prices_costbasis() cannot load costbasis tx or decode opret" << " isLoaded=" << isLoaded << " funcId=" << funcId << std::endl; + std::cerr << "prices_costbasis() cannot load costbasis tx or decode opret" << " isLoaded=" << isLoaded << " funcId=" << (int)funcId << std::endl; return 0; } +// calculates added bet total, returns the last baton txid int64_t prices_batontxid(uint256 &batontxid,CTransaction bettx,uint256 bettxid) { int64_t addedbets = 0; + int32_t vini; + int32_t height; + int32_t retcode; + // iterate through batons, adding up vout1 -> addedbets + while ((retcode = CCgetspenttxid(batontxid, vini, height, bettxid, 1)) == 0) { + + CTransaction txBaton; + uint256 hashBlock; + uint256 bettxid; + CPubKey pk; + bool isLoaded = false; + uint8_t funcId = 0; + int64_t amount; + + if ((isLoaded = myGetTransaction(batontxid, txBaton, hashBlock)) && + txBaton.vout.size() > 0 && + (funcId = prices_addopretdecode(txBaton.vout.back().scriptPubKey, bettxid, pk, amount)) != 0) { + addedbets += amount; + 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; + } + } + + return(addedbets); } @@ -493,7 +523,7 @@ UniValue PricesBet(uint64_t txfee,int64_t amount,int16_t leverage,std::vector= amount+5*txfee ) { betamount = (amount * 199) / 200; - mtx.vout.push_back(MakeCC1vout(cp->evalcode,txfee,mypk)); // baton for total funding + 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)); mtx.vout.push_back(MakeCC1of2vout(cp->evalcode,betamount,pricespk,mypk)); mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(HexStr(pricespk)) << OP_CHECKSIG)); // marker @@ -505,39 +535,40 @@ UniValue PricesBet(uint64_t txfee,int64_t amount,int16_t leverage,std::vector vec; uint256 batontxid; std::string rawtx; char myaddr[64]; - cp = CCinit(&C,EVAL_PRICES); - if ( txfee == 0 ) + 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; std::string rawtx; char myaddr[64]; + cp = CCinit(&C, EVAL_PRICES); + if (txfee == 0) txfee = PRICES_TXFEE; mypk = pubkey2pk(Mypubkey()); - pricespk = GetUnspendable(cp,0); - GetCCaddress(cp,myaddr,mypk); - if ( AddNormalinputs(mtx,mypk,amount+txfee,64) >= amount+txfee ) + pricespk = GetUnspendable(cp, 0); + GetCCaddress(cp, myaddr, mypk); + if (AddNormalinputs(mtx, mypk, amount + txfee, 64) >= amount + txfee) { - if ( prices_batontxid(batontxid,bettx,bettxid) >= 0 ) + if (prices_batontxid(batontxid, bettx, bettxid) >= 0) { - mtx.vin.push_back(CTxIn(batontxid,0,CScript())); - mtx.vout.push_back(MakeCC1vout(cp->evalcode,txfee,mypk)); // baton for total funding - mtx.vout.push_back(MakeCC1vout(cp->evalcode,amount,pricespk)); - rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,prices_addopret(bettxid,mypk,amount)); - return(prices_rawtxresult(result,rawtx,0)); + mtx.vin.push_back(CTxIn(batontxid, 0, CScript())); + mtx.vout.push_back(MakeCC1vout(cp->evalcode, txfee, mypk)); // baton for total funding + mtx.vout.push_back(MakeCC1vout(cp->evalcode, amount, pricespk)); + rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_addopret(bettxid, mypk, amount)); + return(prices_rawtxresult(result, rawtx, 0)); } else { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","couldnt find batonttxid")); + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "couldnt find batonttxid")); return(result); } } - result.push_back(Pair("result","error")); - result.push_back(Pair("error","not enough funds")); + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "not enough funds")); return(result); } +// set cost basis (open price) for the bet UniValue PricesSetcostbasis(int64_t txfee, uint256 bettxid) { int32_t nextheight = komodo_nextheight(); @@ -559,7 +590,7 @@ UniValue PricesSetcostbasis(int64_t txfee, uint256 bettxid) { if (prices_betopretdecode(bettx.vout[numvouts - 1].scriptPubKey, pk, firstheight, positionsize, leverage, firstprice, vec, tokenid) == 'B') { - if (nextheight < firstheight + PRICES_DAYWINDOW) { + if (nextheight <= firstheight + PRICES_DAYWINDOW + PRICES_SMOOTHWIDTH) { result.push_back(Pair("result", "error")); result.push_back(Pair("error", "cannot calculate costbasis yet")); return(result); @@ -567,7 +598,7 @@ UniValue PricesSetcostbasis(int64_t txfee, uint256 bettxid) addedbets = prices_batontxid(batontxid, bettx, bettxid); mtx.vin.push_back(CTxIn(bettxid, 1, CScript())); // spend vin1 - for (i = 0; i < PRICES_DAYWINDOW; i++) // we need a full day to check if there was a rekt + for (i = 0; i < PRICES_DAYWINDOW + PRICES_SMOOTHWIDTH; i++) // the last datum for 24h is the costbasis value { if ((profits = prices_syntheticprofits(true, costbasis, firstheight, firstheight + i, leverage, vec, positionsize, addedbets)) < 0) { // we are in loss @@ -584,7 +615,7 @@ UniValue PricesSetcostbasis(int64_t txfee, uint256 bettxid) result.push_back(Pair("myfee", myfee)); mtx.vout.push_back(CTxOut(myfee, CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); mtx.vout.push_back(MakeCC1vout(cp->evalcode, bettx.vout[1].nValue - myfee - txfee, pricespk)); - rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_costbasisopret(bettxid, mypk, firstheight + PRICES_DAYWINDOW - 1, costbasis)); + rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_costbasisopret(bettxid, mypk, firstheight + PRICES_DAYWINDOW /*- 1*/, costbasis)); return(prices_rawtxresult(result, rawtx, 0)); } } From 2f077d3103d057c1a6292df41fc937dd9a81a7e1 Mon Sep 17 00:00:00 2001 From: dimxy Date: Mon, 15 Apr 2019 21:19:19 +0500 Subject: [PATCH 044/242] yet logging --- src/cc/prices.cpp | 214 +++++++++++++++++++++++----------------------- 1 file changed, 107 insertions(+), 107 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index fe3ae9c3a..cac6c15e2 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -240,142 +240,142 @@ int32_t prices_syntheticvec(std::vector &vec,std::vector } // calculates price for synthetic expression -int64_t prices_syntheticprice(std::vector vec,int32_t height,int32_t minmax,int16_t leverage) +int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t minmax, int16_t leverage) { - int32_t i,value,errcode,depth,retval = -1; - uint16_t opcode; - int64_t *pricedata,pricestack[4],price,den,a,b,c; + int32_t i, value, errcode, depth, retval = -1; + uint16_t opcode; + int64_t *pricedata, pricestack[4], price, den, a, b, c; - pricedata = (int64_t *)calloc(sizeof(*pricedata)*3,1 + PRICES_DAYWINDOW*2 + PRICES_SMOOTHWIDTH); + pricedata = (int64_t *)calloc(sizeof(*pricedata) * 3, 1 + PRICES_DAYWINDOW * 2 + PRICES_SMOOTHWIDTH); price = den = depth = errcode = 0; - for (i=0; i Date: Mon, 15 Apr 2019 21:43:22 +0500 Subject: [PATCH 045/242] addfunding rpc added --- src/cc/CCPrices.h | 8 +-- src/cc/prices.cpp | 8 +-- src/rpc/blockchain.cpp | 107 +++++++++++++++++++++++++++++++++++++++++ src/rpc/server.cpp | 1 + src/rpc/server.h | 1 + 5 files changed, 117 insertions(+), 8 deletions(-) diff --git a/src/cc/CCPrices.h b/src/cc/CCPrices.h index a32264a88..62da19aab 100644 --- a/src/cc/CCPrices.h +++ b/src/cc/CCPrices.h @@ -38,11 +38,11 @@ int32_t komodo_priceget(int64_t *buf64,int32_t ind,int32_t height,int32_t numblo bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn); // CCcustom -UniValue PricesBet(uint64_t txfee,int64_t amount,int16_t leverage,std::vector synthetic); -UniValue PricesAddFunding(uint64_t txfee,uint256 bettxid,int64_t amount); +UniValue PricesBet(int64_t txfee,int64_t amount,int16_t leverage,std::vector synthetic); +UniValue PricesAddFunding(int64_t txfee,uint256 bettxid,int64_t amount); UniValue PricesSetcostbasis(int64_t txfee,uint256 bettxid); -UniValue PricesRekt(uint64_t txfee,uint256 bettxid,int32_t rektheight); -UniValue PricesCashout(uint64_t txfee,uint256 bettxid); +UniValue PricesRekt(int64_t txfee,uint256 bettxid,int32_t rektheight); +UniValue PricesCashout(int64_t txfee,uint256 bettxid); UniValue PricesInfo(uint256 bettxid,int32_t refheight); UniValue PricesList(); diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index cac6c15e2..e6f5db97d 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -497,7 +497,7 @@ int64_t prices_batontxid(uint256 &batontxid,CTransaction bettx,uint256 bettxid) return(addedbets); } -UniValue PricesBet(uint64_t txfee,int64_t amount,int16_t leverage,std::vector synthetic) +UniValue PricesBet(int64_t txfee,int64_t amount,int16_t leverage,std::vector synthetic) { int32_t nextheight = komodo_nextheight(); CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(),nextheight); UniValue result(UniValue::VOBJ); @@ -535,7 +535,7 @@ UniValue PricesBet(uint64_t txfee,int64_t amount,int16_t leverage,std::vector vexpr; + SplitStr(sexpr, vexpr); + + // debug print parsed strings: + std::cerr << "parsed synthetic: "; + for (auto s : vexpr) + std::cerr << s << " "; + std::cerr << std::endl; + + return PricesBet(txfee, amount, leverage, vexpr); +} + +// pricesaddfunding rpc implementation +UniValue pricesaddfunding(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 2) + throw runtime_error("pricesaddfunding bettxid 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 txfee = 10000; + uint256 bettxid = Parseuint256(params[0].get_str().c_str()); + CAmount amount = atoll(params[1].get_str().c_str()); + + return PricesAddFunding(txfee, bettxid, amount); +} + +// rpc pricessetcostbasis implementation +UniValue pricessetcostbasis(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error("pricessetcostbasis bettxid\n"); + LOCK(cs_main); + UniValue ret(UniValue::VOBJ); + + if (ASSETCHAINS_CBOPRET == 0) + throw JSONRPCError(RPC_INVALID_PARAMETER, "only -ac_cbopret chains have prices"); + + uint256 bettxid = Parseuint256(params[0].get_str().c_str()); + if( bettxid.IsNull() ) + throw runtime_error("invalid bettxid\n"); + + int64_t txfee = 10000; + + return PricesSetcostbasis(txfee, bettxid); +} + +UniValue pricescashout(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error("pricescashout bettxid\n"); + LOCK(cs_main); + UniValue ret(UniValue::VOBJ); + + if (ASSETCHAINS_CBOPRET == 0) + throw JSONRPCError(RPC_INVALID_PARAMETER, "only -ac_cbopret chains have prices"); + + uint256 bettxid = Parseuint256(params[0].get_str().c_str()); + if (bettxid.IsNull()) + throw runtime_error("invalid bettxid\n"); + + int64_t txfee = 10000; + + return PricesCashout(txfee, bettxid); +} + +UniValue pricesrekt(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 2) + throw runtime_error("pricesrekt bettxid height\n"); + LOCK(cs_main); + UniValue ret(UniValue::VOBJ); + + if (ASSETCHAINS_CBOPRET == 0) + throw JSONRPCError(RPC_INVALID_PARAMETER, "only -ac_cbopret chains have prices"); + + uint256 bettxid = Parseuint256(params[0].get_str().c_str()); + if (bettxid.IsNull()) + throw runtime_error("invalid bettxid\n"); + + int32_t height = atoi(params[0].get_str().c_str()); + + int64_t txfee = 10000; + + return PricesRekt(txfee, bettxid, height); +} + UniValue gettxout(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 2 || params.size() > 3) diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 3cc23a4fd..29e616bca 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -468,6 +468,7 @@ static const CRPCCommand vRPCCommands[] = { "prices", "pricessetcostbasis", &pricessetcostbasis, true }, { "prices", "pricescashout", &pricescashout, true }, { "prices", "pricesrekt", &pricesrekt, true }, + { "prices", "pricesaddfunding", &pricesaddfunding, true }, // Pegs { "pegs", "pegsaddress", &pegsaddress, true }, diff --git a/src/rpc/server.h b/src/rpc/server.h index aef17d931..2bd0b91c6 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -501,6 +501,7 @@ extern UniValue pricesbet(const UniValue& params, bool fHelp); extern UniValue pricessetcostbasis(const UniValue& params, bool fHelp); extern UniValue pricescashout(const UniValue& params, bool fHelp); extern UniValue pricesrekt(const UniValue& params, bool fHelp); +extern UniValue pricesaddfunding(const UniValue& params, bool fHelp); // test rpc: From 505619e202dac0e23759cc80be162d3c76e0e6f4 Mon Sep 17 00:00:00 2001 From: dimxy Date: Mon, 15 Apr 2019 22:15:12 +0500 Subject: [PATCH 046/242] init batontxid added checks for rpc --- src/cc/prices.cpp | 2 ++ src/rpc/blockchain.cpp | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index e6f5db97d..28bfaf848 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -471,6 +471,8 @@ int64_t prices_batontxid(uint256 &batontxid,CTransaction bettx,uint256 bettxid) int32_t height; int32_t retcode; + batontxid = bettxid; // initially set to the source bet tx + // iterate through batons, adding up vout1 -> addedbets while ((retcode = CCgetspenttxid(batontxid, vini, height, bettxid, 1)) == 0) { diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index aad8c4c6c..550355cff 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1348,7 +1348,8 @@ UniValue pricesbet(const UniValue& params, bool fHelp) UniValue pricesaddfunding(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 2) - throw runtime_error("pricesaddfunding bettxid amount\n"); + throw runtime_error("pricesaddfunding bettxid amount\n" + "where amount is in satoshis\n"); LOCK(cs_main); UniValue ret(UniValue::VOBJ); @@ -1357,7 +1358,12 @@ UniValue pricesaddfunding(const UniValue& params, bool fHelp) CAmount txfee = 10000; uint256 bettxid = Parseuint256(params[0].get_str().c_str()); + if( bettxid.IsNull() ) + throw runtime_error("invalid bettxid\n"); + CAmount amount = atoll(params[1].get_str().c_str()); + if( amount <= 0 ) + throw runtime_error("invalid amount\n"); return PricesAddFunding(txfee, bettxid, amount); } From b7756c071b9718005651fa2a93bd0af40ddd8840 Mon Sep 17 00:00:00 2001 From: dimxy Date: Mon, 15 Apr 2019 22:37:26 +0500 Subject: [PATCH 047/242] txfee --- src/cc/prices.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 28bfaf848..f3b0c71ef 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -464,7 +464,7 @@ int64_t prices_costbasis(CTransaction bettx) } // calculates added bet total, returns the last baton txid -int64_t prices_batontxid(uint256 &batontxid,CTransaction bettx,uint256 bettxid) +int64_t prices_batontxid(uint256 &batontxid, CTransaction bettx, uint256 bettxid) { int64_t addedbets = 0; int32_t vini; @@ -490,12 +490,11 @@ int64_t prices_batontxid(uint256 &batontxid,CTransaction bettx,uint256 bettxid) addedbets += amount; std::cerr << "prices_batontxid() added amount=" << amount << std::endl; } - else { + else { std::cerr << "prices_batontxid() cannot load or decode add bet tx, isLoaded=" << isLoaded << " funcId=" << (int)funcId << std::endl; } } - return(addedbets); } @@ -548,7 +547,7 @@ UniValue PricesAddFunding(int64_t txfee, uint256 bettxid, int64_t amount) mypk = pubkey2pk(Mypubkey()); pricespk = GetUnspendable(cp, 0); GetCCaddress(cp, myaddr, mypk); - if (AddNormalinputs(mtx, mypk, amount + txfee, 64) >= amount + txfee) + if (AddNormalinputs(mtx, mypk, amount + 2*txfee, 64) >= amount + 2*txfee) { if (prices_batontxid(batontxid, bettx, bettxid) >= 0) { From 411f68ab807b51684f602cef3c0535838de5381d Mon Sep 17 00:00:00 2001 From: dimxy Date: Mon, 15 Apr 2019 23:16:19 +0500 Subject: [PATCH 048/242] corr batontxid change --- src/cc/prices.cpp | 63 ++++++++++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 25 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index f3b0c71ef..7808a38ee 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -472,9 +472,9 @@ int64_t prices_batontxid(uint256 &batontxid, CTransaction bettx, uint256 bettxid int32_t retcode; batontxid = bettxid; // initially set to the source bet tx - + uint256 sourcetxid = bettxid; // iterate through batons, adding up vout1 -> addedbets - while ((retcode = CCgetspenttxid(batontxid, vini, height, bettxid, 1)) == 0) { + while ((retcode = CCgetspenttxid(batontxid, vini, height, sourcetxid, 1)) == 0) { CTransaction txBaton; uint256 hashBlock; @@ -492,47 +492,53 @@ int64_t prices_batontxid(uint256 &batontxid, CTransaction bettx, uint256 bettxid } else { std::cerr << "prices_batontxid() cannot load or decode add bet tx, isLoaded=" << isLoaded << " funcId=" << (int)funcId << std::endl; + return -1; } + sourcetxid = batontxid; } return(addedbets); } -UniValue PricesBet(int64_t txfee,int64_t amount,int16_t leverage,std::vector synthetic) +UniValue PricesBet(int64_t txfee, int64_t amount, int16_t leverage, std::vector synthetic) { int32_t nextheight = komodo_nextheight(); - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(),nextheight); UniValue result(UniValue::VOBJ); - struct CCcontract_info *cp,C; CPubKey pricespk,mypk; int64_t betamount,firstprice; std::vector vec; char myaddr[64]; std::string rawtx; - if ( leverage > PRICES_MAXLEVERAGE || leverage < -PRICES_MAXLEVERAGE ) + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nextheight); UniValue result(UniValue::VOBJ); + struct CCcontract_info *cp, C; CPubKey pricespk, mypk; int64_t betamount, firstprice; + std::vector vec; + char myaddr[64]; + std::string rawtx; + + if (leverage > PRICES_MAXLEVERAGE || leverage < -PRICES_MAXLEVERAGE) { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","leverage too big")); + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "leverage too big")); return(result); } - cp = CCinit(&C,EVAL_PRICES); - if ( txfee == 0 ) + cp = CCinit(&C, EVAL_PRICES); + if (txfee == 0) txfee = PRICES_TXFEE; mypk = pubkey2pk(Mypubkey()); - pricespk = GetUnspendable(cp,0); - GetCCaddress(cp,myaddr,mypk); - if ( prices_syntheticvec(vec,synthetic) < 0 || (firstprice= prices_syntheticprice(vec,nextheight-1,1,leverage)) < 0 || vec.size() == 0 || vec.size() > 4096 ) + pricespk = GetUnspendable(cp, 0); + GetCCaddress(cp, myaddr, mypk); + if (prices_syntheticvec(vec, synthetic) < 0 || (firstprice = prices_syntheticprice(vec, nextheight - 1, 1, leverage)) < 0 || vec.size() == 0 || vec.size() > 4096) { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","invalid synthetic")); + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "invalid synthetic")); return(result); } - if ( AddNormalinputs(mtx,mypk,amount+5*txfee,64) >= amount+5*txfee ) + if (AddNormalinputs(mtx, mypk, amount + 5 * txfee, 64) >= amount + 5 * txfee) { betamount = (amount * 199) / 200; - 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)); - mtx.vout.push_back(MakeCC1of2vout(cp->evalcode,betamount,pricespk,mypk)); + 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)); + mtx.vout.push_back(MakeCC1of2vout(cp->evalcode, betamount, pricespk, mypk)); mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(HexStr(pricespk)) << OP_CHECKSIG)); // marker - rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,prices_betopret(mypk,nextheight-1,amount,leverage,firstprice,vec,zeroid)); - return(prices_rawtxresult(result,rawtx,0)); + rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_betopret(mypk, nextheight - 1, amount, leverage, firstprice, vec, zeroid)); + return(prices_rawtxresult(result, rawtx, 0)); } - result.push_back(Pair("result","error")); - result.push_back(Pair("error","not enough funds")); + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "not enough funds")); return(result); } @@ -540,13 +546,20 @@ 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; std::string rawtx; char myaddr[64]; + struct CCcontract_info *cp, C; CTransaction bettx; + CPubKey pricespk, mypk; + //int64_t addedbets = 0, betamount, firstprice; + std::vector vec; + uint256 batontxid; + std::string rawtx; + //char myaddr[64]; + cp = CCinit(&C, EVAL_PRICES); if (txfee == 0) txfee = PRICES_TXFEE; mypk = pubkey2pk(Mypubkey()); pricespk = GetUnspendable(cp, 0); - GetCCaddress(cp, myaddr, mypk); + //GetCCaddress(cp, myaddr, mypk); if (AddNormalinputs(mtx, mypk, amount + 2*txfee, 64) >= amount + 2*txfee) { if (prices_batontxid(batontxid, bettx, bettxid) >= 0) From e4de8aca2d791136e1a190efd73a50527aa1532f Mon Sep 17 00:00:00 2001 From: dimxy Date: Mon, 15 Apr 2019 23:27:06 +0500 Subject: [PATCH 049/242] corr baton vin --- src/cc/prices.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 7808a38ee..dfed22378 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -474,7 +474,7 @@ int64_t prices_batontxid(uint256 &batontxid, CTransaction bettx, uint256 bettxid batontxid = bettxid; // initially set to the source bet tx uint256 sourcetxid = bettxid; // iterate through batons, adding up vout1 -> addedbets - while ((retcode = CCgetspenttxid(batontxid, vini, height, sourcetxid, 1)) == 0) { + while ((retcode = CCgetspenttxid(batontxid, vini, height, sourcetxid, 0)) == 0) { CTransaction txBaton; uint256 hashBlock; @@ -531,7 +531,7 @@ UniValue PricesBet(int64_t txfee, int64_t amount, int16_t leverage, std::vector< { betamount = (amount * 199) / 200; 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)); + mtx.vout.push_back(MakeCC1vout(cp->evalcode, (amount - betamount) + 2 * txfee, pricespk)); // vout1, when spent, costbasis is set mtx.vout.push_back(MakeCC1of2vout(cp->evalcode, betamount, pricespk, mypk)); mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(HexStr(pricespk)) << OP_CHECKSIG)); // marker rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_betopret(mypk, nextheight - 1, amount, leverage, firstprice, vec, zeroid)); From 59fbfbcae7e42f3354a50b74524c6907e3eeea21 Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 16 Apr 2019 00:19:10 +0500 Subject: [PATCH 050/242] pricesinfo height opt --- src/cc/prices.cpp | 13 +++++++++++++ src/wallet/rpcwallet.cpp | 10 ++++++---- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index dfed22378..486d97f8c 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -397,6 +397,11 @@ int64_t prices_syntheticprofits(bool calcCostbasis, int64_t &costbasis, int32_t { int64_t price, profits = 0; + if (height < firstheight) { + fprintf(stderr, "requested height is lower than bet firstheight.%d\n", height); + return 0; + } + int32_t minmax = (height < firstheight + PRICES_DAYWINDOW); // if we are within 24h then use min or max value if ((price = prices_syntheticprice(vec, height, minmax, leverage)) < 0) @@ -768,6 +773,14 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) { if (prices_betopretdecode(bettx.vout[numvouts - 1].scriptPubKey, pk, firstheight, positionsize, leverage, firstprice, vec, tokenid) == 'B') { + if (refheight > 0 && refheight < firstheight) { + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "incorrect height")); + return(result); + } + if (refheight == 0) + refheight = komodo_nextheight()-1; + costbasis = prices_costbasis(bettx); addedbets = prices_batontxid(batontxid, bettx, bettxid); if ((profits = prices_syntheticprofits(false, costbasis, firstheight, refheight, leverage, vec, positionsize, addedbets)) < 0) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 05283c0b9..8d6af20c2 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -6931,13 +6931,15 @@ UniValue priceslist(const UniValue& params, bool fHelp) UniValue pricesinfo(const UniValue& params, bool fHelp) { uint256 bettxid; int32_t height; - if ( fHelp || params.size() != 2 ) - throw runtime_error("pricesinfo fundingtxid height\n"); + if ( fHelp || params.size() != 1 && params.size() != 2) + throw runtime_error("pricesinfo fundingtxid [height]\n"); if ( ensure_CCrequirements(EVAL_PRICES) < 0 ) throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); bettxid = Parseuint256((char *)params[0].get_str().c_str()); - height = atoi(params[1].get_str().c_str()); - return(PricesInfo(bettxid,height)); + height = 0; + if (params.size() == 2) + height = atoi(params[1].get_str().c_str()); + return(PricesInfo(bettxid, height)); } UniValue dicefund(const UniValue& params, bool fHelp) From e0fa061cc9f09695a081171a83ede61cf545d9b0 Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 16 Apr 2019 13:25:07 +0500 Subject: [PATCH 051/242] help message --- src/wallet/rpcwallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 8d6af20c2..a155603d9 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -6932,7 +6932,7 @@ UniValue pricesinfo(const UniValue& params, bool fHelp) { uint256 bettxid; int32_t height; if ( fHelp || params.size() != 1 && params.size() != 2) - throw runtime_error("pricesinfo fundingtxid [height]\n"); + throw runtime_error("pricesinfo bettxid [height]\n"); if ( ensure_CCrequirements(EVAL_PRICES) < 0 ) throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); bettxid = Parseuint256((char *)params[0].get_str().c_str()); From efaedac711614e3973f4f5ffde5a12dbba101f98 Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 16 Apr 2019 23:08:39 +0500 Subject: [PATCH 052/242] first validation code added --- src/cc/prices.cpp | 284 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 248 insertions(+), 36 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 486d97f8c..0dd667c1f 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -126,35 +126,240 @@ uint8_t prices_finalopretdecode(CScript scriptPubKey,uint256 &bettxid,int64_t &p return(0); } +bool CheckPricesOpret(const CTransaction & tx, vscript_t &opret) +{ + return (tx.vout.size() == 0 || !GetOpReturnData(tx.vout.back().scriptPubKey, opret) || opret.size() < 3 || opret.begin()[0] != EVAL_PRICES) || opret.begin()[1] == 0; +} + +bool ValidateBetTx(struct CCcontract_info *cp, Eval *eval, const CTransaction & bettx) +{ + uint256 tokenid; + int64_t positionsize, firstprice; + int32_t firstheight; + int16_t leverage; + CPubKey pk, pricespk; + std::vector vec; + + if (bettx.vout.size() < 5 || bettx.vout.size() > 6) + return eval->Invalid("incorrect vout number for bet tx"); + + vscript_t opret; + if( prices_betopretdecode(bettx.vout.back().scriptPubKey, pk, firstheight, positionsize, leverage, firstprice, vec, tokenid) != 'B') + return eval->Invalid("cannot decode opreturn for bet tx"); + + pricespk = GetUnspendable(cp, 0); + + if (MakeCC1vout(cp->evalcode, bettx.vout[0].nValue, pk) != bettx.vout[0]) + return eval->Invalid("cannot validate vout0 in bet tx with pk from opreturn"); + if (MakeCC1vout(cp->evalcode, bettx.vout[1].nValue, pricespk) != bettx.vout[1]) + return eval->Invalid("cannot validate vout1 in bet tx with global pk"); + if( MakeCC1of2vout(cp->evalcode, bettx.vout[2].nValue, pk, pricespk) != bettx.vout[2] ) + return eval->Invalid("cannot validate 1of2 vout2 in bet tx with pk from opreturn"); + + return true; +} + + +bool ValidateAddFundingTx(struct CCcontract_info *cp, Eval *eval, const CTransaction & addfundingtx) +{ + uint256 bettxid; + int64_t amount; + CPubKey pk, pricespk; + + if (addfundingtx.vout.size() < 3 || addfundingtx.vout.size() > 4) + return eval->Invalid("incorrect vout number for add funding tx"); + + vscript_t opret; + if (prices_addopretdecode(addfundingtx.vout.back().scriptPubKey, bettxid, pk, amount) != 'A') + return eval->Invalid("cannot decode opreturn for add funding tx"); + + pricespk = GetUnspendable(cp, 0); + + if (MakeCC1vout(cp->evalcode, addfundingtx.vout[0].nValue, pk) != addfundingtx.vout[0]) + return eval->Invalid("cannot validate vout0 in add funding tx with pk from opreturn"); + 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"); + + return true; +} + +bool ValidateCostbasisTx(struct CCcontract_info *cp, Eval *eval, const CTransaction & costbasistx, const CTransaction & bettx) +{ + uint256 bettxid; + int64_t amount; + CPubKey pk, pricespk; + int32_t height; + + // check basic structure: + if (costbasistx.vout.size() < 3 || costbasistx.vout.size() > 4) + return eval->Invalid("incorrect vout number for add funding tx"); + + vscript_t opret; + if (prices_costbasisopretdecode(costbasistx.vout.back().scriptPubKey, bettxid, pk, height, amount) != 'C') + return eval->Invalid("cannot decode opreturn for setcostbasis tx"); + + pricespk = GetUnspendable(cp, 0); + if (MakeCC1vout(cp->evalcode, costbasistx.vout[0].nValue, pk) != costbasistx.vout[0]) + return eval->Invalid("cannot validate vout0 in add funding tx with pk from opreturn"); + if (MakeCC1vout(cp->evalcode, costbasistx.vout[1].nValue, pricespk) != costbasistx.vout[1]) + return eval->Invalid("cannot validate vout1 in add funding tx with global pk"); + + if (bettx.vout.size() < 1) // maybe this is already checked outside, but it is safe to check here too and have encapsulated check + return eval->Invalid("incorrect bettx"); + + // check costbasis rules: + if (costbasistx.vout[0].nValue > bettx.vout[1].nValue / 10) + return eval->Invalid("costbasis myfee too big"); + + uint256 tokenid; + int64_t positionsize, firstprice; + int32_t firstheight; + int16_t leverage; + std::vector vec; + if (prices_betopretdecode(bettx.vout.back().scriptPubKey, pk, firstheight, positionsize, leverage, firstprice, vec, tokenid) != 'B') + return eval->Invalid("cannot decode opreturn for bet tx"); + + if( firstheight + PRICES_DAYWINDOW + PRICES_SMOOTHWIDTH > chainActive.Height() ) + return eval->Invalid("cannot calculate costbasis yet"); + + return true; +} + +bool ValidateFinalTx(struct CCcontract_info *cp, Eval *eval, const CTransaction & finaltx) +{ + uint256 bettxid; + int64_t amount; + CPubKey pk, pricespk; + int64_t profits; + int32_t height; + int64_t firstprice, costbasis, addedbets, positionsize; + int16_t leverage; + + if (finaltx.vout.size() < 2 || finaltx.vout.size() > 3) + return eval->Invalid("incorrect vout number for final tx"); + + vscript_t opret; + if (prices_finalopretdecode(finaltx.vout.back().scriptPubKey, bettxid, profits, height, pk, firstprice, costbasis, addedbets, positionsize, leverage) != 'F') + return eval->Invalid("cannot decode opreturn for final tx"); + + pricespk = GetUnspendable(cp, 0); + + if (MakeCC1vout(cp->evalcode, finaltx.vout[0].nValue, pk) != finaltx.vout[0]) + return eval->Invalid("cannot validate vout0 in final tx with pk from opreturn"); + + 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"); + + return true; +} + bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn) { + vscript_t vopret; + + // check basic opret rules: + if (CheckPricesOpret(tx, vopret)) + return eval->Invalid("tx has no prices opreturn"); + + uint8_t funcId = vopret.begin()[1]; + + CTransaction vintx; + vscript_t vintxOpret; + int32_t ccVinCount = 0; + int32_t prevoutN = 0; + // load vintx: + for (auto vin : tx.vin) + if (cp->ismyvin(vin.scriptSig)) { + uint256 hashBlock; + if (myGetTransaction(vin.prevout.hash, vintx, hashBlock)) + return eval->Invalid("cannot load vin tx"); + prevoutN = vin.prevout.n; + ccVinCount++; + } + if (ccVinCount != 1) // must be only one cc vintx + return eval->Invalid("incorrect cc vin txns num"); + + if (!CheckPricesOpret(vintx, vintxOpret)) + return eval->Invalid("cannot find prices opret in vintx"); + + if (vintxOpret.begin()[1] == 'B' && prevoutN == 3) { // check basic spending rules + return eval->Invalid("cannot spend bet marker"); + } + + switch (funcId) { + case 'B': // bet + return eval->Invalid("unexpected validate for bet funcid"); + + case 'A': // add funding + // check tx structure: + if (!ValidateAddFundingTx(cp, eval, tx)) + return false; // invalid state is already set in the func + + if (vintxOpret.begin()[1] == 'B') { + if (!ValidateBetTx(cp, eval, vintx)) // check tx structure + return false; + } + else if (vintxOpret.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 vout to spend"); + } + break; + + case 'C': // set costbasis + if (!ValidateBetTx(cp, eval, vintx)) // first check bet tx + return false; + if (!ValidateCostbasisTx(cp, eval, tx, vintx)) + return false; + if (prevoutN != 1) { // check spending rules + return eval->Invalid("incorrect vout to spend"); + } + break; + + case 'F': // final tx + if (!ValidateBetTx(cp, eval, vintx)) // first check bet tx + return false; + if (!ValidateFinalTx(cp, eval, tx)) + return false; + if (prevoutN != 2) { // check spending rules + return eval->Invalid("incorrect vout to spend"); + } + break; + + default: + return eval->Invalid("invalid funcid"); + } + return true; } // end of consensus code // helper functions for rpc calls in rpcwallet.cpp -int64_t AddPricesInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,char *destaddr,int64_t total,int32_t maxinputs,uint256 vintxid,int32_t vinvout) +int64_t AddPricesInputs(struct CCcontract_info *cp, CMutableTransaction &mtx, char *destaddr, int64_t total, int32_t maxinputs, uint256 vintxid, int32_t vinvout) { - int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector origpubkey; CTransaction vintx; int32_t vout,n = 0; + int64_t nValue, price, totalinputs = 0; uint256 txid, hashBlock; std::vector origpubkey; CTransaction vintx; int32_t vout, n = 0; std::vector > unspentOutputs; - SetCCunspents(unspentOutputs,destaddr); - for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) + + SetCCunspents(unspentOutputs, destaddr); + for (std::vector >::const_iterator it = unspentOutputs.begin(); it != unspentOutputs.end(); it++) { txid = it->first.txhash; vout = (int32_t)it->first.index; - if ( vout == vinvout && txid == vintxid ) + if (vout == vinvout && txid == vintxid) continue; - if ( GetTransaction(txid,vintx,hashBlock,false) != 0 && vout < vintx.vout.size() ) + if (GetTransaction(txid, vintx, hashBlock, false) != 0 && vout < vintx.vout.size()) { - if ( (nValue= vintx.vout[vout].nValue) >= total/maxinputs && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 ) + if ((nValue = vintx.vout[vout].nValue) >= total / maxinputs && myIsutxo_spentinmempool(ignoretxid, ignorevin, txid, vout) == 0) { - if ( total != 0 && maxinputs != 0 ) - mtx.vin.push_back(CTxIn(txid,vout,CScript())); + if (total != 0 && maxinputs != 0) + mtx.vin.push_back(CTxIn(txid, vout, CScript())); nValue = it->second.satoshis; totalinputs += nValue; n++; - if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) ) + if ((total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs)) break; } } @@ -162,51 +367,55 @@ int64_t AddPricesInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,char return(totalinputs); } -UniValue prices_rawtxresult(UniValue &result,std::string rawtx,int32_t broadcastflag) +UniValue prices_rawtxresult(UniValue &result, std::string rawtx, int32_t broadcastflag) { CTransaction tx; - if ( rawtx.size() > 0 ) + if (rawtx.size() > 0) { - result.push_back(Pair("hex",rawtx)); - if ( DecodeHexTx(tx,rawtx) != 0 ) + result.push_back(Pair("hex", rawtx)); + if (DecodeHexTx(tx, rawtx) != 0) { - if ( broadcastflag != 0 && myAddtomempool(tx) != 0 ) + if (broadcastflag != 0 && myAddtomempool(tx) != 0) RelayTransaction(tx); - result.push_back(Pair("txid",tx.GetHash().ToString())); - result.push_back(Pair("result","success")); - } else result.push_back(Pair("error","decode hex")); - } else result.push_back(Pair("error","couldnt finalize CCtx")); + result.push_back(Pair("txid", tx.GetHash().ToString())); + result.push_back(Pair("result", "success")); + } + else + result.push_back(Pair("error", "decode hex")); + } + else + result.push_back(Pair("error", "couldnt finalize CCtx")); return(result); } -int32_t prices_syntheticvec(std::vector &vec,std::vector synthetic) +int32_t prices_syntheticvec(std::vector &vec, std::vector synthetic) { - int32_t i,need,ind,depth = 0; std::string opstr; uint16_t opcode,weight; + int32_t i, need, ind, depth = 0; std::string opstr; uint16_t opcode, weight; if (synthetic.size() == 0) { std::cerr << "prices_syntheticvec() expression is empty" << std::endl; return(-1); } - for (i=0; i= 0 ) + else if (!is_weight_str(opstr) && (ind = komodo_priceind(opstr.c_str())) >= 0) opcode = ind, need = 0; - else if ( (weight= atoi(opstr.c_str())) > 0 && weight < KOMODO_MAXPRICES ) + else if ((weight = atoi(opstr.c_str())) > 0 && weight < KOMODO_MAXPRICES) { opcode = PRICES_WEIGHT | weight; need = 1; @@ -231,9 +440,9 @@ int32_t prices_syntheticvec(std::vector &vec,std::vector } vec.push_back(opcode); } - if ( depth != 0 ) + if (depth != 0) { - fprintf(stderr,"prices_syntheticvec() depth.%d not empty\n",depth); + fprintf(stderr, "prices_syntheticvec() depth.%d not empty\n", depth); return(-5); } return(0); @@ -446,6 +655,7 @@ int64_t prices_costbasis(CTransaction bettx) uint256 txidCostbasis; int32_t vini; int32_t height; + if (CCgetspenttxid(txidCostbasis, vini, height, bettx.GetHash(), 1) < 0) { std::cerr << "prices_costbasis() no costbasis txid found" << std::endl; return 0; @@ -509,9 +719,11 @@ UniValue PricesBet(int64_t txfee, int64_t amount, int16_t leverage, std::vector< { int32_t nextheight = komodo_nextheight(); CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nextheight); UniValue result(UniValue::VOBJ); - struct CCcontract_info *cp, C; CPubKey pricespk, mypk; int64_t betamount, firstprice; + struct CCcontract_info *cp, C; + CPubKey pricespk, mypk; + int64_t betamount, firstprice; std::vector vec; - char myaddr[64]; + //char myaddr[64]; std::string rawtx; if (leverage > PRICES_MAXLEVERAGE || leverage < -PRICES_MAXLEVERAGE) @@ -525,7 +737,7 @@ UniValue PricesBet(int64_t txfee, int64_t amount, int16_t leverage, std::vector< txfee = PRICES_TXFEE; mypk = pubkey2pk(Mypubkey()); pricespk = GetUnspendable(cp, 0); - GetCCaddress(cp, myaddr, mypk); + //GetCCaddress(cp, myaddr, mypk); if (prices_syntheticvec(vec, synthetic) < 0 || (firstprice = prices_syntheticprice(vec, nextheight - 1, 1, leverage)) < 0 || vec.size() == 0 || vec.size() > 4096) { result.push_back(Pair("result", "error")); From ea4fc69f0cf0fa91bbc9d2a099852bbaf60e7ef6 Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 16 Apr 2019 23:20:57 +0500 Subject: [PATCH 053/242] test invalid costabasis --- src/cc/prices.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 0dd667c1f..817120fc3 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -316,6 +316,7 @@ bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx if (prevoutN != 1) { // check spending rules return eval->Invalid("incorrect vout to spend"); } + return eval->Invalid("test: costbasis is good"); break; case 'F': // final tx From bf4f084d082636610363473a63e07347ef046127 Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 16 Apr 2019 23:38:52 +0500 Subject: [PATCH 054/242] costbasis tx added txfee input --- src/cc/prices.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 817120fc3..6773a0314 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -843,12 +843,20 @@ UniValue PricesSetcostbasis(int64_t txfee, uint256 bettxid) result.push_back(Pair("rekt", 0)); prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice); - myfee = bettx.vout[1].nValue / 10; // fee for setting costbasis - result.push_back(Pair("myfee", myfee)); - mtx.vout.push_back(CTxOut(myfee, CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); - mtx.vout.push_back(MakeCC1vout(cp->evalcode, bettx.vout[1].nValue - myfee - txfee, pricespk)); - rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_costbasisopret(bettxid, mypk, firstheight + PRICES_DAYWINDOW /*- 1*/, costbasis)); - return(prices_rawtxresult(result, rawtx, 0)); + + if (AddNormalinputs(mtx, mypk, txfee, 64) >= txfee) + { + myfee = bettx.vout[1].nValue / 10; // fee for setting costbasis + result.push_back(Pair("myfee", myfee)); + + mtx.vout.push_back(CTxOut(myfee, CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); + mtx.vout.push_back(MakeCC1vout(cp->evalcode, bettx.vout[1].nValue - myfee - txfee, pricespk)); + rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_costbasisopret(bettxid, mypk, firstheight + PRICES_DAYWINDOW /*- 1*/, costbasis)); + return(prices_rawtxresult(result, rawtx, 0)); + } + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "not enough funds")); + return(result); } } result.push_back(Pair("result", "error")); From ec783e9a4e18099dc9979fe967a4ffd3624aa19b Mon Sep 17 00:00:00 2001 From: dimxy Date: Wed, 17 Apr 2019 00:00:27 +0500 Subject: [PATCH 055/242] txfee costbasis corr --- src/cc/prices.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 6773a0314..b996348a4 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -829,7 +829,7 @@ UniValue PricesSetcostbasis(int64_t txfee, uint256 bettxid) } addedbets = prices_batontxid(batontxid, bettx, bettxid); - mtx.vin.push_back(CTxIn(bettxid, 1, CScript())); // spend vin1 + mtx.vin.push_back(CTxIn(bettxid, 1, CScript())); // spend vin1 with betamount for (i = 0; i < PRICES_DAYWINDOW + PRICES_SMOOTHWIDTH; i++) // the last datum for 24h is the costbasis value { if ((profits = prices_syntheticprofits(true, costbasis, firstheight, firstheight + i, leverage, vec, positionsize, addedbets)) < 0) @@ -844,13 +844,13 @@ UniValue PricesSetcostbasis(int64_t txfee, uint256 bettxid) prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice); - if (AddNormalinputs(mtx, mypk, txfee, 64) >= txfee) + if (AddNormalinputs(mtx, mypk, txfee, 4) >= txfee) { myfee = bettx.vout[1].nValue / 10; // fee for setting costbasis result.push_back(Pair("myfee", myfee)); mtx.vout.push_back(CTxOut(myfee, CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); - mtx.vout.push_back(MakeCC1vout(cp->evalcode, bettx.vout[1].nValue - myfee - txfee, pricespk)); + mtx.vout.push_back(MakeCC1vout(cp->evalcode, bettx.vout[1].nValue - myfee, pricespk)); rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_costbasisopret(bettxid, mypk, firstheight + PRICES_DAYWINDOW /*- 1*/, costbasis)); return(prices_rawtxresult(result, rawtx, 0)); } From e5905381dfc218d67244e7d080c09807f958bae5 Mon Sep 17 00:00:00 2001 From: dimxy Date: Wed, 17 Apr 2019 00:10:14 +0500 Subject: [PATCH 056/242] corr not cond --- src/cc/prices.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index b996348a4..16c85440d 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -271,7 +271,7 @@ bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx for (auto vin : tx.vin) if (cp->ismyvin(vin.scriptSig)) { uint256 hashBlock; - if (myGetTransaction(vin.prevout.hash, vintx, hashBlock)) + if (!myGetTransaction(vin.prevout.hash, vintx, hashBlock)) return eval->Invalid("cannot load vin tx"); prevoutN = vin.prevout.n; ccVinCount++; From 1269c4d9d014e9deb9b4f73095b105c8929a1bde Mon Sep 17 00:00:00 2001 From: dimxy Date: Wed, 17 Apr 2019 00:24:24 +0500 Subject: [PATCH 057/242] corr CheckPricesOpret --- src/cc/prices.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 16c85440d..a027f6065 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -16,6 +16,8 @@ #include "CCassets.h" #include "CCPrices.h" +#define IS_CHARINSTR(c, str) (std::string(str).find((char)(c)) != std::string::npos) + /* CBOPRET creates trustless oracles, which can be used for making a synthetic cash settlement system based on real world prices; @@ -128,7 +130,8 @@ uint8_t prices_finalopretdecode(CScript scriptPubKey,uint256 &bettxid,int64_t &p bool CheckPricesOpret(const CTransaction & tx, vscript_t &opret) { - return (tx.vout.size() == 0 || !GetOpReturnData(tx.vout.back().scriptPubKey, opret) || opret.size() < 3 || opret.begin()[0] != EVAL_PRICES) || opret.begin()[1] == 0; + return !(tx.vout.size() < 1 || !GetOpReturnData(tx.vout.back().scriptPubKey, opret) || opret.size() < 3 || opret.begin()[0] != EVAL_PRICES || + IS_CHARINSTR(opret.begin()[1], "BACF")); } bool ValidateBetTx(struct CCcontract_info *cp, Eval *eval, const CTransaction & bettx) From 41cad58fe7a747e199a40f6edd73f93baca0ebda Mon Sep 17 00:00:00 2001 From: dimxy Date: Wed, 17 Apr 2019 00:30:00 +0500 Subject: [PATCH 058/242] yet CheckPriceOpret corr --- src/cc/prices.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index a027f6065..73a2ecd15 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -130,8 +130,7 @@ uint8_t prices_finalopretdecode(CScript scriptPubKey,uint256 &bettxid,int64_t &p bool CheckPricesOpret(const CTransaction & tx, vscript_t &opret) { - return !(tx.vout.size() < 1 || !GetOpReturnData(tx.vout.back().scriptPubKey, opret) || opret.size() < 3 || opret.begin()[0] != EVAL_PRICES || - IS_CHARINSTR(opret.begin()[1], "BACF")); + return tx.vout.size() > 0 && GetOpReturnData(tx.vout.back().scriptPubKey, opret) && opret.size() > 2 && opret.begin()[0] == EVAL_PRICES && IS_CHARINSTR(opret.begin()[1], "BACF"); } bool ValidateBetTx(struct CCcontract_info *cp, Eval *eval, const CTransaction & bettx) From aa728ec1a99c2e92b36a25fb3bcd3dfdee180032 Mon Sep 17 00:00:00 2001 From: dimxy Date: Wed, 17 Apr 2019 00:36:42 +0500 Subject: [PATCH 059/242] corr validate code op ! --- src/cc/prices.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 73a2ecd15..3477b1394 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -128,6 +128,7 @@ uint8_t prices_finalopretdecode(CScript scriptPubKey,uint256 &bettxid,int64_t &p return(0); } +// price opret basic validation and retrieval bool CheckPricesOpret(const CTransaction & tx, vscript_t &opret) { return tx.vout.size() > 0 && GetOpReturnData(tx.vout.back().scriptPubKey, opret) && opret.size() > 2 && opret.begin()[0] == EVAL_PRICES && IS_CHARINSTR(opret.begin()[1], "BACF"); @@ -260,7 +261,7 @@ bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx vscript_t vopret; // check basic opret rules: - if (CheckPricesOpret(tx, vopret)) + if (!CheckPricesOpret(tx, vopret)) return eval->Invalid("tx has no prices opreturn"); uint8_t funcId = vopret.begin()[1]; From c427df8e9852c5dcd20b3297b136bdb25b76f853 Mon Sep 17 00:00:00 2001 From: dimxy Date: Wed, 17 Apr 2019 11:07:10 +0500 Subject: [PATCH 060/242] corr vout0 check costbasis --- src/cc/prices.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 3477b1394..600ef08a1 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -195,17 +195,17 @@ bool ValidateCostbasisTx(struct CCcontract_info *cp, Eval *eval, const CTransact // check basic structure: if (costbasistx.vout.size() < 3 || costbasistx.vout.size() > 4) - return eval->Invalid("incorrect vout number for add funding tx"); + return eval->Invalid("incorrect vout count for costbasis tx"); vscript_t opret; if (prices_costbasisopretdecode(costbasistx.vout.back().scriptPubKey, bettxid, pk, height, amount) != 'C') - return eval->Invalid("cannot decode opreturn for setcostbasis tx"); + return eval->Invalid("cannot decode opreturn for costbasis tx"); pricespk = GetUnspendable(cp, 0); - if (MakeCC1vout(cp->evalcode, costbasistx.vout[0].nValue, pk) != costbasistx.vout[0]) - return eval->Invalid("cannot validate vout0 in add funding tx with pk from opreturn"); + if (CTxOut(costbasistx.vout[0].nValue, CScript() << ParseHex(HexStr(pk)) << OP_CHECKSIG) != costbasistx.vout[0]) //might go to any pk who calculated costbasis + return eval->Invalid("cannot validate vout0 in costbasis tx with pk from opreturn"); if (MakeCC1vout(cp->evalcode, costbasistx.vout[1].nValue, pricespk) != costbasistx.vout[1]) - return eval->Invalid("cannot validate vout1 in add funding tx with global pk"); + return eval->Invalid("cannot validate vout1 in costbasis tx with global pk"); if (bettx.vout.size() < 1) // maybe this is already checked outside, but it is safe to check here too and have encapsulated check return eval->Invalid("incorrect bettx"); @@ -218,8 +218,9 @@ bool ValidateCostbasisTx(struct CCcontract_info *cp, Eval *eval, const CTransact int64_t positionsize, firstprice; int32_t firstheight; int16_t leverage; + CPubKey betpk; std::vector vec; - if (prices_betopretdecode(bettx.vout.back().scriptPubKey, pk, firstheight, positionsize, leverage, firstprice, vec, tokenid) != 'B') + if (prices_betopretdecode(bettx.vout.back().scriptPubKey, betpk, firstheight, positionsize, leverage, firstprice, vec, tokenid) != 'B') return eval->Invalid("cannot decode opreturn for bet tx"); if( firstheight + PRICES_DAYWINDOW + PRICES_SMOOTHWIDTH > chainActive.Height() ) @@ -270,7 +271,7 @@ bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx vscript_t vintxOpret; int32_t ccVinCount = 0; int32_t prevoutN = 0; - // load vintx: + // load vintx (might be either bet or add funding tx): for (auto vin : tx.vin) if (cp->ismyvin(vin.scriptSig)) { uint256 hashBlock; @@ -651,6 +652,7 @@ void prices_betjson(UniValue &result,int64_t profits,int64_t costbasis,int64_t p result.push_back(Pair("firstprice",ValueFromAmount(firstprice))); } +// retrives costbasis from a tx spending bettx vout1 int64_t prices_costbasis(CTransaction bettx) { int64_t costbasis = 0; From 1eccfc7485b0e6f70179e26f9f9a70661e2bbda3 Mon Sep 17 00:00:00 2001 From: dimxy Date: Wed, 17 Apr 2019 15:20:35 +0500 Subject: [PATCH 061/242] corr errors after rebase added comments --- src/komodo_defs.h | 2 +- src/komodo_gateway.h | 3 ++- src/rpc/blockchain.cpp | 33 ++++++++++++++++++++------------- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/komodo_defs.h b/src/komodo_defs.h index ee44132bc..94d7300aa 100644 --- a/src/komodo_defs.h +++ b/src/komodo_defs.h @@ -101,7 +101,7 @@ int32_t komodo_dpowconfs(int32_t height,int32_t numconfs); int8_t komodo_segid(int32_t nocache,int32_t height); int32_t komodo_heightpricebits(uint64_t *seedp,uint32_t *heightbits,int32_t nHeight); char *komodo_pricename(char *name,int32_t ind); -int32_t komodo_priceind(char *symbol); +int32_t komodo_priceind(const char *symbol); int32_t komodo_pricesinit(); int64_t komodo_priceave(int64_t *tmpbuf,int64_t *correlated,int32_t cskip); int64_t komodo_pricecorrelated(uint64_t seed,int32_t ind,uint32_t *rawprices,int32_t rawskip,uint32_t *nonzprices,int32_t smoothwidth); diff --git a/src/komodo_gateway.h b/src/komodo_gateway.h index 3f1d5ec5e..5ce9d223f 100644 --- a/src/komodo_gateway.h +++ b/src/komodo_gateway.h @@ -2448,6 +2448,7 @@ int32_t komodo_priceind(const char *symbol) return(-1); } +// returns price value which is in a 10% interval for more than 50% points for the preceding 24 hours int64_t komodo_pricecorrelated(uint64_t seed,int32_t ind,uint32_t *rawprices,int32_t rawskip,uint32_t *nonzprices,int32_t smoothwidth) { int32_t i,j,k,n,iter,correlation,maxcorrelation=0; int64_t firstprice,price,sum,den,mult,refprice,lowprice,highprice; @@ -2486,7 +2487,7 @@ int64_t komodo_pricecorrelated(uint64_t seed,int32_t ind,uint32_t *rawprices,int //fprintf(stderr,"%.1f ",(double)price/10000); sum += price; correlation++; - if ( correlation > (PRICES_DAYWINDOW>>1) ) + if ( correlation > (PRICES_DAYWINDOW>>1) ) // if there are more than 50% raw price values lay within +/-5% interval from the refprice picked from random pos { if ( nonzprices == 0 ) return(refprice * mult); diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 550355cff..26a7f6867 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -43,6 +43,9 @@ #include +#include "cc/CCinclude.h" +#include "cc/CCPrices.h" + using namespace std; extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry); @@ -1165,7 +1168,7 @@ UniValue paxprice(const UniValue& params, bool fHelp) return(-1); for (i=0; i vexpr; @@ -1349,7 +1353,7 @@ UniValue pricesaddfunding(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 2) throw runtime_error("pricesaddfunding bettxid amount\n" - "where amount is in satoshis\n"); + "where amount is in satoshis\n"); LOCK(cs_main); UniValue ret(UniValue::VOBJ); @@ -1358,11 +1362,11 @@ UniValue pricesaddfunding(const UniValue& params, bool fHelp) CAmount txfee = 10000; uint256 bettxid = Parseuint256(params[0].get_str().c_str()); - if( bettxid.IsNull() ) + if (bettxid.IsNull()) throw runtime_error("invalid bettxid\n"); CAmount amount = atoll(params[1].get_str().c_str()); - if( amount <= 0 ) + if (amount <= 0) throw runtime_error("invalid amount\n"); return PricesAddFunding(txfee, bettxid, amount); @@ -1380,7 +1384,7 @@ UniValue pricessetcostbasis(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_INVALID_PARAMETER, "only -ac_cbopret chains have prices"); uint256 bettxid = Parseuint256(params[0].get_str().c_str()); - if( bettxid.IsNull() ) + if (bettxid.IsNull()) throw runtime_error("invalid bettxid\n"); int64_t txfee = 10000; @@ -1388,6 +1392,7 @@ UniValue pricessetcostbasis(const UniValue& params, bool fHelp) return PricesSetcostbasis(txfee, bettxid); } +// pricescashout rpc implementation UniValue pricescashout(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) @@ -1407,6 +1412,7 @@ UniValue pricescashout(const UniValue& params, bool fHelp) return PricesCashout(txfee, bettxid); } +// pricesrekt rpc implementation UniValue pricesrekt(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 2) @@ -1428,6 +1434,7 @@ UniValue pricesrekt(const UniValue& params, bool fHelp) return PricesRekt(txfee, bettxid, height); } + UniValue gettxout(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 2 || params.size() > 3) @@ -2057,4 +2064,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 From e66d51a261ffde9610a6e20c2cb1fcc0c320c0f3 Mon Sep 17 00:00:00 2001 From: dimxy Date: Wed, 17 Apr 2019 15:55:15 +0500 Subject: [PATCH 062/242] komodo_gateway.h back into fsm state plus some comments --- src/komodo_gateway.h | 58 ++++++++---------------------------------- src/rpc/blockchain.cpp | 4 +-- 2 files changed, 12 insertions(+), 50 deletions(-) diff --git a/src/komodo_gateway.h b/src/komodo_gateway.h index 5ce9d223f..0ae1b6b44 100644 --- a/src/komodo_gateway.h +++ b/src/komodo_gateway.h @@ -16,23 +16,6 @@ // paxdeposit equivalent in reverse makes opreturn and KMD does the same in reverse #include "komodo_defs.h" -#ifdef _WIN32 -#ifdef _MSC_VER -#define sleep(x) Sleep(1000*(x)) -#endif -#endif - -#ifdef _WIN32 -#ifdef _MSC_VER -void usleep(int32_t micros) -{ - if (micros < 1000) - Sleep(1); - else Sleep(micros / 1000); -} -#endif -#endif - /*#include "secp256k1/include/secp256k1.h" #include "secp256k1/include/secp256k1_schnorrsig.h" #include "secp256k1/include/secp256k1_musig.h" @@ -2071,13 +2054,10 @@ int32_t get_stockprices(uint32_t now,uint32_t *prices,std::vector s uint32_t get_dailyfx(uint32_t *prices) { //{"base":"USD","rates":{"BGN":1.74344803,"NZD":1.471652701,"ILS":3.6329113924,"RUB":65.1997682296,"CAD":1.3430201462,"USD":1.0,"PHP":52.8641469068,"CHF":0.9970582992,"AUD":1.4129078267,"JPY":110.6792654662,"TRY":5.6523444464,"HKD":7.8499732573,"MYR":4.0824567659,"HRK":6.6232840078,"CZK":22.9862720628,"IDR":14267.4986628633,"DKK":6.6551078624,"NOK":8.6806917454,"HUF":285.131039401,"GBP":0.7626582278,"MXN":19.4183455161,"THB":31.8702085933,"ISK":122.5708682475,"ZAR":14.7033339276,"BRL":3.9750401141,"SGD":1.3573720806,"PLN":3.8286682118,"INR":69.33187734,"KRW":1139.1602781244,"RON":4.2423783206,"CNY":6.7387234801,"SEK":9.3385630237,"EUR":0.8914244963},"date":"2019-03-28"} - char url[512],*datestr; cJSON *json,*rates; int32_t i; uint32_t datenum=0,price = 0; - sprintf(url,"https://api.openrates.io/latest?base=USD"); if ( (json= get_urljson(url)) != 0 ) //if ( (json= send_curl(url,(char *)"dailyfx")) != 0 ) { - std::cerr << "Forex USD rates:" << std::endl; if ( (rates= jobj(json,(char *)"rates")) != 0 ) { for (i=0; i strvec) { int32_t i,errs=0; uint32_t price; char *symbol; - std::cerr << "Crypto binance BTC rates:" << std::endl; - for (i=0; i= PRICES_DAYWINDOW ) @@ -2487,11 +2451,11 @@ int64_t komodo_pricecorrelated(uint64_t seed,int32_t ind,uint32_t *rawprices,int //fprintf(stderr,"%.1f ",(double)price/10000); sum += price; correlation++; - if ( correlation > (PRICES_DAYWINDOW>>1) ) // if there are more than 50% raw price values lay within +/-5% interval from the refprice picked from random pos + if ( correlation > (PRICES_DAYWINDOW>>1) ) { if ( nonzprices == 0 ) return(refprice * mult); - fprintf(stderr,"-> %.4f\n",(double)sum*mult/correlation); + //fprintf(stderr,"-> %.4f\n",(double)sum*mult/correlation); //return(sum*mult/correlation); n = 0; i = (iter + seed) % PRICES_DAYWINDOW; @@ -2509,12 +2473,12 @@ int64_t komodo_pricecorrelated(uint64_t seed,int32_t ind,uint32_t *rawprices,int else { nonzprices[i] = price; - fprintf(stderr,"(%d %u) ",i,rawprices[i*rawskip]); + //fprintf(stderr,"(%d %u) ",i,rawprices[i*rawskip]); n++; } } } - fprintf(stderr,"ind.%d iter.%d j.%d i.%d n.%d correlation.%d ref %llu -> %llu\n",ind,iter,j,i,n,correlation,(long long)refprice,(long long)sum/correlation); + //fprintf(stderr,"ind.%d iter.%d j.%d i.%d n.%d correlation.%d ref %llu -> %llu\n",ind,iter,j,i,n,correlation,(long long)refprice,(long long)sum/correlation); if ( n != correlation ) return(-1); sum = den = n = 0; @@ -2537,8 +2501,7 @@ int64_t komodo_pricecorrelated(uint64_t seed,int32_t ind,uint32_t *rawprices,int fprintf(stderr,"seed.%llu n.%d vs correlation.%d sum %llu, den %llu\n",(long long)seed,n,correlation,(long long)sum,(long long)den); return(-1); } - std::cerr << "sum=" << sum << " mult=" << mult << " den=" << den << std::endl; - fprintf(stderr,"firstprice.%llu weighted -> %.8f\n",(long long)firstprice,((double)(sum*mult) / den) / COIN); + //fprintf(stderr,"firstprice.%llu weighted -> %.8f\n",(long long)firstprice,((double)(sum*mult) / den) / COIN); return((sum * mult) / den); } } @@ -2838,4 +2801,3 @@ int32_t komodo_priceget(int64_t *buf64,int32_t ind,int32_t height,int32_t numblo pthread_mutex_unlock(&pricemutex); return(retval); } - diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 26a7f6867..afb81e706 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1158,11 +1158,11 @@ UniValue paxprice(const UniValue& params, bool fHelp) } return ret; } - +// fills pricedata with raw price, correlated and smoothed values for numblock /*int32_t prices_extract(int64_t *pricedata,int32_t firstheight,int32_t numblocks,int32_t ind) { int32_t height,i,n,width,numpricefeeds = -1; uint64_t seed,ignore,rngval; uint32_t rawprices[1440*6],*ptr; int64_t *tmpbuf; - width = numblocks+PRICES_DAYWINDOW*2+PRICES_SMOOTHWIDTH; + width = numblocks+PRICES_DAYWINDOW*2+PRICES_SMOOTHWIDTH; // need 2*PRICES_DAYWINDOW previous raw price points to calc PRICES_DAYWINDOW correlated points to calc, in turn, smoothed point komodo_heightpricebits(&seed,rawprices,firstheight + numblocks - 1); if ( firstheight < width ) return(-1); From 6a1d7d5bbe27364dab39b27bd78257abd27dc9a8 Mon Sep 17 00:00:00 2001 From: dimxy Date: Wed, 17 Apr 2019 19:34:56 +0500 Subject: [PATCH 063/242] komodo_defs.h reset --- src/komodo_defs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/komodo_defs.h b/src/komodo_defs.h index 94d7300aa..c42c725f8 100644 --- a/src/komodo_defs.h +++ b/src/komodo_defs.h @@ -101,7 +101,7 @@ int32_t komodo_dpowconfs(int32_t height,int32_t numconfs); int8_t komodo_segid(int32_t nocache,int32_t height); int32_t komodo_heightpricebits(uint64_t *seedp,uint32_t *heightbits,int32_t nHeight); char *komodo_pricename(char *name,int32_t ind); -int32_t komodo_priceind(const char *symbol); +int32_t komodo_priceind(char *symbol); int32_t komodo_pricesinit(); int64_t komodo_priceave(int64_t *tmpbuf,int64_t *correlated,int32_t cskip); int64_t komodo_pricecorrelated(uint64_t seed,int32_t ind,uint32_t *rawprices,int32_t rawskip,uint32_t *nonzprices,int32_t smoothwidth); @@ -112,4 +112,4 @@ int32_t komodo_priceget(int64_t *buf64,int32_t ind,int32_t height,int32_t numblo uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue,int32_t tipheight); -#endif +#endif \ No newline at end of file From c99acae5fa58b02f7ad945d3fca29aa7753f7f7a Mon Sep 17 00:00:00 2001 From: dimxy Date: Wed, 17 Apr 2019 19:55:30 +0500 Subject: [PATCH 064/242] switched to komodo_pricesget --- src/cc/prices.cpp | 2 +- src/komodo_defs.h | 2 +- src/komodo_gateway.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 600ef08a1..e9265c51a 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -472,7 +472,7 @@ int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t { case 0: // indices pricestack[depth] = 0; - if (prices_extract(pricedata, height, 1, value) == 0) + if (komodo_priceget(pricedata, height, 1, value) == 0) { // push price to the prices stack if (!minmax) diff --git a/src/komodo_defs.h b/src/komodo_defs.h index c42c725f8..2fcd29df3 100644 --- a/src/komodo_defs.h +++ b/src/komodo_defs.h @@ -101,7 +101,7 @@ int32_t komodo_dpowconfs(int32_t height,int32_t numconfs); int8_t komodo_segid(int32_t nocache,int32_t height); int32_t komodo_heightpricebits(uint64_t *seedp,uint32_t *heightbits,int32_t nHeight); char *komodo_pricename(char *name,int32_t ind); -int32_t komodo_priceind(char *symbol); +int32_t komodo_priceind(const char *symbol); int32_t komodo_pricesinit(); int64_t komodo_priceave(int64_t *tmpbuf,int64_t *correlated,int32_t cskip); int64_t komodo_pricecorrelated(uint64_t seed,int32_t ind,uint32_t *rawprices,int32_t rawskip,uint32_t *nonzprices,int32_t smoothwidth); diff --git a/src/komodo_gateway.h b/src/komodo_gateway.h index 0ae1b6b44..1fafcc856 100644 --- a/src/komodo_gateway.h +++ b/src/komodo_gateway.h @@ -2401,7 +2401,7 @@ char *komodo_pricename(char *name,int32_t ind) return(0); } // finds index for its symbol name -int32_t komodo_priceind(char *symbol) +int32_t komodo_priceind(const char *symbol) { char name[65]; int32_t i,n = (int32_t)(komodo_cbopretsize(ASSETCHAINS_CBOPRET) / sizeof(uint32_t)); for (i=1; i Date: Wed, 17 Apr 2019 21:02:32 +0500 Subject: [PATCH 065/242] ccflag = false --- src/cc/prices.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index e9265c51a..56f357257 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1035,11 +1035,10 @@ UniValue PricesList() CPubKey pk, pricespk; std::vector vec; CTransaction vintx; - char str[65]; cp = CCinit(&C, EVAL_PRICES); pricespk = GetUnspendable(cp, 0); - SetCCtxids(addressIndex, cp->normaladdr); + SetCCtxids(addressIndex, cp->normaladdr, false); for (std::vector >::const_iterator it = addressIndex.begin(); it != addressIndex.end(); it++) { txid = it->first.txhash; @@ -1047,7 +1046,7 @@ UniValue PricesList() { if (vintx.vout.size() > 0 && prices_betopretdecode(vintx.vout[vintx.vout.size() - 1].scriptPubKey, pk, height, amount, leverage, firstprice, vec, tokenid) == 'B') { - result.push_back(uint256_str(str, txid)); + result.push_back(txid.GetHex()); } } } From 8a46a75d0ea7d80e6e3f73d737db653947851706 Mon Sep 17 00:00:00 2001 From: dimxy Date: Wed, 17 Apr 2019 21:59:25 +0500 Subject: [PATCH 066/242] skip till 2100 --- src/cc/prices.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 56f357257..6331f1bec 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -261,6 +261,9 @@ bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx { vscript_t vopret; + + if (strcmp(ASSETCHAINS_SYMBOL, "REKT0") == 0 && chainActive.Height() < 2100) + return true; // check basic opret rules: if (!CheckPricesOpret(tx, vopret)) return eval->Invalid("tx has no prices opreturn"); From a80dd2763e9191fdf0ea933e6fc16bf8315fcb3c Mon Sep 17 00:00:00 2001 From: dimxy Date: Thu, 18 Apr 2019 21:17:29 +0500 Subject: [PATCH 067/242] 1of2 change to 1 for bettx --- src/cc/prices.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 6331f1bec..a800e9c23 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -156,7 +156,7 @@ bool ValidateBetTx(struct CCcontract_info *cp, Eval *eval, const CTransaction & return eval->Invalid("cannot validate vout0 in bet tx with pk from opreturn"); if (MakeCC1vout(cp->evalcode, bettx.vout[1].nValue, pricespk) != bettx.vout[1]) return eval->Invalid("cannot validate vout1 in bet tx with global pk"); - if( MakeCC1of2vout(cp->evalcode, bettx.vout[2].nValue, pk, pricespk) != bettx.vout[2] ) + if( MakeCC1vout(cp->evalcode, bettx.vout[2].nValue, pricespk) != bettx.vout[2] ) return eval->Invalid("cannot validate 1of2 vout2 in bet tx with pk from opreturn"); return true; @@ -323,7 +323,7 @@ bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx if (prevoutN != 1) { // check spending rules return eval->Invalid("incorrect vout to spend"); } - return eval->Invalid("test: costbasis is good"); + //return eval->Invalid("test: costbasis is good"); break; case 'F': // final tx @@ -758,7 +758,7 @@ UniValue PricesBet(int64_t txfee, int64_t amount, int16_t leverage, std::vector< betamount = (amount * 199) / 200; 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(MakeCC1of2vout(cp->evalcode, betamount, pricespk, mypk)); + mtx.vout.push_back(MakeCC1vout(cp->evalcode, betamount, pricespk)); mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(HexStr(pricespk)) << OP_CHECKSIG)); // marker rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_betopret(mypk, nextheight - 1, amount, leverage, firstprice, vec, zeroid)); return(prices_rawtxresult(result, rawtx, 0)); From f6a0ede3868260f0670c9cb7bffa0a21d871a01a Mon Sep 17 00:00:00 2001 From: dimxy Date: Thu, 18 Apr 2019 21:44:46 +0500 Subject: [PATCH 068/242] corr priceget params --- src/cc/prices.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index a800e9c23..92500e6c0 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -475,7 +475,7 @@ int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t { case 0: // indices pricestack[depth] = 0; - if (komodo_priceget(pricedata, height, 1, value) == 0) + if (komodo_priceget(pricedata, value, height, 1) == 0) { // push price to the prices stack if (!minmax) From 26724cae9038ff17a0f487205370ebb28bb2136e Mon Sep 17 00:00:00 2001 From: dimxy Date: Thu, 18 Apr 2019 21:53:53 +0500 Subject: [PATCH 069/242] pricesget ret check corr --- src/cc/prices.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 92500e6c0..91d3ad1b0 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -437,7 +437,7 @@ int32_t prices_syntheticvec(std::vector &vec, std::vector return(-3); } depth -= need; - std::cerr << "opcode=" << opcode << " opstr=" << opstr << " need=" << need << " depth-=need=" << depth << std::endl; + std::cerr << "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; @@ -475,7 +475,7 @@ int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t { case 0: // indices pricestack[depth] = 0; - if (komodo_priceget(pricedata, value, height, 1) == 0) + if (komodo_priceget(pricedata, value, height, 1) >= 0) { // push price to the prices stack if (!minmax) From a031847df53cc5fcb3d7211369fe7d5537329c60 Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 19 Apr 2019 01:08:02 +0500 Subject: [PATCH 070/242] leverage check 0 coin as double --- src/rpc/blockchain.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index afb81e706..fefec1337 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1324,7 +1324,10 @@ UniValue prices(const UniValue& params, bool fHelp) UniValue pricesbet(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 3) - throw runtime_error("pricesbet amount leverage \"synthetic-expression\"\n"); + throw runtime_error("pricesbet amount leverage \"synthetic-expression\"\n" + "amount is in coins\n" + "leverage is integer non-zero value, positive for long, negative for short position\n" + "synthetic-expression example \"BTC_USD, 1\"\n"); LOCK(cs_main); UniValue ret(UniValue::VOBJ); @@ -1332,8 +1335,10 @@ UniValue pricesbet(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_INVALID_PARAMETER, "only -ac_cbopret chains have prices"); CAmount txfee = 10000; - CAmount amount = atoll(params[0].get_str().c_str()); + CAmount amount = atof(params[0].get_str().c_str()) * COIN; int16_t leverage = (int16_t)atoi(params[1].get_str().c_str()); + if (leverage == 0) + throw runtime_error("invalid leverage\n"); std::string sexpr = params[2].get_str(); std::vector vexpr; From acd979ea067bdc414e2ae3632c2fa0a6589c905e Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 19 Apr 2019 01:16:12 +0500 Subject: [PATCH 071/242] set costbasis before 24 as temp show it txid --- src/cc/prices.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 91d3ad1b0..60b8dff51 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -656,14 +656,15 @@ void prices_betjson(UniValue &result,int64_t profits,int64_t costbasis,int64_t p } // retrives costbasis from a tx spending bettx vout1 -int64_t prices_costbasis(CTransaction bettx) +int64_t prices_costbasis(CTransaction bettx, uint256 &txidCostbasis) { int64_t costbasis = 0; // if vout1 is spent, follow and extract costbasis from opreturn //uint8_t prices_costbasisopretdecode(CScript scriptPubKey,uint256 &bettxid,CPubKey &pk,int32_t &height,int64_t &costbasis) - uint256 txidCostbasis; + //uint256 txidCostbasis; int32_t vini; int32_t height; + txidCostbasis = zeroid; if (CCgetspenttxid(txidCostbasis, vini, height, bettx.GetHash(), 1) < 0) { std::cerr << "prices_costbasis() no costbasis txid found" << std::endl; @@ -886,7 +887,8 @@ UniValue PricesRekt(int64_t txfee, uint256 bettxid, int32_t rektheight) { if (prices_betopretdecode(bettx.vout[numvouts - 1].scriptPubKey, pk, firstheight, positionsize, leverage, firstprice, vec, tokenid) == 'B') { - costbasis = prices_costbasis(bettx); + uint256 costbasistxid; + costbasis = prices_costbasis(bettx, costbasistxid); if (costbasis == 0) { result.push_back(Pair("result", "error")); result.push_back(Pair("error", "costbasis not defined yet")); @@ -951,7 +953,9 @@ UniValue PricesCashout(int64_t txfee, uint256 bettxid) { if (prices_betopretdecode(bettx.vout[numvouts - 1].scriptPubKey, pk, firstheight, positionsize, leverage, firstprice, vec, tokenid) == 'B') { - costbasis = prices_costbasis(bettx); + uint256 costbasistxid; + + costbasis = prices_costbasis(bettx, costbasistxid); if (costbasis == 0) { result.push_back(Pair("result", "error")); result.push_back(Pair("error", "costbasis not defined yet")); @@ -997,6 +1001,7 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) std::vector vec; CPubKey pk, mypk, pricespk; std::string rawtx; + uint256 costbasistxid; if (myGetTransaction(bettxid, bettx, hashBlock) != 0 && (numvouts = bettx.vout.size()) > 3) { @@ -1010,9 +1015,9 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) if (refheight == 0) refheight = komodo_nextheight()-1; - costbasis = prices_costbasis(bettx); + costbasis = prices_costbasis(bettx, costbasistxid); addedbets = prices_batontxid(batontxid, bettx, bettxid); - if ((profits = prices_syntheticprofits(false, costbasis, firstheight, refheight, leverage, vec, positionsize, addedbets)) < 0) + if ((profits = prices_syntheticprofits(true, costbasis, firstheight, refheight, leverage, vec, positionsize, addedbets)) < 0) { result.push_back(Pair("rekt", 1)); result.push_back(Pair("rektfee", (positionsize + addedbets) / 500)); @@ -1020,6 +1025,8 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) else result.push_back(Pair("rekt", 0)); result.push_back(Pair("batontxid", batontxid.GetHex())); + if(!costbasistxid.IsNull()) + result.push_back(Pair("costbasistxid", costbasistxid.GetHex())); prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice); result.push_back(Pair("height", (int64_t)refheight)); return(result); From 771273f195b94869eef5c918350710c34ad78ab2 Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 19 Apr 2019 01:29:55 +0500 Subject: [PATCH 072/242] costbasis logging --- src/cc/prices.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 60b8dff51..26bc5b403 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -628,14 +628,22 @@ int64_t prices_syntheticprofits(bool calcCostbasis, int64_t &costbasis, int32_t } if (calcCostbasis) { if (minmax) { // if we are within day window, set costbasis to max or min price value - if (leverage > 0 && price > costbasis) + if (leverage > 0 && price > costbasis) { costbasis = price; // set costbasis - else if (leverage < 0 && (costbasis == 0 || price < costbasis)) + std::cerr << "prices_syntheticprofits() minmax costbasis=" << costbasis << " price=" << price << std::endl; + } + else if (leverage < 0 && (costbasis == 0 || price < costbasis)) { costbasis = price; - // else -> use the previous value + std::cerr << "prices_syntheticprofits() minmax costbasis=" << costbasis << " price=" << price << std::endl; + } + else { //-> use the previous value + std::cerr << "prices_syntheticprofits() unchanged costbasis=" << costbasis << " price=" << price << std::endl; + } + } else { costbasis = price; // smoothed value + std::cerr << "prices_syntheticprofits() smoothed costbasis=" << costbasis << " price=" << price << std::endl; } } From d7565e75b252b1e6fda0676a2401eb446fc65edb Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 19 Apr 2019 01:36:26 +0500 Subject: [PATCH 073/242] lev log --- src/cc/prices.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 26bc5b403..7228e478b 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -637,7 +637,7 @@ int64_t prices_syntheticprofits(bool calcCostbasis, int64_t &costbasis, int32_t std::cerr << "prices_syntheticprofits() minmax costbasis=" << costbasis << " price=" << price << std::endl; } else { //-> use the previous value - std::cerr << "prices_syntheticprofits() unchanged costbasis=" << costbasis << " price=" << price << std::endl; + std::cerr << "prices_syntheticprofits() unchanged costbasis=" << costbasis << " price=" << price << " leverage=" << leverage << std::endl; } } @@ -1025,6 +1025,7 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) costbasis = prices_costbasis(bettx, costbasistxid); addedbets = prices_batontxid(batontxid, bettx, bettxid); + bool calcCostbasis = costbasis == 0 ? true : false; if ((profits = prices_syntheticprofits(true, costbasis, firstheight, refheight, leverage, vec, positionsize, addedbets)) < 0) { result.push_back(Pair("rekt", 1)); From 24a35a4bb05574527aee0fc6b5fd402f8858018b Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 19 Apr 2019 01:44:31 +0500 Subject: [PATCH 074/242] more lev log --- src/cc/prices.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 7228e478b..b07ba4551 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -60,6 +60,7 @@ CScript prices_betopret(CPubKey mypk,int32_t height,int64_t amount,int16_t lever { CScript opret; opret << OP_RETURN << E_MARSHAL(ss << EVAL_PRICES << 'B' << mypk << height << amount << leverage << firstprice << vec << tokenid); + std::cerr << "prices_betopret() leverage=" << leverage << std::endl; return(opret); } @@ -69,6 +70,7 @@ uint8_t prices_betopretdecode(CScript scriptPubKey,CPubKey &pk,int32_t &height,i GetOpReturnData(scriptPubKey,vopret); if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> pk; ss >> height; ss >> amount; ss >> leverage; ss >> firstprice; ss >> vec; ss >> tokenid) != 0 && e == EVAL_PRICES && f == 'B' ) { + std::cerr << "prices_betopretdecode() leverage=" << leverage << std::endl; return(f); } return(0); From 7e312afc9e83da472569719c5aeaf3211652cde0 Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 19 Apr 2019 02:18:00 +0500 Subject: [PATCH 075/242] char ptrs --- src/cc/prices.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index b07ba4551..31e316c6d 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -67,9 +67,13 @@ CScript prices_betopret(CPubKey mypk,int32_t height,int64_t amount,int16_t lever uint8_t prices_betopretdecode(CScript scriptPubKey,CPubKey &pk,int32_t &height,int64_t &amount,int16_t &leverage,int64_t &firstprice,std::vector &vec,uint256 &tokenid) { std::vector vopret; uint8_t e,f; + unsigned char u, l; GetOpReturnData(scriptPubKey,vopret); - if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> pk; ss >> height; ss >> amount; ss >> leverage; ss >> firstprice; ss >> vec; ss >> tokenid) != 0 && e == EVAL_PRICES && f == 'B' ) + if (vopret.size() > 2 && E_UNMARSHAL(vopret, ss >> e; ss >> f; ss >> pk; ss >> height; ss >> amount; ss >> l; ss >> u; ss >> firstprice; ss >> vec; ss >> tokenid) != 0 && e == EVAL_PRICES && f == 'B') { + unsigned char *p = (unsigned char*)&leverage; + *p = l; + *(p + 1) = u; std::cerr << "prices_betopretdecode() leverage=" << leverage << std::endl; return(f); } From f0f091ba0a5e73bcea28737cd05ffe3b2c9b48ee Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 19 Apr 2019 02:31:07 +0500 Subject: [PATCH 076/242] lev deser restored --- src/cc/prices.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 31e316c6d..42559fd9d 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -60,21 +60,16 @@ CScript prices_betopret(CPubKey mypk,int32_t height,int64_t amount,int16_t lever { CScript opret; opret << OP_RETURN << E_MARSHAL(ss << EVAL_PRICES << 'B' << mypk << height << amount << leverage << firstprice << vec << tokenid); - std::cerr << "prices_betopret() leverage=" << leverage << std::endl; return(opret); } uint8_t prices_betopretdecode(CScript scriptPubKey,CPubKey &pk,int32_t &height,int64_t &amount,int16_t &leverage,int64_t &firstprice,std::vector &vec,uint256 &tokenid) { std::vector vopret; uint8_t e,f; - unsigned char u, l; + GetOpReturnData(scriptPubKey,vopret); - if (vopret.size() > 2 && E_UNMARSHAL(vopret, ss >> e; ss >> f; ss >> pk; ss >> height; ss >> amount; ss >> l; ss >> u; ss >> firstprice; ss >> vec; ss >> tokenid) != 0 && e == EVAL_PRICES && f == 'B') + if (vopret.size() > 2 && E_UNMARSHAL(vopret, ss >> e; ss >> f; ss >> pk; ss >> height; ss >> amount; ss >> leverage; ss >> firstprice; ss >> vec; ss >> tokenid) != 0 && e == EVAL_PRICES && f == 'B') { - unsigned char *p = (unsigned char*)&leverage; - *p = l; - *(p + 1) = u; - std::cerr << "prices_betopretdecode() leverage=" << leverage << std::endl; return(f); } return(0); From d3dbbacaefc24cbd66fa649d39a82aaf8343022a Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 19 Apr 2019 02:33:52 +0500 Subject: [PATCH 077/242] set calcCostbasis for temp --- src/cc/prices.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 42559fd9d..96042b076 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1027,7 +1027,7 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) costbasis = prices_costbasis(bettx, costbasistxid); addedbets = prices_batontxid(batontxid, bettx, bettxid); bool calcCostbasis = costbasis == 0 ? true : false; - if ((profits = prices_syntheticprofits(true, costbasis, firstheight, refheight, leverage, vec, positionsize, addedbets)) < 0) + if ((profits = prices_syntheticprofits(calcCostbasis, costbasis, firstheight, refheight, leverage, vec, positionsize, addedbets)) < 0) { result.push_back(Pair("rekt", 1)); result.push_back(Pair("rektfee", (positionsize + addedbets) / 500)); From 9642776c0a1ea44d3a54cdf7d20de7fa78d97aa7 Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 19 Apr 2019 02:47:51 +0500 Subject: [PATCH 078/242] profits log --- src/cc/prices.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 96042b076..e1c64782c 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -649,7 +649,10 @@ int64_t prices_syntheticprofits(bool calcCostbasis, int64_t &costbasis, int32_t } profits = costbasis > 0 ? ((price * SATOSHIDEN) / costbasis) - SATOSHIDEN : 0; + std::cerr << "prices_syntheticprofits() profits1=" << profits << std::endl; profits *= leverage * positionsize; + std::cerr << "prices_syntheticprofits() profits2=" << profits << std::endl; + return(positionsize + addedbets + profits); } From 5fa528c0ab5b7a192f9c3ac2e3d9c151da42c9ae Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 19 Apr 2019 03:00:16 +0500 Subject: [PATCH 079/242] try double profits --- src/cc/prices.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index e1c64782c..4579371fc 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -649,11 +649,20 @@ int64_t prices_syntheticprofits(bool calcCostbasis, int64_t &costbasis, int32_t } profits = costbasis > 0 ? ((price * SATOSHIDEN) / costbasis) - SATOSHIDEN : 0; - std::cerr << "prices_syntheticprofits() profits1=" << profits << std::endl; - profits *= leverage * positionsize; - std::cerr << "prices_syntheticprofits() profits2=" << profits << std::endl; + std::cerr << "prices_syntheticprofits() (price * SATOSHIDEN)=" << (price * SATOSHIDEN) << std::endl; + std::cerr << "prices_syntheticprofits() (price * SATOSHIDEN)/costbasis=" << (price * SATOSHIDEN)/costbasis << std::endl; - return(positionsize + addedbets + profits); + std::cerr << "prices_syntheticprofits() profits1=" << profits << std::endl; + std::cerr << "prices_syntheticprofits() profits double=" << (double)price / (double)costbasis -1.0 << std::endl; + double dprofits = (double)price / (double)costbasis - 1.0; + + profits *= leverage * positionsize; + dprofits *= leverage * positionsize; + std::cerr << "prices_syntheticprofits() profits2=" << profits << std::endl; + std::cerr << "prices_syntheticprofits() dprofits=" << dprofits << std::endl; + + + return(positionsize + addedbets + dprofits); } void prices_betjson(UniValue &result,int64_t profits,int64_t costbasis,int64_t positionsize,int64_t addedbets,int16_t leverage,int32_t firstheight,int64_t firstprice) From 3d2c1ea5e062c92f3b578693d10cd68091e58774 Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 19 Apr 2019 03:15:55 +0500 Subject: [PATCH 080/242] calc costbasis for firstheight --- src/cc/prices.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 4579371fc..bcd9ee497 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1038,8 +1038,13 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) costbasis = prices_costbasis(bettx, costbasistxid); addedbets = prices_batontxid(batontxid, bettx, bettxid); - bool calcCostbasis = costbasis == 0 ? true : false; - if ((profits = prices_syntheticprofits(calcCostbasis, costbasis, firstheight, refheight, leverage, vec, positionsize, addedbets)) < 0) + if( costbasis == 0 && prices_syntheticprofits(true, costbasis, firstheight, firstheight, leverage, vec, positionsize, addedbets) < 0) { + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "cannot calculate costbasis")); + return(result); + } + + if ((profits = prices_syntheticprofits(false, costbasis, firstheight, refheight, leverage, vec, positionsize, addedbets)) < 0) { result.push_back(Pair("rekt", 1)); result.push_back(Pair("rektfee", (positionsize + addedbets) / 500)); From d36e8227d0e74c6442e0892e9b7fc636a1c8a4b7 Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 19 Apr 2019 12:26:20 +0500 Subject: [PATCH 081/242] corr costbasis & profits calc added json params --- src/cc/prices.cpp | 105 ++++++++++++++++++++++++++-------------------- 1 file changed, 60 insertions(+), 45 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index bcd9ee497..483e48937 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -611,9 +611,9 @@ int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t } // calculates profit/loss for the bet -int64_t prices_syntheticprofits(bool calcCostbasis, int64_t &costbasis, int32_t firstheight, int32_t height, int16_t leverage, std::vector vec, int64_t positionsize, int64_t addedbets) +int64_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t height, int16_t leverage, std::vector vec, int64_t positionsize, int64_t addedbets, int64_t &price) { - int64_t price, profits = 0; + int64_t profits = 0; if (height < firstheight) { fprintf(stderr, "requested height is lower than bet firstheight.%d\n", height); @@ -627,53 +627,57 @@ int64_t prices_syntheticprofits(bool calcCostbasis, int64_t &costbasis, int32_t fprintf(stderr, "unexpected zero synthetic price at height.%d\n", height); return(0); } - if (calcCostbasis) { - if (minmax) { // if we are within day window, set costbasis to max or min price value - if (leverage > 0 && price > costbasis) { - costbasis = price; // set costbasis - std::cerr << "prices_syntheticprofits() minmax costbasis=" << costbasis << " price=" << price << std::endl; - } - else if (leverage < 0 && (costbasis == 0 || price < costbasis)) { - costbasis = price; - std::cerr << "prices_syntheticprofits() minmax costbasis=" << costbasis << " price=" << price << std::endl; - } - else { //-> use the previous value - std::cerr << "prices_syntheticprofits() unchanged costbasis=" << costbasis << " price=" << price << " leverage=" << leverage << std::endl; - } + + if (minmax) { // if we are within day window, set costbasis to max or min price value + if (leverage > 0 && price > costbasis) { + costbasis = price; // set temp costbasis + std::cerr << "prices_syntheticprofits() minmax costbasis=" << costbasis << " price=" << price << std::endl; + } + else if (leverage < 0 && (costbasis == 0 || price < costbasis)) { + costbasis = price; + std::cerr << "prices_syntheticprofits() minmax costbasis=" << costbasis << " price=" << price << std::endl; + } + else { //-> use the previous value + std::cerr << "prices_syntheticprofits() unchanged costbasis=" << costbasis << " price=" << price << " leverage=" << leverage << std::endl; + } - } - else { - costbasis = price; // smoothed value - std::cerr << "prices_syntheticprofits() smoothed costbasis=" << costbasis << " price=" << price << std::endl; - } } + else { + // use provided costbasis + std::cerr << "prices_syntheticprofits() provided costbasis=" << costbasis << " price=" << price << std::endl; + if (costbasis == 0) + costbasis = price; + } + - profits = costbasis > 0 ? ((price * SATOSHIDEN) / costbasis) - SATOSHIDEN : 0; - std::cerr << "prices_syntheticprofits() (price * SATOSHIDEN)=" << (price * SATOSHIDEN) << std::endl; - std::cerr << "prices_syntheticprofits() (price * SATOSHIDEN)/costbasis=" << (price * SATOSHIDEN)/costbasis << std::endl; + profits = costbasis > 0 ? ( ((price / 10000 * SATOSHIDEN) / costbasis) - SATOSHIDEN / 10000 ) : 0; + std::cerr << "prices_syntheticprofits() (price /10000 * SATOSHIDEN)=" << (price /10000 * SATOSHIDEN) << std::endl; + std::cerr << "prices_syntheticprofits() (price /10000 * SATOSHIDEN)/costbasis=" << (price /10000 * SATOSHIDEN)/costbasis << std::endl; std::cerr << "prices_syntheticprofits() profits1=" << profits << std::endl; - std::cerr << "prices_syntheticprofits() profits double=" << (double)price / (double)costbasis -1.0 << std::endl; - double dprofits = (double)price / (double)costbasis - 1.0; + //std::cerr << "prices_syntheticprofits() profits double=" << (double)price / (double)costbasis -1.0 << std::endl; + //double dprofits = (double)price / (double)costbasis - 1.0; profits *= leverage * positionsize; - dprofits *= leverage * positionsize; + //dprofits *= leverage * positionsize; std::cerr << "prices_syntheticprofits() profits2=" << profits << std::endl; - std::cerr << "prices_syntheticprofits() dprofits=" << dprofits << std::endl; + //std::cerr << "prices_syntheticprofits() dprofits=" << dprofits << std::endl; - return(positionsize + addedbets + dprofits); + return profits; // (positionsize + addedbets + profits); } -void prices_betjson(UniValue &result,int64_t profits,int64_t costbasis,int64_t positionsize,int64_t addedbets,int16_t leverage,int32_t firstheight,int64_t firstprice) +void prices_betjson(UniValue &result,int64_t profits,int64_t costbasis,int64_t positionsize,int64_t addedbets,int16_t leverage,int32_t firstheight,int64_t firstprice, int64_t lastprice) { result.push_back(Pair("profits",ValueFromAmount(profits))); result.push_back(Pair("costbasis",ValueFromAmount(costbasis))); result.push_back(Pair("positionsize",ValueFromAmount(positionsize))); + result.push_back(Pair("equity", ValueFromAmount(positionsize + addedbets + profits))); result.push_back(Pair("addedbets",ValueFromAmount(addedbets))); result.push_back(Pair("leverage",(int64_t)leverage)); result.push_back(Pair("firstheight",(int64_t)firstheight)); result.push_back(Pair("firstprice",ValueFromAmount(firstprice))); + result.push_back(Pair("lastprice", ValueFromAmount(lastprice))); } // retrives costbasis from a tx spending bettx vout1 @@ -837,7 +841,7 @@ UniValue PricesSetcostbasis(int64_t txfee, uint256 bettxid) CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nextheight); UniValue result(UniValue::VOBJ); struct CCcontract_info *cp, C; CTransaction bettx; uint256 hashBlock, batontxid, tokenid; - int64_t myfee, positionsize = 0, addedbets, firstprice = 0, profits = 0, costbasis = 0; + int64_t myfee, positionsize = 0, addedbets, firstprice = 0, lastprice, profits = 0, costbasis = 0; int32_t i, firstheight = 0, height, numvouts; int16_t leverage = 0; std::vector vec; CPubKey pk, mypk, pricespk; std::string rawtx; @@ -852,7 +856,7 @@ UniValue PricesSetcostbasis(int64_t txfee, uint256 bettxid) { if (prices_betopretdecode(bettx.vout[numvouts - 1].scriptPubKey, pk, firstheight, positionsize, leverage, firstprice, vec, tokenid) == 'B') { - if (nextheight <= firstheight + PRICES_DAYWINDOW + PRICES_SMOOTHWIDTH) { + if (nextheight <= firstheight + PRICES_DAYWINDOW + 1) { result.push_back(Pair("result", "error")); result.push_back(Pair("error", "cannot calculate costbasis yet")); return(result); @@ -860,9 +864,9 @@ UniValue PricesSetcostbasis(int64_t txfee, uint256 bettxid) addedbets = prices_batontxid(batontxid, bettx, bettxid); mtx.vin.push_back(CTxIn(bettxid, 1, CScript())); // spend vin1 with betamount - for (i = 0; i < PRICES_DAYWINDOW + PRICES_SMOOTHWIDTH; i++) // the last datum for 24h is the costbasis value + for (i = 0; i < PRICES_DAYWINDOW + 1; i++) // the last datum for 24h is the costbasis value { - if ((profits = prices_syntheticprofits(true, costbasis, firstheight, firstheight + i, leverage, vec, positionsize, addedbets)) < 0) + if ((profits = prices_syntheticprofits(costbasis, firstheight, firstheight + i, leverage, vec, positionsize, addedbets, lastprice)) < 0) { // we are in loss result.push_back(Pair("rekt", (int64_t)1)); result.push_back(Pair("rektheight", (int64_t)firstheight + i)); @@ -872,7 +876,7 @@ UniValue PricesSetcostbasis(int64_t txfee, uint256 bettxid) if (i == PRICES_DAYWINDOW) result.push_back(Pair("rekt", 0)); - prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice); + prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice, lastprice); if (AddNormalinputs(mtx, mypk, txfee, 4) >= txfee) { @@ -898,7 +902,16 @@ UniValue PricesRekt(int64_t txfee, uint256 bettxid, int32_t rektheight) { int32_t nextheight = komodo_nextheight(); CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nextheight); UniValue result(UniValue::VOBJ); - struct CCcontract_info *cp, C; CTransaction bettx; uint256 hashBlock, tokenid, batontxid; int64_t myfee = 0, positionsize, addedbets, firstprice, profits, ignore, costbasis = 0; int32_t firstheight, numvouts; int16_t leverage; std::vector vec; CPubKey pk, mypk, pricespk; std::string rawtx; + struct CCcontract_info *cp, C; + CTransaction bettx; + uint256 hashBlock, tokenid, batontxid; + int64_t myfee = 0, positionsize, addedbets, firstprice, lastprice, profits, ignore, costbasis = 0; + int32_t firstheight, numvouts; + int16_t leverage; + std::vector vec; + CPubKey pk, mypk, pricespk; + std::string rawtx; + cp = CCinit(&C, EVAL_PRICES); if (txfee == 0) txfee = PRICES_TXFEE; @@ -917,11 +930,11 @@ UniValue PricesRekt(int64_t txfee, uint256 bettxid, int32_t rektheight) } addedbets = prices_batontxid(batontxid, bettx, bettxid); - if ((profits = prices_syntheticprofits(false, costbasis /*ignore*/, firstheight, rektheight, leverage, vec, positionsize, addedbets)) < 0) + if ((profits = prices_syntheticprofits(costbasis /*ignore*/, firstheight, rektheight, leverage, vec, positionsize, addedbets, lastprice)) < 0) { myfee = (positionsize + addedbets) / 500; } - prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice); + prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice, lastprice); if (myfee != 0) { mtx.vin.push_back(CTxIn(bettxid, 2, CScript())); @@ -956,7 +969,7 @@ UniValue PricesCashout(int64_t txfee, uint256 bettxid) struct CCcontract_info *cp, C; char destaddr[64]; CTransaction bettx; uint256 hashBlock, batontxid, tokenid; - int64_t CCchange = 0, positionsize, inputsum, ignore, addedbets, firstprice, profits, costbasis = 0; + int64_t CCchange = 0, positionsize, inputsum, ignore, addedbets, firstprice, lastprice, profits, costbasis = 0; int32_t i, firstheight, height, numvouts; int16_t leverage; std::vector vec; @@ -984,14 +997,14 @@ UniValue PricesCashout(int64_t txfee, uint256 bettxid) } addedbets = prices_batontxid(batontxid, bettx, bettxid); - if ((profits = prices_syntheticprofits(false, costbasis, firstheight, nextheight - 1, leverage, vec, positionsize, addedbets)) < 0) + if ((profits = prices_syntheticprofits(costbasis, firstheight, nextheight - 1, leverage, vec, positionsize, addedbets, lastprice)) < 0) { - prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice); + prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice, lastprice); result.push_back(Pair("result", "error")); result.push_back(Pair("error", "position rekt")); return(result); } - prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice); + prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice, lastprice); mtx.vin.push_back(CTxIn(bettxid, 2, CScript())); if ((inputsum = AddPricesInputs(cp, mtx, destaddr, profits + txfee, 64, bettxid, 2)) > profits + txfee) CCchange = (inputsum - profits); @@ -1016,7 +1029,7 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) UniValue result(UniValue::VOBJ); CTransaction bettx; uint256 hashBlock, batontxid, tokenid; - int64_t myfee, ignore = 0, positionsize = 0, addedbets = 0, firstprice = 0, profits = 0, costbasis = 0; + int64_t myfee, ignore = 0, positionsize = 0, addedbets = 0, firstprice = 0, lastprice, profits = 0, costbasis = 0; int32_t i, firstheight = 0, height, numvouts; int16_t leverage = 0; std::vector vec; @@ -1038,13 +1051,15 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) costbasis = prices_costbasis(bettx, costbasistxid); addedbets = prices_batontxid(batontxid, bettx, bettxid); + + /* if( costbasis == 0 && prices_syntheticprofits(true, costbasis, firstheight, firstheight, leverage, vec, positionsize, addedbets) < 0) { result.push_back(Pair("result", "error")); result.push_back(Pair("error", "cannot calculate costbasis")); return(result); - } + } */ - if ((profits = prices_syntheticprofits(false, costbasis, firstheight, refheight, leverage, vec, positionsize, addedbets)) < 0) + if ((profits = prices_syntheticprofits(costbasis, firstheight, refheight, leverage, vec, positionsize, addedbets, lastprice)) < 0) { result.push_back(Pair("rekt", 1)); result.push_back(Pair("rektfee", (positionsize + addedbets) / 500)); @@ -1054,7 +1069,7 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) result.push_back(Pair("batontxid", batontxid.GetHex())); if(!costbasistxid.IsNull()) result.push_back(Pair("costbasistxid", costbasistxid.GetHex())); - prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice); + prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice, lastprice); result.push_back(Pair("height", (int64_t)refheight)); return(result); } From 7f59d7c76e35f9f08d98c73e36e8a2aff4b83cac Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 19 Apr 2019 13:41:24 +0500 Subject: [PATCH 082/242] pricedata logging --- src/cc/prices.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 483e48937..ef47c5f7f 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -478,6 +478,7 @@ int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t pricestack[depth] = 0; if (komodo_priceget(pricedata, value, height, 1) >= 0) { + std::cerr << "prices_syntheticprice" << " pricedata[0]=" << pricedata[0] << " pricedata[1]=" << pricedata[1] << " pricedata[2]=" << pricedata[2] << std::endl; // push price to the prices stack if (!minmax) pricestack[depth] = pricedata[2]; // use smoothed value if we are over 24h From f7912ee8f4a8060bca580b5106576afac17344ea Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 19 Apr 2019 13:47:14 +0500 Subject: [PATCH 083/242] more pricedata log --- src/cc/prices.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index ef47c5f7f..12d91ad74 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -478,7 +478,7 @@ int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t pricestack[depth] = 0; if (komodo_priceget(pricedata, value, height, 1) >= 0) { - std::cerr << "prices_syntheticprice" << " pricedata[0]=" << pricedata[0] << " pricedata[1]=" << pricedata[1] << " pricedata[2]=" << pricedata[2] << std::endl; + std::cerr << "prices_syntheticprice" << " pricedata[0]=" << pricedata[0] << " pricedata[1]=" << pricedata[1] << " pricedata[2]=" << pricedata[2] << " pricedata_int32[2]=" << *((uint32_t*)pricedata[2]) << std::endl; // push price to the prices stack if (!minmax) pricestack[depth] = pricedata[2]; // use smoothed value if we are over 24h From bcd6e1a4d9671ddb7e55d3e171bd47f3b54ce187 Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 19 Apr 2019 13:51:53 +0500 Subject: [PATCH 084/242] clear lowest pos in price --- src/cc/prices.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 12d91ad74..de20efcff 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -628,6 +628,10 @@ int64_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t fprintf(stderr, "unexpected zero synthetic price at height.%d\n", height); return(0); } + + // clear lowest positions: + price /= 10000; + price *= 10000; if (minmax) { // if we are within day window, set costbasis to max or min price value if (leverage > 0 && price > costbasis) { From d15e1b3a8f52c45d1cbfaf745f1361ff57a70770 Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 19 Apr 2019 13:57:14 +0500 Subject: [PATCH 085/242] removed bad logging --- src/cc/prices.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index de20efcff..51f4d7ddf 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -478,7 +478,7 @@ int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t pricestack[depth] = 0; if (komodo_priceget(pricedata, value, height, 1) >= 0) { - std::cerr << "prices_syntheticprice" << " pricedata[0]=" << pricedata[0] << " pricedata[1]=" << pricedata[1] << " pricedata[2]=" << pricedata[2] << " pricedata_int32[2]=" << *((uint32_t*)pricedata[2]) << std::endl; + std::cerr << "prices_syntheticprice" << " pricedata[0]=" << pricedata[0] << " pricedata[1]=" << pricedata[1] << " pricedata[2]=" << pricedata[2] << std::endl; // push price to the prices stack if (!minmax) pricestack[depth] = pricedata[2]; // use smoothed value if we are over 24h From 41f5437f09c0f98b36004c482962d1d0c9bd5c93 Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 19 Apr 2019 14:26:14 +0500 Subject: [PATCH 086/242] define for 10000 factor added --- src/cc/CCPrices.h | 1 + src/cc/prices.cpp | 14 +++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/cc/CCPrices.h b/src/cc/CCPrices.h index 62da19aab..1402a995c 100644 --- a/src/cc/CCPrices.h +++ b/src/cc/CCPrices.h @@ -34,6 +34,7 @@ int32_t komodo_priceget(int64_t *buf64,int32_t ind,int32_t height,int32_t numblo #define PRICES_MMD (KOMODO_MAXPRICES * 6) // 0011 0000 0000 0000 #define PRICES_MMM (KOMODO_MAXPRICES * 7) // 0011 1000 0000 0000 #define PRICES_DDD (KOMODO_MAXPRICES * 8) // 0100 0000 0000 0000 +#define PRICES_NORMFACTOR 10000 bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn); diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 51f4d7ddf..4454c4d0d 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -630,8 +630,8 @@ int64_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t } // clear lowest positions: - price /= 10000; - price *= 10000; + price /= PRICES_NORMFACTOR; + price *= PRICES_NORMFACTOR; if (minmax) { // if we are within day window, set costbasis to max or min price value if (leverage > 0 && price > costbasis) { @@ -655,17 +655,17 @@ int64_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t } - profits = costbasis > 0 ? ( ((price / 10000 * SATOSHIDEN) / costbasis) - SATOSHIDEN / 10000 ) : 0; - std::cerr << "prices_syntheticprofits() (price /10000 * SATOSHIDEN)=" << (price /10000 * SATOSHIDEN) << std::endl; - std::cerr << "prices_syntheticprofits() (price /10000 * SATOSHIDEN)/costbasis=" << (price /10000 * SATOSHIDEN)/costbasis << std::endl; + profits = costbasis > 0 ? ((price / PRICES_NORMFACTOR * SATOSHIDEN) / costbasis) - SATOSHIDEN / PRICES_NORMFACTOR : 0; + std::cerr << "prices_syntheticprofits() test value1 (price/PRICES_NORMFACTOR * SATOSHIDEN)=" << (price / PRICES_NORMFACTOR * SATOSHIDEN) << std::endl; + std::cerr << "prices_syntheticprofits() test value2 (price/PRICES_NORMFACTOR * SATOSHIDEN)/costbasis=" << (price / PRICES_NORMFACTOR * SATOSHIDEN)/costbasis << std::endl; - std::cerr << "prices_syntheticprofits() profits1=" << profits << std::endl; + std::cerr << "prices_syntheticprofits() fract profits=" << profits << std::endl; //std::cerr << "prices_syntheticprofits() profits double=" << (double)price / (double)costbasis -1.0 << std::endl; //double dprofits = (double)price / (double)costbasis - 1.0; profits *= leverage * positionsize; //dprofits *= leverage * positionsize; - std::cerr << "prices_syntheticprofits() profits2=" << profits << std::endl; + std::cerr << "prices_syntheticprofits() val profits=" << profits << std::endl; //std::cerr << "prices_syntheticprofits() dprofits=" << dprofits << std::endl; From 0684f7ab6e086cf6ebdff057bd5ecd2985dab030 Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 19 Apr 2019 20:32:18 +0500 Subject: [PATCH 087/242] corrected temp costbasis calculation for priceinfo corrected equity loss check --- src/cc/prices.cpp | 78 ++++++++++++++++++++++++++++++----------------- 1 file changed, 50 insertions(+), 28 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 4454c4d0d..b94cb7dfe 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -672,12 +672,12 @@ int64_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t return profits; // (positionsize + addedbets + profits); } -void prices_betjson(UniValue &result,int64_t profits,int64_t costbasis,int64_t positionsize,int64_t addedbets,int16_t leverage,int32_t firstheight,int64_t firstprice, int64_t lastprice) +void prices_betjson(UniValue &result,int64_t profits,int64_t costbasis,int64_t positionsize,int64_t addedbets,int16_t leverage,int32_t firstheight,int64_t firstprice, int64_t lastprice, int64_t equity) { result.push_back(Pair("profits",ValueFromAmount(profits))); result.push_back(Pair("costbasis",ValueFromAmount(costbasis))); result.push_back(Pair("positionsize",ValueFromAmount(positionsize))); - result.push_back(Pair("equity", ValueFromAmount(positionsize + addedbets + profits))); + result.push_back(Pair("equity", ValueFromAmount(equity))); result.push_back(Pair("addedbets",ValueFromAmount(addedbets))); result.push_back(Pair("leverage",(int64_t)leverage)); result.push_back(Pair("firstheight",(int64_t)firstheight)); @@ -846,7 +846,7 @@ UniValue PricesSetcostbasis(int64_t txfee, uint256 bettxid) CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nextheight); UniValue result(UniValue::VOBJ); struct CCcontract_info *cp, C; CTransaction bettx; uint256 hashBlock, batontxid, tokenid; - int64_t myfee, positionsize = 0, addedbets, firstprice = 0, lastprice, profits = 0, costbasis = 0; + int64_t myfee, positionsize = 0, addedbets, firstprice = 0, lastprice, profits = 0, costbasis = 0, equity; int32_t i, firstheight = 0, height, numvouts; int16_t leverage = 0; std::vector vec; CPubKey pk, mypk, pricespk; std::string rawtx; @@ -871,17 +871,19 @@ UniValue PricesSetcostbasis(int64_t txfee, uint256 bettxid) mtx.vin.push_back(CTxIn(bettxid, 1, CScript())); // spend vin1 with betamount for (i = 0; i < PRICES_DAYWINDOW + 1; i++) // the last datum for 24h is the costbasis value { - if ((profits = prices_syntheticprofits(costbasis, firstheight, firstheight + i, leverage, vec, positionsize, addedbets, lastprice)) < 0) + profits = prices_syntheticprofits(costbasis, firstheight, firstheight + i, leverage, vec, positionsize, addedbets, lastprice); + equity = positionsize + addedbets + profits; + if (equity < 0) { // we are in loss result.push_back(Pair("rekt", (int64_t)1)); result.push_back(Pair("rektheight", (int64_t)firstheight + i)); break; } } - if (i == PRICES_DAYWINDOW) + if (i == PRICES_DAYWINDOW + 1) result.push_back(Pair("rekt", 0)); - prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice, lastprice); + prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice, lastprice, equity); if (AddNormalinputs(mtx, mypk, txfee, 4) >= txfee) { @@ -910,7 +912,7 @@ UniValue PricesRekt(int64_t txfee, uint256 bettxid, int32_t rektheight) struct CCcontract_info *cp, C; CTransaction bettx; uint256 hashBlock, tokenid, batontxid; - int64_t myfee = 0, positionsize, addedbets, firstprice, lastprice, profits, ignore, costbasis = 0; + int64_t myfee = 0, positionsize, addedbets, firstprice, lastprice, profits, ignore, costbasis = 0, equity; int32_t firstheight, numvouts; int16_t leverage; std::vector vec; @@ -935,11 +937,13 @@ UniValue PricesRekt(int64_t txfee, uint256 bettxid, int32_t rektheight) } addedbets = prices_batontxid(batontxid, bettx, bettxid); - if ((profits = prices_syntheticprofits(costbasis /*ignore*/, firstheight, rektheight, leverage, vec, positionsize, addedbets, lastprice)) < 0) + profits = prices_syntheticprofits(costbasis, firstheight, rektheight, leverage, vec, positionsize, addedbets, lastprice); + equity = positionsize + addedbets + profits; + if (equity < 0) { myfee = (positionsize + addedbets) / 500; } - prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice, lastprice); + prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice, lastprice, equity); if (myfee != 0) { mtx.vin.push_back(CTxIn(bettxid, 2, CScript())); @@ -974,7 +978,7 @@ UniValue PricesCashout(int64_t txfee, uint256 bettxid) struct CCcontract_info *cp, C; char destaddr[64]; CTransaction bettx; uint256 hashBlock, batontxid, tokenid; - int64_t CCchange = 0, positionsize, inputsum, ignore, addedbets, firstprice, lastprice, profits, costbasis = 0; + int64_t CCchange = 0, positionsize, inputsum, ignore, addedbets, firstprice, lastprice, profits, costbasis = 0, equity; int32_t i, firstheight, height, numvouts; int16_t leverage; std::vector vec; @@ -1002,14 +1006,16 @@ UniValue PricesCashout(int64_t txfee, uint256 bettxid) } addedbets = prices_batontxid(batontxid, bettx, bettxid); - if ((profits = prices_syntheticprofits(costbasis, firstheight, nextheight - 1, leverage, vec, positionsize, addedbets, lastprice)) < 0) + profits = prices_syntheticprofits(costbasis, firstheight, nextheight - 1, leverage, vec, positionsize, addedbets, lastprice); + equity = positionsize + addedbets + profits; + if (equity < 0) { - prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice, lastprice); + prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice, lastprice, equity); result.push_back(Pair("result", "error")); result.push_back(Pair("error", "position rekt")); return(result); } - prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice, lastprice); + prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice, lastprice, equity); mtx.vin.push_back(CTxIn(bettxid, 2, CScript())); if ((inputsum = AddPricesInputs(cp, mtx, destaddr, profits + txfee, 64, bettxid, 2)) > profits + txfee) CCchange = (inputsum - profits); @@ -1034,7 +1040,7 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) UniValue result(UniValue::VOBJ); CTransaction bettx; uint256 hashBlock, batontxid, tokenid; - int64_t myfee, ignore = 0, positionsize = 0, addedbets = 0, firstprice = 0, lastprice, profits = 0, costbasis = 0; + int64_t myfee, ignore = 0, positionsize = 0, addedbets = 0, firstprice = 0, lastprice, profits = 0, costbasis = 0, equity; int32_t i, firstheight = 0, height, numvouts; int16_t leverage = 0; std::vector vec; @@ -1057,24 +1063,40 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) costbasis = prices_costbasis(bettx, costbasistxid); addedbets = prices_batontxid(batontxid, bettx, bettxid); - /* - if( costbasis == 0 && prices_syntheticprofits(true, costbasis, firstheight, firstheight, leverage, vec, positionsize, addedbets) < 0) { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "cannot calculate costbasis")); - return(result); - } */ - - if ((profits = prices_syntheticprofits(costbasis, firstheight, refheight, leverage, vec, positionsize, addedbets, lastprice)) < 0) - { - result.push_back(Pair("rekt", 1)); - result.push_back(Pair("rektfee", (positionsize + addedbets) / 500)); + if (costbasis != 0) { // costbasis fixed + profits = prices_syntheticprofits(costbasis, firstheight, refheight, leverage, vec, positionsize, addedbets, lastprice); + equity = positionsize + addedbets + profits; + if (equity < 0) + { + result.push_back(Pair("rekt", 1)); + result.push_back(Pair("rektfee", (positionsize + addedbets) / 500)); + result.push_back(Pair("rektheight", (int64_t)refheight)); + } + else + result.push_back(Pair("rekt", 0)); } - else - result.push_back(Pair("rekt", 0)); + else { + for (i = 0; i < PRICES_DAYWINDOW + 1; i++) // the last datum for 24h is the costbasis value + { + profits = prices_syntheticprofits(costbasis, firstheight, firstheight + i, leverage, vec, positionsize, addedbets, lastprice); + equity = positionsize + addedbets + profits; + if (equity < 0) + { // we are in loss + result.push_back(Pair("rekt", (int64_t)1)); + result.push_back(Pair("rektfee", (positionsize + addedbets) / 500)); + result.push_back(Pair("rektheight", (int64_t)firstheight + i)); + break; + } + } + if (i == PRICES_DAYWINDOW + 1) + result.push_back(Pair("rekt", 0)); + } + + result.push_back(Pair("batontxid", batontxid.GetHex())); if(!costbasistxid.IsNull()) result.push_back(Pair("costbasistxid", costbasistxid.GetHex())); - prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice, lastprice); + prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice, lastprice, equity); result.push_back(Pair("height", (int64_t)refheight)); return(result); } From 01dfdc6b67a1d2b540c1458deabe2ccabe0b3255 Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 19 Apr 2019 22:12:21 +0500 Subject: [PATCH 088/242] addfunding now in coins try correct fraction of profits --- src/cc/prices.cpp | 2 +- src/rpc/blockchain.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index b94cb7dfe..026c75181 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -663,7 +663,7 @@ int64_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t //std::cerr << "prices_syntheticprofits() profits double=" << (double)price / (double)costbasis -1.0 << std::endl; //double dprofits = (double)price / (double)costbasis - 1.0; - profits *= leverage * positionsize; + profits *= leverage * positionsize / SATOSHIDEN; //dprofits *= leverage * positionsize; std::cerr << "prices_syntheticprofits() val profits=" << profits << std::endl; //std::cerr << "prices_syntheticprofits() dprofits=" << dprofits << std::endl; diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index fefec1337..1f6fcadcf 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1358,7 +1358,7 @@ UniValue pricesaddfunding(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 2) throw runtime_error("pricesaddfunding bettxid amount\n" - "where amount is in satoshis\n"); + "where amount is in coins\n"); LOCK(cs_main); UniValue ret(UniValue::VOBJ); @@ -1370,7 +1370,7 @@ UniValue pricesaddfunding(const UniValue& params, bool fHelp) if (bettxid.IsNull()) throw runtime_error("invalid bettxid\n"); - CAmount amount = atoll(params[1].get_str().c_str()); + CAmount amount = atof(params[1].get_str().c_str()) * COIN; if (amount <= 0) throw runtime_error("invalid amount\n"); From 71b960a1e144cf3c77803789ca368ffb1d31126f Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 19 Apr 2019 22:22:06 +0500 Subject: [PATCH 089/242] yet corr profits fraction --- src/cc/prices.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 026c75181..23e3aa22a 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -655,7 +655,7 @@ int64_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t } - profits = costbasis > 0 ? ((price / PRICES_NORMFACTOR * SATOSHIDEN) / costbasis) - SATOSHIDEN / PRICES_NORMFACTOR : 0; + profits = costbasis > 0 ? (((price / PRICES_NORMFACTOR * SATOSHIDEN) / costbasis) - SATOSHIDEN / PRICES_NORMFACTOR) * PRICES_NORMFACTOR : 0; std::cerr << "prices_syntheticprofits() test value1 (price/PRICES_NORMFACTOR * SATOSHIDEN)=" << (price / PRICES_NORMFACTOR * SATOSHIDEN) << std::endl; std::cerr << "prices_syntheticprofits() test value2 (price/PRICES_NORMFACTOR * SATOSHIDEN)/costbasis=" << (price / PRICES_NORMFACTOR * SATOSHIDEN)/costbasis << std::endl; From 5f30987ad68a0201b5a1036b667e53b3db7867a7 Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 19 Apr 2019 22:30:25 +0500 Subject: [PATCH 090/242] outprice --- src/cc/prices.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 23e3aa22a..9c1935ac4 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -612,9 +612,10 @@ int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t } // calculates profit/loss for the bet -int64_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t height, int16_t leverage, std::vector vec, int64_t positionsize, int64_t addedbets, int64_t &price) +int64_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t height, int16_t leverage, std::vector vec, int64_t positionsize, int64_t addedbets, int64_t &outprice) { int64_t profits = 0; + int64_t price; if (height < firstheight) { fprintf(stderr, "requested height is lower than bet firstheight.%d\n", height); @@ -632,6 +633,7 @@ int64_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t // clear lowest positions: price /= PRICES_NORMFACTOR; price *= PRICES_NORMFACTOR; + outprice = price; if (minmax) { // if we are within day window, set costbasis to max or min price value if (leverage > 0 && price > costbasis) { From d5d633140e107e6e578a063e41af672abc3de80e Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 19 Apr 2019 22:51:49 +0500 Subject: [PATCH 091/242] corr calc profits refheight --- src/cc/prices.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 9c1935ac4..3a220b16f 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1078,7 +1078,8 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) result.push_back(Pair("rekt", 0)); } else { - for (i = 0; i < PRICES_DAYWINDOW + 1; i++) // the last datum for 24h is the costbasis value + bool isRekt = false; + for (i = 0; i < PRICES_DAYWINDOW + 1 && firstheight + i <= refheight; i++) // the last datum for 24h is the costbasis value { profits = prices_syntheticprofits(costbasis, firstheight, firstheight + i, leverage, vec, positionsize, addedbets, lastprice); equity = positionsize + addedbets + profits; @@ -1087,10 +1088,11 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) result.push_back(Pair("rekt", (int64_t)1)); result.push_back(Pair("rektfee", (positionsize + addedbets) / 500)); result.push_back(Pair("rektheight", (int64_t)firstheight + i)); + isRekt = true; break; } } - if (i == PRICES_DAYWINDOW + 1) + if (!isRekt /*i == PRICES_DAYWINDOW + 1*/) result.push_back(Pair("rekt", 0)); } From 5d296e44f5b14709c747cf6cf6243069591f114d Mon Sep 17 00:00:00 2001 From: dimxy Date: Sun, 21 Apr 2019 12:39:03 +0500 Subject: [PATCH 092/242] try SATOSHIDEN as signed --- src/cc/prices.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 3a220b16f..2fd7a60df 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -158,7 +158,7 @@ bool ValidateBetTx(struct CCcontract_info *cp, Eval *eval, const CTransaction & if (MakeCC1vout(cp->evalcode, bettx.vout[1].nValue, pricespk) != bettx.vout[1]) return eval->Invalid("cannot validate vout1 in bet tx with global pk"); if( MakeCC1vout(cp->evalcode, bettx.vout[2].nValue, pricespk) != bettx.vout[2] ) - return eval->Invalid("cannot validate 1of2 vout2 in bet tx with pk from opreturn"); + return eval->Invalid("cannot validate vout2 in bet tx with pk from opreturn"); return true; } @@ -665,7 +665,7 @@ int64_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t //std::cerr << "prices_syntheticprofits() profits double=" << (double)price / (double)costbasis -1.0 << std::endl; //double dprofits = (double)price / (double)costbasis - 1.0; - profits *= leverage * positionsize / SATOSHIDEN; + profits *= leverage * positionsize / (int64_t)SATOSHIDEN; //dprofits *= leverage * positionsize; std::cerr << "prices_syntheticprofits() val profits=" << profits << std::endl; //std::cerr << "prices_syntheticprofits() dprofits=" << dprofits << std::endl; From 82c656037409f341f0cd803d4384ce875e687efa Mon Sep 17 00:00:00 2001 From: dimxy Date: Sun, 21 Apr 2019 13:19:25 +0500 Subject: [PATCH 093/242] costbasis=0 zero div prevention in logging --- src/cc/prices.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 2fd7a60df..c302e6d73 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -659,7 +659,7 @@ int64_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t profits = costbasis > 0 ? (((price / PRICES_NORMFACTOR * SATOSHIDEN) / costbasis) - SATOSHIDEN / PRICES_NORMFACTOR) * PRICES_NORMFACTOR : 0; std::cerr << "prices_syntheticprofits() test value1 (price/PRICES_NORMFACTOR * SATOSHIDEN)=" << (price / PRICES_NORMFACTOR * SATOSHIDEN) << std::endl; - std::cerr << "prices_syntheticprofits() test value2 (price/PRICES_NORMFACTOR * SATOSHIDEN)/costbasis=" << (price / PRICES_NORMFACTOR * SATOSHIDEN)/costbasis << std::endl; + std::cerr << "prices_syntheticprofits() test value2 (price/PRICES_NORMFACTOR * SATOSHIDEN)/costbasis=" << (costbasis != 0 ? (price / PRICES_NORMFACTOR * SATOSHIDEN)/costbasis : -1) << std::endl; std::cerr << "prices_syntheticprofits() fract profits=" << profits << std::endl; //std::cerr << "prices_syntheticprofits() profits double=" << (double)price / (double)costbasis -1.0 << std::endl; From efec12bcf532b38c917f1ea504d97ea4bac2ab9b Mon Sep 17 00:00:00 2001 From: dimxy Date: Sun, 21 Apr 2019 21:01:02 +0500 Subject: [PATCH 094/242] if TESTMODE PRICES_DAYWINDOW=3 --- src/cc/CCPrices.h | 3 ++- src/cc/prices.cpp | 3 +++ src/komodo_defs.h | 5 +++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/cc/CCPrices.h b/src/cc/CCPrices.h index 1402a995c..0225ff69b 100644 --- a/src/cc/CCPrices.h +++ b/src/cc/CCPrices.h @@ -17,10 +17,11 @@ #ifndef CC_PRICES_H #define CC_PRICES_H +#include "komodo_defs.h" #include "CCinclude.h" int32_t komodo_priceget(int64_t *buf64,int32_t ind,int32_t height,int32_t numblocks); -#define PRICES_DAYWINDOW ((3600*24/ASSETCHAINS_BLOCKTIME) + 1) +// #define PRICES_DAYWINDOW ((3600*24/ASSETCHAINS_BLOCKTIME) + 1) // defined in komodo_defs.h #define PRICES_TXFEE 10000 #define PRICES_MAXLEVERAGE 777 #define PRICES_SMOOTHWIDTH 1 diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index c302e6d73..d8944df9f 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1102,6 +1102,9 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) result.push_back(Pair("costbasistxid", costbasistxid.GetHex())); prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice, lastprice, equity); result.push_back(Pair("height", (int64_t)refheight)); +#ifdef TESTMODE + result.push_back(Pair("test_daywindow", PRICES_DAYWINDOW)); +#endif return(result); } } diff --git a/src/komodo_defs.h b/src/komodo_defs.h index 2fcd29df3..d5a9a21e2 100644 --- a/src/komodo_defs.h +++ b/src/komodo_defs.h @@ -38,7 +38,12 @@ #define KOMODO_MAXNVALUE (((uint64_t)1 << 63) - 1) #define KOMODO_BIT63SET(x) ((x) & ((uint64_t)1 << 63)) #define KOMODO_VALUETOOBIG(x) ((x) > (uint64_t)10000000001*COIN) + +#ifndef TESTMODE #define PRICES_DAYWINDOW ((3600*24/ASSETCHAINS_BLOCKTIME) + 1) +#else +#define PRICES_DAYWINDOW (3) +#endif extern uint8_t ASSETCHAINS_TXPOW,ASSETCHAINS_PUBLIC; int32_t MAX_BLOCK_SIZE(int32_t height); From a18ab80ddeef2650345590f2b3d552333835a9aa Mon Sep 17 00:00:00 2001 From: dimxy Date: Mon, 22 Apr 2019 11:30:15 +0500 Subject: [PATCH 095/242] mypriceslist added --- src/cc/CCPrices.h | 2 +- src/cc/prices.cpp | 21 ++++++++++----------- src/rpc/server.cpp | 1 + src/rpc/server.h | 1 + src/wallet/rpcwallet.cpp | 13 ++++++++++++- 5 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/cc/CCPrices.h b/src/cc/CCPrices.h index 0225ff69b..c7f3961d5 100644 --- a/src/cc/CCPrices.h +++ b/src/cc/CCPrices.h @@ -46,7 +46,7 @@ UniValue PricesSetcostbasis(int64_t txfee,uint256 bettxid); UniValue PricesRekt(int64_t txfee,uint256 bettxid,int32_t rektheight); UniValue PricesCashout(int64_t txfee,uint256 bettxid); UniValue PricesInfo(uint256 bettxid,int32_t refheight); -UniValue PricesList(); +UniValue PricesList(CPubKey mypk); #endif diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index d8944df9f..425b125c1 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1113,14 +1113,14 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) return(result); } -UniValue PricesList() +UniValue PricesList(CPubKey mypk) { - UniValue result(UniValue::VARR); std::vector > addressIndex; - struct CCcontract_info *cp, C; - int64_t amount, firstprice; int32_t height; int16_t leverage; uint256 txid, hashBlock, tokenid; - CPubKey pk, pricespk; - std::vector vec; - CTransaction vintx; + UniValue result(UniValue::VARR); std::vector > addressIndex; + struct CCcontract_info *cp, C; + int64_t amount, firstprice; int32_t height; int16_t leverage; uint256 txid, hashBlock, tokenid; + CPubKey pk, pricespk; + std::vector vec; + CTransaction vintx; cp = CCinit(&C, EVAL_PRICES); pricespk = GetUnspendable(cp, 0); @@ -1130,13 +1130,12 @@ UniValue PricesList() txid = it->first.txhash; if (GetTransaction(txid, vintx, hashBlock, false) != 0) { - if (vintx.vout.size() > 0 && prices_betopretdecode(vintx.vout[vintx.vout.size() - 1].scriptPubKey, pk, height, amount, leverage, firstprice, vec, tokenid) == 'B') + if (vintx.vout.size() > 0 && prices_betopretdecode(vintx.vout[vintx.vout.size() - 1].scriptPubKey, pk, height, amount, leverage, firstprice, vec, tokenid) == 'B' && + (mypk == CPubKey() || mypk == pk)) // if only mypubkey to list { result.push_back(txid.GetHex()); } } } return(result); -} - - +} \ No newline at end of file diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 29e616bca..13f235e26 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -463,6 +463,7 @@ static const CRPCCommand vRPCCommands[] = { "prices", "prices", &prices, true }, { "prices", "pricesaddress", &pricesaddress, true }, { "prices", "priceslist", &priceslist, true }, + { "prices", "mypriceslist", &mypriceslist, true }, { "prices", "pricesinfo", &pricesinfo, true }, { "prices", "pricesbet", &pricesbet, true }, { "prices", "pricessetcostbasis", &pricessetcostbasis, true }, diff --git a/src/rpc/server.h b/src/rpc/server.h index 2bd0b91c6..98a0d046f 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -271,6 +271,7 @@ extern UniValue oraclesdata(const UniValue& params, bool fHelp); extern UniValue oraclessamples(const UniValue& params, bool fHelp); extern UniValue pricesaddress(const UniValue& params, bool fHelp); extern UniValue priceslist(const UniValue& params, bool fHelp); +extern UniValue mypriceslist(const UniValue& params, bool fHelp); extern UniValue pricesinfo(const UniValue& params, bool fHelp); extern UniValue pegsaddress(const UniValue& params, bool fHelp); extern UniValue marmaraaddress(const UniValue& params, bool fHelp); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index a155603d9..8c6e4530f 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -6925,7 +6925,18 @@ UniValue priceslist(const UniValue& params, bool fHelp) throw runtime_error("priceslist\n"); if ( ensure_CCrequirements(EVAL_PRICES) < 0 ) throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); - return(PricesList()); + CPubKey emptypk; + return(PricesList(emptypk)); +} + +UniValue mypriceslist(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() > 0) + throw runtime_error("priceslist\n"); + if (ensure_CCrequirements(EVAL_PRICES) < 0) + throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + CPubKey mypk = pubkey2pk(Mypubkey()); + return(PricesList(mypk)); } UniValue pricesinfo(const UniValue& params, bool fHelp) From c19d636d7d5a0091e66354262bd75afc89c1beff Mon Sep 17 00:00:00 2001 From: dimxy Date: Mon, 22 Apr 2019 13:18:32 +0500 Subject: [PATCH 096/242] added all|open|close opt param to priceslist, mypriceslist --- src/cc/CCPrices.h | 2 +- src/cc/prices.cpp | 21 ++++++++++++++++++--- src/wallet/rpcwallet.cpp | 32 +++++++++++++++++++++++++++----- 3 files changed, 46 insertions(+), 9 deletions(-) diff --git a/src/cc/CCPrices.h b/src/cc/CCPrices.h index c7f3961d5..900ee7505 100644 --- a/src/cc/CCPrices.h +++ b/src/cc/CCPrices.h @@ -46,7 +46,7 @@ UniValue PricesSetcostbasis(int64_t txfee,uint256 bettxid); UniValue PricesRekt(int64_t txfee,uint256 bettxid,int32_t rektheight); UniValue PricesCashout(int64_t txfee,uint256 bettxid); UniValue PricesInfo(uint256 bettxid,int32_t refheight); -UniValue PricesList(CPubKey mypk); +UniValue PricesList(uint32_t filter, CPubKey mypk); #endif diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 425b125c1..06e64b739 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1054,7 +1054,8 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) { if (prices_betopretdecode(bettx.vout[numvouts - 1].scriptPubKey, pk, firstheight, positionsize, leverage, firstprice, vec, tokenid) == 'B') { - if (refheight > 0 && refheight < firstheight) { + // check acceptable refheight: + if (refheight < 0 || refheight > 0 && refheight < firstheight) { result.push_back(Pair("result", "error")); result.push_back(Pair("error", "incorrect height")); return(result); @@ -1113,7 +1114,7 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) return(result); } -UniValue PricesList(CPubKey mypk) +UniValue PricesList(uint32_t filter, CPubKey mypk) { UniValue result(UniValue::VARR); std::vector > addressIndex; struct CCcontract_info *cp, C; @@ -1133,7 +1134,21 @@ UniValue PricesList(CPubKey mypk) if (vintx.vout.size() > 0 && prices_betopretdecode(vintx.vout[vintx.vout.size() - 1].scriptPubKey, pk, height, amount, leverage, firstprice, vec, tokenid) == 'B' && (mypk == CPubKey() || mypk == pk)) // if only mypubkey to list { - result.push_back(txid.GetHex()); + bool bAppend = false; + if (filter == 0) + bAppend = true; + else { + int32_t vini; + int32_t height; + uint256 finaltxid; + + int32_t spent = CCgetspenttxid(finaltxid, vini, height, txid, 2); + if (filter == 1 && spent < 0 || + filter == 2 && spent == 0) + bAppend = true; + } + if (bAppend) + result.push_back(txid.GetHex()); } } } diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 8c6e4530f..a25c879e2 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -6919,24 +6919,46 @@ UniValue faucetget(const UniValue& params, bool fHelp) return(result); } +uint32_t pricesGetParam(UniValue param) { + uint32_t filter = 0; + if (strcmpi(param.get_str().c_str(), "all") == 0) + filter = 0; + if (strcmpi(param.get_str().c_str(), "open") == 0) + filter = 1; + if (strcmpi(param.get_str().c_str(), "closed") == 0) + filter = 2; + else + throw runtime_error("incorrect parameter\n"); +} + UniValue priceslist(const UniValue& params, bool fHelp) { - if ( fHelp || params.size() > 0 ) - throw runtime_error("priceslist\n"); + if ( fHelp || params.size() != 0 || params.size() != 1) + throw runtime_error("priceslist [all|open|closed]\n"); if ( ensure_CCrequirements(EVAL_PRICES) < 0 ) throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + uint32_t filter = 0; + if (params.size() == 1) + filter = pricesGetParam(params[0]); + CPubKey emptypk; - return(PricesList(emptypk)); + + return(PricesList(filter, emptypk)); } UniValue mypriceslist(const UniValue& params, bool fHelp) { if (fHelp || params.size() > 0) - throw runtime_error("priceslist\n"); + throw runtime_error("mypriceslist [all|open|closed]\n"); if (ensure_CCrequirements(EVAL_PRICES) < 0) throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + + uint32_t filter = 0; + if (params.size() == 1) + filter = pricesGetParam(params[0]); CPubKey mypk = pubkey2pk(Mypubkey()); - return(PricesList(mypk)); + + return(PricesList(filter, mypk)); } UniValue pricesinfo(const UniValue& params, bool fHelp) From 8b763d971b49c3e59062e0a770a0af41cae66014 Mon Sep 17 00:00:00 2001 From: dimxy Date: Mon, 22 Apr 2019 13:24:27 +0500 Subject: [PATCH 097/242] added missing return --- src/wallet/rpcwallet.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index a25c879e2..01b3d72fb 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -59,6 +59,7 @@ #include #include "komodo_defs.h" +#include using namespace std; @@ -6929,6 +6930,7 @@ uint32_t pricesGetParam(UniValue param) { filter = 2; else throw runtime_error("incorrect parameter\n"); + return filter; } UniValue priceslist(const UniValue& params, bool fHelp) From b2c7484255db2743cf0add2dc38de171d6efeff6 Mon Sep 17 00:00:00 2001 From: dimxy Date: Mon, 22 Apr 2019 13:47:35 +0500 Subject: [PATCH 098/242] param to lower case --- src/cc/CCinclude.h | 1 + src/wallet/rpcwallet.cpp | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/cc/CCinclude.h b/src/cc/CCinclude.h index db1ee7475..21c987248 100644 --- a/src/cc/CCinclude.h +++ b/src/cc/CCinclude.h @@ -298,6 +298,7 @@ UniValue ValueFromAmount(const CAmount& amount); int64_t TotalPubkeyNormalInputs(const CTransaction &tx, const CPubKey &pubkey); int64_t TotalPubkeyCCInputs(const CTransaction &tx, const CPubKey &pubkey); +inline std::string STR_TOLOWER(const std::string &str) { std::string out; for (std::string::const_iterator i = str.begin(); i != str.end(); i++) out += std::tolower(*i); return out; } // bitcoin LogPrintStr with category "-debug" cmdarg support for C++ ostringstream: #define CCLOG_INFO 0 diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 01b3d72fb..4ac8c5f4e 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -6922,11 +6922,11 @@ UniValue faucetget(const UniValue& params, bool fHelp) uint32_t pricesGetParam(UniValue param) { uint32_t filter = 0; - if (strcmpi(param.get_str().c_str(), "all") == 0) + if (STR_TOLOWER(param.get_str()) == "all") filter = 0; - if (strcmpi(param.get_str().c_str(), "open") == 0) + if (STR_TOLOWER(param.get_str()) == "open") filter = 1; - if (strcmpi(param.get_str().c_str(), "closed") == 0) + if (STR_TOLOWER(param.get_str()) == "closed") filter = 2; else throw runtime_error("incorrect parameter\n"); From 0e3351557e353963f93c63240575adbb62b130ac Mon Sep 17 00:00:00 2001 From: dimxy Date: Mon, 22 Apr 2019 14:19:49 +0500 Subject: [PATCH 099/242] corr param num check --- src/wallet/rpcwallet.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 4ac8c5f4e..6cb13a1db 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -6924,9 +6924,9 @@ uint32_t pricesGetParam(UniValue param) { uint32_t filter = 0; if (STR_TOLOWER(param.get_str()) == "all") filter = 0; - if (STR_TOLOWER(param.get_str()) == "open") + else if (STR_TOLOWER(param.get_str()) == "open") filter = 1; - if (STR_TOLOWER(param.get_str()) == "closed") + else if (STR_TOLOWER(param.get_str()) == "closed") filter = 2; else throw runtime_error("incorrect parameter\n"); @@ -6935,7 +6935,7 @@ uint32_t pricesGetParam(UniValue param) { UniValue priceslist(const UniValue& params, bool fHelp) { - if ( fHelp || params.size() != 0 || params.size() != 1) + if ( fHelp || params.size() != 0 && params.size() != 1) throw runtime_error("priceslist [all|open|closed]\n"); if ( ensure_CCrequirements(EVAL_PRICES) < 0 ) throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); @@ -6950,7 +6950,7 @@ UniValue priceslist(const UniValue& params, bool fHelp) UniValue mypriceslist(const UniValue& params, bool fHelp) { - if (fHelp || params.size() > 0) + if (fHelp || params.size() != 0 && params.size() != 1) throw runtime_error("mypriceslist [all|open|closed]\n"); if (ensure_CCrequirements(EVAL_PRICES) < 0) throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); From 51e5260627517fab457fd5f9b1ab52dc26d49df8 Mon Sep 17 00:00:00 2001 From: dimxy Date: Mon, 22 Apr 2019 16:33:21 +0500 Subject: [PATCH 100/242] corrected profits calc - cast to int64 --- src/cc/prices.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 06e64b739..188b773ef 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -649,25 +649,25 @@ int64_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t } } - else { + else { // use provided costbasis std::cerr << "prices_syntheticprofits() provided costbasis=" << costbasis << " price=" << price << std::endl; - if (costbasis == 0) - costbasis = price; + //if (costbasis == 0) + // costbasis = price; } profits = costbasis > 0 ? (((price / PRICES_NORMFACTOR * SATOSHIDEN) / costbasis) - SATOSHIDEN / PRICES_NORMFACTOR) * PRICES_NORMFACTOR : 0; std::cerr << "prices_syntheticprofits() test value1 (price/PRICES_NORMFACTOR * SATOSHIDEN)=" << (price / PRICES_NORMFACTOR * SATOSHIDEN) << std::endl; - std::cerr << "prices_syntheticprofits() test value2 (price/PRICES_NORMFACTOR * SATOSHIDEN)/costbasis=" << (costbasis != 0 ? (price / PRICES_NORMFACTOR * SATOSHIDEN)/costbasis : -1) << std::endl; + std::cerr << "prices_syntheticprofits() test value2 (price/PRICES_NORMFACTOR * SATOSHIDEN)/costbasis=" << (costbasis != 0 ? (price / PRICES_NORMFACTOR * SATOSHIDEN)/costbasis : 0) << std::endl; - std::cerr << "prices_syntheticprofits() fract profits=" << profits << std::endl; + std::cerr << "prices_syntheticprofits() fractional profits=" << profits << std::endl; //std::cerr << "prices_syntheticprofits() profits double=" << (double)price / (double)costbasis -1.0 << std::endl; //double dprofits = (double)price / (double)costbasis - 1.0; - profits *= leverage * positionsize / (int64_t)SATOSHIDEN; + profits *= ((int64_t)leverage * (int64_t)positionsize) / (int64_t)SATOSHIDEN; //dprofits *= leverage * positionsize; - std::cerr << "prices_syntheticprofits() val profits=" << profits << std::endl; + std::cerr << "prices_syntheticprofits() value of profits=" << profits << " leverage=" << leverage << " positionsize=" << positionsize << std::endl; //std::cerr << "prices_syntheticprofits() dprofits=" << dprofits << std::endl; @@ -1143,8 +1143,8 @@ UniValue PricesList(uint32_t filter, CPubKey mypk) uint256 finaltxid; int32_t spent = CCgetspenttxid(finaltxid, vini, height, txid, 2); - if (filter == 1 && spent < 0 || - filter == 2 && spent == 0) + if (filter == 1 && spent < 0 || // open positions + filter == 2 && spent == 0) // closed positions bAppend = true; } if (bAppend) From 1bdd83f1d1c690203ddfc0ea2a0a8f737fc4c23f Mon Sep 17 00:00:00 2001 From: dimxy Date: Mon, 22 Apr 2019 16:44:56 +0500 Subject: [PATCH 101/242] changed profits calc (prevent conversion to 0) --- src/cc/prices.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 188b773ef..a22c312b0 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -665,9 +665,10 @@ int64_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t //std::cerr << "prices_syntheticprofits() profits double=" << (double)price / (double)costbasis -1.0 << std::endl; //double dprofits = (double)price / (double)costbasis - 1.0; - profits *= ((int64_t)leverage * (int64_t)positionsize) / (int64_t)SATOSHIDEN; + profits *= ((int64_t)leverage * (int64_t)positionsize); + profits /= (int64_t)SATOSHIDEN; //dprofits *= leverage * positionsize; - std::cerr << "prices_syntheticprofits() value of profits=" << profits << " leverage=" << leverage << " positionsize=" << positionsize << std::endl; + std::cerr << "prices_syntheticprofits() value of profits=" << profits << std::endl; //std::cerr << "prices_syntheticprofits() dprofits=" << dprofits << std::endl; From 96c82c5208f5d70b398fa0eee0896bc466b4c308 Mon Sep 17 00:00:00 2001 From: dimxy Date: Mon, 22 Apr 2019 23:48:47 +0500 Subject: [PATCH 102/242] corr validate for cashout --- src/cc/prices.cpp | 95 +++++++++++++++++++++++++++++++---------------- 1 file changed, 62 insertions(+), 33 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index a22c312b0..03af42d90 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -130,12 +130,13 @@ uint8_t prices_finalopretdecode(CScript scriptPubKey,uint256 &bettxid,int64_t &p } // price opret basic validation and retrieval -bool CheckPricesOpret(const CTransaction & tx, vscript_t &opret) +static bool CheckPricesOpret(const CTransaction & tx, vscript_t &opret) { return tx.vout.size() > 0 && GetOpReturnData(tx.vout.back().scriptPubKey, opret) && opret.size() > 2 && opret.begin()[0] == EVAL_PRICES && IS_CHARINSTR(opret.begin()[1], "BACF"); } -bool ValidateBetTx(struct CCcontract_info *cp, Eval *eval, const CTransaction & bettx) +// validate bet tx helper +static bool ValidateBetTx(struct CCcontract_info *cp, Eval *eval, const CTransaction & bettx) { uint256 tokenid; int64_t positionsize, firstprice; @@ -163,12 +164,13 @@ bool ValidateBetTx(struct CCcontract_info *cp, Eval *eval, const CTransaction & return true; } - -bool ValidateAddFundingTx(struct CCcontract_info *cp, Eval *eval, const CTransaction & addfundingtx) +// validate add funding tx helper +static bool ValidateAddFundingTx(struct CCcontract_info *cp, Eval *eval, const CTransaction & addfundingtx, const CTransaction & vintx) { uint256 bettxid; int64_t amount; CPubKey pk, pricespk; + vscript_t vintxOpret; if (addfundingtx.vout.size() < 3 || addfundingtx.vout.size() > 4) return eval->Invalid("incorrect vout number for add funding tx"); @@ -179,6 +181,9 @@ bool ValidateAddFundingTx(struct CCcontract_info *cp, Eval *eval, const CTransac pricespk = GetUnspendable(cp, 0); + if (CheckPricesOpret(vintx, vintxOpret) && vintxOpret.begin()[1] == 'B' && vintx.GetHash() != bettxid) // if vintx is bettx + return eval->Invalid("incorrect bettx id"); + if (MakeCC1vout(cp->evalcode, addfundingtx.vout[0].nValue, pk) != addfundingtx.vout[0]) return eval->Invalid("cannot validate vout0 in add funding tx with pk from opreturn"); if (MakeCC1vout(cp->evalcode, addfundingtx.vout[1].nValue, pricespk) != addfundingtx.vout[1]) @@ -187,7 +192,8 @@ bool ValidateAddFundingTx(struct CCcontract_info *cp, Eval *eval, const CTransac return true; } -bool ValidateCostbasisTx(struct CCcontract_info *cp, Eval *eval, const CTransaction & costbasistx, const CTransaction & bettx) +// validate costbasis tx helper +static bool ValidateCostbasisTx(struct CCcontract_info *cp, Eval *eval, const CTransaction & costbasistx, const CTransaction & bettx) { uint256 bettxid; int64_t amount; @@ -208,8 +214,11 @@ bool ValidateCostbasisTx(struct CCcontract_info *cp, Eval *eval, const CTransact if (MakeCC1vout(cp->evalcode, costbasistx.vout[1].nValue, pricespk) != costbasistx.vout[1]) return eval->Invalid("cannot validate vout1 in costbasis tx with global pk"); - if (bettx.vout.size() < 1) // maybe this is already checked outside, but it is safe to check here too and have encapsulated check - return eval->Invalid("incorrect bettx"); + if (bettx.GetHash() != bettxid) + return eval->Invalid("incorrect bettx id"); + + if (bettx.vout.size() < 1) // for safety and for check encapsulation + return eval->Invalid("incorrect bettx no vouts"); // check costbasis rules: if (costbasistx.vout[0].nValue > bettx.vout[1].nValue / 10) @@ -230,7 +239,8 @@ bool ValidateCostbasisTx(struct CCcontract_info *cp, Eval *eval, const CTransact return true; } -bool ValidateFinalTx(struct CCcontract_info *cp, Eval *eval, const CTransaction & finaltx) +// validate final tx helper +static bool ValidateFinalTx(struct CCcontract_info *cp, Eval *eval, const CTransaction & finaltx, const CTransaction & bettx) { uint256 bettxid; int64_t amount; @@ -247,6 +257,9 @@ bool ValidateFinalTx(struct CCcontract_info *cp, Eval *eval, const CTransaction if (prices_finalopretdecode(finaltx.vout.back().scriptPubKey, bettxid, profits, height, pk, firstprice, costbasis, addedbets, positionsize, leverage) != 'F') return eval->Invalid("cannot decode opreturn for final tx"); + if (bettx.GetHash() != bettxid) + return eval->Invalid("incorrect bettx id"); + pricespk = GetUnspendable(cp, 0); if (MakeCC1vout(cp->evalcode, finaltx.vout[0].nValue, pk) != finaltx.vout[0]) @@ -258,11 +271,11 @@ bool ValidateFinalTx(struct CCcontract_info *cp, Eval *eval, const CTransaction return true; } +// validate prices tx function bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn) { vscript_t vopret; - if (strcmp(ASSETCHAINS_SYMBOL, "REKT0") == 0 && chainActive.Height() < 2100) return true; // check basic opret rules: @@ -271,28 +284,44 @@ bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx uint8_t funcId = vopret.begin()[1]; - CTransaction vintx; - vscript_t vintxOpret; + CTransaction firstVinTx; + vscript_t firstVinTxOpret; + bool foundFirst = false; int32_t ccVinCount = 0; - int32_t prevoutN = 0; - // load vintx (might be either bet or add funding tx): + uint32_t prevoutN = 0; + + // check basic rules: + + // find first cc vin and load vintx (might be either bet or add funding tx): for (auto vin : tx.vin) if (cp->ismyvin(vin.scriptSig)) { + CTransaction vintx; uint256 hashBlock; + vscript_t vintxOpret; + if (!myGetTransaction(vin.prevout.hash, vintx, hashBlock)) - return eval->Invalid("cannot load vin tx"); - prevoutN = vin.prevout.n; + return eval->Invalid("cannot load vintx"); + + if (!CheckPricesOpret(vintx, vintxOpret)) + return eval->Invalid("cannot find prices opret in vintx"); + + if (vintxOpret.begin()[1] == 'B' && prevoutN == 3) { + return eval->Invalid("cannot spend bet marker"); + } + + if (!foundFirst) { + prevoutN = vin.prevout.n; + firstVinTx = vintx; + firstVinTxOpret = vintxOpret; + foundFirst = true; + } ccVinCount++; } - if (ccVinCount != 1) // must be only one cc vintx - return eval->Invalid("incorrect cc vin txns num"); + if (!foundFirst) + return eval->Invalid("prices cc vin not found"); - if (!CheckPricesOpret(vintx, vintxOpret)) - return eval->Invalid("cannot find prices opret in vintx"); - - if (vintxOpret.begin()[1] == 'B' && prevoutN == 3) { // check basic spending rules - return eval->Invalid("cannot spend bet marker"); - } + if (funcId != 'F' && ccVinCount > 1) + return eval->Invalid("only one prices cc vin allowed for this tx"); switch (funcId) { case 'B': // bet @@ -300,26 +329,26 @@ bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx case 'A': // add funding // check tx structure: - if (!ValidateAddFundingTx(cp, eval, tx)) + if (!ValidateAddFundingTx(cp, eval, tx, firstVinTx)) return false; // invalid state is already set in the func - if (vintxOpret.begin()[1] == 'B') { - if (!ValidateBetTx(cp, eval, vintx)) // check tx structure + if (firstVinTxOpret.begin()[1] == 'B') { + if (!ValidateBetTx(cp, eval, firstVinTx)) // check tx structure return false; } - else if (vintxOpret.begin()[1] == 'A') { + 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 vout to spend"); + return eval->Invalid("incorrect vintx vout to spend"); } break; case 'C': // set costbasis - if (!ValidateBetTx(cp, eval, vintx)) // first check bet tx - return false; - if (!ValidateCostbasisTx(cp, eval, tx, vintx)) + if (!ValidateCostbasisTx(cp, eval, tx, firstVinTx)) + return false; + if (!ValidateBetTx(cp, eval, firstVinTx)) return false; if (prevoutN != 1) { // check spending rules return eval->Invalid("incorrect vout to spend"); @@ -328,9 +357,9 @@ bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx break; case 'F': // final tx - if (!ValidateBetTx(cp, eval, vintx)) // first check bet tx + if (!ValidateFinalTx(cp, eval, tx, firstVinTx)) return false; - if (!ValidateFinalTx(cp, eval, tx)) + if (!ValidateBetTx(cp, eval, firstVinTx)) return false; if (prevoutN != 2) { // check spending rules return eval->Invalid("incorrect vout to spend"); From a4aad9e05b720209dad0c7d41f764f7cb454b98d Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 23 Apr 2019 00:09:51 +0500 Subject: [PATCH 103/242] corr check vout0 validation in ValidateFinalTX --- src/cc/prices.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 03af42d90..a22127fe9 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -262,7 +262,7 @@ static bool ValidateFinalTx(struct CCcontract_info *cp, Eval *eval, const CTrans pricespk = GetUnspendable(cp, 0); - if (MakeCC1vout(cp->evalcode, finaltx.vout[0].nValue, pk) != finaltx.vout[0]) + if (CTxOut(finaltx.vout[0].nValue, CScript() << ParseHex(HexStr(pk)) << OP_CHECKSIG) != finaltx.vout[0]) return eval->Invalid("cannot validate vout0 in final tx with pk from opreturn"); if( finaltx.vout.size() == 3 && MakeCC1vout(cp->evalcode, finaltx.vout[1].nValue, pricespk) != finaltx.vout[1] ) @@ -272,6 +272,17 @@ static bool ValidateFinalTx(struct CCcontract_info *cp, Eval *eval, const CTrans } // validate prices tx function +// important checks: +// tx structure +// reference to the bet tx vout +// referenced bet tx structure +// referrenced bet txid in opret +// disable marker spending +// TODO: +// opret params (firstprice,positionsize...) +// cashout balance (PricesExactAmounts) +// costbasis calculation (?) +// use the special addr for fees bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn) { vscript_t vopret; From b56dc25c8d95c93117af07e9e306e20a284929b5 Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 23 Apr 2019 11:23:24 +0500 Subject: [PATCH 104/242] added logging to PricesList --- src/cc/prices.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index a22127fe9..999d35023 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1172,10 +1172,10 @@ UniValue PricesList(uint32_t filter, CPubKey mypk) txid = it->first.txhash; if (GetTransaction(txid, vintx, hashBlock, false) != 0) { + bool bAppend = false; if (vintx.vout.size() > 0 && prices_betopretdecode(vintx.vout[vintx.vout.size() - 1].scriptPubKey, pk, height, amount, leverage, firstprice, vec, tokenid) == 'B' && (mypk == CPubKey() || mypk == pk)) // if only mypubkey to list { - bool bAppend = false; if (filter == 0) bAppend = true; else { @@ -1191,6 +1191,7 @@ UniValue PricesList(uint32_t filter, CPubKey mypk) if (bAppend) result.push_back(txid.GetHex()); } + std::cerr << "PricesList() " << " bettxid=" << txid.GetHex() << " mypk=" << HexStr(mypk) << " opret pk=" << HexStr(pk) << " filter=" << filter << " bAppend=" << bAppend << std::endl; } } return(result); From 37aa2fbe88a8897b42e8bdfb92b6cffb5fe13acb Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 23 Apr 2019 14:23:16 +0500 Subject: [PATCH 105/242] test transaction moved to a separate file added a new test tx to try to spend bettx marker --- src/Makefile.am | 5 ++ src/cc/prices.cpp | 2 +- src/rpc/server.cpp | 4 - src/rpc/server.h | 6 -- src/wallet/rpcwallet.cpp | 178 --------------------------------------- 5 files changed, 6 insertions(+), 189 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 7e1647a6c..d335e0c04 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -524,6 +524,11 @@ if GLIBC_BACK_COMPAT libbitcoin_util_a_SOURCES += compat/glibc_compat.cpp endif +if ENABLE_TESTS +libbitcoin_util_a_SOURCES += rpc/testtransactions.cpp +endif + + # cli: zcash-cli libbitcoin_cli_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) libbitcoin_cli_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 999d35023..99fc34711 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -331,7 +331,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) + if (funcId != 'F' && 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"); switch (funcId) { diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 13f235e26..d18f551e6 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -571,10 +571,6 @@ static const CRPCCommand vRPCCommands[] = { "util", "reconsiderblock", &reconsiderblock, true }, /* Not shown in help */ { "hidden", "setmocktime", &setmocktime, true }, - { "hidden", "test_ac", &test_ac, true }, - { "hidden", "test_heirmarker", &test_heirmarker, true }, - { "hidden", "test_proof", &test_proof, true }, - { "hidden", "test_burntx", &test_burntx, true }, #ifdef ENABLE_WALLET diff --git a/src/rpc/server.h b/src/rpc/server.h index 98a0d046f..a215f9bc3 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -505,10 +505,4 @@ extern UniValue pricesrekt(const UniValue& params, bool fHelp); extern UniValue pricesaddfunding(const UniValue& params, bool fHelp); -// test rpc: -extern UniValue test_ac(const UniValue& params, bool fHelp); -extern UniValue test_heirmarker(const UniValue& params, bool fHelp); -extern UniValue test_burntx(const UniValue& params, bool fHelp); -extern UniValue test_proof(const UniValue& params, bool fHelp); - #endif // BITCOIN_RPCSERVER_H diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 6cb13a1db..8b9f82920 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -7972,181 +7972,3 @@ void RegisterWalletRPCCommands(CRPCTable &tableRPC) tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]); } -UniValue test_ac(const UniValue& params, bool fHelp) -{ - // make fake token tx: - struct CCcontract_info *cp, C; - - if (fHelp || (params.size() != 4)) - throw runtime_error("incorrect params\n"); - if (ensure_CCrequirements(EVAL_HEIR) < 0) - throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); - - std::vector pubkey1; - std::vector pubkey2; - - pubkey1 = ParseHex(params[0].get_str().c_str()); - pubkey2 = ParseHex(params[1].get_str().c_str()); - - CPubKey pk1 = pubkey2pk(pubkey1); - CPubKey pk2 = pubkey2pk(pubkey2); - - if(!pk1.IsValid() || !pk2.IsValid()) - throw runtime_error("invalid pubkey\n"); - - int64_t txfee = 10000; - int64_t amount = atoll(params[2].get_str().c_str()) * COIN; - uint256 fundingtxid = Parseuint256((char *)params[3].get_str().c_str()); - - CPubKey myPubkey = pubkey2pk(Mypubkey()); - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); - - int64_t normalInputs = AddNormalinputs(mtx, myPubkey, txfee + amount, 60); - - if( normalInputs < txfee + amount) - throw runtime_error("not enough normals\n"); - - mtx.vout.push_back(MakeCC1of2vout(EVAL_HEIR, amount, pk1, pk2)); - - CScript opret; - fundingtxid = revuint256(fundingtxid); - - opret << OP_RETURN << E_MARSHAL(ss << (uint8_t)EVAL_HEIR << (uint8_t)'A' << fundingtxid << (uint8_t)0); - - cp = CCinit(&C, EVAL_HEIR); - return(FinalizeCCTx(0, cp, mtx, myPubkey, txfee, opret)); -} - -UniValue test_heirmarker(const UniValue& params, bool fHelp) -{ - // make fake token tx: - struct CCcontract_info *cp, C; - - if (fHelp || (params.size() != 1)) - throw runtime_error("incorrect params\n"); - if (ensure_CCrequirements(EVAL_HEIR) < 0) - throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); - - uint256 fundingtxid = Parseuint256((char *)params[0].get_str().c_str()); - - CPubKey myPubkey = pubkey2pk(Mypubkey()); - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); - - int64_t normalInputs = AddNormalinputs(mtx, myPubkey, 10000, 60); - if (normalInputs < 10000) - throw runtime_error("not enough normals\n"); - - mtx.vin.push_back(CTxIn(fundingtxid, 1)); - mtx.vout.push_back(MakeCC1vout(EVAL_HEIR, 10000, myPubkey)); - - CScript opret; - fundingtxid = revuint256(fundingtxid); - - opret << OP_RETURN << E_MARSHAL(ss << (uint8_t)EVAL_HEIR << (uint8_t)'C' << fundingtxid << (uint8_t)0); - - cp = CCinit(&C, EVAL_HEIR); - return(FinalizeCCTx(0, cp, mtx, myPubkey, 10000, opret)); -} - -UniValue test_burntx(const UniValue& params, bool fHelp) -{ - // make fake token tx: - struct CCcontract_info *cp, C; - - if (fHelp || (params.size() != 1)) - throw runtime_error("incorrect params\n"); - if (ensure_CCrequirements(EVAL_TOKENS) < 0) - throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); - - uint256 tokenid = Parseuint256((char *)params[0].get_str().c_str()); - - CPubKey myPubkey = pubkey2pk(Mypubkey()); - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); - - int64_t normalInputs = AddNormalinputs(mtx, myPubkey, 10000, 60); - if (normalInputs < 10000) - throw runtime_error("not enough normals\n"); - - CPubKey burnpk = pubkey2pk(ParseHex(CC_BURNPUBKEY)); - - mtx.vin.push_back(CTxIn(tokenid, 0)); - mtx.vin.push_back(CTxIn(tokenid, 1)); - mtx.vout.push_back(MakeTokensCC1vout(EVAL_TOKENS, 1, burnpk)); - - std::vector voutPubkeys; - voutPubkeys.push_back(burnpk); - - cp = CCinit(&C, EVAL_TOKENS); - - std::vector vopret; - GetNonfungibleData(tokenid, vopret); - if (vopret.size() > 0) - cp->additionalTokensEvalcode2 = vopret.begin()[0]; - - uint8_t tokenpriv[33]; - char unspendableTokenAddr[64]; - CPubKey unspPk = GetUnspendable(cp, tokenpriv); - GetCCaddress(cp, unspendableTokenAddr, unspPk); - CCaddr2set(cp, EVAL_TOKENS, unspPk, tokenpriv, unspendableTokenAddr); - return(FinalizeCCTx(0, cp, mtx, myPubkey, 10000, EncodeTokenOpRet(tokenid, voutPubkeys, std::make_pair(0, vscript_t())))); -} - -UniValue test_proof(const UniValue& params, bool fHelp) -{ - UniValue result(UniValue::VOBJ); - std::vectorproof; - - if (fHelp || (params.size() != 2)) - throw runtime_error("incorrect params\n"); - - - proof = ParseHex(params[0].get_str()); - uint256 cointxid = Parseuint256((char *)params[1].get_str().c_str()); - - std::vector txids; - - CMerkleBlock merkleBlock; - if (!E_UNMARSHAL(proof, ss >> merkleBlock)) { - result.push_back(Pair("error", "could not unmarshal proof")); - return result; - } - uint256 merkleRoot = merkleBlock.txn.ExtractMatches(txids); - - result.push_back(Pair("source_root", merkleRoot.GetHex())); - - for (int i = 0; i < txids.size(); i++) - std::cerr << "merkle block txid=" << txids[0].GetHex() << std::endl; - - - std::vector vMatches(txids.size()); - for (auto v : vMatches) v = true; - CPartialMerkleTree verifTree(txids, vMatches); - - result.push_back(Pair("verif_root", verifTree.ExtractMatches(txids).GetHex())); - - if (std::find(txids.begin(), txids.end(), cointxid) == txids.end()) { - fprintf(stderr, "invalid proof for this cointxid\n"); - } - - std::vector vMerkleTree; - bool f; - ::BuildMerkleTree(&f, txids, vMerkleTree); - - std::vector vMerkleBranch = ::GetMerkleBranch(0, txids.size(), vMerkleTree); - - uint256 ourResult = SafeCheckMerkleBranch(zeroid, vMerkleBranch, 0); - result.push_back(Pair("SafeCheckMerkleBranch", ourResult.GetHex())); - - return result; -} - -void f(UniValue *p) { - - if (p) - p->push_back(make_pair("x", "y")); - - // or... - if (p) - (*p).push_back(make_pair("x", "y")); - -} \ No newline at end of file From c088fa62d59b511d57be83a7ec9caae2bf6b8b10 Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 23 Apr 2019 14:32:40 +0500 Subject: [PATCH 106/242] testtransactions.cpp added --- src/rpc/testtransactions.cpp | 261 +++++++++++++++++++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100644 src/rpc/testtransactions.cpp diff --git a/src/rpc/testtransactions.cpp b/src/rpc/testtransactions.cpp new file mode 100644 index 000000000..3decf862b --- /dev/null +++ b/src/rpc/testtransactions.cpp @@ -0,0 +1,261 @@ +// Copyright (c) 2010 Satoshi Nakamoto +// Copyright (c) 2009-2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +/****************************************************************************** + * Copyright © 2014-2019 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#include "amount.h" +#include "chain.h" +#include "chainparams.h" +#include "checkpoints.h" +#include "crosschain.h" +#include "base58.h" +#include "consensus/validation.h" +#include "cc/eval.h" +#include "main.h" +#include "primitives/transaction.h" +#include "rpc/server.h" +#include "streams.h" +#include "sync.h" +#include "util.h" +#include "script/script.h" +#include "script/script_error.h" +#include "script/sign.h" +#include "script/standard.h" + +#include + +#include + +#include + +#include "cc/CCinclude.h" +#include "cc/CCPrices.h" + + +UniValue test_ac(const UniValue& params, bool fHelp) +{ + // make fake token tx: + struct CCcontract_info *cp, C; + + if (fHelp || (params.size() != 4)) + throw runtime_error("incorrect params\n"); + if (ensure_CCrequirements(EVAL_HEIR) < 0) + throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + + std::vector pubkey1; + std::vector pubkey2; + + pubkey1 = ParseHex(params[0].get_str().c_str()); + pubkey2 = ParseHex(params[1].get_str().c_str()); + + CPubKey pk1 = pubkey2pk(pubkey1); + CPubKey pk2 = pubkey2pk(pubkey2); + + if (!pk1.IsValid() || !pk2.IsValid()) + throw runtime_error("invalid pubkey\n"); + + int64_t txfee = 10000; + int64_t amount = atoll(params[2].get_str().c_str()) * COIN; + uint256 fundingtxid = Parseuint256((char *)params[3].get_str().c_str()); + + CPubKey myPubkey = pubkey2pk(Mypubkey()); + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + + int64_t normalInputs = AddNormalinputs(mtx, myPubkey, txfee + amount, 60); + + if (normalInputs < txfee + amount) + throw runtime_error("not enough normals\n"); + + mtx.vout.push_back(MakeCC1of2vout(EVAL_HEIR, amount, pk1, pk2)); + + CScript opret; + fundingtxid = revuint256(fundingtxid); + + opret << OP_RETURN << E_MARSHAL(ss << (uint8_t)EVAL_HEIR << (uint8_t)'A' << fundingtxid << (uint8_t)0); + + cp = CCinit(&C, EVAL_HEIR); + return(FinalizeCCTx(0, cp, mtx, myPubkey, txfee, opret)); +} + +UniValue test_heirmarker(const UniValue& params, bool fHelp) +{ + // make fake token tx: + struct CCcontract_info *cp, C; + + if (fHelp || (params.size() != 1)) + throw runtime_error("incorrect params\n"); + if (ensure_CCrequirements(EVAL_HEIR) < 0) + throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + + uint256 fundingtxid = Parseuint256((char *)params[0].get_str().c_str()); + + CPubKey myPubkey = pubkey2pk(Mypubkey()); + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + + int64_t normalInputs = AddNormalinputs(mtx, myPubkey, 10000, 60); + if (normalInputs < 10000) + throw runtime_error("not enough normals\n"); + + mtx.vin.push_back(CTxIn(fundingtxid, 1)); + mtx.vout.push_back(MakeCC1vout(EVAL_HEIR, 10000, myPubkey)); + + CScript opret; + fundingtxid = revuint256(fundingtxid); + + opret << OP_RETURN << E_MARSHAL(ss << (uint8_t)EVAL_HEIR << (uint8_t)'C' << fundingtxid << (uint8_t)0); + + cp = CCinit(&C, EVAL_HEIR); + return(FinalizeCCTx(0, cp, mtx, myPubkey, 10000, opret)); +} + +UniValue test_burntx(const UniValue& params, bool fHelp) +{ + // make fake token tx: + struct CCcontract_info *cp, C; + + if (fHelp || (params.size() != 1)) + throw runtime_error("incorrect params\n"); + if (ensure_CCrequirements(EVAL_TOKENS) < 0) + throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + + uint256 tokenid = Parseuint256((char *)params[0].get_str().c_str()); + + CPubKey myPubkey = pubkey2pk(Mypubkey()); + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + + int64_t normalInputs = AddNormalinputs(mtx, myPubkey, 10000, 60); + if (normalInputs < 10000) + throw runtime_error("not enough normals\n"); + + CPubKey burnpk = pubkey2pk(ParseHex(CC_BURNPUBKEY)); + + mtx.vin.push_back(CTxIn(tokenid, 0)); + mtx.vin.push_back(CTxIn(tokenid, 1)); + mtx.vout.push_back(MakeTokensCC1vout(EVAL_TOKENS, 1, burnpk)); + + std::vector voutPubkeys; + voutPubkeys.push_back(burnpk); + + cp = CCinit(&C, EVAL_TOKENS); + + std::vector vopret; + GetNonfungibleData(tokenid, vopret); + if (vopret.size() > 0) + cp->additionalTokensEvalcode2 = vopret.begin()[0]; + + uint8_t tokenpriv[33]; + char unspendableTokenAddr[64]; + CPubKey unspPk = GetUnspendable(cp, tokenpriv); + GetCCaddress(cp, unspendableTokenAddr, unspPk); + CCaddr2set(cp, EVAL_TOKENS, unspPk, tokenpriv, unspendableTokenAddr); + return(FinalizeCCTx(0, cp, mtx, myPubkey, 10000, EncodeTokenOpRet(tokenid, voutPubkeys, std::make_pair(0, vscript_t())))); +} + +UniValue test_proof(const UniValue& params, bool fHelp) +{ + UniValue result(UniValue::VOBJ); + std::vectorproof; + + if (fHelp || (params.size() != 2)) + throw runtime_error("incorrect params\n"); + + + proof = ParseHex(params[0].get_str()); + uint256 cointxid = Parseuint256((char *)params[1].get_str().c_str()); + + std::vector txids; + + CMerkleBlock merkleBlock; + if (!E_UNMARSHAL(proof, ss >> merkleBlock)) { + result.push_back(Pair("error", "could not unmarshal proof")); + return result; + } + uint256 merkleRoot = merkleBlock.txn.ExtractMatches(txids); + + result.push_back(Pair("source_root", merkleRoot.GetHex())); + + for (int i = 0; i < txids.size(); i++) + std::cerr << "merkle block txid=" << txids[0].GetHex() << std::endl; + + + std::vector vMatches(txids.size()); + for (auto v : vMatches) v = true; + CPartialMerkleTree verifTree(txids, vMatches); + + result.push_back(Pair("verif_root", verifTree.ExtractMatches(txids).GetHex())); + + if (std::find(txids.begin(), txids.end(), cointxid) == txids.end()) { + fprintf(stderr, "invalid proof for this cointxid\n"); + } + + std::vector vMerkleTree; + bool f; + ::BuildMerkleTree(&f, txids, vMerkleTree); + + std::vector vMerkleBranch = ::GetMerkleBranch(0, txids.size(), vMerkleTree); + + uint256 ourResult = SafeCheckMerkleBranch(zeroid, vMerkleBranch, 0); + result.push_back(Pair("SafeCheckMerkleBranch", ourResult.GetHex())); + + return result; +} + +UniValue test_pricesmarker(const UniValue& params, bool fHelp) +{ + // make fake token tx: + struct CCcontract_info *cp, C; + + if (fHelp || (params.size() != 1)) + throw runtime_error("incorrect params\n"); + if (ensure_CCrequirements(EVAL_PRICES) < 0) + throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + + uint256 bettxid = Parseuint256((char *)params[0].get_str().c_str()); + + cp = CCinit(&C, EVAL_PRICES); + CPubKey myPubkey = pubkey2pk(Mypubkey()); + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + + int64_t normalInputs = AddNormalinputs(mtx, myPubkey, 10000, 60); + if (normalInputs < 10000) + throw runtime_error("not enough normals\n"); + + mtx.vin.push_back(CTxIn(bettxid, 1)); + mtx.vout.push_back(CTxOut(1000, ParseHex(HexStr(myPubkey))); + + return(FinalizeCCTx(0, cp, mtx, myPubkey, 10000, CScript())); +} + + +static const CRPCCommand commands[] = +{ // category name actor (function) okSafeMode + // --------------------- ------------------------ ----------------------- ---------- + + /* Not shown in help */ + { "hidden", "test_ac", &test_ac, true }, + { "hidden", "test_heirmarker", &test_heirmarker, true }, + { "hidden", "test_proof", &test_proof, true }, + { "hidden", "test_burntx", &test_burntx, true }, + { "hidden", "test_pricesmarker", &test_pricesmarker, true } +}; + +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 From ea96f4d5284ce4600ef8d774c036045bfdf4eebb Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 23 Apr 2019 14:37:45 +0500 Subject: [PATCH 107/242] moved testtransaction to server lib --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index d335e0c04..e6c1fbb14 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -525,7 +525,7 @@ libbitcoin_util_a_SOURCES += compat/glibc_compat.cpp endif if ENABLE_TESTS -libbitcoin_util_a_SOURCES += rpc/testtransactions.cpp +libbitcoin_server_a_SOURCES += rpc/testtransactions.cpp endif From f341b517a3a6360a859aa75d58f36c849174777b Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 23 Apr 2019 14:51:36 +0500 Subject: [PATCH 108/242] corr include, syntax err --- src/rpc/testtransactions.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/rpc/testtransactions.cpp b/src/rpc/testtransactions.cpp index 3decf862b..85895a2df 100644 --- a/src/rpc/testtransactions.cpp +++ b/src/rpc/testtransactions.cpp @@ -18,6 +18,8 @@ * * ******************************************************************************/ +#include + #include "amount.h" #include "chain.h" #include "chainparams.h" @@ -43,9 +45,13 @@ #include + #include "cc/CCinclude.h" #include "cc/CCPrices.h" +using namespace std; + +int32_t ensure_CCrequirements(uint8_t evalcode); UniValue test_ac(const UniValue& params, bool fHelp) { @@ -236,7 +242,7 @@ UniValue test_pricesmarker(const UniValue& params, bool fHelp) throw runtime_error("not enough normals\n"); mtx.vin.push_back(CTxIn(bettxid, 1)); - mtx.vout.push_back(CTxOut(1000, ParseHex(HexStr(myPubkey))); + mtx.vout.push_back(CTxOut(1000, CScript() << ParseHex(HexStr(myPubkey)) << OP_CHECKSIG)); return(FinalizeCCTx(0, cp, mtx, myPubkey, 10000, CScript())); } From a8065c046224d2311919b97ad7fdadafbc6e4e05 Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 23 Apr 2019 15:02:38 +0500 Subject: [PATCH 109/242] added testtransactions rpc to table --- src/rpc/register.h | 7 +++++++ src/rpc/testtransactions.cpp | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/rpc/register.h b/src/rpc/register.h index 072517d88..245f76e22 100644 --- a/src/rpc/register.h +++ b/src/rpc/register.h @@ -35,6 +35,10 @@ void RegisterMiningRPCCommands(CRPCTable &tableRPC); /** Register raw transaction RPC commands */ void RegisterRawTransactionRPCCommands(CRPCTable &tableRPC); +/** Register test transaction RPC commands */ +void RegisterTesttransactionsRPCCommands(CRPCTable &tableRPC); + + static inline void RegisterAllCoreRPCCommands(CRPCTable &tableRPC) { RegisterBlockchainRPCCommands(tableRPC); @@ -42,6 +46,9 @@ static inline void RegisterAllCoreRPCCommands(CRPCTable &tableRPC) RegisterMiscRPCCommands(tableRPC); RegisterMiningRPCCommands(tableRPC); RegisterRawTransactionRPCCommands(tableRPC); +#ifdef TESTMODE + RegisterTesttransactionsRPCCommands(tableRPC); +#endif } #endif diff --git a/src/rpc/testtransactions.cpp b/src/rpc/testtransactions.cpp index 85895a2df..35c35c8f8 100644 --- a/src/rpc/testtransactions.cpp +++ b/src/rpc/testtransactions.cpp @@ -260,7 +260,7 @@ static const CRPCCommand commands[] = { "hidden", "test_pricesmarker", &test_pricesmarker, true } }; -void RegisterBlockchainRPCCommands(CRPCTable &tableRPC) +void RegisterTesttransactionsRPCCommands(CRPCTable &tableRPC) { for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]); From 8982ffd91870b730b51f40f41d31f52216b1235b Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 23 Apr 2019 15:10:26 +0500 Subject: [PATCH 110/242] added opret to test tx spending marker --- src/rpc/testtransactions.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/rpc/testtransactions.cpp b/src/rpc/testtransactions.cpp index 35c35c8f8..ddf7c8895 100644 --- a/src/rpc/testtransactions.cpp +++ b/src/rpc/testtransactions.cpp @@ -221,6 +221,7 @@ UniValue test_proof(const UniValue& params, bool fHelp) return result; } +extern CScript prices_costbasisopret(uint256 bettxid, CPubKey mypk, int32_t height, int64_t costbasis); UniValue test_pricesmarker(const UniValue& params, bool fHelp) { // make fake token tx: @@ -244,7 +245,7 @@ UniValue test_pricesmarker(const UniValue& params, bool fHelp) mtx.vin.push_back(CTxIn(bettxid, 1)); mtx.vout.push_back(CTxOut(1000, CScript() << ParseHex(HexStr(myPubkey)) << OP_CHECKSIG)); - return(FinalizeCCTx(0, cp, mtx, myPubkey, 10000, CScript())); + return(FinalizeCCTx(0, cp, mtx, myPubkey, 10000, prices_costbasisopret(bettxid, myPubkey, 100, 100))); } From 1bf4baf408e55b8bf82a43a3de49c566a8bcb480 Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 23 Apr 2019 15:56:54 +0500 Subject: [PATCH 111/242] added normal inputs pubkey validation --- src/cc/prices.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 99fc34711..6982771cf 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -161,6 +161,15 @@ static bool ValidateBetTx(struct CCcontract_info *cp, Eval *eval, const CTransac if( MakeCC1vout(cp->evalcode, bettx.vout[2].nValue, pricespk) != bettx.vout[2] ) return eval->Invalid("cannot validate vout2 in bet tx with pk from opreturn"); + // validate if normal inputs are really signed by originator pubkey (someone not cheating with originator pubkey) + CAmount ccOutputs = 0; + for (auto vout : bettx.vout) + if (vout.scriptPubKey.IsPayToCryptoCondition()) + ccOutputs += vout.nValue; + CAmount normalInputs = TotalPubkeyNormalInputs(bettx, pk); + if (normalInputs < ccOutputs) + return eval->Invalid("bettx normal input signed with not pubkey in opret"); + return true; } From 36227f2e9cba7f76533380d2effadb6140db8fdb Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 23 Apr 2019 16:39:53 +0500 Subject: [PATCH 112/242] test window=7 --- src/komodo_defs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/komodo_defs.h b/src/komodo_defs.h index d5a9a21e2..02e51cd2f 100644 --- a/src/komodo_defs.h +++ b/src/komodo_defs.h @@ -42,7 +42,7 @@ #ifndef TESTMODE #define PRICES_DAYWINDOW ((3600*24/ASSETCHAINS_BLOCKTIME) + 1) #else -#define PRICES_DAYWINDOW (3) +#define PRICES_DAYWINDOW (7) #endif extern uint8_t ASSETCHAINS_TXPOW,ASSETCHAINS_PUBLIC; From dee7212413689d4d2aa9f100798bc6c5b75d58ea Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 23 Apr 2019 16:47:58 +0500 Subject: [PATCH 113/242] temp pubkey validation removed --- src/cc/prices.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 6982771cf..b0d4a7952 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -167,7 +167,7 @@ static bool ValidateBetTx(struct CCcontract_info *cp, Eval *eval, const CTransac if (vout.scriptPubKey.IsPayToCryptoCondition()) ccOutputs += vout.nValue; CAmount normalInputs = TotalPubkeyNormalInputs(bettx, pk); - if (normalInputs < ccOutputs) + if (0 && normalInputs < ccOutputs) return eval->Invalid("bettx normal input signed with not pubkey in opret"); return true; From 3de3298e572e69bc607b81638485ac2e1b479ee9 Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 23 Apr 2019 17:05:30 +0500 Subject: [PATCH 114/242] test bad pk to bettx --- src/cc/prices.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index b0d4a7952..e1d69206b 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -167,7 +167,7 @@ static bool ValidateBetTx(struct CCcontract_info *cp, Eval *eval, const CTransac if (vout.scriptPubKey.IsPayToCryptoCondition()) ccOutputs += vout.nValue; CAmount normalInputs = TotalPubkeyNormalInputs(bettx, pk); - if (0 && normalInputs < ccOutputs) + if (normalInputs < ccOutputs) return eval->Invalid("bettx normal input signed with not pubkey in opret"); return true; @@ -289,9 +289,9 @@ static bool ValidateFinalTx(struct CCcontract_info *cp, Eval *eval, const CTrans // disable marker spending // TODO: // opret params (firstprice,positionsize...) +// costbasis calculation // cashout balance (PricesExactAmounts) -// costbasis calculation (?) -// use the special addr for fees +// use the special address for 50% fees bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn) { vscript_t vopret; @@ -843,7 +843,7 @@ UniValue PricesBet(int64_t txfee, int64_t amount, int16_t leverage, std::vector< 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, betamount, pricespk)); mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(HexStr(pricespk)) << OP_CHECKSIG)); // marker - rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_betopret(mypk, nextheight - 1, amount, leverage, firstprice, vec, zeroid)); + rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_betopret(/*mypk*/ pubkey2pk(ParseHex("03069fc09829259b3cd7b53bd97714498614f9ca323287bc783e39b02046f696db")), nextheight - 1, amount, leverage, firstprice, vec, zeroid)); return(prices_rawtxresult(result, rawtx, 0)); } result.push_back(Pair("result", "error")); From 37a09bf6cd180c1db84fbcafa8df0e852e9f7b85 Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 23 Apr 2019 17:24:55 +0500 Subject: [PATCH 115/242] test bettx vout0 to fake pk --- src/cc/prices.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index e1d69206b..896cb37d3 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -839,7 +839,7 @@ UniValue PricesBet(int64_t txfee, int64_t amount, int16_t leverage, std::vector< if (AddNormalinputs(mtx, mypk, amount + 5 * txfee, 64) >= amount + 5 * txfee) { betamount = (amount * 199) / 200; - mtx.vout.push_back(MakeCC1vout(cp->evalcode, txfee, mypk)); // vout0 baton for total funding + mtx.vout.push_back(MakeCC1vout(cp->evalcode, txfee, /*mypk*/pubkey2pk(ParseHex("03069fc09829259b3cd7b53bd97714498614f9ca323287bc783e39b02046f696db")))); // 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, betamount, pricespk)); mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(HexStr(pricespk)) << OP_CHECKSIG)); // marker From db8619363c762ca5f601b80f3e0c57a22cea5628 Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 23 Apr 2019 20:07:07 +0500 Subject: [PATCH 116/242] added costbasis validation removed cycling in setcostbasis --- src/cc/prices.cpp | 119 +++++++++++++++++++++++++++++++++------------- 1 file changed, 85 insertions(+), 34 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 896cb37d3..b9ca2e5d6 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -44,6 +44,8 @@ CBOPRET creates trustless oracles, which can be used for making a synthetic cash */ +int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t height, int16_t leverage, std::vector vec, int64_t positionsize, int64_t addedbets, int64_t &profits, int64_t &outprice); + // helpers: // returns true if there are only digits and no alphas or slashes in 's' @@ -161,6 +163,10 @@ static bool ValidateBetTx(struct CCcontract_info *cp, Eval *eval, const CTransac if( MakeCC1vout(cp->evalcode, bettx.vout[2].nValue, pricespk) != bettx.vout[2] ) return eval->Invalid("cannot validate vout2 in bet tx with pk from opreturn"); + int64_t betamount = bettx.vout[2].nValue; + if( betamount != (positionsize * 199) / 200 ) + return eval->Invalid("invalid position size in the opreturn"); + // validate if normal inputs are really signed by originator pubkey (someone not cheating with originator pubkey) CAmount ccOutputs = 0; for (auto vout : bettx.vout) @@ -170,6 +176,9 @@ static bool ValidateBetTx(struct CCcontract_info *cp, Eval *eval, const CTransac if (normalInputs < ccOutputs) return eval->Invalid("bettx normal input signed with not pubkey in opret"); + if (leverage > PRICES_MAXLEVERAGE || leverage < -PRICES_MAXLEVERAGE) + return eval->Invalid("invalid leverage"); + return true; } @@ -205,7 +214,7 @@ static bool ValidateAddFundingTx(struct CCcontract_info *cp, Eval *eval, const C static bool ValidateCostbasisTx(struct CCcontract_info *cp, Eval *eval, const CTransaction & costbasistx, const CTransaction & bettx) { uint256 bettxid; - int64_t amount; + int64_t costbasisInOpret; CPubKey pk, pricespk; int32_t height; @@ -214,7 +223,7 @@ static bool ValidateCostbasisTx(struct CCcontract_info *cp, Eval *eval, const CT return eval->Invalid("incorrect vout count for costbasis tx"); vscript_t opret; - if (prices_costbasisopretdecode(costbasistx.vout.back().scriptPubKey, bettxid, pk, height, amount) != 'C') + if (prices_costbasisopretdecode(costbasistx.vout.back().scriptPubKey, bettxid, pk, height, costbasisInOpret) != 'C') return eval->Invalid("cannot decode opreturn for costbasis tx"); pricespk = GetUnspendable(cp, 0); @@ -244,6 +253,13 @@ static bool ValidateCostbasisTx(struct CCcontract_info *cp, Eval *eval, const CT if( firstheight + PRICES_DAYWINDOW + PRICES_SMOOTHWIDTH > chainActive.Height() ) return eval->Invalid("cannot calculate costbasis yet"); + + int64_t costbasis = 0, profits, lastprice; + int32_t retcode = prices_syntheticprofits(costbasis, firstheight, firstheight + PRICES_DAYWINDOW, leverage, vec, positionsize, 0, profits, lastprice); + if (retcode < 0) + return eval->Invalid("cannot calculate costbasis yet"); + if( costbasis != costbasisInOpret ) + return eval->Invalid("incorrect costbasis value"); return true; } @@ -281,12 +297,16 @@ static bool ValidateFinalTx(struct CCcontract_info *cp, Eval *eval, const CTrans } // validate prices tx function -// important checks: -// tx structure -// reference to the bet tx vout +// performed checks: +// basic tx structure (vout num) +// basic tx opret structure +// reference to the bet tx vout +// referenced bet txid in tx opret // referenced bet tx structure -// referrenced bet txid in opret -// disable marker spending +// non-final tx has only 1 cc vin +// cc vouts to self with mypubkey from opret +// cc vouts to global pk with global pk +// for bet tx that normal inputs digned with my pubkey from the opret >= cc outputs - disable betting for other pubkeys (Do we need this rule?) // TODO: // opret params (firstprice,positionsize...) // costbasis calculation @@ -661,22 +681,21 @@ int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t } // calculates profit/loss for the bet -int64_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t height, int16_t leverage, std::vector vec, int64_t positionsize, int64_t addedbets, int64_t &outprice) +int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t height, int16_t leverage, std::vector vec, int64_t positionsize, int64_t addedbets, int64_t &profits, int64_t &outprice) { - int64_t profits = 0; int64_t price; if (height < firstheight) { fprintf(stderr, "requested height is lower than bet firstheight.%d\n", height); - return 0; + return -1; } int32_t minmax = (height < firstheight + PRICES_DAYWINDOW); // if we are within 24h then use min or max value if ((price = prices_syntheticprice(vec, height, minmax, leverage)) < 0) { - fprintf(stderr, "unexpected zero synthetic price at height.%d\n", height); - return(0); + fprintf(stderr, "error getting synthetic price at height.%d\n", height); + return -1; } // clear lowest positions: @@ -684,7 +703,7 @@ int64_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t price *= PRICES_NORMFACTOR; outprice = price; - if (minmax) { // if we are within day window, set costbasis to max or min price value + 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 << " price=" << price << std::endl; @@ -699,13 +718,17 @@ int64_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t } else { - // use provided costbasis - std::cerr << "prices_syntheticprofits() provided costbasis=" << costbasis << " price=" << price << std::endl; - //if (costbasis == 0) - // costbasis = price; + if (costbasis == 0) { + // if costbasis not set, just set it + costbasis = price; + std::cerr << "prices_syntheticprofits() set costbasis=" << costbasis << std::endl; + } + else { + // use provided costbasis + std::cerr << "prices_syntheticprofits() provided costbasis=" << costbasis << " price=" << price << std::endl; + } } - profits = costbasis > 0 ? (((price / PRICES_NORMFACTOR * SATOSHIDEN) / costbasis) - SATOSHIDEN / PRICES_NORMFACTOR) * PRICES_NORMFACTOR : 0; std::cerr << "prices_syntheticprofits() test value1 (price/PRICES_NORMFACTOR * SATOSHIDEN)=" << (price / PRICES_NORMFACTOR * SATOSHIDEN) << std::endl; std::cerr << "prices_syntheticprofits() test value2 (price/PRICES_NORMFACTOR * SATOSHIDEN)/costbasis=" << (costbasis != 0 ? (price / PRICES_NORMFACTOR * SATOSHIDEN)/costbasis : 0) << std::endl; @@ -720,8 +743,7 @@ int64_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t std::cerr << "prices_syntheticprofits() value of profits=" << profits << std::endl; //std::cerr << "prices_syntheticprofits() dprofits=" << dprofits << std::endl; - - return profits; // (positionsize + addedbets + profits); + return 0; // (positionsize + addedbets + profits); } void prices_betjson(UniValue &result,int64_t profits,int64_t costbasis,int64_t positionsize,int64_t addedbets,int16_t leverage,int32_t firstheight,int64_t firstprice, int64_t lastprice, int64_t equity) @@ -839,11 +861,11 @@ UniValue PricesBet(int64_t txfee, int64_t amount, int16_t leverage, std::vector< if (AddNormalinputs(mtx, mypk, amount + 5 * txfee, 64) >= amount + 5 * txfee) { betamount = (amount * 199) / 200; - mtx.vout.push_back(MakeCC1vout(cp->evalcode, txfee, /*mypk*/pubkey2pk(ParseHex("03069fc09829259b3cd7b53bd97714498614f9ca323287bc783e39b02046f696db")))); // vout0 baton for total funding + 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, betamount, pricespk)); mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(HexStr(pricespk)) << OP_CHECKSIG)); // marker - rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_betopret(/*mypk*/ pubkey2pk(ParseHex("03069fc09829259b3cd7b53bd97714498614f9ca323287bc783e39b02046f696db")), nextheight - 1, amount, leverage, firstprice, vec, zeroid)); + rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_betopret(mypk, nextheight - 1, amount, leverage, firstprice, vec, zeroid)); return(prices_rawtxresult(result, rawtx, 0)); } result.push_back(Pair("result", "error")); @@ -921,19 +943,24 @@ UniValue PricesSetcostbasis(int64_t txfee, uint256 bettxid) addedbets = prices_batontxid(batontxid, bettx, bettxid); mtx.vin.push_back(CTxIn(bettxid, 1, CScript())); // spend vin1 with betamount - for (i = 0; i < PRICES_DAYWINDOW + 1; i++) // the last datum for 24h is the costbasis value - { - profits = prices_syntheticprofits(costbasis, firstheight, firstheight + i, leverage, vec, positionsize, addedbets, lastprice); + //for (i = 0; i < PRICES_DAYWINDOW + 1; i++) // the last datum for 24h is the actual costbasis value + //{ + int32_t retcode = prices_syntheticprofits(costbasis, firstheight, firstheight + PRICES_DAYWINDOW, leverage, vec, positionsize, addedbets, profits, lastprice); + if (retcode < 0) { + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "cannot calculate costbasis error getting price")); + return(result); + } equity = positionsize + addedbets + profits; - if (equity < 0) + /*if (equity < 0) { // we are in loss result.push_back(Pair("rekt", (int64_t)1)); result.push_back(Pair("rektheight", (int64_t)firstheight + i)); break; - } - } - if (i == PRICES_DAYWINDOW + 1) - result.push_back(Pair("rekt", 0)); + }*/ + //} + //if (i == PRICES_DAYWINDOW + 1) + // result.push_back(Pair("rekt", 0)); prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice, lastprice, equity); @@ -989,7 +1016,13 @@ UniValue PricesRekt(int64_t txfee, uint256 bettxid, int32_t rektheight) } addedbets = prices_batontxid(batontxid, bettx, bettxid); - profits = prices_syntheticprofits(costbasis, firstheight, rektheight, leverage, vec, positionsize, addedbets, lastprice); + int32_t retcode = prices_syntheticprofits(costbasis, firstheight, rektheight, leverage, vec, positionsize, addedbets, profits, lastprice); + if (retcode < 0) { + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "cannot get price")); + return(result); + } + equity = positionsize + addedbets + profits; if (equity < 0) { @@ -1058,7 +1091,12 @@ UniValue PricesCashout(int64_t txfee, uint256 bettxid) } addedbets = prices_batontxid(batontxid, bettx, bettxid); - profits = prices_syntheticprofits(costbasis, firstheight, nextheight - 1, leverage, vec, positionsize, addedbets, lastprice); + int32_t retcode = prices_syntheticprofits(costbasis, firstheight, nextheight - 1, leverage, vec, positionsize, addedbets, profits, lastprice); + if (retcode < 0) { + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "cannot get price")); + return(result); + } equity = positionsize + addedbets + profits; if (equity < 0) { @@ -1102,6 +1140,9 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) if (myGetTransaction(bettxid, bettx, hashBlock) != 0 && (numvouts = bettx.vout.size()) > 3) { + if (hashBlock.IsNull()) + throw std::runtime_error("tx still in mempool"); + if (prices_betopretdecode(bettx.vout[numvouts - 1].scriptPubKey, pk, firstheight, positionsize, leverage, firstprice, vec, tokenid) == 'B') { // check acceptable refheight: @@ -1117,7 +1158,12 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) addedbets = prices_batontxid(batontxid, bettx, bettxid); if (costbasis != 0) { // costbasis fixed - profits = prices_syntheticprofits(costbasis, firstheight, refheight, leverage, vec, positionsize, addedbets, lastprice); + int32_t retcode = prices_syntheticprofits(costbasis, firstheight, refheight, leverage, vec, positionsize, addedbets, profits, lastprice); + if (retcode < 0) { + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "cannot get price")); + return(result); + } equity = positionsize + addedbets + profits; if (equity < 0) { @@ -1132,7 +1178,12 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) bool isRekt = false; for (i = 0; i < PRICES_DAYWINDOW + 1 && firstheight + i <= refheight; i++) // the last datum for 24h is the costbasis value { - profits = prices_syntheticprofits(costbasis, firstheight, firstheight + i, leverage, vec, positionsize, addedbets, lastprice); + int32_t retcode = prices_syntheticprofits(costbasis, firstheight, firstheight + i, leverage, vec, positionsize, addedbets, profits, lastprice); + if (retcode < 0) { + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "cannot get price")); + return(result); + } equity = positionsize + addedbets + profits; if (equity < 0) { // we are in loss From 187ce2a657150d5ff1e9b1748bc4f0196a99e200 Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 23 Apr 2019 22:04:54 +0500 Subject: [PATCH 117/242] costbasis validation logging --- src/cc/prices.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index b9ca2e5d6..667dc681c 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -258,7 +258,8 @@ static bool ValidateCostbasisTx(struct CCcontract_info *cp, Eval *eval, const CT int32_t retcode = prices_syntheticprofits(costbasis, firstheight, firstheight + PRICES_DAYWINDOW, leverage, vec, positionsize, 0, profits, lastprice); if (retcode < 0) return eval->Invalid("cannot calculate costbasis yet"); - if( costbasis != costbasisInOpret ) + std::cerr << "ValidateCostbasisTx() costbasis=" << costbasis << " costbasisInOpret=" << costbasisInOpret << std::endl; + if( 0 && costbasis != costbasisInOpret ) return eval->Invalid("incorrect costbasis value"); return true; From 58577b64e1a9397d9a3e49ded568409a6e2052f0 Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 23 Apr 2019 22:49:13 +0500 Subject: [PATCH 118/242] changed valid height --- src/cc/prices.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 667dc681c..7228ee9a8 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -317,7 +317,7 @@ bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx { vscript_t vopret; - if (strcmp(ASSETCHAINS_SYMBOL, "REKT0") == 0 && chainActive.Height() < 2100) + if (strcmp(ASSETCHAINS_SYMBOL, "REKT0") == 0 && chainActive.Height() < 2965) return true; // check basic opret rules: if (!CheckPricesOpret(tx, vopret)) From b6f1b2dcc11007023e030a2c0b206e8573ad9b59 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Thu, 25 Apr 2019 10:14:23 +0800 Subject: [PATCH 119/242] remove print --- src/miner.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/miner.cpp b/src/miner.cpp index e199acccd..3e1ba3be2 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -721,7 +721,7 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 } return(0); } - fprintf(stderr, "Created notary payment coinbase totalsat.%lu\n",totalsats); + //fprintf(stderr, "Created notary payment coinbase totalsat.%lu\n",totalsats); } else fprintf(stderr, "vout 2 of notarisation is not OP_RETURN scriptlen.%i\n", scriptlen); } if ( ASSETCHAINS_CBOPRET != 0 ) From 57ef70d08eba39274364120167304bcc398f43ea Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Thu, 25 Apr 2019 10:48:21 +0800 Subject: [PATCH 120/242] fix notarizations left math error --- src/rpc/misc.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index c2ba9d702..e8010ede3 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -1299,11 +1299,11 @@ UniValue getnotarypayinfo(const UniValue& params, bool fHelp) balance = checkburnaddress(received, TotalNotaryPay, height, "REDVp3ox1pbcWYCzySadfHhk8UU3HM4k5x"); notarycount = komodo_notaries(notarypubkeys, height, chainActive[height]->GetBlockTime()); - NotaryPay = komodo_notarypayamount(height, notarycount); + NotaryPay = komodo_notarypayamount(height, notarycount)*notarycount; bool spent = (received != balance); if ( !spent ) { - notaleft = (balance - TotalNotaryPay) / NotaryPay; + notaleft = ((int64_t)balance - TotalNotaryPay) / NotaryPay; daysleft = (((ASSETCHAINS_BLOCKTIME * 5) * notaleft) / 3600) / 24; endheight = (notaleft * 5) + height; } From 0331607b713b83eebc64ff8a241cdb3fb24bcc9f Mon Sep 17 00:00:00 2001 From: dimxy Date: Thu, 25 Apr 2019 13:15:22 +0500 Subject: [PATCH 121/242] costbasis calc now only for smoothed val added costbasis calc for added bets removed test windows 7 --- src/cc/prices.cpp | 215 +++++++++++++++++++++++++++------------------- src/komodo_defs.h | 8 +- 2 files changed, 132 insertions(+), 91 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 7228ee9a8..bf6eb46c7 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -132,9 +132,12 @@ uint8_t prices_finalopretdecode(CScript scriptPubKey,uint256 &bettxid,int64_t &p } // price opret basic validation and retrieval -static bool CheckPricesOpret(const CTransaction & tx, vscript_t &opret) +static uint8_t CheckPricesOpret(const CTransaction & tx, vscript_t &opret) { - return 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], "BACF")) + return opret.begin()[1]; + else + return (uint8_t)0; } // validate bet tx helper @@ -164,8 +167,10 @@ static bool ValidateBetTx(struct CCcontract_info *cp, Eval *eval, const CTransac return eval->Invalid("cannot validate vout2 in bet tx with pk from opreturn"); int64_t betamount = bettx.vout[2].nValue; - if( betamount != (positionsize * 199) / 200 ) + if (betamount != (positionsize * 199) / 200) { return eval->Invalid("invalid position size in the opreturn"); + std::cerr << "ValidateBetTx() " << "invalid position size in the opreturn" << std::endl; + } // validate if normal inputs are really signed by originator pubkey (someone not cheating with originator pubkey) CAmount ccOutputs = 0; @@ -173,11 +178,15 @@ static bool ValidateBetTx(struct CCcontract_info *cp, Eval *eval, const CTransac if (vout.scriptPubKey.IsPayToCryptoCondition()) ccOutputs += vout.nValue; CAmount normalInputs = TotalPubkeyNormalInputs(bettx, pk); - if (normalInputs < ccOutputs) - return eval->Invalid("bettx normal input signed with not pubkey in opret"); + if (normalInputs < ccOutputs) { + // return eval->Invalid("bettx normal inputs not signed with pubkey in opret"); + std::cerr << "ValidateBetTx() " << "warning: bettx normal inputs signed with pubkey in opreturn =" << normalInputs << std::endl; + } - if (leverage > PRICES_MAXLEVERAGE || leverage < -PRICES_MAXLEVERAGE) - return eval->Invalid("invalid leverage"); + if (leverage > PRICES_MAXLEVERAGE || leverage < -PRICES_MAXLEVERAGE) { + // return eval->Invalid("invalid leverage"); + std::cerr << "ValidateBetTx() " << "invalid leverage" << std::endl; + } return true; } @@ -199,8 +208,11 @@ static bool ValidateAddFundingTx(struct CCcontract_info *cp, Eval *eval, const C pricespk = GetUnspendable(cp, 0); - if (CheckPricesOpret(vintx, vintxOpret) && vintxOpret.begin()[1] == 'B' && vintx.GetHash() != bettxid) // if vintx is bettx - return eval->Invalid("incorrect bettx id"); + if (CheckPricesOpret(vintx, vintxOpret) != 'B') // if vintx is bettx + return eval->Invalid("incorrect bettx"); + + if (vintx.GetHash() != bettxid) // if vintx is bettx + return eval->Invalid("incorrect bet txid in opreturn"); if (MakeCC1vout(cp->evalcode, addfundingtx.vout[0].nValue, pk) != addfundingtx.vout[0]) return eval->Invalid("cannot validate vout0 in add funding tx with pk from opreturn"); @@ -239,8 +251,10 @@ static bool ValidateCostbasisTx(struct CCcontract_info *cp, Eval *eval, const CT return eval->Invalid("incorrect bettx no vouts"); // check costbasis rules: - if (costbasistx.vout[0].nValue > bettx.vout[1].nValue / 10) - return eval->Invalid("costbasis myfee too big"); + if (costbasistx.vout[0].nValue > bettx.vout[1].nValue / 10) { + // return eval->Invalid("costbasis myfee too big"); + std::cerr << "ValidateBetTx() " << "costbasis myfee too big" << std::endl; + } uint256 tokenid; int64_t positionsize, firstprice; @@ -251,16 +265,20 @@ static bool ValidateCostbasisTx(struct CCcontract_info *cp, Eval *eval, const CT if (prices_betopretdecode(bettx.vout.back().scriptPubKey, betpk, firstheight, positionsize, leverage, firstprice, vec, tokenid) != 'B') return eval->Invalid("cannot decode opreturn for bet tx"); - if( firstheight + PRICES_DAYWINDOW + PRICES_SMOOTHWIDTH > chainActive.Height() ) - return eval->Invalid("cannot calculate costbasis yet"); + if (firstheight + PRICES_DAYWINDOW + PRICES_SMOOTHWIDTH > chainActive.Height()) { + // return eval->Invalid("cannot calculate costbasis yet"); + std::cerr << "ValidateBetTx() " << "cannot calculate costbasis yet" << std::endl; + } int64_t costbasis = 0, profits, lastprice; int32_t retcode = prices_syntheticprofits(costbasis, firstheight, firstheight + PRICES_DAYWINDOW, leverage, vec, positionsize, 0, profits, lastprice); if (retcode < 0) return eval->Invalid("cannot calculate costbasis yet"); std::cerr << "ValidateCostbasisTx() costbasis=" << costbasis << " costbasisInOpret=" << costbasisInOpret << std::endl; - if( 0 && costbasis != costbasisInOpret ) - return eval->Invalid("incorrect costbasis value"); + if (costbasis != costbasisInOpret) { + // return eval->Invalid("incorrect costbasis value"); + std::cerr << "ValidateBetTx() " << "incorrect costbasis value" << std::endl; + } return true; } @@ -320,7 +338,7 @@ bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx if (strcmp(ASSETCHAINS_SYMBOL, "REKT0") == 0 && chainActive.Height() < 2965) return true; // check basic opret rules: - if (!CheckPricesOpret(tx, vopret)) + if (CheckPricesOpret(tx, vopret) == 0) return eval->Invalid("tx has no prices opreturn"); uint8_t funcId = vopret.begin()[1]; @@ -334,7 +352,7 @@ bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx // check basic rules: // find first cc vin and load vintx (might be either bet or add funding tx): - for (auto vin : tx.vin) + for (auto vin : tx.vin) { if (cp->ismyvin(vin.scriptSig)) { CTransaction vintx; uint256 hashBlock; @@ -343,12 +361,12 @@ bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx if (!myGetTransaction(vin.prevout.hash, vintx, hashBlock)) return eval->Invalid("cannot load vintx"); - if (!CheckPricesOpret(vintx, vintxOpret)) + if (CheckPricesOpret(vintx, vintxOpret) == 0) return eval->Invalid("cannot find prices opret in vintx"); - if (vintxOpret.begin()[1] == 'B' && prevoutN == 3) { - return eval->Invalid("cannot spend bet marker"); - } + //if (vintxOpret.begin()[1] == 'B' && prevoutN == 3) { + // return eval->Invalid("cannot spend bet marker"); + //} if (!foundFirst) { prevoutN = vin.prevout.n; @@ -358,6 +376,7 @@ bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx } ccVinCount++; } + } if (!foundFirst) return eval->Invalid("prices cc vin not found"); @@ -550,7 +569,7 @@ int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t { std::cerr << "prices_syntheticprice" << " pricedata[0]=" << pricedata[0] << " pricedata[1]=" << pricedata[1] << " pricedata[2]=" << pricedata[2] << std::endl; // push price to the prices stack - if (!minmax) + /*if (!minmax) pricestack[depth] = pricedata[2]; // use smoothed value if we are over 24h else { @@ -559,8 +578,12 @@ int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t pricestack[depth] = (pricedata[1] > pricedata[2]) ? pricedata[1] : pricedata[2]; // MAX else pricestack[depth] = (pricedata[1] < pricedata[2]) ? pricedata[1] : pricedata[2]; // MIN - } + }*/ + pricestack[depth] = pricedata[2]; } + else + errcode = -1; + if (pricestack[depth] == 0) errcode = -1; @@ -682,7 +705,7 @@ int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t } // calculates profit/loss for the bet -int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t height, int16_t leverage, std::vector vec, int64_t positionsize, int64_t addedbets, int64_t &profits, int64_t &outprice) +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) { int64_t price; @@ -794,30 +817,33 @@ int64_t prices_costbasis(CTransaction bettx, uint256 &txidCostbasis) } // calculates added bet total, returns the last baton txid -int64_t prices_batontxid(uint256 &batontxid, CTransaction bettx, uint256 bettxid) +int64_t prices_enumaddedbets(uint256 &batontxid, std::vector> &addedBets, uint256 bettxid) { - int64_t addedbets = 0; + int64_t addedBetsTotal = 0; int32_t vini; int32_t height; int32_t retcode; batontxid = bettxid; // initially set to the source bet tx uint256 sourcetxid = bettxid; + addedBets.clear(); // iterate through batons, adding up vout1 -> addedbets while ((retcode = CCgetspenttxid(batontxid, vini, height, sourcetxid, 0)) == 0) { CTransaction txBaton; - uint256 hashBlock; - uint256 bettxid; + CBlockIndex blockIdx; + uint256 bettxidInOpret; CPubKey pk; bool isLoaded = false; uint8_t funcId = 0; int64_t amount; + EvalRef eval; - if ((isLoaded = myGetTransaction(batontxid, txBaton, hashBlock)) && + if ((isLoaded = eval->GetTxConfirmed(batontxid, txBaton, blockIdx)) && txBaton.vout.size() > 0 && - (funcId = prices_addopretdecode(txBaton.vout.back().scriptPubKey, bettxid, pk, amount)) != 0) { - addedbets += amount; + (funcId = prices_addopretdecode(txBaton.vout.back().scriptPubKey, bettxidInOpret, pk, amount)) != 0) { + addedBetsTotal += amount; + addedBets.push_back(std::make_pair(blockIdx.GetHeight(), amount)); std::cerr << "prices_batontxid() added amount=" << amount << std::endl; } else { @@ -827,7 +853,7 @@ int64_t prices_batontxid(uint256 &batontxid, CTransaction bettx, uint256 bettxid sourcetxid = batontxid; } - return(addedbets); + return(addedBetsTotal); } UniValue PricesBet(int64_t txfee, int64_t amount, int16_t leverage, std::vector synthetic) @@ -894,7 +920,8 @@ UniValue PricesAddFunding(int64_t txfee, uint256 bettxid, int64_t amount) //GetCCaddress(cp, myaddr, mypk); if (AddNormalinputs(mtx, mypk, amount + 2*txfee, 64) >= amount + 2*txfee) { - if (prices_batontxid(batontxid, bettx, bettxid) >= 0) + std::vector> addedBets; + if (prices_enumaddedbets(batontxid, addedBets, bettxid) >= 0) { mtx.vin.push_back(CTxIn(batontxid, 0, CScript())); mtx.vout.push_back(MakeCC1vout(cp->evalcode, txfee, mypk)); // baton for total funding @@ -915,6 +942,7 @@ UniValue PricesAddFunding(int64_t txfee, uint256 bettxid, int64_t amount) } // set cost basis (open price) for the bet + UniValue PricesSetcostbasis(int64_t txfee, uint256 bettxid) { int32_t nextheight = komodo_nextheight(); @@ -925,7 +953,7 @@ UniValue PricesSetcostbasis(int64_t txfee, uint256 bettxid) int32_t i, firstheight = 0, height, numvouts; int16_t leverage = 0; std::vector vec; CPubKey pk, mypk, pricespk; std::string rawtx; - +/* cp = CCinit(&C, EVAL_PRICES); if (txfee == 0) txfee = PRICES_TXFEE; @@ -942,7 +970,7 @@ UniValue PricesSetcostbasis(int64_t txfee, uint256 bettxid) return(result); } - addedbets = prices_batontxid(batontxid, bettx, bettxid); + addedbets = prices_enumaddedbets(batontxid, bettx, bettxid); mtx.vin.push_back(CTxIn(bettxid, 1, CScript())); // spend vin1 with betamount //for (i = 0; i < PRICES_DAYWINDOW + 1; i++) // the last datum for 24h is the actual costbasis value //{ @@ -953,12 +981,12 @@ UniValue PricesSetcostbasis(int64_t txfee, uint256 bettxid) return(result); } equity = positionsize + addedbets + profits; - /*if (equity < 0) - { // we are in loss - result.push_back(Pair("rekt", (int64_t)1)); - result.push_back(Pair("rektheight", (int64_t)firstheight + i)); - break; - }*/ + //if (equity < 0) + //{ // we are in loss + // result.push_back(Pair("rekt", (int64_t)1)); + // result.push_back(Pair("rektheight", (int64_t)firstheight + i)); + // break; + //} //} //if (i == PRICES_DAYWINDOW + 1) // result.push_back(Pair("rekt", 0)); @@ -972,7 +1000,7 @@ UniValue PricesSetcostbasis(int64_t txfee, uint256 bettxid) mtx.vout.push_back(CTxOut(myfee, CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); mtx.vout.push_back(MakeCC1vout(cp->evalcode, bettx.vout[1].nValue - myfee, pricespk)); - rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_costbasisopret(bettxid, mypk, firstheight + PRICES_DAYWINDOW /*- 1*/, costbasis)); + rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_costbasisopret(bettxid, mypk, firstheight + PRICES_DAYWINDOW , costbasis)); // -1 return(prices_rawtxresult(result, rawtx, 0)); } result.push_back(Pair("result", "error")); @@ -981,7 +1009,7 @@ UniValue PricesSetcostbasis(int64_t txfee, uint256 bettxid) } } result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "cant find bettxid")); + result.push_back(Pair("error", "cant find bettxid")); */ return(result); } @@ -1009,6 +1037,8 @@ UniValue PricesRekt(int64_t txfee, uint256 bettxid, int32_t rektheight) if (prices_betopretdecode(bettx.vout[numvouts - 1].scriptPubKey, pk, firstheight, positionsize, leverage, firstprice, vec, tokenid) == 'B') { uint256 costbasistxid; + std::vector> addedBets; + costbasis = prices_costbasis(bettx, costbasistxid); if (costbasis == 0) { result.push_back(Pair("result", "error")); @@ -1016,7 +1046,7 @@ UniValue PricesRekt(int64_t txfee, uint256 bettxid, int32_t rektheight) return(result); } - addedbets = prices_batontxid(batontxid, bettx, bettxid); + addedbets = prices_enumaddedbets(batontxid, addedBets, bettxid); int32_t retcode = prices_syntheticprofits(costbasis, firstheight, rektheight, leverage, vec, positionsize, addedbets, profits, lastprice); if (retcode < 0) { result.push_back(Pair("result", "error")); @@ -1083,6 +1113,7 @@ UniValue PricesCashout(int64_t txfee, uint256 bettxid) if (prices_betopretdecode(bettx.vout[numvouts - 1].scriptPubKey, pk, firstheight, positionsize, leverage, firstprice, vec, tokenid) == 'B') { uint256 costbasistxid; + std::vector> addedBets; costbasis = prices_costbasis(bettx, costbasistxid); if (costbasis == 0) { @@ -1091,7 +1122,7 @@ UniValue PricesCashout(int64_t txfee, uint256 bettxid) return(result); } - addedbets = prices_batontxid(batontxid, bettx, bettxid); + addedbets = prices_enumaddedbets(batontxid, addedBets, bettxid); int32_t retcode = prices_syntheticprofits(costbasis, firstheight, nextheight - 1, leverage, vec, positionsize, addedbets, profits, lastprice); if (retcode < 0) { result.push_back(Pair("result", "error")); @@ -1126,12 +1157,24 @@ UniValue PricesCashout(int64_t txfee, uint256 bettxid) return(result); } +int32_t prices_scanchain(const CTransaction &tx, int64_t &costbasis, int64_t lastprice) { + + vscript_t opret; + uint8_t funcId; + if (tx.vout.size() < 1 || (funcId = CheckPricesOpret(tx, opret)) == 0) { + std::cerr << "prices_scanchain() " << "incorrect tx, must be \'B\' or \'A\'" << std::endl; + return -1; + } + return 0; +} + + UniValue PricesInfo(uint256 bettxid, int32_t refheight) { UniValue result(UniValue::VOBJ); CTransaction bettx; uint256 hashBlock, batontxid, tokenid; - int64_t myfee, ignore = 0, positionsize = 0, addedbets = 0, firstprice = 0, lastprice, profits = 0, costbasis = 0, equity; + int64_t myfee, ignore = 0, positionsize = 0, addedbets = 0, firstprice = 0, lastprice = 0, costbasis = 0, equity; int32_t i, firstheight = 0, height, numvouts; int16_t leverage = 0; std::vector vec; @@ -1155,59 +1198,57 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) if (refheight == 0) refheight = komodo_nextheight()-1; - costbasis = prices_costbasis(bettx, costbasistxid); - addedbets = prices_batontxid(batontxid, bettx, bettxid); + //costbasis = prices_costbasis(bettx, costbasistxid); + std::vector> addedbets; + prices_enumaddedbets(batontxid, addedbets, bettxid); - if (costbasis != 0) { // costbasis fixed - int32_t retcode = prices_syntheticprofits(costbasis, firstheight, refheight, leverage, vec, positionsize, addedbets, profits, lastprice); + + bool isRekt = false; + int64_t totalprofits = 0, totaladdedbets = 0; + + for (int32_t h = firstheight; ; h++) // the last datum for 24h is the costbasis value + { + int64_t profits, lastprice; + int32_t retcode = prices_syntheticprofits(costbasis, firstheight, h, leverage, vec, positionsize, profits, lastprice); if (retcode < 0) { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "cannot get price")); - return(result); + std::cerr << "PricesInfo() prices_syntheticprofits returned -1, stopping" << std::endl; + break; } - equity = positionsize + addedbets + profits; - if (equity < 0) - { - result.push_back(Pair("rekt", 1)); - result.push_back(Pair("rektfee", (positionsize + addedbets) / 500)); - result.push_back(Pair("rektheight", (int64_t)refheight)); - } - else - result.push_back(Pair("rekt", 0)); - } - else { - bool isRekt = false; - for (i = 0; i < PRICES_DAYWINDOW + 1 && firstheight + i <= refheight; i++) // the last datum for 24h is the costbasis value - { - int32_t retcode = prices_syntheticprofits(costbasis, firstheight, firstheight + i, leverage, vec, positionsize, addedbets, profits, lastprice); + totalprofits = profits; + + for (int i = 0; i < addedbets.size(); i++) { + // get profits for added bets: + int64_t costbasis = 0; // costbasis for added bet + int32_t retcode = prices_syntheticprofits(costbasis, addedbets[i].first, h, leverage, vec, addedbets[i].second, profits, lastprice); if (retcode < 0) { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "cannot get price")); - return(result); - } - equity = positionsize + addedbets + profits; - if (equity < 0) - { // we are in loss - result.push_back(Pair("rekt", (int64_t)1)); - result.push_back(Pair("rektfee", (positionsize + addedbets) / 500)); - result.push_back(Pair("rektheight", (int64_t)firstheight + i)); - isRekt = true; + std::cerr << "PricesInfo() error: prices_syntheticprofits returned -1 for addedbet" << std::endl; break; } + totalprofits += profits; + totaladdedbets += addedbets[i].second; + } + + equity = positionsize + totaladdedbets + totalprofits; + if (equity < 0) + { // we are in loss + result.push_back(Pair("rekt", (int64_t)1)); + result.push_back(Pair("rektfee", (positionsize + totaladdedbets) / 500)); + result.push_back(Pair("rektheight", (int64_t)h)); + isRekt = true; + break; } - if (!isRekt /*i == PRICES_DAYWINDOW + 1*/) - result.push_back(Pair("rekt", 0)); } - - + if (!isRekt) + result.push_back(Pair("rekt", 0)); + result.push_back(Pair("batontxid", batontxid.GetHex())); if(!costbasistxid.IsNull()) result.push_back(Pair("costbasistxid", costbasistxid.GetHex())); - prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice, lastprice, equity); + prices_betjson(result, totalprofits, costbasis, positionsize, totaladdedbets, leverage, firstheight, firstprice, lastprice, equity); result.push_back(Pair("height", (int64_t)refheight)); -#ifdef TESTMODE - result.push_back(Pair("test_daywindow", PRICES_DAYWINDOW)); -#endif +//#ifdef TESTMODE +// result.push_back(Pair("test_daywindow", PRICES_DAYWINDOW)); +//#endif return(result); } } diff --git a/src/komodo_defs.h b/src/komodo_defs.h index 02e51cd2f..bcfc4ff4b 100644 --- a/src/komodo_defs.h +++ b/src/komodo_defs.h @@ -39,11 +39,11 @@ #define KOMODO_BIT63SET(x) ((x) & ((uint64_t)1 << 63)) #define KOMODO_VALUETOOBIG(x) ((x) > (uint64_t)10000000001*COIN) -#ifndef TESTMODE +//#ifndef TESTMODE #define PRICES_DAYWINDOW ((3600*24/ASSETCHAINS_BLOCKTIME) + 1) -#else -#define PRICES_DAYWINDOW (7) -#endif +//#else +//#define PRICES_DAYWINDOW (7) +//#endif extern uint8_t ASSETCHAINS_TXPOW,ASSETCHAINS_PUBLIC; int32_t MAX_BLOCK_SIZE(int32_t height); From f290e2e2b3b89f3519f7f2bacb0fcd8666976e73 Mon Sep 17 00:00:00 2001 From: dimxy Date: Thu, 25 Apr 2019 13:23:42 +0500 Subject: [PATCH 122/242] corr link err (corr func def) --- src/cc/prices.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index bf6eb46c7..23e0f50ad 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -44,7 +44,7 @@ CBOPRET creates trustless oracles, which can be used for making a synthetic cash */ -int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t height, int16_t leverage, std::vector vec, int64_t positionsize, int64_t addedbets, int64_t &profits, int64_t &outprice); +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); // helpers: @@ -271,7 +271,7 @@ static bool ValidateCostbasisTx(struct CCcontract_info *cp, Eval *eval, const CT } int64_t costbasis = 0, profits, lastprice; - int32_t retcode = prices_syntheticprofits(costbasis, firstheight, firstheight + PRICES_DAYWINDOW, leverage, vec, positionsize, 0, profits, lastprice); + int32_t retcode = prices_syntheticprofits(costbasis, firstheight, firstheight + PRICES_DAYWINDOW, leverage, vec, positionsize, profits, lastprice); if (retcode < 0) return eval->Invalid("cannot calculate costbasis yet"); std::cerr << "ValidateCostbasisTx() costbasis=" << costbasis << " costbasisInOpret=" << costbasisInOpret << std::endl; @@ -1047,7 +1047,7 @@ UniValue PricesRekt(int64_t txfee, uint256 bettxid, int32_t rektheight) } addedbets = prices_enumaddedbets(batontxid, addedBets, bettxid); - int32_t retcode = prices_syntheticprofits(costbasis, firstheight, rektheight, leverage, vec, positionsize, addedbets, profits, lastprice); + int32_t retcode = prices_syntheticprofits(costbasis, firstheight, rektheight, leverage, vec, positionsize, profits, lastprice); if (retcode < 0) { result.push_back(Pair("result", "error")); result.push_back(Pair("error", "cannot get price")); @@ -1123,7 +1123,7 @@ UniValue PricesCashout(int64_t txfee, uint256 bettxid) } addedbets = prices_enumaddedbets(batontxid, addedBets, bettxid); - int32_t retcode = prices_syntheticprofits(costbasis, firstheight, nextheight - 1, leverage, vec, positionsize, addedbets, profits, lastprice); + int32_t retcode = prices_syntheticprofits(costbasis, firstheight, nextheight - 1, leverage, vec, positionsize, profits, lastprice); if (retcode < 0) { result.push_back(Pair("result", "error")); result.push_back(Pair("error", "cannot get price")); From 1c4c7f677ac2be4c01a6d1abf1897ab680f84ea0 Mon Sep 17 00:00:00 2001 From: dimxy Date: Thu, 25 Apr 2019 15:21:22 +0500 Subject: [PATCH 123/242] added prices_scanchain func added all bets params to json --- src/cc/prices.cpp | 219 ++++++++++++++++++++++++++++------------------ 1 file changed, 136 insertions(+), 83 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 23e0f50ad..b0147cdd8 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -18,6 +18,13 @@ #define IS_CHARINSTR(c, str) (std::string(str).find((char)(c)) != std::string::npos) +typedef struct BetInfo { + int64_t amount; + int32_t firstheight; + int64_t costbasis; + int64_t profits; +} betinfo; + /* CBOPRET creates trustless oracles, which can be used for making a synthetic cash settlement system based on real world prices; @@ -770,17 +777,30 @@ int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t return 0; // (positionsize + addedbets + profits); } -void prices_betjson(UniValue &result,int64_t profits,int64_t costbasis,int64_t positionsize,int64_t addedbets,int16_t leverage,int32_t firstheight,int64_t firstprice, int64_t lastprice, int64_t equity) +void prices_betjson(UniValue &result, std::vector bets, int16_t leverage, int32_t endheight, int64_t lastprice) { - result.push_back(Pair("profits",ValueFromAmount(profits))); - result.push_back(Pair("costbasis",ValueFromAmount(costbasis))); - result.push_back(Pair("positionsize",ValueFromAmount(positionsize))); - result.push_back(Pair("equity", ValueFromAmount(equity))); - result.push_back(Pair("addedbets",ValueFromAmount(addedbets))); - result.push_back(Pair("leverage",(int64_t)leverage)); - result.push_back(Pair("firstheight",(int64_t)firstheight)); - result.push_back(Pair("firstprice",ValueFromAmount(firstprice))); - result.push_back(Pair("lastprice", ValueFromAmount(lastprice))); + + UniValue resultbets(UniValue::VARR); + int64_t totalbets = 0; + int64_t totalprofits = 0; + + for (auto b : bets) { + resultbets.push_back(Pair("positionsize", ValueFromAmount(b.amount))); + resultbets.push_back(Pair("profits", ValueFromAmount(b.profits))); + resultbets.push_back(Pair("costbasis", ValueFromAmount(b.costbasis))); + resultbets.push_back(Pair("firstheight", b.firstheight)); + totalbets += b.amount; + totalprofits += b.profits; + } + int64_t equity = totalbets + totalprofits; + + result.push_back(resultbets); + result.push_back(Pair("leverage", (int64_t)leverage)); + result.push_back(Pair("TotalPositionSize", totalbets)); + result.push_back(Pair("TotalProfits", totalprofits)); + result.push_back(Pair("equity", equity)); + result.push_back(Pair("LastPrice", ValueFromAmount(lastprice))); + result.push_back(Pair("LastHeight", endheight)); } // retrives costbasis from a tx spending bettx vout1 @@ -817,7 +837,7 @@ int64_t prices_costbasis(CTransaction bettx, uint256 &txidCostbasis) } // calculates added bet total, returns the last baton txid -int64_t prices_enumaddedbets(uint256 &batontxid, std::vector> &addedBets, uint256 bettxid) +int64_t prices_enumaddedbets(uint256 &batontxid, std::vector &bets, uint256 bettxid) { int64_t addedBetsTotal = 0; int32_t vini; @@ -826,7 +846,7 @@ int64_t prices_enumaddedbets(uint256 &batontxid, std::vector addedbets while ((retcode = CCgetspenttxid(batontxid, vini, height, sourcetxid, 0)) == 0) { @@ -842,8 +862,12 @@ int64_t prices_enumaddedbets(uint256 &batontxid, std::vectorGetTxConfirmed(batontxid, txBaton, blockIdx)) && txBaton.vout.size() > 0 && (funcId = prices_addopretdecode(txBaton.vout.back().scriptPubKey, bettxidInOpret, pk, amount)) != 0) { + BetInfo added; + addedBetsTotal += amount; - addedBets.push_back(std::make_pair(blockIdx.GetHeight(), amount)); + added.amount = amount; + added.firstheight = blockIdx.GetHeight(); + bets.push_back(added); std::cerr << "prices_batontxid() added amount=" << amount << std::endl; } else { @@ -920,8 +944,8 @@ UniValue PricesAddFunding(int64_t txfee, uint256 bettxid, int64_t amount) //GetCCaddress(cp, myaddr, mypk); if (AddNormalinputs(mtx, mypk, amount + 2*txfee, 64) >= amount + 2*txfee) { - std::vector> addedBets; - if (prices_enumaddedbets(batontxid, addedBets, bettxid) >= 0) + 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)); // baton for total funding @@ -1036,15 +1060,15 @@ UniValue PricesRekt(int64_t txfee, uint256 bettxid, int32_t rektheight) { if (prices_betopretdecode(bettx.vout[numvouts - 1].scriptPubKey, pk, firstheight, positionsize, leverage, firstprice, vec, tokenid) == 'B') { - uint256 costbasistxid; - std::vector> addedBets; + //uint256 costbasistxid; + std::vector addedBets; - costbasis = prices_costbasis(bettx, costbasistxid); + /*costbasis = prices_costbasis(bettx, costbasistxid); if (costbasis == 0) { result.push_back(Pair("result", "error")); result.push_back(Pair("error", "costbasis not defined yet")); return(result); - } + }*/ addedbets = prices_enumaddedbets(batontxid, addedBets, bettxid); int32_t retcode = prices_syntheticprofits(costbasis, firstheight, rektheight, leverage, vec, positionsize, profits, lastprice); @@ -1059,7 +1083,7 @@ UniValue PricesRekt(int64_t txfee, uint256 bettxid, int32_t rektheight) { myfee = (positionsize + addedbets) / 500; } - prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice, lastprice, equity); + //prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice, lastprice, equity); if (myfee != 0) { mtx.vin.push_back(CTxIn(bettxid, 2, CScript())); @@ -1112,15 +1136,16 @@ UniValue PricesCashout(int64_t txfee, uint256 bettxid) { if (prices_betopretdecode(bettx.vout[numvouts - 1].scriptPubKey, pk, firstheight, positionsize, leverage, firstprice, vec, tokenid) == 'B') { - uint256 costbasistxid; - std::vector> addedBets; + //uint256 costbasistxid; + std::vector addedBets; + /* costbasis = prices_costbasis(bettx, costbasistxid); if (costbasis == 0) { result.push_back(Pair("result", "error")); result.push_back(Pair("error", "costbasis not defined yet")); return(result); - } + }*/ addedbets = prices_enumaddedbets(batontxid, addedBets, bettxid); int32_t retcode = prices_syntheticprofits(costbasis, firstheight, nextheight - 1, leverage, vec, positionsize, profits, lastprice); @@ -1132,12 +1157,12 @@ UniValue PricesCashout(int64_t txfee, uint256 bettxid) equity = positionsize + addedbets + profits; if (equity < 0) { - prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice, lastprice, equity); + //prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice, lastprice, equity); result.push_back(Pair("result", "error")); result.push_back(Pair("error", "position rekt")); return(result); } - prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice, lastprice, equity); + //prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice, lastprice, equity); mtx.vin.push_back(CTxIn(bettxid, 2, CScript())); if ((inputsum = AddPricesInputs(cp, mtx, destaddr, profits + txfee, 64, bettxid, 2)) > profits + txfee) CCchange = (inputsum - profits); @@ -1157,14 +1182,62 @@ UniValue PricesCashout(int64_t txfee, uint256 bettxid) return(result); } -int32_t prices_scanchain(const CTransaction &tx, int64_t &costbasis, int64_t lastprice) { +int32_t prices_scanchain(std::vector &bets, int16_t leverage, std::vector vec, int64_t &lastprice, int32_t &endheight) { vscript_t opret; uint8_t funcId; - if (tx.vout.size() < 1 || (funcId = CheckPricesOpret(tx, opret)) == 0) { + + + /* if (bettx.vout.size() < 1 || (funcId = CheckPricesOpret(bettx, opret)) == 0) { std::cerr << "prices_scanchain() " << "incorrect tx, must be \'B\' or \'A\'" << std::endl; return -1; + }*/ + + + // check acceptable refheight: +/* if (refheight < 0 || refheight > 0 && refheight < firstheight) { + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "incorrect height")); + return(result); } + if (refheight == 0) + refheight = komodo_nextheight() - 1;*/ + + //costbasis = prices_costbasis(bettx, costbasistxid) + + + + if (bets.size() == 0) + return -1; + + for (int32_t h = bets[0].firstheight; ; h++) // the last datum for 24h is the costbasis value + { + int64_t total = 0; + int64_t totalprofits = 0; + + for (int i = 0; i < bets.size(); i++) { + int64_t costbasis, profits; + + int32_t retcode = prices_syntheticprofits(costbasis, bets[i].firstheight, h, leverage, vec, bets[i].amount, profits, lastprice); + if (retcode < 0) { + std::cerr << "PricesInfo() error: prices_syntheticprofits returned -1 for addedbet" << std::endl; + break; + } + total += bets[i].amount; + totalprofits += profits; + + bets[i].costbasis = costbasis; + bets[i].profits = profits; + endheight = h; + } + + int64_t equity = total + totalprofits; + if (equity < 0) + { // we are in loss + break; + } + } + return 0; } @@ -1174,78 +1247,58 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) UniValue result(UniValue::VOBJ); CTransaction bettx; uint256 hashBlock, batontxid, tokenid; - int64_t myfee, ignore = 0, positionsize = 0, addedbets = 0, firstprice = 0, lastprice = 0, costbasis = 0, equity; - int32_t i, firstheight = 0, height, numvouts; + int64_t myfee; + int64_t positionsize = 0, firstprice = 0, lastprice = 0, costbasis = 0, equity; + int32_t i, firstheight = 0, endheight; int16_t leverage = 0; std::vector vec; CPubKey pk, mypk, pricespk; std::string rawtx; - uint256 costbasistxid; + //uint256 costbasistxid; - if (myGetTransaction(bettxid, bettx, hashBlock) != 0 && (numvouts = bettx.vout.size()) > 3) + if (myGetTransaction(bettxid, bettx, hashBlock) && bettx.vout.size() > 3) { if (hashBlock.IsNull()) throw std::runtime_error("tx still in mempool"); - if (prices_betopretdecode(bettx.vout[numvouts - 1].scriptPubKey, pk, firstheight, positionsize, leverage, firstprice, vec, tokenid) == 'B') + if (prices_betopretdecode(bettx.vout.back().scriptPubKey, pk, firstheight, positionsize, leverage, firstprice, vec, tokenid) == 'B') { - // check acceptable refheight: - if (refheight < 0 || refheight > 0 && refheight < firstheight) { + bool isRekt; + std::vector bets; + BetInfo bet1; + bet1.amount = positionsize; + bet1.firstheight = firstheight; + bets.push_back(bet1); + + prices_enumaddedbets(batontxid, bets, bettxid); + + if( prices_scanchain(bets, leverage, vec, lastprice, endheight) < 0 ) { result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "incorrect height")); + result.push_back(Pair("error", "error scanning chain")); return(result); } - if (refheight == 0) - refheight = komodo_nextheight()-1; - - //costbasis = prices_costbasis(bettx, costbasistxid); - std::vector> addedbets; - prices_enumaddedbets(batontxid, addedbets, bettxid); - - - bool isRekt = false; - int64_t totalprofits = 0, totaladdedbets = 0; - - for (int32_t h = firstheight; ; h++) // the last datum for 24h is the costbasis value - { - int64_t profits, lastprice; - int32_t retcode = prices_syntheticprofits(costbasis, firstheight, h, leverage, vec, positionsize, profits, lastprice); - if (retcode < 0) { - std::cerr << "PricesInfo() prices_syntheticprofits returned -1, stopping" << std::endl; - break; - } - totalprofits = profits; - - for (int i = 0; i < addedbets.size(); i++) { - // get profits for added bets: - int64_t costbasis = 0; // costbasis for added bet - int32_t retcode = prices_syntheticprofits(costbasis, addedbets[i].first, h, leverage, vec, addedbets[i].second, profits, lastprice); - if (retcode < 0) { - std::cerr << "PricesInfo() error: prices_syntheticprofits returned -1 for addedbet" << std::endl; - break; - } - totalprofits += profits; - totaladdedbets += addedbets[i].second; - } - - equity = positionsize + totaladdedbets + totalprofits; - if (equity < 0) - { // we are in loss - result.push_back(Pair("rekt", (int64_t)1)); - result.push_back(Pair("rektfee", (positionsize + totaladdedbets) / 500)); - result.push_back(Pair("rektheight", (int64_t)h)); - isRekt = true; - break; - } + + int64_t totalbet = 0; + int64_t totalprofits = 0; + for (auto b : bets) { + totalbet += b.amount; + totalprofits += b.profits; } - if (!isRekt) + int64_t equity = totalbet + totalprofits; + + if (!equity < 0) result.push_back(Pair("rekt", 0)); + else + { + result.push_back(Pair("rekt", (int64_t)1)); + result.push_back(Pair("rektfee", totalbet / 500)); + result.push_back(Pair("rektheight", (int64_t)endheight)); + } result.push_back(Pair("batontxid", batontxid.GetHex())); - if(!costbasistxid.IsNull()) - result.push_back(Pair("costbasistxid", costbasistxid.GetHex())); - prices_betjson(result, totalprofits, costbasis, positionsize, totaladdedbets, leverage, firstheight, firstprice, lastprice, equity); - result.push_back(Pair("height", (int64_t)refheight)); + + prices_betjson(result, bets, leverage, endheight, lastprice); + //result.push_back(Pair("height", (int64_t)endheight)); //#ifdef TESTMODE // result.push_back(Pair("test_daywindow", PRICES_DAYWINDOW)); //#endif @@ -1253,7 +1306,7 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) } } result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "cant find bettxid")); + result.push_back(Pair("error", "cant find bettxid or incorrect")); return(result); } From 879a9fbaf85dfc0e72e8137a7701f62b4b45cefb Mon Sep 17 00:00:00 2001 From: dimxy Date: Thu, 25 Apr 2019 15:34:55 +0500 Subject: [PATCH 124/242] corr break from loop --- src/cc/prices.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index b0147cdd8..7b68292f0 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1210,6 +1210,7 @@ int32_t prices_scanchain(std::vector &bets, int16_t leverage, std::vect if (bets.size() == 0) return -1; + bool stop = false; for (int32_t h = bets[0].firstheight; ; h++) // the last datum for 24h is the costbasis value { int64_t total = 0; @@ -1220,7 +1221,8 @@ int32_t prices_scanchain(std::vector &bets, int16_t leverage, std::vect int32_t retcode = prices_syntheticprofits(costbasis, bets[i].firstheight, h, leverage, vec, bets[i].amount, profits, lastprice); if (retcode < 0) { - std::cerr << "PricesInfo() error: prices_syntheticprofits returned -1 for addedbet" << std::endl; + std::cerr << "prices_scanchain() error: prices_syntheticprofits returned -1 for addedbet" << std::endl; + stop = true; break; } total += bets[i].amount; @@ -1228,9 +1230,12 @@ int32_t prices_scanchain(std::vector &bets, int16_t leverage, std::vect bets[i].costbasis = costbasis; bets[i].profits = profits; - endheight = h; } + if (stop) + break; + + endheight = h; int64_t equity = total + totalprofits; if (equity < 0) { // we are in loss From 91704c0b0addf2400e93657c7dc86ab51cdb3b41 Mon Sep 17 00:00:00 2001 From: dimxy Date: Thu, 25 Apr 2019 15:40:55 +0500 Subject: [PATCH 125/242] result to varr --- src/cc/prices.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 7b68292f0..9c3a34d95 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -794,6 +794,7 @@ void prices_betjson(UniValue &result, std::vector bets, int16_t leverag } int64_t equity = totalbets + totalprofits; + result.setArray(); result.push_back(resultbets); result.push_back(Pair("leverage", (int64_t)leverage)); result.push_back(Pair("TotalPositionSize", totalbets)); From 6005562b6acc9d4247d7416b984a6740d8fd7408 Mon Sep 17 00:00:00 2001 From: dimxy Date: Thu, 25 Apr 2019 15:50:19 +0500 Subject: [PATCH 126/242] corr resultbets entry --- src/cc/prices.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 9c3a34d95..130389702 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -785,16 +785,17 @@ void prices_betjson(UniValue &result, std::vector bets, int16_t leverag int64_t totalprofits = 0; for (auto b : bets) { - resultbets.push_back(Pair("positionsize", ValueFromAmount(b.amount))); - resultbets.push_back(Pair("profits", ValueFromAmount(b.profits))); - resultbets.push_back(Pair("costbasis", ValueFromAmount(b.costbasis))); - resultbets.push_back(Pair("firstheight", b.firstheight)); + UniValue entry(UniValue::VOBJ); + entry.push_back(Pair("positionsize", ValueFromAmount(b.amount))); + entry.push_back(Pair("profits", ValueFromAmount(b.profits))); + entry.push_back(Pair("costbasis", ValueFromAmount(b.costbasis))); + entry.push_back(Pair("firstheight", b.firstheight)); + resultbets.push_back(entry); totalbets += b.amount; totalprofits += b.profits; } int64_t equity = totalbets + totalprofits; - result.setArray(); result.push_back(resultbets); result.push_back(Pair("leverage", (int64_t)leverage)); result.push_back(Pair("TotalPositionSize", totalbets)); From ae4d2faa6927419dc121faf9d4a2ad4e9f1f7f35 Mon Sep 17 00:00:00 2001 From: dimxy Date: Thu, 25 Apr 2019 15:59:07 +0500 Subject: [PATCH 127/242] corr adding array to json res --- src/cc/prices.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 130389702..ef0dfc680 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -796,7 +796,7 @@ void prices_betjson(UniValue &result, std::vector bets, int16_t leverag } int64_t equity = totalbets + totalprofits; - result.push_back(resultbets); + result.push_back(Pair("bets", resultbets)); result.push_back(Pair("leverage", (int64_t)leverage)); result.push_back(Pair("TotalPositionSize", totalbets)); result.push_back(Pair("TotalProfits", totalprofits)); From 1c219dbf67903d2cccd506be1e21458f83573278 Mon Sep 17 00:00:00 2001 From: dimxy Date: Thu, 25 Apr 2019 16:10:05 +0500 Subject: [PATCH 128/242] corr costbasis init corr json vals precision --- src/cc/prices.cpp | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index ef0dfc680..5683f7b3d 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -23,6 +23,8 @@ typedef struct BetInfo { int32_t firstheight; int64_t costbasis; int64_t profits; + + BetInfo() { amount = 0; firstheight = 0; costbasis = 0; profits = 0; } } betinfo; /* @@ -798,9 +800,9 @@ void prices_betjson(UniValue &result, std::vector bets, int16_t leverag result.push_back(Pair("bets", resultbets)); result.push_back(Pair("leverage", (int64_t)leverage)); - result.push_back(Pair("TotalPositionSize", totalbets)); - result.push_back(Pair("TotalProfits", totalprofits)); - result.push_back(Pair("equity", equity)); + result.push_back(Pair("TotalPositionSize", ValueFromAmount(totalbets))); + result.push_back(Pair("TotalProfits", ValueFromAmount(totalprofits))); + result.push_back(Pair("equity", ValueFromAmount(equity))); result.push_back(Pair("LastPrice", ValueFromAmount(lastprice))); result.push_back(Pair("LastHeight", endheight)); } @@ -1215,30 +1217,26 @@ int32_t prices_scanchain(std::vector &bets, int16_t leverage, std::vect bool stop = false; for (int32_t h = bets[0].firstheight; ; h++) // the last datum for 24h is the costbasis value { - int64_t total = 0; + int64_t totalbets = 0; int64_t totalprofits = 0; for (int i = 0; i < bets.size(); i++) { int64_t costbasis, profits; - - int32_t retcode = prices_syntheticprofits(costbasis, bets[i].firstheight, h, leverage, vec, bets[i].amount, profits, lastprice); + int32_t retcode = prices_syntheticprofits(bets[i].costbasis, bets[i].firstheight, h, leverage, vec, bets[i].amount, bets[i].profits, lastprice); if (retcode < 0) { std::cerr << "prices_scanchain() error: prices_syntheticprofits returned -1 for addedbet" << std::endl; stop = true; break; } - total += bets[i].amount; - totalprofits += profits; - - bets[i].costbasis = costbasis; - bets[i].profits = profits; + totalbets += bets[i].amount; + totalprofits += bets[i].profits; } if (stop) break; endheight = h; - int64_t equity = total + totalprofits; + int64_t equity = totalbets + totalprofits; if (equity < 0) { // we are in loss break; From 10447109dddcf59e5181f31757ed84bec9e42aaf Mon Sep 17 00:00:00 2001 From: dimxy Date: Thu, 25 Apr 2019 16:16:18 +0500 Subject: [PATCH 129/242] corr equity compare --- src/cc/prices.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 5683f7b3d..d1c5ea00d 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1291,7 +1291,7 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) } int64_t equity = totalbet + totalprofits; - if (!equity < 0) + if (equity >= 0) result.push_back(Pair("rekt", 0)); else { From 00a39266aafd3df4d4f2d7d559ea84610f2c3988 Mon Sep 17 00:00:00 2001 From: dimxy Date: Thu, 25 Apr 2019 17:15:27 +0500 Subject: [PATCH 130/242] corr perm costbasis calc --- src/cc/prices.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index d1c5ea00d..caf1f491d 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -739,31 +739,31 @@ 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 << " price=" << price << 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 << " price=" << price << std::endl; - } - else { //-> use the previous value - std::cerr << "prices_syntheticprofits() unchanged costbasis=" << costbasis << " price=" << price << " leverage=" << leverage << 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 (costbasis == 0) { + if (height == firstheight + PRICES_DAYWINDOW) { // if costbasis not set, just set it costbasis = price; - std::cerr << "prices_syntheticprofits() set costbasis=" << costbasis << std::endl; + std::cerr << "prices_syntheticprofits() permanent costbasis=" << costbasis << " height=" << height << std::endl; } else { // use provided costbasis - std::cerr << "prices_syntheticprofits() provided costbasis=" << costbasis << " price=" << price << std::endl; + //std::cerr << "prices_syntheticprofits() provided costbasis=" << costbasis << " price=" << price << std::endl; } } profits = costbasis > 0 ? (((price / PRICES_NORMFACTOR * SATOSHIDEN) / costbasis) - SATOSHIDEN / PRICES_NORMFACTOR) * PRICES_NORMFACTOR : 0; - std::cerr << "prices_syntheticprofits() test value1 (price/PRICES_NORMFACTOR * SATOSHIDEN)=" << (price / PRICES_NORMFACTOR * SATOSHIDEN) << std::endl; + //std::cerr << "prices_syntheticprofits() test value1 (price/PRICES_NORMFACTOR * SATOSHIDEN)=" << (price / PRICES_NORMFACTOR * SATOSHIDEN) << std::endl; std::cerr << "prices_syntheticprofits() test value2 (price/PRICES_NORMFACTOR * SATOSHIDEN)/costbasis=" << (costbasis != 0 ? (price / PRICES_NORMFACTOR * SATOSHIDEN)/costbasis : 0) << std::endl; std::cerr << "prices_syntheticprofits() fractional profits=" << profits << std::endl; @@ -773,7 +773,7 @@ int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t profits *= ((int64_t)leverage * (int64_t)positionsize); profits /= (int64_t)SATOSHIDEN; //dprofits *= leverage * positionsize; - std::cerr << "prices_syntheticprofits() value of profits=" << profits << std::endl; + std::cerr << "prices_syntheticprofits() profits=" << profits << std::endl; //std::cerr << "prices_syntheticprofits() dprofits=" << dprofits << std::endl; return 0; // (positionsize + addedbets + profits); @@ -1220,11 +1220,11 @@ int32_t prices_scanchain(std::vector &bets, int16_t leverage, std::vect int64_t totalbets = 0; int64_t totalprofits = 0; + // scan upto the chain tip for (int i = 0; i < bets.size(); i++) { - int64_t costbasis, profits; int32_t retcode = prices_syntheticprofits(bets[i].costbasis, bets[i].firstheight, h, leverage, vec, bets[i].amount, bets[i].profits, lastprice); if (retcode < 0) { - std::cerr << "prices_scanchain() error: prices_syntheticprofits returned -1 for addedbet" << std::endl; + std::cerr << "prices_scanchain() prices_syntheticprofits returned -1, breaking" << std::endl; stop = true; break; } From fe3e906c46578d28f778c5b505e7a4ee5679cd80 Mon Sep 17 00:00:00 2001 From: dimxy Date: Thu, 25 Apr 2019 17:33:07 +0500 Subject: [PATCH 131/242] added height > firstheight check --- src/cc/prices.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index caf1f491d..54d883f95 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1215,27 +1215,31 @@ int32_t prices_scanchain(std::vector &bets, int16_t leverage, std::vect return -1; bool stop = false; - for (int32_t h = bets[0].firstheight; ; h++) // the last datum for 24h is the costbasis value + for (int32_t height = bets[0].firstheight; ; height++) // the last datum for 24h is the costbasis value { int64_t totalbets = 0; int64_t totalprofits = 0; // scan upto the chain tip for (int i = 0; i < bets.size(); i++) { - int32_t retcode = prices_syntheticprofits(bets[i].costbasis, bets[i].firstheight, h, leverage, vec, bets[i].amount, bets[i].profits, lastprice); - if (retcode < 0) { - std::cerr << "prices_scanchain() prices_syntheticprofits returned -1, breaking" << std::endl; - stop = true; - break; + + if (height > bets[i].firstheight) { + + int32_t retcode = prices_syntheticprofits(bets[i].costbasis, bets[i].firstheight, height, leverage, vec, bets[i].amount, bets[i].profits, lastprice); + if (retcode < 0) { + std::cerr << "prices_scanchain() prices_syntheticprofits returned -1, breaking" << std::endl; + stop = true; + break; + } + totalbets += bets[i].amount; + totalprofits += bets[i].profits; } - totalbets += bets[i].amount; - totalprofits += bets[i].profits; } if (stop) break; - endheight = h; + endheight = height; int64_t equity = totalbets + totalprofits; if (equity < 0) { // we are in loss From 02858d910307735e9885be00a7139a74dc4827a2 Mon Sep 17 00:00:00 2001 From: dimxy Date: Thu, 25 Apr 2019 18:59:37 +0500 Subject: [PATCH 132/242] corr Cashout and Rekt funcs --- src/cc/prices.cpp | 230 ++++++++++++++++++++++------------------------ 1 file changed, 108 insertions(+), 122 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 54d883f95..4cc942b70 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -24,7 +24,7 @@ typedef struct BetInfo { int64_t costbasis; int64_t profits; - BetInfo() { amount = 0; firstheight = 0; costbasis = 0; profits = 0; } + BetInfo() { amount = 0; firstheight = 0; costbasis = 0; profits = 0; } // important to clear costbasis as it will be calculated as minmax } betinfo; /* @@ -713,7 +713,7 @@ int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t return(price / den); } -// calculates profit/loss for the bet +// calculates costbasis and profit/loss for the bet 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) { int64_t price; @@ -779,6 +779,7 @@ int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t return 0; // (positionsize + addedbets + profits); } +// makes result json object void prices_betjson(UniValue &result, std::vector bets, int16_t leverage, int32_t endheight, int64_t lastprice) { @@ -840,7 +841,7 @@ int64_t prices_costbasis(CTransaction bettx, uint256 &txidCostbasis) return 0; } -// calculates added bet total, returns the last baton txid +// enumerates and retrieves added bets, returns the last baton txid int64_t prices_enumaddedbets(uint256 &batontxid, std::vector &bets, uint256 bettxid) { int64_t addedBetsTotal = 0; @@ -969,8 +970,49 @@ UniValue PricesAddFunding(int64_t txfee, uint256 bettxid, int64_t amount) return(result); } -// set cost basis (open price) for the bet +// scan chain from the initial bet's first position upto the chain tip and calculate bet's costbasises and profits, breaks if rekt detected +int32_t prices_scanchain(std::vector &bets, int16_t leverage, std::vector vec, int64_t &lastprice, int32_t &endheight) { + if (bets.size() == 0) + return -1; + + bool stop = false; + for (int32_t height = bets[0].firstheight; ; height++) // the last datum for 24h is the costbasis value + { + int64_t totalbets = 0; + int64_t totalprofits = 0; + + // scan upto the chain tip + for (int i = 0; i < bets.size(); i++) { + + if (height > bets[i].firstheight) { + + int32_t retcode = prices_syntheticprofits(bets[i].costbasis, bets[i].firstheight, height, leverage, vec, bets[i].amount, bets[i].profits, lastprice); + if (retcode < 0) { + std::cerr << "prices_scanchain() prices_syntheticprofits returned -1, breaking" << std::endl; + stop = true; + break; + } + totalbets += bets[i].amount; + totalprofits += bets[i].profits; + } + } + + if (stop) + break; + + endheight = height; + int64_t equity = totalbets + totalprofits; + if (equity < 0) + { // we are in loss + break; + } + } + + return 0; +} + +// set cost basis (open price) for the bet UniValue PricesSetcostbasis(int64_t txfee, uint256 bettxid) { int32_t nextheight = komodo_nextheight(); @@ -1048,8 +1090,8 @@ UniValue PricesRekt(int64_t txfee, uint256 bettxid, int32_t rektheight) struct CCcontract_info *cp, C; CTransaction bettx; uint256 hashBlock, tokenid, batontxid; - int64_t myfee = 0, positionsize, addedbets, firstprice, lastprice, profits, ignore, costbasis = 0, equity; - int32_t firstheight, numvouts; + int64_t myfee = 0, firstprice, lastprice = 0, positionsize; + int32_t firstheight; int16_t leverage; std::vector vec; CPubKey pk, mypk, pricespk; @@ -1060,40 +1102,45 @@ UniValue PricesRekt(int64_t txfee, uint256 bettxid, int32_t rektheight) txfee = PRICES_TXFEE; mypk = pubkey2pk(Mypubkey()); pricespk = GetUnspendable(cp, 0); - if (myGetTransaction(bettxid, bettx, hashBlock) != 0 && (numvouts = bettx.vout.size()) > 3) + if (myGetTransaction(bettxid, bettx, hashBlock) != 0 && bettx.vout.size() > 3) { - if (prices_betopretdecode(bettx.vout[numvouts - 1].scriptPubKey, pk, firstheight, positionsize, leverage, firstprice, vec, tokenid) == 'B') + if (prices_betopretdecode(bettx.vout.back().scriptPubKey, pk, firstheight, positionsize, leverage, firstprice, vec, tokenid) == 'B') { - //uint256 costbasistxid; - std::vector addedBets; + int32_t endheight; + std::vector bets; + BetInfo bet1; + bet1.amount = positionsize; + bet1.firstheight = firstheight; + bets.push_back(bet1); - /*costbasis = prices_costbasis(bettx, costbasistxid); - if (costbasis == 0) { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "costbasis not defined yet")); - return(result); - }*/ + prices_enumaddedbets(batontxid, bets, bettxid); - addedbets = prices_enumaddedbets(batontxid, addedBets, bettxid); - int32_t retcode = prices_syntheticprofits(costbasis, firstheight, rektheight, leverage, vec, positionsize, profits, lastprice); - if (retcode < 0) { + if (prices_scanchain(bets, leverage, vec, lastprice, endheight) < 0) { result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "cannot get price")); + result.push_back(Pair("error", "error scanning chain")); return(result); } - equity = positionsize + addedbets + profits; + int64_t totalbets = 0; + int64_t totalprofits = 0; + for (auto b : bets) { + totalbets += b.amount; + totalprofits += b.profits; + } + + prices_betjson(result, bets, leverage, endheight, lastprice); // fill output json + + int64_t equity = totalbets + totalprofits; if (equity < 0) { - myfee = (positionsize + addedbets) / 500; + myfee = totalbets / 500; // consolation fee for loss } - //prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice, lastprice, equity); if (myfee != 0) { mtx.vin.push_back(CTxIn(bettxid, 2, CScript())); mtx.vout.push_back(CTxOut(myfee, CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); mtx.vout.push_back(MakeCC1vout(cp->evalcode, bettx.vout[2].nValue - myfee - txfee, pricespk)); - rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_finalopret(bettxid, profits, rektheight, mypk, firstprice, costbasis, addedbets, positionsize, leverage)); + rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_finalopret(bettxid, totalprofits, rektheight, mypk, firstprice, 0, totalbets - positionsize, positionsize, leverage)); return(prices_rawtxresult(result, rawtx, 0)); } else @@ -1111,7 +1158,7 @@ UniValue PricesRekt(int64_t txfee, uint256 bettxid, int32_t rektheight) } } result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "cant find bettxid")); + result.push_back(Pair("error", "cant load or incorrect bettx")); return(result); } @@ -1122,8 +1169,8 @@ UniValue PricesCashout(int64_t txfee, uint256 bettxid) struct CCcontract_info *cp, C; char destaddr[64]; CTransaction bettx; uint256 hashBlock, batontxid, tokenid; - int64_t CCchange = 0, positionsize, inputsum, ignore, addedbets, firstprice, lastprice, profits, costbasis = 0, equity; - int32_t i, firstheight, height, numvouts; + int64_t CCchange = 0, positionsize, inputsum, firstprice, lastprice = 0; + int32_t firstheight, height; int16_t leverage; std::vector vec; CPubKey pk, mypk, pricespk; @@ -1136,44 +1183,48 @@ UniValue PricesCashout(int64_t txfee, uint256 bettxid) mypk = pubkey2pk(Mypubkey()); pricespk = GetUnspendable(cp, 0); GetCCaddress(cp, destaddr, pricespk); - if (myGetTransaction(bettxid, bettx, hashBlock) != 0 && (numvouts = bettx.vout.size()) > 3) + if (myGetTransaction(bettxid, bettx, hashBlock) != 0 && bettx.vout.size() > 3) { - if (prices_betopretdecode(bettx.vout[numvouts - 1].scriptPubKey, pk, firstheight, positionsize, leverage, firstprice, vec, tokenid) == 'B') + if (prices_betopretdecode(bettx.vout.back().scriptPubKey, pk, firstheight, positionsize, leverage, firstprice, vec, tokenid) == 'B') { - //uint256 costbasistxid; - std::vector addedBets; + int32_t endheight; + std::vector bets; + BetInfo bet1; + bet1.amount = positionsize; + bet1.firstheight = firstheight; + bets.push_back(bet1); - /* - costbasis = prices_costbasis(bettx, costbasistxid); - if (costbasis == 0) { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "costbasis not defined yet")); - return(result); - }*/ + prices_enumaddedbets(batontxid, bets, bettxid); - addedbets = prices_enumaddedbets(batontxid, addedBets, bettxid); - int32_t retcode = prices_syntheticprofits(costbasis, firstheight, nextheight - 1, leverage, vec, positionsize, profits, lastprice); - if (retcode < 0) { + if (prices_scanchain(bets, leverage, vec, lastprice, endheight) < 0) { result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "cannot get price")); + result.push_back(Pair("error", "error scanning chain")); return(result); } - equity = positionsize + addedbets + profits; + + int64_t totalbets = 0; + int64_t totalprofits = 0; + for (auto b : bets) { + totalbets += b.amount; + totalprofits += b.profits; + } + prices_betjson(result, bets, leverage, endheight, lastprice); // fill output json + + int64_t equity = totalbets + totalprofits; if (equity < 0) { - //prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice, lastprice, equity); result.push_back(Pair("result", "error")); result.push_back(Pair("error", "position rekt")); return(result); } - //prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice, lastprice, equity); + mtx.vin.push_back(CTxIn(bettxid, 2, CScript())); - if ((inputsum = AddPricesInputs(cp, mtx, destaddr, profits + txfee, 64, bettxid, 2)) > profits + txfee) - CCchange = (inputsum - profits); - mtx.vout.push_back(CTxOut(bettx.vout[2].nValue + profits, CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); + if ((inputsum = AddPricesInputs(cp, mtx, destaddr, equity + txfee, 64, bettxid, 2)) > equity + txfee) + CCchange = (inputsum - equity); + mtx.vout.push_back(CTxOut(bettx.vout[2].nValue + equity, CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); if (CCchange >= txfee) mtx.vout.push_back(MakeCC1vout(cp->evalcode, CCchange, pricespk)); - rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_finalopret(bettxid, profits, nextheight - 1, mypk, firstprice, costbasis, addedbets, positionsize, leverage)); + rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_finalopret(bettxid, totalprofits, nextheight - 1, mypk, firstprice, 0, totalbets-positionsize, positionsize, leverage)); return(prices_rawtxresult(result, rawtx, 0)); } else @@ -1183,82 +1234,18 @@ UniValue PricesCashout(int64_t txfee, uint256 bettxid) return(result); } } + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "cant load or incorrect bettx")); return(result); } -int32_t prices_scanchain(std::vector &bets, int16_t leverage, std::vector vec, int64_t &lastprice, int32_t &endheight) { - - vscript_t opret; - uint8_t funcId; - - - /* if (bettx.vout.size() < 1 || (funcId = CheckPricesOpret(bettx, opret)) == 0) { - std::cerr << "prices_scanchain() " << "incorrect tx, must be \'B\' or \'A\'" << std::endl; - return -1; - }*/ - - - // check acceptable refheight: -/* if (refheight < 0 || refheight > 0 && refheight < firstheight) { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "incorrect height")); - return(result); - } - if (refheight == 0) - refheight = komodo_nextheight() - 1;*/ - - //costbasis = prices_costbasis(bettx, costbasistxid) - - - - if (bets.size() == 0) - return -1; - - bool stop = false; - for (int32_t height = bets[0].firstheight; ; height++) // the last datum for 24h is the costbasis value - { - int64_t totalbets = 0; - int64_t totalprofits = 0; - - // scan upto the chain tip - for (int i = 0; i < bets.size(); i++) { - - if (height > bets[i].firstheight) { - - int32_t retcode = prices_syntheticprofits(bets[i].costbasis, bets[i].firstheight, height, leverage, vec, bets[i].amount, bets[i].profits, lastprice); - if (retcode < 0) { - std::cerr << "prices_scanchain() prices_syntheticprofits returned -1, breaking" << std::endl; - stop = true; - break; - } - totalbets += bets[i].amount; - totalprofits += bets[i].profits; - } - } - - if (stop) - break; - - endheight = height; - int64_t equity = totalbets + totalprofits; - if (equity < 0) - { // we are in loss - break; - } - } - - return 0; -} - - UniValue PricesInfo(uint256 bettxid, int32_t refheight) { UniValue result(UniValue::VOBJ); CTransaction bettx; uint256 hashBlock, batontxid, tokenid; - int64_t myfee; - int64_t positionsize = 0, firstprice = 0, lastprice = 0, costbasis = 0, equity; - int32_t i, firstheight = 0, endheight; + int64_t positionsize = 0, firstprice = 0, lastprice = 0; + int32_t firstheight = 0, endheight; int16_t leverage = 0; std::vector vec; CPubKey pk, mypk, pricespk; @@ -1272,7 +1259,6 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) if (prices_betopretdecode(bettx.vout.back().scriptPubKey, pk, firstheight, positionsize, leverage, firstprice, vec, tokenid) == 'B') { - bool isRekt; std::vector bets; BetInfo bet1; bet1.amount = positionsize; @@ -1287,20 +1273,20 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) return(result); } - int64_t totalbet = 0; + int64_t totalbets = 0; int64_t totalprofits = 0; for (auto b : bets) { - totalbet += b.amount; + totalbets += b.amount; totalprofits += b.profits; } - int64_t equity = totalbet + totalprofits; + int64_t equity = totalbets + totalprofits; if (equity >= 0) result.push_back(Pair("rekt", 0)); else { result.push_back(Pair("rekt", (int64_t)1)); - result.push_back(Pair("rektfee", totalbet / 500)); + result.push_back(Pair("rektfee", totalbets / 500)); result.push_back(Pair("rektheight", (int64_t)endheight)); } From 82557a93a404d1b9e8722583ff78b04d5d555515 Mon Sep 17 00:00:00 2001 From: dimxy Date: Thu, 25 Apr 2019 19:47:33 +0500 Subject: [PATCH 133/242] added checks for closed --- src/cc/prices.cpp | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 4cc942b70..d1bb48b48 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1077,9 +1077,9 @@ UniValue PricesSetcostbasis(int64_t txfee, uint256 bettxid) result.push_back(Pair("error", "not enough funds")); return(result); } - } + } */ result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "cant find bettxid")); */ + result.push_back(Pair("error", "deprecated")); return(result); } @@ -1106,9 +1106,18 @@ UniValue PricesRekt(int64_t txfee, uint256 bettxid, int32_t rektheight) { if (prices_betopretdecode(bettx.vout.back().scriptPubKey, pk, firstheight, positionsize, leverage, firstprice, vec, tokenid) == 'B') { - int32_t endheight; + uint256 finaltxid; + int32_t vini; + int32_t finalheight, endheight; std::vector bets; BetInfo bet1; + + if (CCgetspenttxid(finaltxid, vini, finalheight, bettxid, 2) < 0) { + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "position closed")); + return result; + } + bet1.amount = positionsize; bet1.firstheight = firstheight; bets.push_back(bet1); @@ -1170,7 +1179,7 @@ UniValue PricesCashout(int64_t txfee, uint256 bettxid) CTransaction bettx; uint256 hashBlock, batontxid, tokenid; int64_t CCchange = 0, positionsize, inputsum, firstprice, lastprice = 0; - int32_t firstheight, height; + int32_t firstheight; int16_t leverage; std::vector vec; CPubKey pk, mypk, pricespk; @@ -1187,13 +1196,21 @@ UniValue PricesCashout(int64_t txfee, uint256 bettxid) { if (prices_betopretdecode(bettx.vout.back().scriptPubKey, pk, firstheight, positionsize, leverage, firstprice, vec, tokenid) == 'B') { - int32_t endheight; + uint256 finaltxid; + int32_t vini; + int32_t finalheight, endheight; std::vector bets; BetInfo bet1; + + if (CCgetspenttxid(finaltxid, vini, finalheight, bettxid, 2) < 0) { + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "position closed")); + return result; + } + bet1.amount = positionsize; bet1.firstheight = firstheight; bets.push_back(bet1); - prices_enumaddedbets(batontxid, bets, bettxid); if (prices_scanchain(bets, leverage, vec, lastprice, endheight) < 0) { @@ -1259,8 +1276,17 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) if (prices_betopretdecode(bettx.vout.back().scriptPubKey, pk, firstheight, positionsize, leverage, firstprice, vec, tokenid) == 'B') { + uint256 finaltxid; + int32_t vini; + int32_t finalheight, endheight; std::vector bets; BetInfo bet1; + + if (CCgetspenttxid(finaltxid, vini, finalheight, bettxid, 2) < 0) + result.push_back(Pair("status", "closed")); + else + result.push_back(Pair("status", "open")); + bet1.amount = positionsize; bet1.firstheight = firstheight; bets.push_back(bet1); From c3854b80841c5f7595f4cc3b55f55809f2aeea2a Mon Sep 17 00:00:00 2001 From: dimxy Date: Thu, 25 Apr 2019 20:22:04 +0500 Subject: [PATCH 134/242] corr cashout amount --- src/cc/prices.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index d1bb48b48..5fca48739 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -917,10 +917,10 @@ UniValue PricesBet(int64_t txfee, int64_t amount, int16_t leverage, std::vector< if (AddNormalinputs(mtx, mypk, amount + 5 * txfee, 64) >= amount + 5 * txfee) { betamount = (amount * 199) / 200; - mtx.vout.push_back(MakeCC1vout(cp->evalcode, txfee, mypk)); // vout0 baton for total funding + 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, betamount, pricespk)); - mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(HexStr(pricespk)) << OP_CHECKSIG)); // marker + mtx.vout.push_back(MakeCC1vout(cp->evalcode, betamount, pricespk)); // betamount + mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(HexStr(pricespk)) << OP_CHECKSIG)); // normal marker rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_betopret(mypk, nextheight - 1, amount, leverage, firstprice, vec, zeroid)); return(prices_rawtxresult(result, rawtx, 0)); } @@ -1235,10 +1235,10 @@ UniValue PricesCashout(int64_t txfee, uint256 bettxid) return(result); } - mtx.vin.push_back(CTxIn(bettxid, 2, CScript())); + //mtx.vin.push_back(CTxIn(bettxid, 2, CScript())); // take back betamount (with fee subtracted) if ((inputsum = AddPricesInputs(cp, mtx, destaddr, equity + txfee, 64, bettxid, 2)) > equity + txfee) CCchange = (inputsum - equity); - mtx.vout.push_back(CTxOut(bettx.vout[2].nValue + equity, CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); + mtx.vout.push_back(CTxOut(equity, CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); if (CCchange >= txfee) mtx.vout.push_back(MakeCC1vout(cp->evalcode, CCchange, pricespk)); rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_finalopret(bettxid, totalprofits, nextheight - 1, mypk, firstprice, 0, totalbets-positionsize, positionsize, leverage)); From 4f5d16905a0722b4fd20ea721f9165a83233fe45 Mon Sep 17 00:00:00 2001 From: dimxy Date: Thu, 25 Apr 2019 20:28:26 +0500 Subject: [PATCH 135/242] corr check open/closed --- src/cc/prices.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 5fca48739..df7817876 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1112,7 +1112,7 @@ UniValue PricesRekt(int64_t txfee, uint256 bettxid, int32_t rektheight) std::vector bets; BetInfo bet1; - if (CCgetspenttxid(finaltxid, vini, finalheight, bettxid, 2) < 0) { + if (CCgetspenttxid(finaltxid, vini, finalheight, bettxid, 2) == 0) { result.push_back(Pair("result", "error")); result.push_back(Pair("error", "position closed")); return result; @@ -1202,7 +1202,7 @@ UniValue PricesCashout(int64_t txfee, uint256 bettxid) std::vector bets; BetInfo bet1; - if (CCgetspenttxid(finaltxid, vini, finalheight, bettxid, 2) < 0) { + if (CCgetspenttxid(finaltxid, vini, finalheight, bettxid, 2) == 0) { result.push_back(Pair("result", "error")); result.push_back(Pair("error", "position closed")); return result; @@ -1282,7 +1282,7 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) std::vector bets; BetInfo bet1; - if (CCgetspenttxid(finaltxid, vini, finalheight, bettxid, 2) < 0) + if (CCgetspenttxid(finaltxid, vini, finalheight, bettxid, 2) == 0) result.push_back(Pair("status", "closed")); else result.push_back(Pair("status", "open")); From 7b17cd8a365801ca0baa6b641a923e95ad80f56b Mon Sep 17 00:00:00 2001 From: dimxy Date: Thu, 25 Apr 2019 23:52:53 +0500 Subject: [PATCH 136/242] changed to cc marker cc marker excluded for addpricesinputs --- src/cc/prices.cpp | 73 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 50 insertions(+), 23 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index df7817876..362967e53 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -24,7 +24,7 @@ typedef struct BetInfo { int64_t costbasis; int64_t profits; - BetInfo() { amount = 0; firstheight = 0; costbasis = 0; profits = 0; } // important to clear costbasis as it will be calculated as minmax + BetInfo() { amount = 0; firstheight = 0; costbasis = 0; profits = 0; } // it is important to clear costbasis as it will be calculated as minmax from inital value 0 } betinfo; /* @@ -445,7 +445,7 @@ bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx // helper functions for rpc calls in rpcwallet.cpp -int64_t AddPricesInputs(struct CCcontract_info *cp, CMutableTransaction &mtx, char *destaddr, int64_t total, int32_t maxinputs, uint256 vintxid, int32_t vinvout) +int64_t AddPricesInputs(struct CCcontract_info *cp, CMutableTransaction &mtx, char *destaddr, int64_t total, int32_t maxinputs) { int64_t nValue, price, totalinputs = 0; uint256 txid, hashBlock; std::vector origpubkey; CTransaction vintx; int32_t vout, n = 0; std::vector > unspentOutputs; @@ -455,10 +455,15 @@ int64_t AddPricesInputs(struct CCcontract_info *cp, CMutableTransaction &mtx, ch { txid = it->first.txhash; vout = (int32_t)it->first.index; - if (vout == vinvout && txid == vintxid) - continue; + //if (vout == exclvout && txid == excltxid) // exclude vout which is added directly to vins outside this function + // continue; if (GetTransaction(txid, vintx, hashBlock, false) != 0 && vout < vintx.vout.size()) { + vscript_t vopret; + uint8_t funcId = CheckPricesOpret(vintx, vopret); + if (funcId == 'B' && vout == 1) // skip cc marker + continue; + if ((nValue = vintx.vout[vout].nValue) >= total / maxinputs && myIsutxo_spentinmempool(ignoretxid, ignorevin, txid, vout) == 0) { if (total != 0 && maxinputs != 0) @@ -866,7 +871,8 @@ int64_t prices_enumaddedbets(uint256 &batontxid, std::vector &bets, uin if ((isLoaded = eval->GetTxConfirmed(batontxid, txBaton, blockIdx)) && txBaton.vout.size() > 0 && - (funcId = prices_addopretdecode(txBaton.vout.back().scriptPubKey, bettxidInOpret, pk, amount)) != 0) { + (funcId = prices_addopretdecode(txBaton.vout.back().scriptPubKey, bettxidInOpret, pk, amount)) != 0) + { BetInfo added; addedBetsTotal += amount; @@ -914,13 +920,14 @@ UniValue PricesBet(int64_t txfee, int64_t amount, int16_t leverage, std::vector< result.push_back(Pair("error", "invalid synthetic")); return(result); } - if (AddNormalinputs(mtx, mypk, amount + 5 * txfee, 64) >= amount + 5 * txfee) + if (AddNormalinputs(mtx, mypk, amount + 4 * txfee, 64) >= amount + 4 * txfee) { betamount = (amount * 199) / 200; 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, betamount, pricespk)); // betamount - mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(HexStr(pricespk)) << OP_CHECKSIG)); // normal marker + // 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 + mtx.vout.push_back(MakeCC1vout(cp->evalcode, betamount, pricespk)); // vout2 betamount + mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(HexStr(pricespk)) << OP_CHECKSIG)); // vout3 normal marker rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_betopret(mypk, nextheight - 1, amount, leverage, firstprice, vec, zeroid)); return(prices_rawtxresult(result, rawtx, 0)); } @@ -953,8 +960,8 @@ UniValue PricesAddFunding(int64_t txfee, uint256 bettxid, int64_t amount) if (prices_enumaddedbets(batontxid, bets, bettxid) >= 0) { mtx.vin.push_back(CTxIn(batontxid, 0, CScript())); - mtx.vout.push_back(MakeCC1vout(cp->evalcode, txfee, mypk)); // baton for total funding - mtx.vout.push_back(MakeCC1vout(cp->evalcode, amount, pricespk)); + 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 rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_addopret(bettxid, mypk, amount)); return(prices_rawtxresult(result, rawtx, 0)); } @@ -1146,7 +1153,7 @@ UniValue PricesRekt(int64_t txfee, uint256 bettxid, int32_t rektheight) } if (myfee != 0) { - mtx.vin.push_back(CTxIn(bettxid, 2, CScript())); + mtx.vin.push_back(CTxIn(bettxid, 1, CScript())); // spend cc marker mtx.vout.push_back(CTxOut(myfee, CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); mtx.vout.push_back(MakeCC1vout(cp->evalcode, bettx.vout[2].nValue - myfee - txfee, pricespk)); rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_finalopret(bettxid, totalprofits, rektheight, mypk, firstprice, 0, totalbets - positionsize, positionsize, leverage)); @@ -1235,8 +1242,8 @@ UniValue PricesCashout(int64_t txfee, uint256 bettxid) return(result); } - //mtx.vin.push_back(CTxIn(bettxid, 2, CScript())); // take back betamount (with fee subtracted) - if ((inputsum = AddPricesInputs(cp, mtx, destaddr, equity + txfee, 64, bettxid, 2)) > equity + txfee) + mtx.vin.push_back(CTxIn(bettxid, 1, CScript())); // spend cc marker + if ((inputsum = AddPricesInputs(cp, mtx, destaddr, equity + txfee, 64)) > equity + txfee) CCchange = (inputsum - equity); mtx.vout.push_back(CTxOut(equity, CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); if (CCchange >= txfee) @@ -1333,23 +1340,29 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) UniValue PricesList(uint32_t filter, CPubKey mypk) { - UniValue result(UniValue::VARR); std::vector > addressIndex; + UniValue result(UniValue::VARR); + std::vector > addressIndex; struct CCcontract_info *cp, C; - int64_t amount, firstprice; int32_t height; int16_t leverage; uint256 txid, hashBlock, tokenid; - CPubKey pk, pricespk; - std::vector vec; - CTransaction vintx; + cp = CCinit(&C, EVAL_PRICES); - pricespk = GetUnspendable(cp, 0); - SetCCtxids(addressIndex, cp->normaladdr, false); - for (std::vector >::const_iterator it = addressIndex.begin(); it != addressIndex.end(); it++) + //pricespk = GetUnspendable(cp, 0); + + auto priceslist = [&](std::vector >::const_iterator it) { + int64_t amount, firstprice; + int32_t height; + int16_t leverage; + uint256 txid, hashBlock, tokenid; + CPubKey pk, pricespk; + std::vector vec; + CTransaction vintx; + txid = it->first.txhash; if (GetTransaction(txid, vintx, hashBlock, false) != 0) { bool bAppend = false; - if (vintx.vout.size() > 0 && prices_betopretdecode(vintx.vout[vintx.vout.size() - 1].scriptPubKey, pk, height, amount, leverage, firstprice, vec, tokenid) == 'B' && + 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 { if (filter == 0) @@ -1369,6 +1382,20 @@ UniValue PricesList(uint32_t filter, CPubKey mypk) } std::cerr << "PricesList() " << " bettxid=" << txid.GetHex() << " mypk=" << HexStr(mypk) << " opret pk=" << HexStr(pk) << " filter=" << filter << " bAppend=" << bAppend << std::endl; } + }; + + + SetCCtxids(addressIndex, cp->normaladdr, false); // old normal marker + for (std::vector >::const_iterator it = addressIndex.begin(); it != addressIndex.end(); it++) + { + priceslist(it); } + + SetCCtxids(addressIndex, cp->unspendableCCaddr, true); // cc marker + for (std::vector >::const_iterator it = addressIndex.begin(); it != addressIndex.end(); it++) + { + priceslist(it); + } + return(result); } \ No newline at end of file From d1c206b347da8b112e884e09135be4b9fbb310f5 Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 26 Apr 2019 00:01:59 +0500 Subject: [PATCH 137/242] corr addrindex --- src/cc/prices.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 362967e53..a86791ddd 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1341,7 +1341,7 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) UniValue PricesList(uint32_t filter, CPubKey mypk) { UniValue result(UniValue::VARR); - std::vector > addressIndex; + std::vector > addressIndex, addressIndexCC; struct CCcontract_info *cp, C; @@ -1391,8 +1391,8 @@ UniValue PricesList(uint32_t filter, CPubKey mypk) priceslist(it); } - SetCCtxids(addressIndex, cp->unspendableCCaddr, true); // cc marker - for (std::vector >::const_iterator it = addressIndex.begin(); it != addressIndex.end(); it++) + SetCCtxids(addressIndexCC, cp->unspendableCCaddr, true); // cc marker + for (std::vector >::const_iterator it = addressIndexCC.begin(); it != addressIndexCC.end(); it++) { priceslist(it); } From 2d677f3addc9c90f09cd299b30529c28bbcbc3d8 Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 26 Apr 2019 00:27:58 +0500 Subject: [PATCH 138/242] logging --- src/cc/prices.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index a86791ddd..9dd9091e9 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1348,7 +1348,7 @@ UniValue PricesList(uint32_t filter, CPubKey mypk) cp = CCinit(&C, EVAL_PRICES); //pricespk = GetUnspendable(cp, 0); - auto priceslist = [&](std::vector >::const_iterator it) + auto priceslist = [&](std::vector >::const_iterator it, int32_t vini) { int64_t amount, firstprice; int32_t height; @@ -1359,6 +1359,7 @@ UniValue PricesList(uint32_t filter, CPubKey mypk) CTransaction vintx; txid = it->first.txhash; + if (GetTransaction(txid, vintx, hashBlock, false) != 0) { bool bAppend = false; @@ -1380,7 +1381,7 @@ UniValue PricesList(uint32_t filter, CPubKey mypk) if (bAppend) result.push_back(txid.GetHex()); } - std::cerr << "PricesList() " << " bettxid=" << txid.GetHex() << " mypk=" << HexStr(mypk) << " opret pk=" << HexStr(pk) << " filter=" << filter << " bAppend=" << bAppend << std::endl; + std::cerr << "PricesList() " << " bettxid=" << txid.GetHex() << " mypk=" << HexStr(mypk) << " opretpk=" << HexStr(pk) << " filter=" << filter << " bAppend=" << bAppend << " index=" << it->first.index << " txindex=" << it->first.txindex << std::endl; } }; @@ -1388,13 +1389,13 @@ 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++) { - priceslist(it); + priceslist(it, 3); } SetCCtxids(addressIndexCC, cp->unspendableCCaddr, true); // cc marker for (std::vector >::const_iterator it = addressIndexCC.begin(); it != addressIndexCC.end(); it++) { - priceslist(it); + priceslist(it, 1); } return(result); From d9a1ff169556c7c8b8f12d391eeef75a3cc8e251 Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 26 Apr 2019 00:48:35 +0500 Subject: [PATCH 139/242] added check vout==index --- src/cc/prices.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 9dd9091e9..0e4280563 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1348,7 +1348,8 @@ UniValue PricesList(uint32_t filter, CPubKey mypk) cp = CCinit(&C, EVAL_PRICES); //pricespk = GetUnspendable(cp, 0); - auto priceslist = [&](std::vector >::const_iterator it, int32_t vini) + // filters and outputs prices bet txid + auto priceslist = [&](std::vector >::const_iterator it, int32_t nvout) { int64_t amount, firstprice; int32_t height; @@ -1359,6 +1360,8 @@ UniValue PricesList(uint32_t filter, CPubKey mypk) CTransaction vintx; txid = it->first.txhash; + if (nvout != it->first.index) // our marker vout + return; if (GetTransaction(txid, vintx, hashBlock, false) != 0) { @@ -1392,11 +1395,12 @@ UniValue PricesList(uint32_t filter, CPubKey mypk) priceslist(it, 3); } + /* for future when switch to cc marker only SetCCtxids(addressIndexCC, cp->unspendableCCaddr, true); // cc marker for (std::vector >::const_iterator it = addressIndexCC.begin(); it != addressIndexCC.end(); it++) { priceslist(it, 1); } - + */ return(result); } \ No newline at end of file From 94d6916ca46d4c11c1c25855652b1417a03e83d2 Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 26 Apr 2019 00:59:30 +0500 Subject: [PATCH 140/242] final tx vout check commented --- src/cc/prices.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 0e4280563..50115924a 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -303,8 +303,10 @@ static bool ValidateFinalTx(struct CCcontract_info *cp, Eval *eval, const CTrans int64_t firstprice, costbasis, addedbets, positionsize; int16_t leverage; - if (finaltx.vout.size() < 2 || finaltx.vout.size() > 3) - return eval->Invalid("incorrect vout number for final tx"); + if (finaltx.vout.size() < 3 || finaltx.vout.size() > 4) { + //return eval->Invalid("incorrect vout number for final tx"); + std::cerr << "ValidateFinalTx()" << " incorrect vout number for final tx =" << finaltx.vout.size() << std::endl; + } vscript_t opret; if (prices_finalopretdecode(finaltx.vout.back().scriptPubKey, bettxid, profits, height, pk, firstprice, costbasis, addedbets, positionsize, leverage) != 'F') @@ -1155,7 +1157,7 @@ UniValue PricesRekt(int64_t txfee, uint256 bettxid, int32_t rektheight) { mtx.vin.push_back(CTxIn(bettxid, 1, CScript())); // spend cc marker mtx.vout.push_back(CTxOut(myfee, CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); - mtx.vout.push_back(MakeCC1vout(cp->evalcode, bettx.vout[2].nValue - myfee - txfee, 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, firstprice, 0, totalbets - positionsize, positionsize, leverage)); return(prices_rawtxresult(result, rawtx, 0)); } From fc1e3209fd01a2a2b1f4f9ea2a8ee730a18a5619 Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 26 Apr 2019 01:09:51 +0500 Subject: [PATCH 141/242] more relaxed validation --- src/cc/prices.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 50115924a..85abc985c 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -375,9 +375,10 @@ bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx if (CheckPricesOpret(vintx, vintxOpret) == 0) return eval->Invalid("cannot find prices opret in vintx"); - //if (vintxOpret.begin()[1] == 'B' && prevoutN == 3) { - // return eval->Invalid("cannot spend bet marker"); - //} + if (funcId != 'F' && vintxOpret.begin()[1] == 'B' && prevoutN == 1) { + //return eval->Invalid("cannot spend bet marker"); + std::cerr << "PricesValidate() " << " non-final tx cannot spend cc marker vout=" << prevoutN << std::endl; + } if (!foundFirst) { prevoutN = vin.prevout.n; @@ -412,7 +413,8 @@ bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx } if (prevoutN != 0) { // check spending rules - return eval->Invalid("incorrect vintx vout to spend"); + // return eval->Invalid("incorrect vintx vout to spend"); + std::cerr << "PricesValidate() " << "add fund tx incorrect vout to spend=" << prevoutN << std::endl; } break; @@ -432,8 +434,9 @@ bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx return false; if (!ValidateBetTx(cp, eval, firstVinTx)) return false; - if (prevoutN != 2) { // check spending rules - return eval->Invalid("incorrect vout to spend"); + 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; } break; From 1141ce95d88e24592646c2f6849361e2aee505d7 Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 26 Apr 2019 01:33:49 +0500 Subject: [PATCH 142/242] bettx comment validation for add fund tx --- src/cc/prices.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 85abc985c..0c6efd755 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -216,9 +216,11 @@ static bool ValidateAddFundingTx(struct CCcontract_info *cp, Eval *eval, const C return eval->Invalid("cannot decode opreturn for add funding tx"); pricespk = GetUnspendable(cp, 0); - - if (CheckPricesOpret(vintx, vintxOpret) != 'B') // if vintx is bettx - return eval->Invalid("incorrect bettx"); + uint8_t funcId; + if ((funcId=CheckPricesOpret(vintx, vintxOpret)) != 'B') { // if vintx is bettx + std::cerr << "ValidateBetTx() " << "bad funcId=" << (funcId?funcId:'0') << std::endl; + //return eval->Invalid("incorrect bettx funcid"); + } if (vintx.GetHash() != bettxid) // if vintx is bettx return eval->Invalid("incorrect bet txid in opreturn"); @@ -262,7 +264,7 @@ static bool ValidateCostbasisTx(struct CCcontract_info *cp, Eval *eval, const CT // check costbasis rules: if (costbasistx.vout[0].nValue > bettx.vout[1].nValue / 10) { // return eval->Invalid("costbasis myfee too big"); - std::cerr << "ValidateBetTx() " << "costbasis myfee too big" << std::endl; + std::cerr << "ValidateCostbasisTx() " << "costbasis myfee too big" << std::endl; } uint256 tokenid; From 50adff8b8c3c4e5f4a1a981c0f1dd63b7b2c4888 Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 26 Apr 2019 01:46:25 +0500 Subject: [PATCH 143/242] corr vintx validation for add tx --- src/cc/prices.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 0c6efd755..6f17311c7 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -216,14 +216,16 @@ static bool ValidateAddFundingTx(struct CCcontract_info *cp, Eval *eval, const C return eval->Invalid("cannot decode opreturn for add funding tx"); pricespk = GetUnspendable(cp, 0); - uint8_t funcId; - if ((funcId=CheckPricesOpret(vintx, vintxOpret)) != 'B') { // if vintx is bettx - std::cerr << "ValidateBetTx() " << "bad funcId=" << (funcId?funcId:'0') << std::endl; - //return eval->Invalid("incorrect bettx funcid"); + uint8_t vintxFuncId = CheckPricesOpret(vintx, vintxOpret); + if (vintxFuncId != 'A' && vintxFuncId != 'B') { // if vintx is bettx + std::cerr << "ValidateAddFundingTx() " << "bad vintx funcId=" << (char)(vintxFuncId ? vintxFuncId :'0') << std::endl; + //return eval->Invalid("incorrect vintx funcid"); } - if (vintx.GetHash() != bettxid) // if vintx is bettx - return eval->Invalid("incorrect bet txid in opreturn"); + if (vintxFuncId == 'B' && vintx.GetHash() != bettxid) {// if vintx is bettx + //return eval->Invalid("incorrect bet txid in opreturn"); + std::cerr << "ValidateAddFundingTx() " << "incorrect net txid" << std::endl; + } if (MakeCC1vout(cp->evalcode, addfundingtx.vout[0].nValue, pk) != addfundingtx.vout[0]) return eval->Invalid("cannot validate vout0 in add funding tx with pk from opreturn"); From eb7d77de1df4cfdea627dcc3f8eb9eb0404e9a7e Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 26 Apr 2019 01:51:51 +0500 Subject: [PATCH 144/242] off costbasis validation --- src/cc/prices.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 6f17311c7..9357e3719 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -243,6 +243,8 @@ static bool ValidateCostbasisTx(struct CCcontract_info *cp, Eval *eval, const CT CPubKey pk, pricespk; int32_t height; + return true; //deprecated + // check basic structure: if (costbasistx.vout.size() < 3 || costbasistx.vout.size() > 4) return eval->Invalid("incorrect vout count for costbasis tx"); From 25b86870c1ac8601325a3fc226baab45e4770443 Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 26 Apr 2019 12:05:57 +0500 Subject: [PATCH 145/242] all return invalid captured --- src/cc/prices.cpp | 78 ++++++++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 34 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 9357e3719..2f8ad287a 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -178,7 +178,6 @@ static bool ValidateBetTx(struct CCcontract_info *cp, Eval *eval, const CTransac int64_t betamount = bettx.vout[2].nValue; if (betamount != (positionsize * 199) / 200) { return eval->Invalid("invalid position size in the opreturn"); - std::cerr << "ValidateBetTx() " << "invalid position size in the opreturn" << std::endl; } // validate if normal inputs are really signed by originator pubkey (someone not cheating with originator pubkey) @@ -188,13 +187,11 @@ static bool ValidateBetTx(struct CCcontract_info *cp, Eval *eval, const CTransac ccOutputs += vout.nValue; CAmount normalInputs = TotalPubkeyNormalInputs(bettx, pk); if (normalInputs < ccOutputs) { - // return eval->Invalid("bettx normal inputs not signed with pubkey in opret"); - std::cerr << "ValidateBetTx() " << "warning: bettx normal inputs signed with pubkey in opreturn =" << normalInputs << std::endl; + return eval->Invalid("bettx normal inputs not signed with pubkey in opret"); } if (leverage > PRICES_MAXLEVERAGE || leverage < -PRICES_MAXLEVERAGE) { - // return eval->Invalid("invalid leverage"); - std::cerr << "ValidateBetTx() " << "invalid leverage" << std::endl; + return eval->Invalid("invalid leverage"); } return true; @@ -218,13 +215,11 @@ static bool ValidateAddFundingTx(struct CCcontract_info *cp, Eval *eval, const C pricespk = GetUnspendable(cp, 0); uint8_t vintxFuncId = CheckPricesOpret(vintx, vintxOpret); if (vintxFuncId != 'A' && vintxFuncId != 'B') { // if vintx is bettx - std::cerr << "ValidateAddFundingTx() " << "bad vintx funcId=" << (char)(vintxFuncId ? vintxFuncId :'0') << std::endl; - //return eval->Invalid("incorrect vintx funcid"); + return eval->Invalid("incorrect vintx funcid"); } if (vintxFuncId == 'B' && vintx.GetHash() != bettxid) {// if vintx is bettx - //return eval->Invalid("incorrect bet txid in opreturn"); - std::cerr << "ValidateAddFundingTx() " << "incorrect net txid" << std::endl; + return eval->Invalid("incorrect bet txid in opreturn"); } if (MakeCC1vout(cp->evalcode, addfundingtx.vout[0].nValue, pk) != addfundingtx.vout[0]) @@ -267,8 +262,7 @@ static bool ValidateCostbasisTx(struct CCcontract_info *cp, Eval *eval, const CT // check costbasis rules: if (costbasistx.vout[0].nValue > bettx.vout[1].nValue / 10) { - // return eval->Invalid("costbasis myfee too big"); - std::cerr << "ValidateCostbasisTx() " << "costbasis myfee too big" << std::endl; + return eval->Invalid("costbasis myfee too big"); } uint256 tokenid; @@ -281,8 +275,7 @@ static bool ValidateCostbasisTx(struct CCcontract_info *cp, Eval *eval, const CT return eval->Invalid("cannot decode opreturn for bet tx"); if (firstheight + PRICES_DAYWINDOW + PRICES_SMOOTHWIDTH > chainActive.Height()) { - // return eval->Invalid("cannot calculate costbasis yet"); - std::cerr << "ValidateBetTx() " << "cannot calculate costbasis yet" << std::endl; + return eval->Invalid("cannot calculate costbasis yet"); } int64_t costbasis = 0, profits, lastprice; @@ -291,8 +284,8 @@ static bool ValidateCostbasisTx(struct CCcontract_info *cp, Eval *eval, const CT return eval->Invalid("cannot calculate costbasis yet"); std::cerr << "ValidateCostbasisTx() costbasis=" << costbasis << " costbasisInOpret=" << costbasisInOpret << std::endl; if (costbasis != costbasisInOpret) { - // return eval->Invalid("incorrect costbasis value"); - std::cerr << "ValidateBetTx() " << "incorrect costbasis value" << std::endl; + //std::cerr << "ValidateBetTx() " << "incorrect costbasis value" << std::endl; + return eval->Invalid("incorrect costbasis value"); } return true; @@ -310,8 +303,8 @@ static bool ValidateFinalTx(struct CCcontract_info *cp, Eval *eval, const CTrans int16_t leverage; if (finaltx.vout.size() < 3 || finaltx.vout.size() > 4) { - //return eval->Invalid("incorrect vout number for final tx"); - std::cerr << "ValidateFinalTx()" << " incorrect vout number for final tx =" << finaltx.vout.size() << std::endl; + //std::cerr << "ValidateFinalTx()" << " incorrect vout number for final tx =" << finaltx.vout.size() << std::endl; + return eval->Invalid("incorrect vout number for final tx"); } vscript_t opret; @@ -378,8 +371,10 @@ bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx if (!myGetTransaction(vin.prevout.hash, vintx, hashBlock)) return eval->Invalid("cannot load vintx"); - if (CheckPricesOpret(vintx, vintxOpret) == 0) - return eval->Invalid("cannot find prices opret in vintx"); + if (CheckPricesOpret(vintx, vintxOpret) == 0) { + //return eval->Invalid("cannot find prices opret in vintx"); + std::cerr << "PricesValidate() " << "cannot find prices opret in vintx" << std::endl; + } if (funcId != 'F' && vintxOpret.begin()[1] == 'B' && prevoutN == 1) { //return eval->Invalid("cannot spend bet marker"); @@ -398,8 +393,10 @@ 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 - return eval->Invalid("only one prices cc vin allowed for this tx"); + if (funcId != 'F' && 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; + } switch (funcId) { case 'B': // bet @@ -407,12 +404,16 @@ 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 + 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; + } if (firstVinTxOpret.begin()[1] == 'B') { - if (!ValidateBetTx(cp, eval, firstVinTx)) // check tx structure - return false; + if (!ValidateBetTx(cp, eval, firstVinTx)) {// check tx structure + // return false; + std::cerr << "PricesValidate() " << "funcId=A ValidatebetTx = false " << eval->state.GetRejectReason() << std::endl; + } } else if (firstVinTxOpret.begin()[1] == 'A') { // no need to validate the previous addfunding tx (it was validated when added) @@ -425,21 +426,30 @@ bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx break; case 'C': // set costbasis - if (!ValidateCostbasisTx(cp, eval, tx, firstVinTx)) - return false; - if (!ValidateBetTx(cp, eval, firstVinTx)) - return false; + if (!ValidateCostbasisTx(cp, eval, tx, firstVinTx)) { + //return false; + std::cerr << "PricesValidate() " << "ValidateCostbasisTx=false " << eval->state.GetRejectReason() << std::endl; + } + if (!ValidateBetTx(cp, eval, firstVinTx)) { + //return false; + std::cerr << "PricesValidate() " << "funcId=C ValidateBetTx=false " << eval->state.GetRejectReason() << std::endl; + } if (prevoutN != 1) { // check spending rules - return eval->Invalid("incorrect vout to spend"); + // return eval->Invalid("incorrect vout to spend"); + std::cerr << "PricesValidate() " << "costbasis tx incorrect vout to spend=" << prevoutN << std::endl; } //return eval->Invalid("test: costbasis is good"); break; case 'F': // final tx - if (!ValidateFinalTx(cp, eval, tx, firstVinTx)) - return false; - if (!ValidateBetTx(cp, eval, firstVinTx)) - return false; + if (!ValidateFinalTx(cp, eval, tx, firstVinTx)) { + ///return false; + std::cerr << "PricesValidate() " << "ValidateFinalTx=false " << eval->state.GetRejectReason() << std::endl; + } + if (!ValidateBetTx(cp, eval, firstVinTx)) { + // return false; + std::cerr << "PricesValidate() " << "ValidateBetTx=false " << eval->state.GetRejectReason() << std::endl; + } 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; From 8d272e1c5f44b0d1f2fbc01eb680517d28498863 Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 26 Apr 2019 19:43:50 +0500 Subject: [PATCH 146/242] val state cleared --- src/cc/prices.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 2f8ad287a..98049164f 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -460,6 +460,7 @@ bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx return eval->Invalid("invalid funcid"); } + eval->state = CValidationState(); return true; } // end of consensus code From ed6fd7e8c611aab49250a1aa95c03a056102342f Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Sat, 27 Apr 2019 02:21:40 +0800 Subject: [PATCH 147/242] attempt at daily snapshot --- src/cc/CCPayments.h | 2 + src/cc/hempcoin_notes.txt | 2 +- src/cc/payments.cpp | 86 +++++++----------------------- src/komodo_defs.h | 1 + src/main.cpp | 107 +++++++++++++++++++++++++++++++++++++- src/rpc/server.cpp | 13 ++--- src/rpc/server.h | 1 + src/txdb.cpp | 89 +++++++++++++++---------------- src/txdb.h | 2 +- src/wallet/rpcwallet.cpp | 13 +++++ 10 files changed, 190 insertions(+), 126 deletions(-) diff --git a/src/cc/CCPayments.h b/src/cc/CCPayments.h index 247a0f2ec..6eeb7bcb3 100644 --- a/src/cc/CCPayments.h +++ b/src/cc/CCPayments.h @@ -20,6 +20,7 @@ #include "CCinclude.h" #define PAYMENTS_TXFEE 10000 +bool komodo_snapshot2(std::map &addressAmounts); bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn); @@ -28,6 +29,7 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr); UniValue PaymentsFund(struct CCcontract_info *cp,char *jsonstr); UniValue PaymentsTxidopret(struct CCcontract_info *cp,char *jsonstr); UniValue PaymentsCreate(struct CCcontract_info *cp,char *jsonstr); +UniValue PaymentsAirdrop(struct CCcontract_info *cp,char *jsonstr); UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr); UniValue PaymentsList(struct CCcontract_info *cp,char *jsonstr); diff --git a/src/cc/hempcoin_notes.txt b/src/cc/hempcoin_notes.txt index f8003ac95..2fd72c897 100644 --- a/src/cc/hempcoin_notes.txt +++ b/src/cc/hempcoin_notes.txt @@ -56,7 +56,7 @@ get the payment fund scriptpubkey hex from vout 0: (the split it at OP_CHECKCRYP put the second half into an OP_RETURN: (the remaining part of the the above scriptpubkey) eg. ./komodo-cli -ac_name=TESTHC opreturn_burn 1 2a0401f00101246a22f046337db779358deaa69b9af053e27d85cb8e8e48b0b13805c084b04f87be6577ee75 opret_burn takes any burn amount and arbitrary hex string. (RPC works, but may have bugs, likely use this for LABS too with some fixes) - this gives a raw hex. Decode it and check the OP_RETURN is right before sending (using this RPC currently adds 3 extra bytes to the front (6a2d2c), which is truncated later on, this should be fixed if possible before making any real chains as its consensus code. Need to try diffrent methods to decode the hex correctly.) + this gives a raw hex. Decode it and check the OP_RETURN is right before sending. -earlytxid=810bd62fb8353fad20267ff2050684b8829affa3edf6b366633931530791dfce restart the chain with earlytxid param before height 100 on all nodes (if not using -testnode=1) ./komodod -ac_name=TESTHC -ac_supply=1000000 -ac_reward=100000000000 -ac_cc=2 -ac_script=2ea22c8020987fad30df055db6fd922c3a57e55d76601229ed3da3b31340112e773df3d0d28103120c008203000401ccb8 -ac_founders=150 -ac_blocktime=20 -ac_nk=96,5 -earlytxid=810bd62fb8353fad20267ff2050684b8829affa3edf6b366633931530791dfce diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index 7dc8cb1b6..6f6ae1a84 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -16,6 +16,18 @@ #include "CCPayments.h" /* +payments airdrop: + - extra RPC to merge all payments inputs to a single utxo, this must be called first and be confirmed before payments release, + or tx will be too big, we can check add payments inputs is only 1 input, at RPC and in validation very early on. + - do getsnapshot2 every 1440 blocks and save the result into some global sorted vector or DB? + -this allows any address balance to be calculated by only iterating each 1439 blocks maximum. + - calculate scriptpubkey to pay from each address, set allocations from balance of each address. allocation = balance? + +payments airdrop paying a token: ( maybe this is more reasonable speed wise? ) + - tokenid, top number of tokens to pay, list of pubkeys to exclude as optional param + - add vector of tokenids to getsnapshot2 - then sort each tokenid by balance. + put the pubkey to pay to as scriptpubkey in the saved vector. + 0) txidopret <- allocation, scriptPubKey, opret 1) create <- locked_blocks, minrelease, list of txidopret @@ -781,76 +793,14 @@ UniValue PaymentsCreate(struct CCcontract_info *cp,char *jsonstr) return(result); } +extern bool komodo_dailysnapshot(int32_t height); + UniValue PaymentsAirdrop(struct CCcontract_info *cp,char *jsonstr) { - // need to code: exclude list of tokenid, dust threshold, maxpayees, excluded pubkeys[] - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); - UniValue result(UniValue::VOBJ); CTransaction tx; CPubKey Paymentspk,mypk; char markeraddr[64]; std::vector txidoprets; uint256 hashBlock; int32_t i,n,numoprets=0,lockedblocks,minrelease; std::string rawtx; int64_t totalallocations = 0; - cJSON *params = payments_reparse(&n,jsonstr); - if ( params != 0 && n >= 4 ) - { - lockedblocks = juint(jitem(params,0),0); - minrelease = juint(jitem(params,1),0); - if ( lockedblocks < 0 || minrelease < 0 ) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","negative parameter")); - if ( params != 0 ) - free_json(params); - return(result); - } - for (i=0; i scriptPubKey,opret; int64_t allocation; - if ( myGetTransaction(txidoprets[i],tx,hashBlock) != 0 && tx.vout.size() > 1 && DecodePaymentsTxidOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,allocation,scriptPubKey,opret) == 'T' ) - { - totalallocations += allocation; - if ( opret.size() > 0 ) - numoprets++; - } - else - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","invalid txidopret")); - result.push_back(Pair("txid",txidoprets[i].GetHex())); - result.push_back(Pair("txi",(int64_t)i)); - if ( params != 0 ) - free_json(params); - return(result); - } - } - if ( numoprets > 1 ) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","too many opreturns")); - result.push_back(Pair("numoprets",(int64_t)numoprets)); - if ( params != 0 ) - free_json(params); - return(result); - } - mypk = pubkey2pk(Mypubkey()); - Paymentspk = GetUnspendable(cp,0); - if ( AddNormalinputs(mtx,mypk,2*PAYMENTS_TXFEE,60) > 0 ) - { - mtx.vout.push_back(MakeCC1of2vout(cp->evalcode,PAYMENTS_TXFEE,Paymentspk,Paymentspk)); - rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,EncodePaymentsOpRet(lockedblocks,minrelease,totalallocations,txidoprets)); - if ( params != 0 ) - free_json(params); - return(payments_rawtxresult(result,rawtx,1)); - } - result.push_back(Pair("result","error")); - result.push_back(Pair("error","not enough normal funds")); - } - else - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","parameters error")); - } - if ( params != 0 ) - free_json(params); - return(result); + uint64_t start = time(NULL); + komodo_dailysnapshot(chainActive.Height()); + //CScript scriptPubKey = GetScriptForDestination(dest); + return(time(NULL)-start); } UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr) diff --git a/src/komodo_defs.h b/src/komodo_defs.h index 2efe5efa2..a9df99c0e 100644 --- a/src/komodo_defs.h +++ b/src/komodo_defs.h @@ -20,6 +20,7 @@ #define ASSETCHAINS_MINHEIGHT 128 #define ASSETCHAINS_MAX_ERAS 3 #define KOMODO_ELECTION_GAP 2000 +#define KOMODO_SNAPSHOT_INTERVAL 1440 // 1440 is approx 1 day. Maybe this can be -ac param to allow for diffrent block times etc.? #define ROUNDROBIN_DELAY 61 #define KOMODO_ASSETCHAIN_MAXLEN 65 #define KOMODO_LIMITED_NETWORKSIZE 4 diff --git a/src/main.cpp b/src/main.cpp index 2e0102b8b..f4511c284 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -642,6 +642,96 @@ UniValue komodo_snapshot(int top) return(result); } +bool komodo_snapshot2(std::map &addressAmounts) +{ + if ( fAddressIndex && pblocktree != 0 ) + { + return pblocktree->Snapshot2(addressAmounts, 0); + } + else return false; +} + +int32_t lastSnapShotHeight = 0; +std::vector > vAddressSnapshot; + +bool komodo_dailysnapshot(int32_t height) +{ + uint256 notarized_hash,notarized_desttxid; int32_t prevMoMheight,notarized_height,undo_height; + notarized_height = komodo_notarized_height(&prevMoMheight,¬arized_hash,¬arized_desttxid); + if ( notarized_height > height-100 ) + { + // notarized height is higher than 100 blocks before this height, so snapshot the notarized height. + undo_height = notarized_height; + } + else + { + //snapshot 100 blocks ago. Could still be reorged but very unlikley and expensive to carry out constantly. + undo_height = height-100; + } + fprintf(stderr, "doing snapshot for height.%i lastSnapShotHeight.%i\n", undo_height, lastSnapShotHeight); + // if we already did this height dont bother doing it again, this is just a reorg. The actual snapshot height cannot be reorged. + if ( undo_height == lastSnapShotHeight ) + return true; + std::map addressAmounts; + if ( !komodo_snapshot2(addressAmounts) ) + return false; + + // undo blocks in reverse order + for (int32_t n = height; n > undo_height; n--) + { + //fprintf(stderr, "undoing block.%i\n",n); + CBlockIndex *pindex; CBlock block; + if ( (pindex= komodo_chainactive(n)) == 0 || komodo_blockload(block, pindex) != 0 ) + return false; + // undo transactions in reverse order + for (int32_t i = block.vtx.size() - 1; i >= 0; i--) + { + const CTransaction &tx = block.vtx[i]; + uint256 hash = tx.GetHash(); + CTxDestination vDest; + //fprintf(stderr, "undong tx.%s\n",hash.GetHex().c_str()); + // loop vouts reverse order + for (unsigned int k = tx.vout.size(); k-- > 0;) + { + const CTxOut &out = tx.vout[k]; + //fprintf(stderr, "scriptpubkey.%s\n",out.scriptPubKey.ToString().c_str() ); + if ( ExtractDestination(out.scriptPubKey, vDest) ) + { + // add outputs to destination + addressAmounts[CBitcoinAddress(vDest).ToString()] += out.nValue; + //fprintf(stderr, "address.%s addcoins.%li\n",CBitcoinAddress(vDest).ToString().c_str(), out.nValue); + } + } + // loop vins in reverse order, get prevout and remove the balance from its destination + for (unsigned int j = tx.vin.size(); j-- > 0;) + { + uint256 blockhash; CTransaction txin; + if ( !tx.IsCoinImport() && !tx.IsCoinBase() && GetTransaction(tx.vin[j].prevout.hash,txin,blockhash,false) ) // myGetTransaction! + { + int vout = tx.vin[j].prevout.n; + if ( ExtractDestination(txin.vout[vout].scriptPubKey, vDest) ) + { + // remove outputs from destination + //fprintf(stderr, "address.%s removecoins.%li\n",CBitcoinAddress(vDest).ToString().c_str(), txin.vout[vout].nValue); + addressAmounts[CBitcoinAddress(vDest).ToString()] -= txin.vout[vout].nValue; + } + } + } + } + } + vAddressSnapshot.clear(); // clear existing snapshot + // convert address string to destination for easier conversion to what ever is required, eg, scriptPubKey. + for ( auto element : addressAmounts) + vAddressSnapshot.push_back(make_pair(element.second, DecodeDestination(element.first))); + // sort the vector by amount, highest at top. + std::sort(vAddressSnapshot.rbegin(), vAddressSnapshot.rend()); + // include only top 5000 address. + if ( vAddressSnapshot.size() > 5000 ) vAddressSnapshot.resize(5000); + lastSnapShotHeight = undo_height; + fprintf(stderr, "vAddressSnapshot.size.%li\n", vAddressSnapshot.size()); + return true; +} + ////////////////////////////////////////////////////////////////////////////// // // mapOrphanTransactions @@ -3096,7 +3186,6 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex uint160 addrHash = addr.size() == 20 ? uint160(addr) : Hash160(addr); // undo spending activity addressIndex.push_back(make_pair(CAddressIndexKey(keyType, addrHash, pindex->GetHeight(), i, hash, j, true), prevout.nValue * -1)); - // restore unspent index addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(keyType, addrHash, input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight))); } @@ -4156,6 +4245,13 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * komodo_pricesupdate(pindexNew->GetHeight(),pblock); if ( ASSETCHAINS_SAPLING <= 0 && pindexNew->nTime > KOMODO_SAPLING_ACTIVATION - 24*3600 ) komodo_activate_sapling(pindexNew); + if ( ASSETCHAINS_CC != 0 && (pindexNew->GetHeight() % KOMODO_SNAPSHOT_INTERVAL) == 0 ) + { + 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, "snapshot completed in: %lu seconds\n", time(NULL)-start); + } return true; } @@ -6095,7 +6191,14 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth } LogPrintf("No coin database inconsistencies in last %i blocks (%i transactions)\n", chainActive.Height() - pindexState->GetHeight(), nGoodTransactions); - + + if ( ASSETCHAINS_CC != 0 && lastSnapShotHeight == 0 ) + { + int32_t init_SS_height = chainActive.Height() - (chainActive.Height() % KOMODO_SNAPSHOT_INTERVAL); + if ( !komodo_dailysnapshot(init_SS_height) ) + fprintf(stderr, "daily snapshot failed, please reindex your chain\n"); // maybe force shutdown here? + } + return true; } diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 79a782c35..7bd5d3419 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -480,12 +480,13 @@ static const CRPCCommand vRPCCommands[] = { "marmara", "marmaralock", &marmara_lock, true }, // Payments - { "payments", "paymentsaddress", &paymentsaddress, true }, - { "payments", "paymentstxidopret", &payments_txidopret, true }, - { "payments", "paymentscreate", &payments_create, true }, - { "payments", "paymentslist", &payments_list, true }, - { "payments", "paymentsinfo", &payments_info, true }, - { "payments", "paymentsfund", &payments_fund, true }, + { "payments", "paymentsaddress", &paymentsaddress, true }, + { "payments", "paymentstxidopret", &payments_txidopret, true }, + { "payments", "paymentscreate", &payments_create, true }, + { "payments", "paymentsairdrop", &payments_airdrop, true }, + { "payments", "paymentslist", &payments_list, true }, + { "payments", "paymentsinfo", &payments_info, true }, + { "payments", "paymentsfund", &payments_fund, true }, { "payments", "paymentsrelease", &payments_release, true }, { "CClib", "cclibaddress", &cclibaddress, true }, diff --git a/src/rpc/server.h b/src/rpc/server.h index bcbe644a3..cf6e4c254 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -287,6 +287,7 @@ extern UniValue payments_release(const UniValue& params, bool fHelp); extern UniValue payments_fund(const UniValue& params, bool fHelp); extern UniValue payments_txidopret(const UniValue& params, bool fHelp); extern UniValue payments_create(const UniValue& params, bool fHelp); +extern UniValue payments_airdrop(const UniValue& params, bool fHelp); extern UniValue payments_info(const UniValue& params, bool fHelp); extern UniValue payments_list(const UniValue& params, bool fHelp); diff --git a/src/txdb.cpp b/src/txdb.cpp index 4c9ea31ca..a7415834c 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -458,13 +458,13 @@ uint32_t komodo_segid32(char *coinaddr); {"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPVMY", 1} \ }; -int32_t CBlockTreeDB::Snapshot2(int64_t dustthreshold, int32_t top ,std::vector > &vaddr, UniValue *ret) +bool CBlockTreeDB::Snapshot2(std::map &addressAmounts, UniValue *ret) { int64_t total = 0; int64_t totalAddresses = 0; std::string address; int64_t utxos = 0; int64_t ignoredAddresses = 0, cryptoConditionsUTXOs = 0, cryptoConditionsTotals = 0; DECLARE_IGNORELIST boost::scoped_ptr iter(NewIterator()); - std::map addressAmounts; + //std::map addressAmounts; for (iter->SeekToLast(); iter->Valid(); iter->Prev()) { boost::this_thread::interruption_point(); @@ -486,40 +486,39 @@ int32_t CBlockTreeDB::Snapshot2(int64_t dustthreshold, int32_t top ,std::vector { cryptoConditionsUTXOs++; cryptoConditionsTotals += nValue; + total += nValue; continue; } - if ( nValue > dustthreshold ) + std::map ::iterator ignored = ignoredMap.find(address); + if (ignored != ignoredMap.end()) { - std::map ::iterator ignored = ignoredMap.find(address); - if (ignored != ignoredMap.end()) - { - fprintf(stderr,"ignoring %s\n", address.c_str()); - ignoredAddresses++; - continue; - } - std::map ::iterator pos = addressAmounts.find(address); - if ( pos == addressAmounts.end() ) - { - // insert new address + utxo amount - //fprintf(stderr, "inserting new address %s with amount %li\n", address.c_str(), nValue); - addressAmounts[address] = nValue; - totalAddresses++; - } - else - { - // update unspent tally for this address - //fprintf(stderr, "updating address %s with new utxo amount %li\n", address.c_str(), nValue); - addressAmounts[address] += nValue; - } - //fprintf(stderr,"{\"%s\", %.8f},\n",address.c_str(),(double)nValue/COIN); - // total += nValue; - utxos++; - } //else fprintf(stderr,"ignoring amount=0 UTXO for %s\n", address.c_str()); + fprintf(stderr,"ignoring %s\n", address.c_str()); + ignoredAddresses++; + continue; + } + std::map ::iterator pos = addressAmounts.find(address); + if ( pos == addressAmounts.end() ) + { + // insert new address + utxo amount + //fprintf(stderr, "inserting new address %s with amount %li\n", address.c_str(), nValue); + addressAmounts[address] = nValue; + totalAddresses++; + } + else + { + // update unspent tally for this address + //fprintf(stderr, "updating address %s with new utxo amount %li\n", address.c_str(), nValue); + addressAmounts[address] += nValue; + } + //fprintf(stderr,"{\"%s\", %.8f},\n",address.c_str(),(double)nValue/COIN); + // total += nValue; + utxos++; + total += nValue; } catch (const std::exception& e) { fprintf(stderr, "DONE %s: LevelDB addressindex exception! - %s\n", __func__, e.what()); - break; + return false; //break; this means failiure of DB? we need to exit here if so for consensus code! } } } @@ -530,30 +529,18 @@ int32_t CBlockTreeDB::Snapshot2(int64_t dustthreshold, int32_t top ,std::vector } } //fprintf(stderr, "total=%f, totalAddresses=%li, utxos=%li, ignored=%li\n", (double) total / COIN, totalAddresses, utxos, ignoredAddresses); - for (std::pair element : addressAmounts) - vaddr.push_back( make_pair(element.second, element.first) ); - std::sort(vaddr.rbegin(), vaddr.rend()); - int topN = 0; - for (std::vector>::iterator it = vaddr.begin(); it!=vaddr.end(); ++it) - { - total += it->first; - topN++; - // If requested, only show top N addresses in output JSON - if ( top == topN ) - break; - } + // this is for the snapshot RPC, you can skip this by passing a 0 as the last argument. if (ret) { - // Total amount in this snapshot, which is less than circulating supply if top parameter is used - // Use the address_total for a total of all address included when using top parameter. - ret->push_back(make_pair("total", (double) (total+cryptoConditionsTotals)/ COIN )); + // Total circulating supply without CC vouts. + ret->push_back(make_pair("total", (double) (total)/ COIN )); // Average amount in each address of this snapshot ret->push_back(make_pair("average",(double) (total/COIN) / totalAddresses )); // Total number of utxos processed in this snaphot ret->push_back(make_pair("utxos", utxos)); // Total number of addresses in this snaphot - ret->push_back(make_pair("total_addresses", top ? top : totalAddresses )); + ret->push_back(make_pair("total_addresses", totalAddresses )); // Total number of ignored addresses in this snaphot ret->push_back(make_pair("ignored_addresses", ignoredAddresses)); // Total number of crypto condition utxos we skipped @@ -561,22 +548,28 @@ int32_t CBlockTreeDB::Snapshot2(int64_t dustthreshold, int32_t top ,std::vector // Total value of skipped crypto condition utxos ret->push_back(make_pair("cc_utxo_value", (double) cryptoConditionsTotals / COIN)); // total of all the address's, does not count coins in CC vouts. - ret->push_back(make_pair("address_total", (double) total/ COIN )); + ret->push_back(make_pair("total_includeCCvouts", (double) (total+cryptoConditionsTotals)/ COIN )); // The snapshot finished at this block height ret->push_back(make_pair("ending_height", chainActive.Height())); } - return(topN); + return true; } UniValue CBlockTreeDB::Snapshot(int top) { int topN = 0; std::vector > vaddr; + //std::vector >> tokenids; + std::map addressAmounts; UniValue result(UniValue::VOBJ); UniValue addressesSorted(UniValue::VARR); result.push_back(Pair("start_time", (int) time(NULL))); - if ( Snapshot2(0,top,vaddr,&result) != 0 ) + if ( Snapshot2(addressAmounts,&result) ) { + for (std::pair element : addressAmounts) + vaddr.push_back( make_pair(element.second, element.first) ); + std::sort(vaddr.rbegin(), vaddr.rend()); + int topN = 0; for (std::vector>::iterator it = vaddr.begin(); it!=vaddr.end(); ++it) { UniValue obj(UniValue::VOBJ); diff --git a/src/txdb.h b/src/txdb.h index b4c4cd6bd..195f4c183 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -116,7 +116,7 @@ public: bool LoadBlockIndexGuts(); bool blockOnchainActive(const uint256 &hash); UniValue Snapshot(int top); - int32_t Snapshot2(int64_t dustthreshold, int32_t top,std::vector > &vaddr, UniValue *ret); + bool Snapshot2(std::map &addressAmounts, UniValue *ret); }; #endif // BITCOIN_TXDB_H diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 8de0ae773..66c534f11 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5629,6 +5629,19 @@ UniValue payments_create(const UniValue& params, bool fHelp) return(PaymentsCreate(cp,(char *)params[0].get_str().c_str())); } +UniValue payments_airdrop(const UniValue& params, bool fHelp) +{ + struct CCcontract_info *cp,C; + //if ( fHelp || params.size() != 1 ) + // throw runtime_error("paymentscreate \"[lockedblocks,minamount,%22paytxid0%22,...,%22paytxidN%22]\"\n"); + //if ( ensure_CCrequirements(EVAL_PAYMENTS) < 0 ) + // throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + //const CKeyStore& keystore = *pwalletMain; + LOCK2(cs_main, pwalletMain->cs_wallet); + //cp = CCinit(&C,EVAL_PAYMENTS); + return(PaymentsAirdrop(0,(char *)params[0].get_str().c_str())); +} + UniValue payments_info(const UniValue& params, bool fHelp) { struct CCcontract_info *cp,C; From 13fdf95907c386e44e86f17cec93e423290aaae5 Mon Sep 17 00:00:00 2001 From: dimxy Date: Sat, 27 Apr 2019 13:01:09 +0500 Subject: [PATCH 148/242] add ave costbasis and liq price (not normalized) --- src/cc/prices.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 98049164f..80533c97d 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -789,7 +789,9 @@ int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t } } + // normalize to 10,000,000 to prevent underflow profits = costbasis > 0 ? (((price / PRICES_NORMFACTOR * SATOSHIDEN) / costbasis) - SATOSHIDEN / PRICES_NORMFACTOR) * PRICES_NORMFACTOR : 0; + //std::cerr << "prices_syntheticprofits() test value1 (price/PRICES_NORMFACTOR * SATOSHIDEN)=" << (price / PRICES_NORMFACTOR * SATOSHIDEN) << std::endl; std::cerr << "prices_syntheticprofits() test value2 (price/PRICES_NORMFACTOR * SATOSHIDEN)/costbasis=" << (costbasis != 0 ? (price / PRICES_NORMFACTOR * SATOSHIDEN)/costbasis : 0) << std::endl; @@ -798,7 +800,8 @@ int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t //double dprofits = (double)price / (double)costbasis - 1.0; profits *= ((int64_t)leverage * (int64_t)positionsize); - profits /= (int64_t)SATOSHIDEN; + profits /= (int64_t)SATOSHIDEN; // de-normalize + //dprofits *= leverage * positionsize; std::cerr << "prices_syntheticprofits() profits=" << profits << std::endl; //std::cerr << "prices_syntheticprofits() dprofits=" << dprofits << std::endl; @@ -1330,11 +1333,17 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) int64_t totalbets = 0; int64_t totalprofits = 0; + int64_t costbasis = 0; for (auto b : bets) { totalbets += b.amount; totalprofits += b.profits; + costbasis += b.amount * b.costbasis; } + int64_t equity = totalbets + totalprofits; + costbasis /= bets.size(); + int64_t liqprice = costbasis - costbasis / leverage; + if (equity >= 0) result.push_back(Pair("rekt", 0)); @@ -1346,8 +1355,12 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) } result.push_back(Pair("batontxid", batontxid.GetHex())); + result.push_back(Pair("costbasis", costbasis)); prices_betjson(result, bets, leverage, endheight, lastprice); + + result.push_back(Pair("LiquidationPrice", liqprice)); + //result.push_back(Pair("height", (int64_t)endheight)); //#ifdef TESTMODE // result.push_back(Pair("test_daywindow", PRICES_DAYWINDOW)); From 8de1d2cd1b9c001f2ebecde21a88ee4560fdda91 Mon Sep 17 00:00:00 2001 From: dimxy Date: Sat, 27 Apr 2019 13:15:26 +0500 Subject: [PATCH 149/242] corr calc average costbasis --- src/cc/prices.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 80533c97d..9c85a20b0 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1341,7 +1341,7 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) } int64_t equity = totalbets + totalprofits; - costbasis /= bets.size(); + costbasis /= totalbets; int64_t liqprice = costbasis - costbasis / leverage; @@ -1355,11 +1355,11 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) } result.push_back(Pair("batontxid", batontxid.GetHex())); - result.push_back(Pair("costbasis", costbasis)); + result.push_back(Pair("costbasis", ValueFromAmount(costbasis))); prices_betjson(result, bets, leverage, endheight, lastprice); - result.push_back(Pair("LiquidationPrice", liqprice)); + result.push_back(Pair("LiquidationPrice", ValueFromAmount(liqprice))); //result.push_back(Pair("height", (int64_t)endheight)); //#ifdef TESTMODE From 9c2ee630b932cff6cee4719c2906d2bc48abb514 Mon Sep 17 00:00:00 2001 From: dimxy Date: Sat, 27 Apr 2019 13:23:57 +0500 Subject: [PATCH 150/242] added logging accum costbasis --- src/cc/prices.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 9c85a20b0..4c83fd72b 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1338,6 +1338,7 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) totalbets += b.amount; totalprofits += b.profits; costbasis += b.amount * b.costbasis; + std::cerr << "PricesInfo() acc costbasis=" << costbasis << " b.amount=" << b.amount << " b.costbasis=" << b.costbasis << std::endl; } int64_t equity = totalbets + totalprofits; From eb515ba1ab6ba953638191fc206b90a17edd9668 Mon Sep 17 00:00:00 2001 From: dimxy Date: Sat, 27 Apr 2019 13:32:07 +0500 Subject: [PATCH 151/242] add norm to average costbasis --- src/cc/prices.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 4c83fd72b..da1098d50 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1337,12 +1337,12 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) for (auto b : bets) { totalbets += b.amount; totalprofits += b.profits; - costbasis += b.amount * b.costbasis; + costbasis += b.amount * b.costbasis / PRICES_NORMFACTOR; // prevent overflow std::cerr << "PricesInfo() acc costbasis=" << costbasis << " b.amount=" << b.amount << " b.costbasis=" << b.costbasis << std::endl; } int64_t equity = totalbets + totalprofits; - costbasis /= totalbets; + costbasis /= totalbets * PRICES_NORMFACTOR; int64_t liqprice = costbasis - costbasis / leverage; From 3c368e8275f7763d9e9940e21605ecf3355876c8 Mon Sep 17 00:00:00 2001 From: dimxy Date: Sat, 27 Apr 2019 13:37:44 +0500 Subject: [PATCH 152/242] corr normalization --- src/cc/prices.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index da1098d50..6e785b6fc 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1342,7 +1342,7 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) } int64_t equity = totalbets + totalprofits; - costbasis /= totalbets * PRICES_NORMFACTOR; + costbasis /= totalbets / PRICES_NORMFACTOR; int64_t liqprice = costbasis - costbasis / leverage; From ba495d5baf9c3c1cb235bea5122cc0160aec33cb Mon Sep 17 00:00:00 2001 From: dimxy Date: Sat, 27 Apr 2019 13:46:26 +0500 Subject: [PATCH 153/242] norm operation grouping --- src/cc/prices.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 6e785b6fc..5d608beb2 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1337,12 +1337,12 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) for (auto b : bets) { totalbets += b.amount; totalprofits += b.profits; - costbasis += b.amount * b.costbasis / PRICES_NORMFACTOR; // prevent overflow + costbasis += b.amount * (b.costbasis / PRICES_NORMFACTOR); // prevent overflow std::cerr << "PricesInfo() acc costbasis=" << costbasis << " b.amount=" << b.amount << " b.costbasis=" << b.costbasis << std::endl; } int64_t equity = totalbets + totalprofits; - costbasis /= totalbets / PRICES_NORMFACTOR; + costbasis /= (totalbets / PRICES_NORMFACTOR); int64_t liqprice = costbasis - costbasis / leverage; From 339e00f4d96d53d0fc821489a802f0fab8cea010 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Sat, 27 Apr 2019 17:45:26 +0800 Subject: [PATCH 154/242] add dpow to BEER, fix crashed node not being able to sync due to future checkpoints. --- src/komodo.h | 2 +- src/main.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/komodo.h b/src/komodo.h index 15c1e5c02..b4c7d12bf 100644 --- a/src/komodo.h +++ b/src/komodo.h @@ -621,7 +621,7 @@ int32_t komodo_voutupdate(bool fJustCheck,int32_t *isratificationp,int32_t notar memset(&MoMoMdata,0,sizeof(MoMoMdata)); if ( matched == 0 && signedmask != 0 && bitweight(signedmask) >= KOMODO_MINRATIFY ) notarized = 1; - if ( strcmp("PIZZA",ccdata.symbol) == 0 || strncmp("TXSCL",ccdata.symbol,5) == 0 ) + if ( strcmp("PIZZA",ccdata.symbol) == 0 || strncmp("TXSCL",ccdata.symbol,5) == 0 || strcmp("BEER",ccdata.symbol) == 0) notarized = 1; if ( 0 && opretlen != 149 ) printf("[%s].%d (%s) matched.%d i.%d j.%d notarized.%d %llx opretlen.%d len.%d offset.%d opoffset.%d\n",ASSETCHAINS_SYMBOL,height,ccdata.symbol,matched,i,j,notarized,(long long)signedmask,opretlen,len,offset,opoffset); diff --git a/src/main.cpp b/src/main.cpp index 2e0102b8b..933a5bb15 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4243,7 +4243,7 @@ static bool ActivateBestChainStep(bool fSkipdpow, CValidationState &state, CBloc // stay on the same chain tip! int32_t notarizedht,prevMoMheight; uint256 notarizedhash,txid; notarizedht = komodo_notarized_height(&prevMoMheight,¬arizedhash,&txid); - if ( !fSkipdpow && pindexFork != 0 && pindexFork->GetHeight() < notarizedht ) + if ( !fSkipdpow && pindexFork != 0 && pindexOldTip->GetHeight() > notarizedht && pindexFork->GetHeight() < notarizedht ) { fprintf(stderr,"pindexFork->GetHeight().%d is < notarizedht %d, so ignore it\n",(int32_t)pindexFork->GetHeight(),notarizedht); return state.DoS(100, error("ActivateBestChainStep(): pindexFork->GetHeight().%d is < notarizedht %d, so ignore it",(int32_t)pindexFork->GetHeight(),notarizedht), From 5dd59ee7c112eeb5efea029d0ab7cb2d854ac561 Mon Sep 17 00:00:00 2001 From: dimxy Date: Sat, 27 Apr 2019 15:23:42 +0500 Subject: [PATCH 155/242] prevent average costbasis zero div --- src/cc/prices.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 5d608beb2..4e0235cd3 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1342,9 +1342,15 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) } int64_t equity = totalbets + totalprofits; - costbasis /= (totalbets / PRICES_NORMFACTOR); - int64_t liqprice = costbasis - costbasis / leverage; - + if (totalbets / PRICES_NORMFACTOR != 0) //prevent zero div + costbasis /= (totalbets / PRICES_NORMFACTOR); + else + costbasis = 0; + int64_t liqprice; + if (leverage != 0) + liqprice = costbasis - costbasis / leverage; + else + liqprice = 0; if (equity >= 0) result.push_back(Pair("rekt", 0)); From b6f98557c8467d35a92d7a5da74a49f42859ffce Mon Sep 17 00:00:00 2001 From: dimxy Date: Sat, 27 Apr 2019 15:32:08 +0500 Subject: [PATCH 156/242] totalbets check zero logging added --- src/cc/prices.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 4e0235cd3..620188ddb 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1338,10 +1338,11 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) totalbets += b.amount; totalprofits += b.profits; costbasis += b.amount * (b.costbasis / PRICES_NORMFACTOR); // prevent overflow - std::cerr << "PricesInfo() acc costbasis=" << costbasis << " b.amount=" << b.amount << " b.costbasis=" << b.costbasis << std::endl; + std::cerr << "PricesInfo() acc costbasis=" << costbasis << " b.amount=" << b.amount << " b.costbasis/PRICES_NORMFACTOR=" << (b.costbasis / PRICES_NORMFACTOR) << std::endl; } int64_t equity = totalbets + totalprofits; + std::cerr << "PricesInfo() " << " totalbets=" << (totalbets / PRICES_NORMFACTOR) << std::endl; if (totalbets / PRICES_NORMFACTOR != 0) //prevent zero div costbasis /= (totalbets / PRICES_NORMFACTOR); else From 87571e8457baa577388c461ac6355d42f18696b3 Mon Sep 17 00:00:00 2001 From: dimxy Date: Sat, 27 Apr 2019 15:37:58 +0500 Subject: [PATCH 157/242] corr totalbets normalization --- src/cc/prices.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 620188ddb..b18a25243 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1343,12 +1343,14 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) int64_t equity = totalbets + totalprofits; std::cerr << "PricesInfo() " << " totalbets=" << (totalbets / PRICES_NORMFACTOR) << std::endl; - if (totalbets / PRICES_NORMFACTOR != 0) //prevent zero div - costbasis /= (totalbets / PRICES_NORMFACTOR); + if (totalbets != 0) { //prevent zero div + costbasis /= totalbets; + costbasis /= PRICES_NORMFACTOR; //denormalization + } else costbasis = 0; int64_t liqprice; - if (leverage != 0) + if (leverage != 0) // prevent zero div liqprice = costbasis - costbasis / leverage; else liqprice = 0; From 3bf8ab37b54c1696c6289bfd15ec1063ecb42b2c Mon Sep 17 00:00:00 2001 From: dimxy Date: Sat, 27 Apr 2019 15:42:48 +0500 Subject: [PATCH 158/242] corr arithmetic normalization --- src/cc/prices.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index b18a25243..04741f9eb 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1345,7 +1345,7 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) std::cerr << "PricesInfo() " << " totalbets=" << (totalbets / PRICES_NORMFACTOR) << std::endl; if (totalbets != 0) { //prevent zero div costbasis /= totalbets; - costbasis /= PRICES_NORMFACTOR; //denormalization + costbasis *= PRICES_NORMFACTOR; //denormalization } else costbasis = 0; From c0a662824f5acea983026a4d47792450480a0e28 Mon Sep 17 00:00:00 2001 From: dimxy Date: Sat, 27 Apr 2019 15:46:51 +0500 Subject: [PATCH 159/242] remove extra logging --- src/cc/prices.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 04741f9eb..e0ef3029c 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1342,7 +1342,6 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) } int64_t equity = totalbets + totalprofits; - std::cerr << "PricesInfo() " << " totalbets=" << (totalbets / PRICES_NORMFACTOR) << std::endl; if (totalbets != 0) { //prevent zero div costbasis /= totalbets; costbasis *= PRICES_NORMFACTOR; //denormalization From f5aea6c1bdc76e50bb1045429de63918b5ad0ca6 Mon Sep 17 00:00:00 2001 From: dimxy Date: Sat, 27 Apr 2019 17:07:27 +0500 Subject: [PATCH 160/242] clear last 0000 for liqprice --- src/cc/prices.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index e0ef3029c..a07267bf3 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1344,13 +1344,16 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) int64_t equity = totalbets + totalprofits; if (totalbets != 0) { //prevent zero div costbasis /= totalbets; - costbasis *= PRICES_NORMFACTOR; //denormalization + costbasis *= PRICES_NORMFACTOR; //denormalization, last posiitons should be == 0000 } else costbasis = 0; int64_t liqprice; - if (leverage != 0) // prevent zero div + if (leverage != 0) {// prevent zero div liqprice = costbasis - costbasis / leverage; + liqprice /= PRICES_NORMFACTOR; + liqprice *= PRICES_NORMFACTOR; // last posiitons should be == 0000 + } else liqprice = 0; From 6e8e695bc8812112559d5a9c6ab7cef5a7b47579 Mon Sep 17 00:00:00 2001 From: dimxy Date: Sat, 27 Apr 2019 17:29:41 +0500 Subject: [PATCH 161/242] comment corrected --- src/cc/prices.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index a07267bf3..3584190f0 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1337,7 +1337,7 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) for (auto b : bets) { totalbets += b.amount; totalprofits += b.profits; - costbasis += b.amount * (b.costbasis / PRICES_NORMFACTOR); // prevent overflow + costbasis += b.amount * (b.costbasis / PRICES_NORMFACTOR); // prevent int64 overflow std::cerr << "PricesInfo() acc costbasis=" << costbasis << " b.amount=" << b.amount << " b.costbasis/PRICES_NORMFACTOR=" << (b.costbasis / PRICES_NORMFACTOR) << std::endl; } From 8b70bbf3070578ea5dd0d8f9c35ec38d6d2141fa Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Sat, 27 Apr 2019 22:30:43 +0800 Subject: [PATCH 162/242] fix --- src/ac/koin | 2 + src/assetchains.json | 11 ++-- src/assetchains.old | 1 + src/cc/CCPayments.h | 2 +- src/cc/COptCCParams.cpp | 116 ++++++++++++++++++++++++++++++++++++++++ src/cc/payments.cpp | 14 +++-- src/fiat/koin | 2 + src/komodo.h | 2 +- src/main.cpp | 65 +++++++++++++--------- 9 files changed, 177 insertions(+), 38 deletions(-) create mode 100755 src/ac/koin create mode 100644 src/cc/COptCCParams.cpp create mode 100755 src/fiat/koin diff --git a/src/ac/koin b/src/ac/koin new file mode 100755 index 000000000..7e76c6b54 --- /dev/null +++ b/src/ac/koin @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=KOIN $1 $2 $3 $4 $5 $6 diff --git a/src/assetchains.json b/src/assetchains.json index 87173697b..99c6557b6 100644 --- a/src/assetchains.json +++ b/src/assetchains.json @@ -237,8 +237,8 @@ "217.182.129.38", "37.187.225.231" ] - }, - { + }, + { "ac_name": "ILN", "ac_supply": "10000000000", "ac_cc": "2", @@ -258,10 +258,15 @@ "ac_cc": "3", "addnode": ["138.201.136.145"] }, -{ + { "ac_name": "VOTE2019", "ac_supply": "123651638", "ac_public": "1", "addnode": ["95.213.238.98"] + }, + { + "ac_name": "KOIN", + "ac_supply": "125000000", + "addnode": ["3.0.32.10"] } ] diff --git a/src/assetchains.old b/src/assetchains.old index 8f0d763b5..a0cbd3b9c 100755 --- a/src/assetchains.old +++ b/src/assetchains.old @@ -50,3 +50,4 @@ echo $pubkey ./komodod -pubkey=$pubkey -ac_name=RICK -ac_supply=90000000000 -ac_reward=100000000 -ac_cc=3 -addnode=138.201.136.145 & ./komodod -pubkey=$pubkey -ac_name=MORTY -ac_supply=90000000000 -ac_reward=100000000 -ac_cc=3 -addnode=138.201.136.145 & ./komodod -pubkey=$pubkey -ac_name=VOTE2019 -ac_supply=123651638 -ac_public=1 -addnode=95.213.238.98 & +./komodod -pubkey=$pubkey -ac_name=KOIN -ac_supply=125000000 -addnode=3.0.32.10 & diff --git a/src/cc/CCPayments.h b/src/cc/CCPayments.h index 6eeb7bcb3..3f5a10087 100644 --- a/src/cc/CCPayments.h +++ b/src/cc/CCPayments.h @@ -20,7 +20,7 @@ #include "CCinclude.h" #define PAYMENTS_TXFEE 10000 -bool komodo_snapshot2(std::map &addressAmounts); +extern std::vector > vAddressSnapshot; bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn); diff --git a/src/cc/COptCCParams.cpp b/src/cc/COptCCParams.cpp new file mode 100644 index 000000000..41c9ba874 --- /dev/null +++ b/src/cc/COptCCParams.cpp @@ -0,0 +1,116 @@ +/*Descriptson and examples of COptCCParams class found in: + script/standard.h/cpp + class COptCCParams + +structure of data in vData payload attached to end of CCvout: + param + OP_1 + param + OP_2 ... etc until OP_16 + OP_PUSHDATA4 is the last OP code to tell things its at the end. + + taken from standard.cpp line 22: COptCCParams::COptCCParams(std::vector &vch) + +EXAMPLE taken from Verus how to create scriptPubKey from COptCCParams class: +EXAMPLE taken from Verus how to decode scriptPubKey from COptCCParams class: +*/ + +bool MakeGuardedOutput(CAmount value, CPubKey &dest, CTransaction &stakeTx, CTxOut &vout) +{ + CCcontract_info *cp, C; + cp = CCinit(&C,EVAL_STAKEGUARD); + + CPubKey ccAddress = CPubKey(ParseHex(cp->CChexstr)); + + // return an output that is bound to the stake transaction and can be spent by presenting either a signed condition by the original + // destination address or a properly signed stake transaction of the same utxo on a fork + vout = MakeCC1of2vout(EVAL_STAKEGUARD, value, dest, ccAddress); + + std::vector vPubKeys = std::vector(); + vPubKeys.push_back(dest); + vPubKeys.push_back(ccAddress); + + std::vector> vData = std::vector>(); + + CVerusHashWriter hw = CVerusHashWriter(SER_GETHASH, PROTOCOL_VERSION); + + hw << stakeTx.vin[0].prevout.hash; + hw << stakeTx.vin[0].prevout.n; + + uint256 utxo = hw.GetHash(); + vData.push_back(std::vector(utxo.begin(), utxo.end())); // Can we use any data here to construct vector? + + CStakeParams p; + if (GetStakeParams(stakeTx, p)) + { + // prev block hash and height is here to make validation easy + vData.push_back(std::vector(p.prevHash.begin(), p.prevHash.end())); + std::vector height = std::vector(4); + for (int i = 0; i < 4; i++) + { + height[i] = (p.blkHeight >> (8 * i)) & 0xff; + } + vData.push_back(height); + + COptCCParams ccp = COptCCParams(COptCCParams::VERSION, EVAL_STAKEGUARD, 1, 2, vPubKeys, vData); + + vout.scriptPubKey << ccp.AsVector() << OP_DROP; + return true; + } + return false; +} + +bool ValidateMatchingStake(const CTransaction &ccTx, uint32_t voutNum, const CTransaction &stakeTx, bool &cheating) +{ + // an invalid or non-matching stake transaction cannot cheat + cheating = false; + + //printf("ValidateMatchingStake: ccTx.vin[0].prevout.hash: %s, ccTx.vin[0].prevout.n: %d\n", ccTx.vin[0].prevout.hash.GetHex().c_str(), ccTx.vin[0].prevout.n); + + if (ccTx.IsCoinBase()) + { + CStakeParams p; + if (ValidateStakeTransaction(stakeTx, p)) + { + std::vector> vParams = std::vector>(); + CScript dummy; + + if (ccTx.vout[voutNum].scriptPubKey.IsPayToCryptoCondition(&dummy, vParams) && vParams.size() > 0) + { + COptCCParams ccp = COptCCParams(vParams[0]); + if (ccp.IsValid() & ccp.vData.size() >= 3 && ccp.vData[2].size() <= 4) + { + CVerusHashWriter hw = CVerusHashWriter(SER_GETHASH, PROTOCOL_VERSION); + + hw << stakeTx.vin[0].prevout.hash; + hw << stakeTx.vin[0].prevout.n; + uint256 utxo = hw.GetHash(); + + uint32_t height = 0; + int i, dataLen = ccp.vData[2].size(); + for (i = dataLen - 1; i >= 0; i--) + { + height = (height << 8) + ccp.vData[2][i]; + } + // for debugging strange issue + // printf("iterator: %d, height: %d, datalen: %d\n", i, height, dataLen); + + if (utxo == uint256(ccp.vData[0])) + { + if (p.prevHash != uint256(ccp.vData[1]) && p.blkHeight >= height) + { + cheating = true; + return true; + } + // if block height is equal and we are at the else, prevHash must have been equal + else if (p.blkHeight == height) + { + return true; + } + } + } + } + } + } + return false; +} diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index 6f6ae1a84..569c4eb14 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -16,17 +16,18 @@ #include "CCPayments.h" /* +use notarizations DB to scan back from the correct height, then undo ALL blocks back to this notarized height! payments airdrop: - extra RPC to merge all payments inputs to a single utxo, this must be called first and be confirmed before payments release, or tx will be too big, we can check add payments inputs is only 1 input, at RPC and in validation very early on. - - do getsnapshot2 every 1440 blocks and save the result into some global sorted vector or DB? + - do getsnapshot2 every 1440 blocks and save the result into some global sorted vector. -this allows any address balance to be calculated by only iterating each 1439 blocks maximum. - calculate scriptpubkey to pay from each address, set allocations from balance of each address. allocation = balance? -payments airdrop paying a token: ( maybe this is more reasonable speed wise? ) +payments airdrop paying a token: - tokenid, top number of tokens to pay, list of pubkeys to exclude as optional param - - add vector of tokenids to getsnapshot2 - then sort each tokenid by balance. - put the pubkey to pay to as scriptpubkey in the saved vector. + - token airdrop code should be the same as normal snapshot, but call a diffrent snapshot function that only fetches the info for a specific tokenid given. + this should be fine to work in validation/rpc level rather than a global saved result, as a single token id doesnt require iterating the whole DB. 0) txidopret <- allocation, scriptPubKey, opret 1) create <- locked_blocks, minrelease, list of txidopret @@ -793,13 +794,10 @@ UniValue PaymentsCreate(struct CCcontract_info *cp,char *jsonstr) return(result); } -extern bool komodo_dailysnapshot(int32_t height); - UniValue PaymentsAirdrop(struct CCcontract_info *cp,char *jsonstr) { uint64_t start = time(NULL); - komodo_dailysnapshot(chainActive.Height()); - //CScript scriptPubKey = GetScriptForDestination(dest); + return(time(NULL)-start); } diff --git a/src/fiat/koin b/src/fiat/koin new file mode 100755 index 000000000..7e76c6b54 --- /dev/null +++ b/src/fiat/koin @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=KOIN $1 $2 $3 $4 $5 $6 diff --git a/src/komodo.h b/src/komodo.h index 15c1e5c02..b4c7d12bf 100644 --- a/src/komodo.h +++ b/src/komodo.h @@ -621,7 +621,7 @@ int32_t komodo_voutupdate(bool fJustCheck,int32_t *isratificationp,int32_t notar memset(&MoMoMdata,0,sizeof(MoMoMdata)); if ( matched == 0 && signedmask != 0 && bitweight(signedmask) >= KOMODO_MINRATIFY ) notarized = 1; - if ( strcmp("PIZZA",ccdata.symbol) == 0 || strncmp("TXSCL",ccdata.symbol,5) == 0 ) + if ( strcmp("PIZZA",ccdata.symbol) == 0 || strncmp("TXSCL",ccdata.symbol,5) == 0 || strcmp("BEER",ccdata.symbol) == 0) notarized = 1; if ( 0 && opretlen != 149 ) printf("[%s].%d (%s) matched.%d i.%d j.%d notarized.%d %llx opretlen.%d len.%d offset.%d opoffset.%d\n",ASSETCHAINS_SYMBOL,height,ccdata.symbol,matched,i,j,notarized,(long long)signedmask,opretlen,len,offset,opoffset); diff --git a/src/main.cpp b/src/main.cpp index f4511c284..8bace2cb0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -656,19 +656,34 @@ std::vector > vAddressSnapshot; bool komodo_dailysnapshot(int32_t height) { - uint256 notarized_hash,notarized_desttxid; int32_t prevMoMheight,notarized_height,undo_height; - notarized_height = komodo_notarized_height(&prevMoMheight,¬arized_hash,¬arized_desttxid); - if ( notarized_height > height-100 ) + uint256 notarized_hash,notarized_desttxid; int32_t prevMoMheight,notarized_height,undo_height,extraoffset; + if ( (extraoffset= height % KOMODO_SNAPSHOT_INTERVAL) != 0 ) { - // notarized height is higher than 100 blocks before this height, so snapshot the notarized height. - undo_height = notarized_height; + // we are on chain init, and need to scan all the way back to the correct height, other wise our node will have a diffrent snapshot to online nodes. + // use the notarizationsDB to scan back from the consesnus height to get the offset we need. + std::string symbol; Notarisation nota; + symbol.assign(ASSETCHAINS_SYMBOL); + ScanNotarisationsDB(height-extraoffset, symbol, 100, nota); + undo_height = nota.second.height; + if ( undo_height == 0 ) undo_height = height-extraoffset-100; + fprintf(stderr, "height.%i-extraoffset.%i = startscanfrom.%i to get undo_height.%i\n", height, extraoffset, height-extraoffset, undo_height); } - else + else { - //snapshot 100 blocks ago. Could still be reorged but very unlikley and expensive to carry out constantly. - undo_height = height-100; + // we are at the right height in connect block to scan back to last notarized height. + notarized_height = komodo_notarized_height(&prevMoMheight,¬arized_hash,¬arized_desttxid); + if ( notarized_height > height-100 ) + { + // notarized height is higher than 100 blocks before this height, so snapshot the notarized height. + undo_height = notarized_height; + } + else + { + //snapshot 100 blocks ago. Could still be reorged but very unlikley and expensive to carry out constantly. + undo_height = height-100; + } } - fprintf(stderr, "doing snapshot for height.%i lastSnapShotHeight.%i\n", undo_height, lastSnapShotHeight); + fprintf(stderr, "doing snapshot for height.%i undo_height.%i\n", height, undo_height); // if we already did this height dont bother doing it again, this is just a reorg. The actual snapshot height cannot be reorged. if ( undo_height == lastSnapShotHeight ) return true; @@ -690,30 +705,29 @@ bool komodo_dailysnapshot(int32_t height) uint256 hash = tx.GetHash(); CTxDestination vDest; //fprintf(stderr, "undong tx.%s\n",hash.GetHex().c_str()); - // loop vouts reverse order + // loop vouts reverse order, remove value recieved. for (unsigned int k = tx.vout.size(); k-- > 0;) { const CTxOut &out = tx.vout[k]; - //fprintf(stderr, "scriptpubkey.%s\n",out.scriptPubKey.ToString().c_str() ); if ( ExtractDestination(out.scriptPubKey, vDest) ) { - // add outputs to destination - addressAmounts[CBitcoinAddress(vDest).ToString()] += out.nValue; - //fprintf(stderr, "address.%s addcoins.%li\n",CBitcoinAddress(vDest).ToString().c_str(), out.nValue); + addressAmounts[CBitcoinAddress(vDest).ToString()] -= out.nValue; + if ( addressAmounts[CBitcoinAddress(vDest).ToString()] < 1 ) + addressAmounts.erase(CBitcoinAddress(vDest).ToString()); + //fprintf(stderr, "VOUT: address.%s remove_coins.%li\n",CBitcoinAddress(vDest).ToString().c_str(), out.nValue); } } - // loop vins in reverse order, get prevout and remove the balance from its destination + // loop vins in reverse order, get prevout and return the sent balance. for (unsigned int j = tx.vin.size(); j-- > 0;) { uint256 blockhash; CTransaction txin; - if ( !tx.IsCoinImport() && !tx.IsCoinBase() && GetTransaction(tx.vin[j].prevout.hash,txin,blockhash,false) ) // myGetTransaction! + if ( !tx.IsCoinImport() && !tx.IsCoinBase() && myGetTransaction(tx.vin[j].prevout.hash,txin,blockhash) ) // myGetTransaction! { int vout = tx.vin[j].prevout.n; if ( ExtractDestination(txin.vout[vout].scriptPubKey, vDest) ) { - // remove outputs from destination - //fprintf(stderr, "address.%s removecoins.%li\n",CBitcoinAddress(vDest).ToString().c_str(), txin.vout[vout].nValue); - addressAmounts[CBitcoinAddress(vDest).ToString()] -= txin.vout[vout].nValue; + //fprintf(stderr, "VIN: address.%s add_coins.%li\n",CBitcoinAddress(vDest).ToString().c_str(), txin.vout[vout].nValue); + addressAmounts[CBitcoinAddress(vDest).ToString()] += txin.vout[vout].nValue; } } } @@ -725,6 +739,8 @@ bool komodo_dailysnapshot(int32_t height) vAddressSnapshot.push_back(make_pair(element.second, DecodeDestination(element.first))); // sort the vector by amount, highest at top. std::sort(vAddressSnapshot.rbegin(), vAddressSnapshot.rend()); + //for (int j = 0; j < 50; j++) + // fprintf(stderr, "j.%i address.%s nValue.%li\n",j, CBitcoinAddress(vAddressSnapshot[j].second).ToString().c_str(), vAddressSnapshot[j].first ); // include only top 5000 address. if ( vAddressSnapshot.size() > 5000 ) vAddressSnapshot.resize(5000); lastSnapShotHeight = undo_height; @@ -4339,10 +4355,10 @@ static bool ActivateBestChainStep(bool fSkipdpow, CValidationState &state, CBloc // stay on the same chain tip! int32_t notarizedht,prevMoMheight; uint256 notarizedhash,txid; notarizedht = komodo_notarized_height(&prevMoMheight,¬arizedhash,&txid); - if ( !fSkipdpow && pindexFork != 0 && pindexFork->GetHeight() < notarizedht ) + if ( !fSkipdpow && pindexFork != 0 && pindexOldTip->GetHeight() > notarizedht && pindexFork->GetHeight() < notarizedht ) { - fprintf(stderr,"pindexFork->GetHeight().%d is < notarizedht %d, so ignore it\n",(int32_t)pindexFork->GetHeight(),notarizedht); - return state.DoS(100, error("ActivateBestChainStep(): pindexFork->GetHeight().%d is < notarizedht %d, so ignore it",(int32_t)pindexFork->GetHeight(),notarizedht), + fprintf(stderr,"pindexOldTip->GetHeight().%d > notarizedht %d && pindexFork->GetHeight().%d is < notarizedht %d, so ignore it\n",(int32_t)pindexFork->GetHeight(),notarizedht,(int32_t)pindexOldTip->GetHeight(),notarizedht); + return state.DoS(100, error("ActivateBestChainStep(): pindexOldTip->GetHeight().%d > notarizedht %d && pindexFork->GetHeight().%d is < notarizedht %d, so ignore it",(int32_t)pindexFork->GetHeight(),notarizedht,(int32_t)pindexOldTip->GetHeight(),notarizedht), REJECT_INVALID, "past-notarized-height"); } // - On ChainDB initialization, pindexOldTip will be null, so there are no removable blocks. @@ -6192,10 +6208,9 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth LogPrintf("No coin database inconsistencies in last %i blocks (%i transactions)\n", chainActive.Height() - pindexState->GetHeight(), nGoodTransactions); - if ( ASSETCHAINS_CC != 0 && lastSnapShotHeight == 0 ) + if ( ASSETCHAINS_CC != 0 && chainActive.Height() > KOMODO_SNAPSHOT_INTERVAL ) { - int32_t init_SS_height = chainActive.Height() - (chainActive.Height() % KOMODO_SNAPSHOT_INTERVAL); - if ( !komodo_dailysnapshot(init_SS_height) ) + if ( !komodo_dailysnapshot(chainActive.Height()) ) fprintf(stderr, "daily snapshot failed, please reindex your chain\n"); // maybe force shutdown here? } From 08cf556b4bbcb22d956ba0c58d389f5fe2ae7e2e Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Sun, 28 Apr 2019 15:08:27 +0800 Subject: [PATCH 163/242] dpow fix --- src/main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index f5b57b364..0fd9cc57e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4250,10 +4250,10 @@ static bool ActivateBestChainStep(bool fSkipdpow, CValidationState &state, CBloc // stay on the same chain tip! int32_t notarizedht,prevMoMheight; uint256 notarizedhash,txid; notarizedht = komodo_notarized_height(&prevMoMheight,¬arizedhash,&txid); - if ( !fSkipdpow && pindexFork != 0 && pindexFork->GetHeight() < notarizedht ) + if ( !fSkipdpow && pindexFork != 0 && pindexOldTip->GetHeight() > notarizedht && pindexFork->GetHeight() < notarizedht ) { - fprintf(stderr,"pindexFork->GetHeight().%d is < notarizedht %d, so ignore it\n",(int32_t)pindexFork->GetHeight(),notarizedht); - return state.DoS(100, error("ActivateBestChainStep(): pindexFork->GetHeight().%d is < notarizedht %d, so ignore it",(int32_t)pindexFork->GetHeight(),notarizedht), + fprintf(stderr,"pindexOldTip->GetHeight().%d > notarizedht %d && pindexFork->GetHeight().%d is < notarizedht %d, so ignore it\n",(int32_t)pindexFork->GetHeight(),notarizedht,(int32_t)pindexOldTip->GetHeight(),notarizedht); + return state.DoS(100, error("ActivateBestChainStep(): pindexOldTip->GetHeight().%d > notarizedht %d && pindexFork->GetHeight().%d is < notarizedht %d, so ignore it",(int32_t)pindexFork->GetHeight(),notarizedht,(int32_t)pindexOldTip->GetHeight(),notarizedht), REJECT_INVALID, "past-notarized-height"); } // - On ChainDB initialization, pindexOldTip will be null, so there are no removable blocks. From 79397bbe88b05a23be828430250967ab9eba0d8a Mon Sep 17 00:00:00 2001 From: dimxy Date: Mon, 29 Apr 2019 16:58:05 +0500 Subject: [PATCH 164/242] corrected costbasis is the latest minmax value --- src/cc/prices.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 3584190f0..1b174a770 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -775,17 +775,14 @@ int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t //else { //-> use the previous value // std::cerr << "prices_syntheticprofits() unchanged costbasis=" << costbasis << " price=" << price << " leverage=" << leverage << std::endl; //} - } else { if (height == firstheight + PRICES_DAYWINDOW) { // if costbasis not set, just set it - costbasis = price; - std::cerr << "prices_syntheticprofits() permanent costbasis=" << costbasis << " height=" << height << std::endl; - } - else { - // use provided costbasis - //std::cerr << "prices_syntheticprofits() provided costbasis=" << costbasis << " price=" << price << std::endl; + //costbasis = price; + + // use calculated minmax costbasis + std::cerr << "prices_syntheticprofits() use permanent costbasis=" << costbasis << " height=" << height << std::endl; } } From 2a0ae738743a250622b5d3f8266aa51b6878889c Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Mon, 29 Apr 2019 22:45:56 +0800 Subject: [PATCH 165/242] payments Airdrop. Working airdrop and syncs TESTHC chain. --- src/cc/CCPayments.h | 2 + src/cc/CCutils.cpp | 2 +- src/cc/eval.cpp | 9 + src/cc/payments.cpp | 541 +++++++++++++++++++++++++++++---------- src/main.cpp | 24 +- src/wallet/rpcwallet.cpp | 14 +- 6 files changed, 425 insertions(+), 167 deletions(-) diff --git a/src/cc/CCPayments.h b/src/cc/CCPayments.h index 3f5a10087..cff304a2e 100644 --- a/src/cc/CCPayments.h +++ b/src/cc/CCPayments.h @@ -18,6 +18,7 @@ #define CC_PAYMENTS_H #include "CCinclude.h" +#include #define PAYMENTS_TXFEE 10000 extern std::vector > vAddressSnapshot; @@ -34,3 +35,4 @@ UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr); UniValue PaymentsList(struct CCcontract_info *cp,char *jsonstr); #endif + diff --git a/src/cc/CCutils.cpp b/src/cc/CCutils.cpp index 65b390c41..acf0da766 100644 --- a/src/cc/CCutils.cpp +++ b/src/cc/CCutils.cpp @@ -74,7 +74,7 @@ CScript getCCopret(const CScript &scriptPubKey) { std::vector> vParams = std::vector>(); CScript dummy; CScript opret; - if ( scriptPubKey.IsPayToCryptoCondition(&dummy, vParams) ) + if ( scriptPubKey.IsPayToCryptoCondition(&dummy, vParams) && vParams.size() == 1 ) { //fprintf(stderr, "vparams.%s\n", HexStr(vParams[0].begin(), vParams[0].end()).c_str()); opret = CScript(vParams[0].begin()+6, vParams[0].end()); diff --git a/src/cc/eval.cpp b/src/cc/eval.cpp index 62f020063..a23a7b16c 100644 --- a/src/cc/eval.cpp +++ b/src/cc/eval.cpp @@ -53,6 +53,15 @@ bool RunCCEval(const CC *cond, const CTransaction &tx, unsigned int nIn) eval->state.GetRejectReason().data(), tx.vin[nIn].prevout.hash.GetHex().data()); if (eval->state.IsError()) fprintf(stderr, "Culprit: %s\n", EncodeHexTx(tx).data()); + CTransaction tmp; + if (mempool.lookup(tx.GetHash(), tmp)) + { + // This is to remove a payments airdrop if it gets stuck in the mempool. + // Miner will mine 1 invalid block, but doesnt stop them mining until a restart. + // This would almost never happen in normal use. + std::list dummy; + mempool.remove(tx,dummy,true); + } return false; } diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index 569c4eb14..e72184719 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -16,6 +16,14 @@ #include "CCPayments.h" /* +192.168.0.139: RH side screen. + ./komodod -ac_name=TESTDP -ac_supply=10000000 -ac_reward=1000000000 -ac_nk=96,5 -ac_blocktime=20 -ac_cc=2 -addndoe=192.168.0.112 + - TESTDP.tar saved after distributing funds randomly. approx block 120. +LH screen: + ./komodod -ac_name=TESTDP -ac_supply=10000000 -ac_reward=1000000000 -ac_nk=96,5 -ac_blocktime=20 -ac_cc=2 -pubkey=0244a96824fa317433f0eaa6d5b1faf68e802b1958df273c24cb82bce1ef8e1aec -gen -genproclimit=1 + +./komodo-cli -ac_name=TESTDP paymentsairdrop '[10,2000,500,"76a9149758abb81ee168dd3824cb55e94df509b35462d788ac",76a9144cfd873dadbfbb4b9c03e77ecaa6cfb74a484f4888ac"]' + use notarizations DB to scan back from the correct height, then undo ALL blocks back to this notarized height! payments airdrop: - extra RPC to merge all payments inputs to a single utxo, this must be called first and be confirmed before payments release, @@ -144,12 +152,53 @@ uint8_t DecodePaymentsOpRet(CScript scriptPubKey,int32_t &lockedblocks,int32_t & script = (uint8_t *)vopret.data(); if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> lockedblocks; ss >> minrelease; ss >> totalallocations; ss >> txidoprets) != 0 ) { - if ( e == EVAL_PAYMENTS && f == 'C' ) + if ( e == EVAL_PAYMENTS && f == 'C' && txidoprets.size() > 1 ) return(f); } return(0); } + +CScript EncodePaymentsSnapsShotOpRet(int32_t lockedblocks,int32_t minrelease,int32_t top,std::vector> excludeScriptPubKeys) +{ + CScript opret; uint8_t evalcode = EVAL_PAYMENTS; + opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'S' << lockedblocks << minrelease << top << excludeScriptPubKeys); + return(opret); +} + +uint8_t DecodePaymentsSnapsShotOpRet(CScript scriptPubKey,int32_t &lockedblocks,int32_t &minrelease,int32_t &top,std::vector> &excludeScriptPubKeys) +{ + std::vector vopret; uint8_t *script,e,f; + GetOpReturnData(scriptPubKey, vopret); + script = (uint8_t *)vopret.data(); + if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> lockedblocks; ss >> minrelease; ss >> top; ss >> excludeScriptPubKeys) != 0 ) + { + if ( e == EVAL_PAYMENTS && f == 'S' ) + return(f); + } + return(0); +} + +CScript EncodePaymentsTokensOpRet(int32_t lockedblocks,int32_t minrelease,int32_t top,std::vector> excludeScriptPubKeys, uint256 tokenid) +{ + CScript opret; uint8_t evalcode = EVAL_PAYMENTS; + opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'O' << lockedblocks << minrelease << top << excludeScriptPubKeys << tokenid); + return(opret); +} + +uint8_t DecodePaymentsTokensOpRet(CScript scriptPubKey,int32_t &lockedblocks,int32_t &minrelease,int32_t &top,std::vector> &excludeScriptPubKeys, uint256 &tokenid) +{ + std::vector vopret; uint8_t *script,e,f; + GetOpReturnData(scriptPubKey, vopret); + script = (uint8_t *)vopret.data(); + if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> lockedblocks; ss >> minrelease; ss >> top; ss >> excludeScriptPubKeys; ss >> tokenid) != 0 ) + { + if ( e == EVAL_PAYMENTS && f == 'O' ) + return(f); + } + return(0); +} + int64_t IsPaymentsvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v,char *cmpaddr) { char destaddr[64]; @@ -184,8 +233,10 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & // change is/must be in vout[0] // only 'F' or 1of2 txidaddr can be spent // all vouts must match exactly - char temp[128], coinaddr[64], txidaddr[64]; std::string scriptpubkey; uint256 createtxid, blockhash; CTransaction tmptx; + char temp[128], coinaddr[64], txidaddr[64]; std::string scriptpubkey; uint256 createtxid, blockhash, tokenid; CTransaction plantx; uint8_t funcid = 0; int32_t i,lockedblocks,minrelease; int64_t change,totalallocations; std::vector txidoprets; bool fHasOpret = false; CPubKey txidpk,Paymentspk; + int32_t top; std::vector> excludeScriptPubKeys; + mpz_t mpzTotalAllocations, mpzAllocation;; mpz_init(mpzTotalAllocations); // user marker vout to get the createtxid if ( tx.vout.size() < 2 ) return(eval->Invalid("not enough vouts")); @@ -200,13 +251,15 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & //printf("createtxid.%s\n",createtxid.ToString().c_str()); // use the createtxid to fetch the tx and all of the plans info. - if ( myGetTransaction(createtxid,tmptx,blockhash) != 0 ) - { - if ( tmptx.vout.size() > 0 && DecodePaymentsOpRet(tmptx.vout[tmptx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) != 0 ) + if ( myGetTransaction(createtxid,plantx,blockhash) != 0 && plantx.vout.size() > 0 ) + { + if ( ((funcid= DecodePaymentsOpRet(plantx.vout[plantx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets)) == 'C' || (funcid= DecodePaymentsSnapsShotOpRet(plantx.vout[plantx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys)) == 'S' || (funcid= DecodePaymentsTokensOpRet(plantx.vout[plantx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys,tokenid)) == 'O') ) { - if ( lockedblocks < 0 || minrelease < 0 || totalallocations <= 0 || txidoprets.size() < 2 ) + if ( lockedblocks < 0 || minrelease < 0 || totalallocations <= 0 ) return(eval->Invalid("negative values")); Paymentspk = GetUnspendable(cp,0); + txidpk = CCtxidaddr(txidaddr,createtxid); + GetCCaddress1of2(cp,coinaddr,Paymentspk,txidpk); //fprintf(stderr, "lockedblocks.%i minrelease.%i totalallocations.%i txidopret1.%s txidopret2.%s\n",lockedblocks, minrelease, totalallocations, txidoprets[0].ToString().c_str(), txidoprets[1].ToString().c_str() ); if ( !CheckTxFee(tx, PAYMENTS_TXFEE+1, chainActive.LastTip()->GetHeight(), chainActive.LastTip()->nTime) ) return eval->Invalid("txfee is too high"); @@ -215,65 +268,101 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & std::vector scriptPubKeys; int64_t checkallocations = 0; i = 0; - BOOST_FOREACH(const uint256& txidopret, txidoprets) + if ( funcid == 'C' ) { - CTransaction tx0; std::vector scriptPubKey,opret; int64_t allocation; - if ( myGetTransaction(txidopret,tx0,blockhash) != 0 && tx0.vout.size() > 1 && DecodePaymentsTxidOpRet(tx0.vout[tx0.vout.size()-1].scriptPubKey,allocation,scriptPubKey,opret) == 'T' ) + // normal payment + for (const uint256& txidopret : txidoprets) { - scriptPubKeys.push_back(CScript(scriptPubKey.begin(), scriptPubKey.end())); - allocations.push_back(allocation); - //fprintf(stderr, "i.%i scriptpubkey.%s allocation.%li\n",i,scriptPubKeys[i].ToString().c_str(),allocation); - checkallocations += allocation; - // if we have an op_return to pay to need to check it exists and is paying the correct opret. - if ( !opret.empty() ) + CTransaction tx0; std::vector scriptPubKey,opret; int64_t allocation; + if ( myGetTransaction(txidopret,tx0,blockhash) != 0 && tx0.vout.size() > 1 && DecodePaymentsTxidOpRet(tx0.vout[tx0.vout.size()-1].scriptPubKey,allocation,scriptPubKey,opret) == 'T' ) { - if ( !fHasOpret ) + scriptPubKeys.push_back(CScript(scriptPubKey.begin(), scriptPubKey.end())); + allocations.push_back(allocation); + //fprintf(stderr, "i.%i scriptpubkey.%s allocation.%li\n",i,scriptPubKeys[i].ToString().c_str(),allocation); + checkallocations += allocation; + // if we have an op_return to pay to need to check it exists and is paying the correct opret. + if ( !opret.empty() ) { - fprintf(stderr, "missing opret.%s in payments release.\n",HexStr(opret.begin(), opret.end()).c_str()); - return(eval->Invalid("missing opret in payments release")); - } - else if ( CScript(opret.begin(),opret.end()) != tx.vout[tx.vout.size()-1].scriptPubKey ) - { - fprintf(stderr, "opret.%s vs opret.%s\n",HexStr(opret.begin(), opret.end()).c_str(), HexStr(tx.vout[tx.vout.size()-1].scriptPubKey.begin(), tx.vout[tx.vout.size()-1].scriptPubKey.end()).c_str()); - return(eval->Invalid("pays incorrect opret")); + if ( !fHasOpret ) + { + fprintf(stderr, "missing opret.%s in payments release.\n",HexStr(opret.begin(), opret.end()).c_str()); + return(eval->Invalid("missing opret in payments release")); + } + else if ( CScript(opret.begin(),opret.end()) != tx.vout[tx.vout.size()-1].scriptPubKey ) + { + fprintf(stderr, "opret.%s vs opret.%s\n",HexStr(opret.begin(), opret.end()).c_str(), HexStr(tx.vout[tx.vout.size()-1].scriptPubKey.begin(), tx.vout[tx.vout.size()-1].scriptPubKey.end()).c_str()); + return(eval->Invalid("pays incorrect opret")); + } } } + i++; } - i++; + mpz_set_si(mpzTotalAllocations,totalallocations); + } + else if ( funcid == 'S' ) + { + // need time for TX to me mined before the next snapshot. + if ( top > 5000 ) + return(eval->Invalid("transaction too big")); + for ( auto address : vAddressSnapshot ) + { + CScript scriptPubKey = GetScriptForDestination(address.second); + for ( auto skipkey : excludeScriptPubKeys ) + { + //fprintf(stderr, "scriptpubkey.%s\n skipkey.%s", HexStr(scriptPubKey).c_str(), HexStr(CScript(skipkey.begin(), skipkey.end())).c_str()); + if ( scriptPubKey != CScript(skipkey.begin(), skipkey.end()) ) + { + mpz_init(mpzAllocation); + i++; + scriptPubKeys.push_back(scriptPubKey); + allocations.push_back(address.first); + mpz_set_si(mpzAllocation,address.first); + mpz_add(mpzTotalAllocations,mpzTotalAllocations,mpzAllocation); + mpz_clear(mpzAllocation); + } + } + if ( i == top ) // we reached top amount to pay, it can be less than this! + break; + } + if ( i != tx.vout.size()-2 ) + return(eval->Invalid("pays wrong amount of recipients")); + } + else if ( funcid == 'O' ) + { + // tokens snapshot. } - // sanity check to make sure we got all the required info + //fprintf(stderr, " allocations.size().%li scriptPubKeys.size.%li\n",allocations.size(), scriptPubKeys.size()); if ( allocations.size() == 0 || scriptPubKeys.size() == 0 || allocations.size() != scriptPubKeys.size() ) return(eval->Invalid("missing data cannot validate")); //fprintf(stderr, "totalallocations.%li checkallocations.%li\n",totalallocations, checkallocations); - if ( totalallocations != checkallocations ) + if ( funcid == 'C' && totalallocations != checkallocations ) // only check for normal payments release. return(eval->Invalid("allocation missmatch")); - - txidpk = CCtxidaddr(txidaddr,createtxid); - GetCCaddress1of2(cp,coinaddr,Paymentspk,txidpk); - //fprintf(stderr, "coinaddr.%s\n", coinaddr); - + // make sure change is in vout 0 and is paying to the contract address. if ( (change= IsPaymentsvout(cp,tx,0,coinaddr)) == 0 ) return(eval->Invalid("change is in wrong vout or is wrong tx type")); // Check vouts go to the right place and pay the right amounts. - int64_t amount = 0, checkamount; int32_t n = 0; + int64_t amount = 0, checkamount; int32_t n = 0; checkamount = tx.GetValueOut() - change - PAYMENTS_TXFEE; + mpz_t mpzCheckamount; mpz_init(mpzCheckamount); mpz_set_si(mpzCheckamount,checkamount); for (i = 1; i < (fHasOpret ? tx.vout.size()-2 : tx.vout.size()-1); i++) { - std::string destscriptPubKey = HexStr(scriptPubKeys[n].begin(),scriptPubKeys[n].end()); - std::string voutscriptPubKey = HexStr(tx.vout[i].scriptPubKey.begin(),tx.vout[i].scriptPubKey.end()); - if ( destscriptPubKey != voutscriptPubKey ) + if ( scriptPubKeys[n] != tx.vout[i].scriptPubKey ) { - fprintf(stderr, "pays wrong destination destscriptPubKey.%s voutscriptPubKey.%s\n", destscriptPubKey.c_str(), voutscriptPubKey.c_str()); + fprintf(stderr, "pays wrong destination destscriptPubKey.%s voutscriptPubKey.%s\n", HexStr(scriptPubKeys[n].begin(),scriptPubKeys[n].end()).c_str(), HexStr(tx.vout[i].scriptPubKey.begin(),tx.vout[i].scriptPubKey.end()).c_str()); return(eval->Invalid("pays wrong address")); } - int64_t test = allocations[n]; - test *= checkamount; - test /= totalallocations; - if ( test != tx.vout[i].nValue && test != tx.vout[i].nValue-1 ) + mpz_init(mpzAllocation); + mpz_set_si(mpzAllocation,allocations[n]); + mpz_mul(mpzAllocation,mpzAllocation,mpzCheckamount); + mpz_cdiv_q(mpzAllocation,mpzAllocation,mpzTotalAllocations); + int64_t test = mpz_get_si(mpzAllocation); + mpz_clear(mpzAllocation); + // Vairance of 1 sat is allowed, for rounding errors. + if ( test >= tx.vout[i].nValue+1 && test <= tx.vout[i].nValue-1 ) { fprintf(stderr, "vout.%i test.%li vs nVlaue.%li\n",i, test, tx.vout[i].nValue); return(eval->Invalid("amounts do not match")); @@ -281,6 +370,7 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & amount += tx.vout[i].nValue; n++; } + mpz_clear(mpzTotalAllocations); // This is a backup check to make sure there are no extra vouts paying something else! if ( checkamount != amount ) return(eval->Invalid("amounts do not match")); @@ -291,6 +381,7 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & return(eval->Invalid("amount is too small")); } + // Check vins i = 0; int32_t ht = chainActive.LastTip()->GetHeight(); BOOST_FOREACH(const CTxIn& vin, tx.vin) @@ -303,17 +394,12 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & Getscriptaddress(destaddr,txin.vout[vin.prevout.n].scriptPubKey); if ( strcmp(destaddr,coinaddr) != 0 ) { + // if does not come from address its in the global payments adddress and we need to check the opreturn. CScript opret; uint256 checktxid; int32_t opret_ind; if ( (opret_ind= has_opret(txin, EVAL_PAYMENTS)) == 0 ) - { - // get op_return from CCvout, - opret = getCCopret(txin.vout[vin.prevout.n].scriptPubKey); - } + opret = getCCopret(txin.vout[vin.prevout.n].scriptPubKey); // get op_return from CCvout, else - { - // get op_return from the op_return - opret = txin.vout[opret_ind].scriptPubKey; - } + opret = txin.vout[opret_ind].scriptPubKey; if ( DecodePaymentsFundOpRet(opret,checktxid) != 'F' || checktxid != createtxid ) { fprintf(stderr, "vin.%i is not a payments CC vout: txid.%s\n", i, txin.GetHash().ToString().c_str()); @@ -404,6 +490,7 @@ int64_t AddPaymentsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CP if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) ) break; } //else fprintf(stderr,"nValue %.8f vs threshold %.8f\n",(double)nValue/COIN,(double)threshold/COIN); + iter++; } } } @@ -482,8 +569,10 @@ int32_t payments_parsehexdata(std::vector &hexdata,cJSON *item,int32_t UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) { int32_t latestheight,nextheight = komodo_nextheight(); - CMutableTransaction tmpmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(),nextheight); UniValue result(UniValue::VOBJ); uint256 createtxid,hashBlock; - CTransaction tx,txO; CPubKey mypk,txidpk,Paymentspk; int32_t i,n,m,numoprets=0,lockedblocks,minrelease; int64_t newamount,inputsum,amount,CCchange=0,totalallocations,checkallocations=0,allocation; CTxOut vout; CScript onlyopret; char txidaddr[64],destaddr[64]; std::vector txidoprets; + CMutableTransaction tmpmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(),nextheight); UniValue result(UniValue::VOBJ); uint256 createtxid,hashBlock,tokenid; + CTransaction tx,txO; CPubKey mypk,txidpk,Paymentspk; int32_t i,n,m,numoprets=0,lockedblocks,minrelease; int64_t newamount,inputsum,amount,CCchange=0,totalallocations=0,checkallocations=0,allocation; CTxOut vout; CScript onlyopret; char txidaddr[64],destaddr[64]; std::vector txidoprets; + int32_t top; std::vector> excludeScriptPubKeys; int8_t funcid; + mpz_t mpzTotalAllocations; mpz_init(mpzTotalAllocations); cJSON *params = payments_reparse(&n,jsonstr); mypk = pubkey2pk(Mypubkey()); Paymentspk = GetUnspendable(cp,0); @@ -491,14 +580,16 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) { createtxid = payments_juint256(jitem(params,0)); amount = jdouble(jitem(params,1),0) * SATOSHIDEN + 0.0000000049; - if ( myGetTransaction(createtxid,tx,hashBlock) != 0 ) + if ( myGetTransaction(createtxid,tx,hashBlock) != 0 && tx.vout.size() > 0 ) { - if ( tx.vout.size() > 0 && DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) != 0 ) + if ( ((funcid= DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets)) == 'C' || (funcid= DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys)) == 'S' || (funcid= DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys,tokenid)) == 'O') ) { - if ( lockedblocks < 0 || minrelease < 0 || totalallocations <= 0 || txidoprets.size() < 2 ) + if ( lockedblocks < 0 || minrelease < 0 || totalallocations <= 0 ) { result.push_back(Pair("result","error")); result.push_back(Pair("error","negative parameter")); + if ( params != 0 ) + free_json(params); return(result); } latestheight = (nextheight - lockedblocks - 1); @@ -508,94 +599,163 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) result.push_back(Pair("error","amount too smal")); result.push_back(Pair("amount",ValueFromAmount(amount))); result.push_back(Pair("minrelease",ValueFromAmount(minrelease*COIN))); + if ( params != 0 ) + free_json(params); return(result); } txidpk = CCtxidaddr(txidaddr,createtxid); mtx.vout.push_back(MakeCC1of2vout(EVAL_PAYMENTS,0,Paymentspk,txidpk)); - m = txidoprets.size(); - for (i=0; i scriptPubKey,opret; - vout.nValue = 0; - if ( myGetTransaction(txidoprets[i],txO,hashBlock) != 0 && txO.vout.size() > 1 && DecodePaymentsTxidOpRet(txO.vout[txO.vout.size()-1].scriptPubKey,allocation,scriptPubKey,opret) == 'T' ) + // normal payments + for (i=0; i 0 ) + std::vector scriptPubKey,opret; + vout.nValue = 0; + if ( myGetTransaction(txidoprets[i],txO,hashBlock) != 0 && txO.vout.size() > 1 && DecodePaymentsTxidOpRet(txO.vout[txO.vout.size()-1].scriptPubKey,allocation,scriptPubKey,opret) == 'T' ) { - onlyopret.resize(opret.size()); - memcpy(&onlyopret[0],&opret[0],opret.size()); - numoprets++; + vout.nValue = allocation; + vout.scriptPubKey.resize(scriptPubKey.size()); + memcpy(&vout.scriptPubKey[0],&scriptPubKey[0],scriptPubKey.size()); + checkallocations += allocation; + if ( opret.size() > 0 ) + { + onlyopret.resize(opret.size()); + memcpy(&onlyopret[0],&opret[0],opret.size()); + numoprets++; + } + } else break; + mtx.vout.push_back(vout); + } + result.push_back(Pair("numoprets",(int64_t)numoprets)); + if ( i != m ) + { + result.push_back(Pair("result","error")); + result.push_back(Pair("error","invalid txidoprets[i]")); + result.push_back(Pair("txi",(int64_t)i)); + if ( params != 0 ) + free_json(params); + return(result); + } + else if ( checkallocations != totalallocations ) + { + result.push_back(Pair("result","error")); + result.push_back(Pair("error","totalallocations mismatch")); + result.push_back(Pair("checkallocations",(int64_t)checkallocations)); + result.push_back(Pair("totalallocations",(int64_t)totalallocations)); + if ( params != 0 ) + free_json(params); + return(result); + } + else if ( numoprets > 1 ) + { + result.push_back(Pair("result","error")); + result.push_back(Pair("error","too many oprets")); + if ( params != 0 ) + free_json(params); + return(result); + } + // set totalallocations to a mpz_t bignum, for amounts calculation later. + mpz_set_si(mpzTotalAllocations,totalallocations); + } + else if ( funcid = 'S' ) + { + // normal snapshot + i = 0; + if ( top > 5000 ) + { + // need to test the maximum number, this is an estimate. + result.push_back(Pair("result","error")); + result.push_back(Pair("error","cannot pay more than 5000 addresses")); + if ( params != 0 ) + free_json(params); + return(result); + } + for ( auto address : vAddressSnapshot ) + { + CScript scriptPubKey = GetScriptForDestination(address.second); + for ( auto skipkey : excludeScriptPubKeys ) + { + if ( scriptPubKey != CScript(skipkey.begin(), skipkey.end()) ) + { + mpz_t mpzAllocation; mpz_init(mpzAllocation); + i++; + //fprintf(stderr, "address: %s nValue.%li \n", CBitcoinAddress(address.second).ToString().c_str(), address.first); + vout.nValue = address.first; + vout.scriptPubKey = scriptPubKey; + mpz_set_si(mpzAllocation,address.first); + mpz_add(mpzTotalAllocations,mpzTotalAllocations,mpzAllocation); //totalallocations += address.first; + mtx.vout.push_back(vout); + mpz_clear(mpzAllocation); + } else fprintf(stderr, "SKIPPED::: %s\n", CBitcoinAddress(address.second).ToString().c_str()); } - } else break; - mtx.vout.push_back(vout); + if ( i == top ) // we reached top amount to pay, it can be less than this! + break; + } + m = i; // this is the amount we got, either top, or all of the address on the chain. } - result.push_back(Pair("numoprets",(int64_t)numoprets)); - if ( i != m ) + else if ( funcid = 'O' ) { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","invalid txidoprets[i]")); - result.push_back(Pair("txi",(int64_t)i)); - if ( params != 0 ) - free_json(params); - return(result); - } - else if ( checkallocations != totalallocations ) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","totalallocations mismatch")); - result.push_back(Pair("checkallocations",(int64_t)checkallocations)); - result.push_back(Pair("totalallocations",(int64_t)totalallocations)); - if ( params != 0 ) - free_json(params); - return(result); - } - else if ( numoprets > 1 ) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","too many oprets")); - if ( params != 0 ) - free_json(params); - return(result); + // token snapshot } newamount = amount; + int64_t totalamountsent = 0; + mpz_t mpzAmount; mpz_init(mpzAmount); mpz_set_si(mpzAmount,amount); for (i=0; i= newamount+2*PAYMENTS_TXFEE ) - { - std::string rawtx; - if ( (CCchange= (inputsum - newamount - 2*PAYMENTS_TXFEE)) >= PAYMENTS_TXFEE ) - mtx.vout[0].nValue = CCchange; - mtx.vout.push_back(CTxOut(PAYMENTS_TXFEE,CScript() << ParseHex(HexStr(txidpk)) << OP_CHECKSIG)); - GetCCaddress1of2(cp,destaddr,Paymentspk,txidpk); - CCaddr1of2set(cp,Paymentspk,txidpk,cp->CCpriv,destaddr); - rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,onlyopret); - if ( params != 0 ) - free_json(params); - result.push_back(Pair("amount",ValueFromAmount(amount))); - result.push_back(Pair("newamount",ValueFromAmount(newamount))); - return(payments_rawtxresult(result,rawtx,1)); - } - else - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","couldnt find enough locked funds")); - } + //fprintf(stderr, "newamount.%li totalamountsent.%li\n", newamount, totalamountsent); + mpz_clear(mpzAmount); mpz_clear(mpzTotalAllocations); } else { result.push_back(Pair("result","error")); result.push_back(Pair("error","couldnt decode paymentscreate txid opret")); + if ( params != 0 ) + free_json(params); + return(result); + } + if ( (inputsum= AddPaymentsInputs(cp,mtx,txidpk,newamount+2*PAYMENTS_TXFEE,CC_MAXVINS/2,createtxid,latestheight)) >= newamount+2*PAYMENTS_TXFEE ) + { + std::string rawtx; + if ( (CCchange= (inputsum - newamount - 2*PAYMENTS_TXFEE)) >= PAYMENTS_TXFEE ) + mtx.vout[0].nValue = CCchange; + mtx.vout.push_back(CTxOut(PAYMENTS_TXFEE,CScript() << ParseHex(HexStr(txidpk)) << OP_CHECKSIG)); + GetCCaddress1of2(cp,destaddr,Paymentspk,txidpk); + CCaddr1of2set(cp,Paymentspk,txidpk,cp->CCpriv,destaddr); + rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,onlyopret); + if ( params != 0 ) + free_json(params); + result.push_back(Pair("amount",ValueFromAmount(amount))); + result.push_back(Pair("newamount",ValueFromAmount(newamount))); + return(payments_rawtxresult(result,rawtx,0)); + } + else + { + result.push_back(Pair("result","error")); + result.push_back(Pair("error","couldnt find enough locked funds")); } } else @@ -618,6 +778,8 @@ UniValue PaymentsFund(struct CCcontract_info *cp,char *jsonstr) { CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); UniValue result(UniValue::VOBJ); CPubKey Paymentspk,mypk,txidpk; uint256 txid,hashBlock; int64_t amount,totalallocations; CScript opret; CTransaction tx; char txidaddr[64]; std::string rawtx; int32_t n,useopret = 0,lockedblocks,minrelease; std::vector txidoprets; + int32_t top; std::vector> excludeScriptPubKeys; // snapshot + uint256 tokenid; cJSON *params = payments_reparse(&n,jsonstr); mypk = pubkey2pk(Mypubkey()); Paymentspk = GetUnspendable(cp,0); @@ -627,14 +789,14 @@ UniValue PaymentsFund(struct CCcontract_info *cp,char *jsonstr) amount = jdouble(jitem(params,1),0) * SATOSHIDEN + 0.0000000049; if ( n == 3 ) useopret = jint(jitem(params,2),0) != 0; - if ( myGetTransaction(txid,tx,hashBlock) == 0 || tx.vout.size() == 1 || DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) == 0 ) + if ( myGetTransaction(txid,tx,hashBlock) == 0 || tx.vout.size() == 1 || (DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) == 0 && DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys) == 0 && DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys,tokenid) == 0) ) { result.push_back(Pair("result","error")); result.push_back(Pair("error","invalid createtxid")); } else if ( AddNormalinputs(mtx,mypk,amount+PAYMENTS_TXFEE,60) > 0 ) { - if ( lockedblocks < 0 || minrelease < 0 || totalallocations <= 0 || txidoprets.size() < 2 ) + if ( lockedblocks < 0 || minrelease < 0 || totalallocations <= 0 ) { result.push_back(Pair("result","error")); result.push_back(Pair("error","negative parameter")); @@ -650,13 +812,13 @@ UniValue PaymentsFund(struct CCcontract_info *cp,char *jsonstr) else { mtx.vout.push_back(MakeCC1vout(EVAL_PAYMENTS,amount,Paymentspk)); + opret = EncodePaymentsFundOpRet(txid); // Use the below one along with other FinalizeCCTx/return, to get the ccvout scriptpubkey - /*opret = EncodePaymentsFundOpRet(txid); - std::vector> vData = std::vector>(); + /*std::vector> vData = std::vector>(); if ( makeCCopret(opret, vData) ) mtx.vout.push_back(MakeCC1vout(EVAL_PAYMENTS,amount,Paymentspk,&vData)); */ } - rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,EncodePaymentsFundOpRet(txid)); + rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,opret); //rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,CScript()); // use this one to get ccvout scriptpubkey. if ( params != 0 ) free_json(params); @@ -796,22 +958,73 @@ UniValue PaymentsCreate(struct CCcontract_info *cp,char *jsonstr) UniValue PaymentsAirdrop(struct CCcontract_info *cp,char *jsonstr) { - uint64_t start = time(NULL); - - return(time(NULL)-start); + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + UniValue result(UniValue::VOBJ); + uint256 hashBlock; CTransaction tx; CPubKey Paymentspk,mypk; char markeraddr[64]; std::string rawtx; + int32_t lockedblocks,minrelease,top,n,i; std::vector> excludeScriptPubKeys; + cJSON *params = payments_reparse(&n,jsonstr); + if ( params != 0 && n >= 4 ) + { + lockedblocks = juint(jitem(params,0),0); + minrelease = juint(jitem(params,1),0); + top = juint(jitem(params,2),0); + if ( lockedblocks < 0 || minrelease < 0 || top < 0 ) + { + result.push_back(Pair("result","error")); + result.push_back(Pair("error","negative parameter")); + if ( params != 0 ) + free_json(params); + return(result); + } + for (i=0; i scriptPubKey; + int32_t len = strlen(inputhex)/2; + scriptPubKey.resize(len); + decode_hex((uint8_t *)scriptPubKey.data(),len,(char *)inputhex); + excludeScriptPubKeys.push_back(scriptPubKey); + } + mypk = pubkey2pk(Mypubkey()); + Paymentspk = GetUnspendable(cp,0); + if ( AddNormalinputs(mtx,mypk,2*PAYMENTS_TXFEE,60) > 0 ) + { + mtx.vout.push_back(MakeCC1of2vout(cp->evalcode,PAYMENTS_TXFEE,Paymentspk,Paymentspk)); + rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,EncodePaymentsSnapsShotOpRet(lockedblocks,minrelease,top,excludeScriptPubKeys)); + if ( params != 0 ) + free_json(params); + return(payments_rawtxresult(result,rawtx,0)); + } + result.push_back(Pair("result","error")); + result.push_back(Pair("error","not enough normal funds")); + } + else + { + result.push_back(Pair("result","error")); + result.push_back(Pair("error","parameters error")); + } + if ( params != 0 ) + free_json(params); + return(result); } UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr) { UniValue result(UniValue::VOBJ),a(UniValue::VARR); CTransaction tx,txO; CPubKey Paymentspk,txidpk; int32_t i,j,n,flag=0,numoprets=0,lockedblocks,minrelease; std::vector txidoprets; int64_t funds,fundsopret,totalallocations=0,allocation; char fundsaddr[64],fundsopretaddr[64],txidaddr[64],*outstr; uint256 createtxid,hashBlock; + int32_t top; std::vector> excludeScriptPubKeys; // snapshot + uint256 tokenid; cJSON *params = payments_reparse(&n,jsonstr); if ( params != 0 && n == 1 ) { Paymentspk = GetUnspendable(cp,0); createtxid = payments_juint256(jitem(params,0)); - if ( myGetTransaction(createtxid,tx,hashBlock) != 0 ) + if ( myGetTransaction(createtxid,tx,hashBlock) != 0 && tx.vout.size() > 0 ) { - if ( tx.vout.size() > 0 && DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) != 0 ) + if ( DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) != 0 ) { if ( lockedblocks < 0 || minrelease < 0 || totalallocations <= 0 || txidoprets.size() < 2 ) { @@ -821,6 +1034,7 @@ UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr) free_json(params); return(result); } + result.push_back(Pair("plan_type","payments")); result.push_back(Pair("lockedblocks",(int64_t)lockedblocks)); result.push_back(Pair("totalallocations",(int64_t)totalallocations)); result.push_back(Pair("minrelease",(int64_t)minrelease)); @@ -849,29 +1063,71 @@ UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr) } else fprintf(stderr,"error decoding voutsize.%d\n",(int32_t)txO.vout.size()); a.push_back(obj); } - flag++; result.push_back(Pair("numoprets",(int64_t)numoprets)); if ( numoprets > 1 ) { + flag++; result.push_back(Pair("result","error")); result.push_back(Pair("error","too many opreturns")); - } - else + } else result.push_back(Pair("txidoprets",a)); + } + else if ( DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys) != 0 ) + { + if ( lockedblocks < 0 || minrelease < 0 || top <= 0 ) { - result.push_back(Pair("txidoprets",a)); - txidpk = CCtxidaddr(txidaddr,createtxid); - GetCCaddress1of2(cp,fundsaddr,Paymentspk,txidpk); - funds = CCaddress_balance(fundsaddr,1); - result.push_back(Pair(fundsaddr,ValueFromAmount(funds))); - GetCCaddress(cp,fundsopretaddr,Paymentspk); - fundsopret = CCaddress_balance(fundsopretaddr,1); // Shows balance for ALL payments plans, not just the one asked for! - result.push_back(Pair(fundsopretaddr,ValueFromAmount(fundsopret))); - result.push_back(Pair("totalfunds",ValueFromAmount(funds+fundsopret))); - result.push_back(Pair("result","success")); + result.push_back(Pair("result","error")); + result.push_back(Pair("error","negative parameter")); + if ( params != 0 ) + free_json(params); + return(result); } + result.push_back(Pair("plan_type","snapshot")); + result.push_back(Pair("lockedblocks",(int64_t)lockedblocks)); + result.push_back(Pair("minrelease",(int64_t)minrelease)); + result.push_back(Pair("top",(int64_t)top)); + for ( auto scriptPubKey : excludeScriptPubKeys ) + a.push_back(HexStr(scriptPubKey.begin(),scriptPubKey.end())); + result.push_back(Pair("excludeScriptPubkeys",a)); + } + else if ( DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys,tokenid) != 0 ) + { + if ( lockedblocks < 0 || minrelease < 0 || top <= 0 ) + { + result.push_back(Pair("result","error")); + result.push_back(Pair("error","negative parameter")); + if ( params != 0 ) + free_json(params); + return(result); + } + result.push_back(Pair("plan_type","token snapshot")); + result.push_back(Pair("lockedblocks",(int64_t)lockedblocks)); + result.push_back(Pair("minrelease",(int64_t)minrelease)); + result.push_back(Pair("top",(int64_t)top)); + result.push_back(Pair("tokenid",tokenid.ToString())); + for ( auto scriptPubKey : excludeScriptPubKeys ) + a.push_back(HexStr(scriptPubKey.begin(),scriptPubKey.end())); + result.push_back(Pair("excludeScriptPubkeys",a)); + } + else + { + result.push_back(Pair("result","error")); + result.push_back(Pair("error","couldnt decode valid payments create txid opreturn")); + } + if ( flag == 0 ) + { + txidpk = CCtxidaddr(txidaddr,createtxid); + GetCCaddress1of2(cp,fundsaddr,Paymentspk,txidpk); + funds = CCaddress_balance(fundsaddr,1); + result.push_back(Pair(fundsaddr,ValueFromAmount(funds))); + GetCCaddress(cp,fundsopretaddr,Paymentspk); + // TODO: Shows balance for ALL payments plans, not just the one asked for! Needs to be reworked. + fundsopret = CCaddress_balance(fundsopretaddr,1); + result.push_back(Pair(fundsopretaddr,ValueFromAmount(fundsopret))); + result.push_back(Pair("totalfunds",ValueFromAmount(funds+fundsopret))); + result.push_back(Pair("result","success")); } } - if ( flag == 0 ) + else { result.push_back(Pair("result","error")); result.push_back(Pair("error","couldnt find valid payments create txid")); @@ -889,8 +1145,9 @@ UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr) UniValue PaymentsList(struct CCcontract_info *cp,char *jsonstr) { - std::vector > addressIndex; uint256 txid,hashBlock; + std::vector > addressIndex; uint256 txid,hashBlock,tokenid; UniValue result(UniValue::VOBJ),a(UniValue::VARR); char markeraddr[64],str[65]; CPubKey Paymentspk; CTransaction tx; int32_t lockedblocks,minrelease; std::vector txidoprets; int64_t totalallocations; + int32_t top; std::vector> excludeScriptPubKeys; Paymentspk = GetUnspendable(cp,0); GetCCaddress1of2(cp,markeraddr,Paymentspk,Paymentspk); SetCCtxids(addressIndex,markeraddr,true); @@ -899,7 +1156,7 @@ UniValue PaymentsList(struct CCcontract_info *cp,char *jsonstr) txid = it->first.txhash; if ( it->first.index == 0 && myGetTransaction(txid,tx,hashBlock) != 0 ) { - if ( tx.vout.size() > 0 && DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) == 'C' ) + if ( tx.vout.size() > 0 && (DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) == 'C' || DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys) == 'S' || DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys,tokenid) == 'O') ) { if ( lockedblocks < 0 || minrelease < 0 || totalallocations <= 0 || txidoprets.size() < 2 ) { diff --git a/src/main.cpp b/src/main.cpp index 8bace2cb0..3168b773c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -656,6 +656,7 @@ std::vector > vAddressSnapshot; bool komodo_dailysnapshot(int32_t height) { + int reorglimit = 10; // CHANGE BACK TO 100 AFTER TESTING! uint256 notarized_hash,notarized_desttxid; int32_t prevMoMheight,notarized_height,undo_height,extraoffset; if ( (extraoffset= height % KOMODO_SNAPSHOT_INTERVAL) != 0 ) { @@ -663,25 +664,16 @@ bool komodo_dailysnapshot(int32_t height) // use the notarizationsDB to scan back from the consesnus height to get the offset we need. std::string symbol; Notarisation nota; symbol.assign(ASSETCHAINS_SYMBOL); - ScanNotarisationsDB(height-extraoffset, symbol, 100, nota); - undo_height = nota.second.height; - if ( undo_height == 0 ) undo_height = height-extraoffset-100; - fprintf(stderr, "height.%i-extraoffset.%i = startscanfrom.%i to get undo_height.%i\n", height, extraoffset, height-extraoffset, undo_height); + if ( ScanNotarisationsDB(height-extraoffset, symbol, 100, nota) == 0 ) + undo_height = height-extraoffset-reorglimit; + else undo_height = nota.second.height; + //fprintf(stderr, "height.%i-extraoffset.%i = startscanfrom.%i to get undo_height.%i\n", height, extraoffset, height-extraoffset, undo_height); } else { // we are at the right height in connect block to scan back to last notarized height. notarized_height = komodo_notarized_height(&prevMoMheight,¬arized_hash,¬arized_desttxid); - if ( notarized_height > height-100 ) - { - // notarized height is higher than 100 blocks before this height, so snapshot the notarized height. - undo_height = notarized_height; - } - else - { - //snapshot 100 blocks ago. Could still be reorged but very unlikley and expensive to carry out constantly. - undo_height = height-100; - } + notarized_height > height-100 ? undo_height = notarized_height : undo_height = height-reorglimit; } fprintf(stderr, "doing snapshot for height.%i undo_height.%i\n", height, undo_height); // if we already did this height dont bother doing it again, this is just a reorg. The actual snapshot height cannot be reorged. @@ -702,9 +694,7 @@ bool komodo_dailysnapshot(int32_t height) for (int32_t i = block.vtx.size() - 1; i >= 0; i--) { const CTransaction &tx = block.vtx[i]; - uint256 hash = tx.GetHash(); CTxDestination vDest; - //fprintf(stderr, "undong tx.%s\n",hash.GetHex().c_str()); // loop vouts reverse order, remove value recieved. for (unsigned int k = tx.vout.size(); k-- > 0;) { @@ -721,7 +711,7 @@ bool komodo_dailysnapshot(int32_t height) for (unsigned int j = tx.vin.size(); j-- > 0;) { uint256 blockhash; CTransaction txin; - if ( !tx.IsCoinImport() && !tx.IsCoinBase() && myGetTransaction(tx.vin[j].prevout.hash,txin,blockhash) ) // myGetTransaction! + if ( !tx.IsCoinImport() && !tx.IsCoinBase() && myGetTransaction(tx.vin[j].prevout.hash,txin,blockhash) ) { int vout = tx.vin[j].prevout.n; if ( ExtractDestination(txin.vout[vout].scriptPubKey, vDest) ) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 66c534f11..8733b2894 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5632,14 +5632,14 @@ UniValue payments_create(const UniValue& params, bool fHelp) UniValue payments_airdrop(const UniValue& params, bool fHelp) { struct CCcontract_info *cp,C; - //if ( fHelp || params.size() != 1 ) - // throw runtime_error("paymentscreate \"[lockedblocks,minamount,%22paytxid0%22,...,%22paytxidN%22]\"\n"); - //if ( ensure_CCrequirements(EVAL_PAYMENTS) < 0 ) - // throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); - //const CKeyStore& keystore = *pwalletMain; + if ( fHelp || params.size() != 1 ) + throw runtime_error("paymentsairdrop \"[lockedblocks,minamount,top,%22paytxid0%22,...,%22paytxidN%22]\"\n"); + if ( ensure_CCrequirements(EVAL_PAYMENTS) < 0 ) + throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + const CKeyStore& keystore = *pwalletMain; LOCK2(cs_main, pwalletMain->cs_wallet); - //cp = CCinit(&C,EVAL_PAYMENTS); - return(PaymentsAirdrop(0,(char *)params[0].get_str().c_str())); + cp = CCinit(&C,EVAL_PAYMENTS); + return(PaymentsAirdrop(cp,(char *)params[0].get_str().c_str())); } UniValue payments_info(const UniValue& params, bool fHelp) From 5e93f5d3b78fb75bf9fea5cc186cb6121e7f5a72 Mon Sep 17 00:00:00 2001 From: dimxy Date: Mon, 29 Apr 2019 20:04:21 +0500 Subject: [PATCH 166/242] satoshiden to prices_normfactor (signed) --- src/cc/CCPrices.h | 4 +++- src/cc/prices.cpp | 37 +++++++++++++++++++------------------ 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/cc/CCPrices.h b/src/cc/CCPrices.h index 900ee7505..9bcae60b2 100644 --- a/src/cc/CCPrices.h +++ b/src/cc/CCPrices.h @@ -35,7 +35,9 @@ int32_t komodo_priceget(int64_t *buf64,int32_t ind,int32_t height,int32_t numblo #define PRICES_MMD (KOMODO_MAXPRICES * 6) // 0011 0000 0000 0000 #define PRICES_MMM (KOMODO_MAXPRICES * 7) // 0011 1000 0000 0000 #define PRICES_DDD (KOMODO_MAXPRICES * 8) // 0100 0000 0000 0000 -#define PRICES_NORMFACTOR 10000 + +#define PRICES_NORMFACTOR (int64_t)(SATOSHIDEN) +#define PRICES_POINTFACTOR (int64_t)10000 bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn); diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 1b174a770..4be0afd4e 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -640,7 +640,7 @@ int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t if (depth >= 2) { b = pricestack[--depth]; a = pricestack[--depth]; - pricestack[depth++] = (a * b) / SATOSHIDEN; + pricestack[depth++] = (a * b) / PRICES_NORMFACTOR; } else errcode = -3; @@ -650,7 +650,7 @@ int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t if (depth >= 2) { b = pricestack[--depth]; a = pricestack[--depth]; - pricestack[depth++] = (a * SATOSHIDEN) / b; + pricestack[depth++] = (a * PRICES_NORMFACTOR) / b; } else errcode = -4; @@ -659,7 +659,7 @@ int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t case PRICES_INV: if (depth >= 1) { a = pricestack[--depth]; - pricestack[depth++] = (SATOSHIDEN * SATOSHIDEN) / a; + pricestack[depth++] = (PRICES_NORMFACTOR * PRICES_NORMFACTOR) / a; } else errcode = -5; @@ -670,7 +670,7 @@ int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t c = pricestack[--depth]; b = pricestack[--depth]; a = pricestack[--depth]; - pricestack[depth++] = (((a * SATOSHIDEN) / b) * SATOSHIDEN) / c; + pricestack[depth++] = (((a * PRICES_NORMFACTOR) / b) * PRICES_NORMFACTOR) / c; } else errcode = -6; @@ -692,7 +692,7 @@ int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t c = pricestack[--depth]; b = pricestack[--depth]; a = pricestack[--depth]; - pricestack[depth++] = ((a * b) / SATOSHIDEN) * c; + pricestack[depth++] = ((a * b) / PRICES_NORMFACTOR) * c; } else errcode = -8; @@ -703,7 +703,7 @@ int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t c = pricestack[--depth]; b = pricestack[--depth]; a = pricestack[--depth]; - pricestack[depth++] = (((((SATOSHIDEN * SATOSHIDEN) / a) * SATOSHIDEN) / b) * SATOSHIDEN) / c; + pricestack[depth++] = (((((PRICES_NORMFACTOR * PRICES_NORMFACTOR) / a) * PRICES_NORMFACTOR) / b) * PRICES_NORMFACTOR) / c; } else errcode = -9; @@ -716,7 +716,7 @@ int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t if (errcode != 0) break; - std::cerr << "pricestack[depth=" << depth << "]=" << pricestack[depth] << std::endl; + std::cerr << "top pricestack[depth-1=" << depth-1 << "]=" << pricestack[depth-1] << std::endl; } free(pricedata); @@ -759,8 +759,8 @@ int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t } // clear lowest positions: - price /= PRICES_NORMFACTOR; - price *= PRICES_NORMFACTOR; + price /= PRICES_POINTFACTOR; + price *= PRICES_POINTFACTOR; outprice = price; if (minmax) { // if we are within day window, set temp costbasis to max (or min) price value @@ -787,17 +787,17 @@ int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t } // normalize to 10,000,000 to prevent underflow - profits = costbasis > 0 ? (((price / PRICES_NORMFACTOR * SATOSHIDEN) / costbasis) - SATOSHIDEN / PRICES_NORMFACTOR) * PRICES_NORMFACTOR : 0; + profits = costbasis > 0 ? (((price / PRICES_POINTFACTOR * PRICES_NORMFACTOR) / costbasis) - PRICES_NORMFACTOR / PRICES_POINTFACTOR) * PRICES_POINTFACTOR : 0; - //std::cerr << "prices_syntheticprofits() test value1 (price/PRICES_NORMFACTOR * SATOSHIDEN)=" << (price / PRICES_NORMFACTOR * SATOSHIDEN) << std::endl; - std::cerr << "prices_syntheticprofits() test value2 (price/PRICES_NORMFACTOR * SATOSHIDEN)/costbasis=" << (costbasis != 0 ? (price / PRICES_NORMFACTOR * SATOSHIDEN)/costbasis : 0) << std::endl; + //std::cerr << "prices_syntheticprofits() test value1 (price/PRICES_POINTFACTOR * PRICES_NORMFACTOR)=" << (price / PRICES_POINTFACTOR * PRICES_NORMFACTOR) << std::endl; + std::cerr << "prices_syntheticprofits() test value2 (price/PRICES_POINTFACTOR * PRICES_NORMFACTOR)/costbasis=" << (costbasis != 0 ? (price / PRICES_POINTFACTOR * PRICES_NORMFACTOR)/costbasis : 0) << std::endl; std::cerr << "prices_syntheticprofits() fractional profits=" << profits << std::endl; //std::cerr << "prices_syntheticprofits() profits double=" << (double)price / (double)costbasis -1.0 << std::endl; //double dprofits = (double)price / (double)costbasis - 1.0; profits *= ((int64_t)leverage * (int64_t)positionsize); - profits /= (int64_t)SATOSHIDEN; // de-normalize + profits /= (int64_t)PRICES_NORMFACTOR; // de-normalize //dprofits *= leverage * positionsize; std::cerr << "prices_syntheticprofits() profits=" << profits << std::endl; @@ -892,6 +892,7 @@ int64_t prices_enumaddedbets(uint256 &batontxid, std::vector &bets, uin EvalRef eval; if ((isLoaded = eval->GetTxConfirmed(batontxid, txBaton, blockIdx)) && + blockIdx.IsValid() && txBaton.vout.size() > 0 && (funcId = prices_addopretdecode(txBaton.vout.back().scriptPubKey, bettxidInOpret, pk, amount)) != 0) { @@ -1334,22 +1335,22 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) for (auto b : bets) { totalbets += b.amount; totalprofits += b.profits; - costbasis += b.amount * (b.costbasis / PRICES_NORMFACTOR); // prevent int64 overflow - std::cerr << "PricesInfo() acc costbasis=" << costbasis << " b.amount=" << b.amount << " b.costbasis/PRICES_NORMFACTOR=" << (b.costbasis / PRICES_NORMFACTOR) << std::endl; + costbasis += b.amount * (b.costbasis / PRICES_POINTFACTOR); // prevent int64 overflow + std::cerr << "PricesInfo() acc costbasis=" << costbasis << " b.amount=" << b.amount << " b.costbasis/PRICES_POINTFACTOR=" << (b.costbasis / PRICES_POINTFACTOR) << std::endl; } int64_t equity = totalbets + totalprofits; if (totalbets != 0) { //prevent zero div costbasis /= totalbets; - costbasis *= PRICES_NORMFACTOR; //denormalization, last posiitons should be == 0000 + costbasis *= PRICES_POINTFACTOR; //denormalization, last posiitons should be == 0000 } else costbasis = 0; int64_t liqprice; if (leverage != 0) {// prevent zero div liqprice = costbasis - costbasis / leverage; - liqprice /= PRICES_NORMFACTOR; - liqprice *= PRICES_NORMFACTOR; // last posiitons should be == 0000 + liqprice /= PRICES_POINTFACTOR; + liqprice *= PRICES_POINTFACTOR; // last posiitons should be == 0000 } else liqprice = 0; From b4a112888b0d882e5a56f77c777668785563d3bd Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Tue, 30 Apr 2019 00:12:00 +0800 Subject: [PATCH 167/242] fix tx expiry height, to 200 blocks --- src/main.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.h b/src/main.h index ec36c976b..d507f9dd6 100644 --- a/src/main.h +++ b/src/main.h @@ -88,7 +88,7 @@ static const unsigned int DEFAULT_MIN_RELAY_TX_FEE = 100; /** Default for -maxorphantx, maximum number of orphan transactions kept in memory */ static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100; /** Default for -txexpirydelta, in number of blocks */ -static const unsigned int DEFAULT_TX_EXPIRY_DELTA = 20; +static const unsigned int DEFAULT_TX_EXPIRY_DELTA = 200; /** The maximum size of a blk?????.dat file (since 0.8) */ static const unsigned int MAX_BLOCKFILE_SIZE = 0x8000000; // 128 MiB static const unsigned int MAX_TEMPFILE_SIZE = 0x1000000; // 16 MiB 0x8000000 From 13a1463f02ea6358a49216bfff379babb60253a3 Mon Sep 17 00:00:00 2001 From: dimxy Date: Mon, 29 Apr 2019 21:23:46 +0500 Subject: [PATCH 168/242] removed clearing precision to 0.0001 --- src/cc/prices.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 4be0afd4e..302777f84 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -716,7 +716,10 @@ int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t if (errcode != 0) break; - std::cerr << "top pricestack[depth-1=" << depth-1 << "]=" << pricestack[depth-1] << std::endl; + if( depth >= 0 ) + std::cerr << "top pricestack[depth-1=" << depth-1 << "]=" << pricestack[depth-1] << std::endl; + else + std::cerr << "pricestack empty" << std::endl; } free(pricedata); @@ -759,8 +762,8 @@ int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t } // clear lowest positions: - price /= PRICES_POINTFACTOR; - price *= PRICES_POINTFACTOR; + //price /= PRICES_POINTFACTOR; + //price *= PRICES_POINTFACTOR; outprice = price; if (minmax) { // if we are within day window, set temp costbasis to max (or min) price value From 911462d1aae3734d68ac31cf918afbd5fef7b477 Mon Sep 17 00:00:00 2001 From: dimxy Date: Mon, 29 Apr 2019 21:30:28 +0500 Subject: [PATCH 169/242] remove clearing prec in pricesinfo --- src/cc/prices.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 302777f84..79a217f16 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1352,8 +1352,8 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) int64_t liqprice; if (leverage != 0) {// prevent zero div liqprice = costbasis - costbasis / leverage; - liqprice /= PRICES_POINTFACTOR; - liqprice *= PRICES_POINTFACTOR; // last posiitons should be == 0000 + //liqprice /= PRICES_POINTFACTOR; + //liqprice *= PRICES_POINTFACTOR; // last posiitons should be == 0000 } else liqprice = 0; From d81d30a27c38cacb2fd2e74d20d4a2928ddec536 Mon Sep 17 00:00:00 2001 From: dimxy Date: Mon, 29 Apr 2019 21:35:58 +0500 Subject: [PATCH 170/242] corr costbasis prec in pricesinfo --- src/cc/prices.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 79a217f16..30149244a 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1344,8 +1344,8 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) int64_t equity = totalbets + totalprofits; if (totalbets != 0) { //prevent zero div + costbasis *= PRICES_POINTFACTOR; // save last 0.0000xxxx positions costbasis /= totalbets; - costbasis *= PRICES_POINTFACTOR; //denormalization, last posiitons should be == 0000 } else costbasis = 0; From 0467d13a107548a613f09cc7e598086ea91535db Mon Sep 17 00:00:00 2001 From: dimxy Date: Mon, 29 Apr 2019 21:50:55 +0500 Subject: [PATCH 171/242] try use floating point to calc average costbasis --- src/cc/prices.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 30149244a..6066100a9 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1334,18 +1334,20 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) int64_t totalbets = 0; int64_t totalprofits = 0; - int64_t costbasis = 0; + double dcostbasis = 0.0; for (auto b : bets) { totalbets += b.amount; totalprofits += b.profits; - costbasis += b.amount * (b.costbasis / PRICES_POINTFACTOR); // prevent int64 overflow - std::cerr << "PricesInfo() acc costbasis=" << costbasis << " b.amount=" << b.amount << " b.costbasis/PRICES_POINTFACTOR=" << (b.costbasis / PRICES_POINTFACTOR) << std::endl; + dcostbasis += b.amount * b.costbasis; + // costbasis += b.amount * (b.costbasis / PRICES_POINTFACTOR); // prevent int64 overflow (but we have underflow for 1/BTC) + // std::cerr << "PricesInfo() acc costbasis=" << costbasis << " b.amount=" << b.amount << " b.costbasis/PRICES_POINTFACTOR=" << (b.costbasis / PRICES_POINTFACTOR) << std::endl; } int64_t equity = totalbets + totalprofits; + int64_t costbasis; if (totalbets != 0) { //prevent zero div - costbasis *= PRICES_POINTFACTOR; // save last 0.0000xxxx positions - costbasis /= totalbets; + // costbasis *= PRICES_POINTFACTOR; // save last 0.0000xxxx positions + costbasis = (int64_t) (dcostbasis / (double)totalbets); } else costbasis = 0; From e6d145f2f52dee6650ed195292dc7191a1201ceb Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 30 Apr 2019 00:39:05 +0500 Subject: [PATCH 172/242] log dcostbasis --- src/cc/prices.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 6066100a9..c57d932e0 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -716,7 +716,7 @@ int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t if (errcode != 0) break; - if( depth >= 0 ) + if( depth > 0 ) std::cerr << "top pricestack[depth-1=" << depth-1 << "]=" << pricestack[depth-1] << std::endl; else std::cerr << "pricestack empty" << std::endl; @@ -1340,7 +1340,7 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) totalprofits += b.profits; dcostbasis += b.amount * b.costbasis; // costbasis += b.amount * (b.costbasis / PRICES_POINTFACTOR); // prevent int64 overflow (but we have underflow for 1/BTC) - // std::cerr << "PricesInfo() acc costbasis=" << costbasis << " b.amount=" << b.amount << " b.costbasis/PRICES_POINTFACTOR=" << (b.costbasis / PRICES_POINTFACTOR) << std::endl; + std::cerr << "PricesInfo() acc dcostbasis=" << dcostbasis << " b.amount=" << b.amount << " b.costbasis/PRICES_POINTFACTOR=" << (b.costbasis / PRICES_POINTFACTOR) << std::endl; } int64_t equity = totalbets + totalprofits; From 656992811cf02ea46c07dc227ddbc706d8e5b2fb Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 30 Apr 2019 00:47:15 +0500 Subject: [PATCH 173/242] long double --- src/cc/prices.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index c57d932e0..a69f68ba0 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1334,7 +1334,7 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) int64_t totalbets = 0; int64_t totalprofits = 0; - double dcostbasis = 0.0; + long double dcostbasis = 0.0; for (auto b : bets) { totalbets += b.amount; totalprofits += b.profits; From b800a223c56b9e1a4ecfeccecf7b7eadab56646b Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 30 Apr 2019 00:52:47 +0500 Subject: [PATCH 174/242] corr double mult --- src/cc/prices.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index a69f68ba0..783e9f03c 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1334,11 +1334,11 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) int64_t totalbets = 0; int64_t totalprofits = 0; - long double dcostbasis = 0.0; + double dcostbasis = 0.0; for (auto b : bets) { totalbets += b.amount; totalprofits += b.profits; - dcostbasis += b.amount * b.costbasis; + dcostbasis += b.amount * (double)b.costbasis; // costbasis += b.amount * (b.costbasis / PRICES_POINTFACTOR); // prevent int64 overflow (but we have underflow for 1/BTC) std::cerr << "PricesInfo() acc dcostbasis=" << dcostbasis << " b.amount=" << b.amount << " b.costbasis/PRICES_POINTFACTOR=" << (b.costbasis / PRICES_POINTFACTOR) << std::endl; } From 23f427373c57296d836e8591bc56552388100f85 Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 30 Apr 2019 01:00:26 +0500 Subject: [PATCH 175/242] costbasis calc temp change to floating point --- src/cc/prices.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 783e9f03c..dcb9b146a 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -790,19 +790,24 @@ int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t } // normalize to 10,000,000 to prevent underflow - profits = costbasis > 0 ? (((price / PRICES_POINTFACTOR * PRICES_NORMFACTOR) / costbasis) - PRICES_NORMFACTOR / PRICES_POINTFACTOR) * PRICES_POINTFACTOR : 0; + //profits = costbasis > 0 ? (((price / PRICES_POINTFACTOR * PRICES_NORMFACTOR) / costbasis) - PRICES_NORMFACTOR / PRICES_POINTFACTOR) * PRICES_POINTFACTOR : 0; + + double dprofits = costbasis > 0 ? ((double)price / (double)costbasis - 1) : 0; //std::cerr << "prices_syntheticprofits() test value1 (price/PRICES_POINTFACTOR * PRICES_NORMFACTOR)=" << (price / PRICES_POINTFACTOR * PRICES_NORMFACTOR) << std::endl; - std::cerr << "prices_syntheticprofits() test value2 (price/PRICES_POINTFACTOR * PRICES_NORMFACTOR)/costbasis=" << (costbasis != 0 ? (price / PRICES_POINTFACTOR * PRICES_NORMFACTOR)/costbasis : 0) << std::endl; + //std::cerr << "prices_syntheticprofits() test value2 (price/PRICES_POINTFACTOR * PRICES_NORMFACTOR)/costbasis=" << (costbasis != 0 ? (price / PRICES_POINTFACTOR * PRICES_NORMFACTOR)/costbasis : 0) << std::endl; - std::cerr << "prices_syntheticprofits() fractional profits=" << profits << std::endl; + //std::cerr << "prices_syntheticprofits() fractional profits=" << profits << std::endl; //std::cerr << "prices_syntheticprofits() profits double=" << (double)price / (double)costbasis -1.0 << std::endl; //double dprofits = (double)price / (double)costbasis - 1.0; - profits *= ((int64_t)leverage * (int64_t)positionsize); - profits /= (int64_t)PRICES_NORMFACTOR; // de-normalize + //profits *= ((int64_t)leverage * (int64_t)positionsize); + //profits /= (int64_t)PRICES_NORMFACTOR; // de-normalize + + dprofits *= ((double)leverage * (double)positionsize); //dprofits *= leverage * positionsize; + profits = dprofits; std::cerr << "prices_syntheticprofits() profits=" << profits << std::endl; //std::cerr << "prices_syntheticprofits() dprofits=" << dprofits << std::endl; From 2a5a86b1ce118e06d742d14c1540237a6d2e0257 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Tue, 30 Apr 2019 11:20:02 +0800 Subject: [PATCH 176/242] change default expiry height to 200 instead of 20. To stop wallet getting corrupted. --- src/main.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.h b/src/main.h index ec36c976b..d507f9dd6 100644 --- a/src/main.h +++ b/src/main.h @@ -88,7 +88,7 @@ static const unsigned int DEFAULT_MIN_RELAY_TX_FEE = 100; /** Default for -maxorphantx, maximum number of orphan transactions kept in memory */ static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100; /** Default for -txexpirydelta, in number of blocks */ -static const unsigned int DEFAULT_TX_EXPIRY_DELTA = 20; +static const unsigned int DEFAULT_TX_EXPIRY_DELTA = 200; /** The maximum size of a blk?????.dat file (since 0.8) */ static const unsigned int MAX_BLOCKFILE_SIZE = 0x8000000; // 128 MiB static const unsigned int MAX_TEMPFILE_SIZE = 0x1000000; // 16 MiB 0x8000000 From 762c878d564e0c877f62ffe9b73b56b81826173c Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 30 Apr 2019 12:16:27 +0500 Subject: [PATCH 177/242] added profits calc with gmp lib --- src/cc/prices.cpp | 42 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index dcb9b146a..36214c735 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -16,6 +16,8 @@ #include "CCassets.h" #include "CCPrices.h" +#include "mini-gmp.h" + #define IS_CHARINSTR(c, str) (std::string(str).find((char)(c)) != std::string::npos) typedef struct BetInfo { @@ -791,9 +793,8 @@ int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t // normalize to 10,000,000 to prevent underflow //profits = costbasis > 0 ? (((price / PRICES_POINTFACTOR * PRICES_NORMFACTOR) / costbasis) - PRICES_NORMFACTOR / PRICES_POINTFACTOR) * PRICES_POINTFACTOR : 0; + //double dprofits = costbasis > 0 ? ((double)price / (double)costbasis - 1) : 0; - double dprofits = costbasis > 0 ? ((double)price / (double)costbasis - 1) : 0; - //std::cerr << "prices_syntheticprofits() test value1 (price/PRICES_POINTFACTOR * PRICES_NORMFACTOR)=" << (price / PRICES_POINTFACTOR * PRICES_NORMFACTOR) << std::endl; //std::cerr << "prices_syntheticprofits() test value2 (price/PRICES_POINTFACTOR * PRICES_NORMFACTOR)/costbasis=" << (costbasis != 0 ? (price / PRICES_POINTFACTOR * PRICES_NORMFACTOR)/costbasis : 0) << std::endl; @@ -804,13 +805,44 @@ int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t //profits *= ((int64_t)leverage * (int64_t)positionsize); //profits /= (int64_t)PRICES_NORMFACTOR; // de-normalize - dprofits *= ((double)leverage * (double)positionsize); + //dprofits *= ((double)leverage * (double)positionsize); //dprofits *= leverage * positionsize; - profits = dprofits; - std::cerr << "prices_syntheticprofits() profits=" << profits << std::endl; + // profits = dprofits; //std::cerr << "prices_syntheticprofits() dprofits=" << dprofits << std::endl; + + + if (costbasis > 0) { + mpz_t mpzProfits; + mpz_t mpzCostbasis; + mpz_t mpzPrice; + + mpz_init(mpzProfits); + mpz_init(mpzCostbasis); + mpz_init(mpzPrice); + + mpz_set_si(mpzCostbasis, costbasis); + mpz_mul_ui(mpzCostbasis, mpzCostbasis, SATOSHIDEN); + mpz_set_si(mpzPrice, price); + + mpz_divexact(mpzProfits, mpzPrice, mpzCostbasis); // profits = (price*SATOSHIDEN)/costbasis // normalization + mpz_sub_ui(mpzProfits, mpzProfits, SATOSHIDEN); // profits -= SATOSHIDEN + + mpz_mul_si(mpzProfits, mpzProfits, leverage); // profits *= leverage + mpz_mul_si(mpzProfits, mpzProfits, positionsize); // profits *= positionsize + mpz_divexact_ui(mpzProfits, mpzPrice, SATOSHIDEN); // profits /= SATOSHIDEN // de-normalization + + profits = mpz_get_si(mpzProfits); + + mpz_clear(mpzProfits); + mpz_clear(mpzCostbasis); + mpz_clear(mpzPrice); + } + else + profits = 0; + + std::cerr << "prices_syntheticprofits() profits=" << profits << std::endl; return 0; // (positionsize + addedbets + profits); } From 00debd2f613be8d3e526b7f042b79394de437da5 Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 30 Apr 2019 12:40:20 +0500 Subject: [PATCH 178/242] try include mini-gmp.c --- src/cc/prices.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 36214c735..a67f4b17f 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -18,6 +18,8 @@ #include "mini-gmp.h" +#include "mini-gmp.c" + #define IS_CHARINSTR(c, str) (std::string(str).find((char)(c)) != std::string::npos) typedef struct BetInfo { From dbc4818b8a46d5a5dd2dde1ef0bd53d21650316e Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 30 Apr 2019 12:44:53 +0500 Subject: [PATCH 179/242] add mini-gmp to Makefile.am --- src/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Makefile.am b/src/Makefile.am index e6c1fbb14..f31a394f6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -302,6 +302,7 @@ libbitcoin_server_a_SOURCES = \ cc/fsm.cpp \ cc/heir.cpp \ cc/oracles.cpp \ + mini-gmp.c \ cc/prices.cpp \ cc/pegs.cpp \ cc/marmara.cpp \ From f8bbf9b13090c4be81cef69f357ef1abc96aaa5b Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 30 Apr 2019 15:08:01 +0500 Subject: [PATCH 180/242] Revert "add mini-gmp to Makefile.am" This reverts commit dbc4818b8a46d5a5dd2dde1ef0bd53d21650316e. --- src/Makefile.am | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index f31a394f6..e6c1fbb14 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -302,7 +302,6 @@ libbitcoin_server_a_SOURCES = \ cc/fsm.cpp \ cc/heir.cpp \ cc/oracles.cpp \ - mini-gmp.c \ cc/prices.cpp \ cc/pegs.cpp \ cc/marmara.cpp \ From d9a53c242ea2e1ec9d4d077791f37a12609c6bcd Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 30 Apr 2019 15:08:18 +0500 Subject: [PATCH 181/242] Revert "try include mini-gmp.c" This reverts commit 00debd2f613be8d3e526b7f042b79394de437da5. --- src/cc/prices.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index a67f4b17f..36214c735 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -18,8 +18,6 @@ #include "mini-gmp.h" -#include "mini-gmp.c" - #define IS_CHARINSTR(c, str) (std::string(str).find((char)(c)) != std::string::npos) typedef struct BetInfo { From bb0e6307067d5e21cc8add375bad7f88827760e9 Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 30 Apr 2019 16:03:26 +0500 Subject: [PATCH 182/242] changed gmp calls to unsigned --- src/cc/prices.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 36214c735..36acd753c 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -822,18 +822,18 @@ int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t mpz_init(mpzCostbasis); mpz_init(mpzPrice); - mpz_set_si(mpzCostbasis, costbasis); + mpz_set_ui(mpzCostbasis, costbasis); mpz_mul_ui(mpzCostbasis, mpzCostbasis, SATOSHIDEN); - mpz_set_si(mpzPrice, price); + mpz_set_ui(mpzPrice, price); mpz_divexact(mpzProfits, mpzPrice, mpzCostbasis); // profits = (price*SATOSHIDEN)/costbasis // normalization mpz_sub_ui(mpzProfits, mpzProfits, SATOSHIDEN); // profits -= SATOSHIDEN - mpz_mul_si(mpzProfits, mpzProfits, leverage); // profits *= leverage - mpz_mul_si(mpzProfits, mpzProfits, positionsize); // profits *= positionsize + mpz_mul_ui(mpzProfits, mpzProfits, leverage); // profits *= leverage + mpz_mul_ui(mpzProfits, mpzProfits, positionsize); // profits *= positionsize mpz_divexact_ui(mpzProfits, mpzPrice, SATOSHIDEN); // profits /= SATOSHIDEN // de-normalization - profits = mpz_get_si(mpzProfits); + profits = mpz_get_ui(mpzProfits); mpz_clear(mpzProfits); mpz_clear(mpzCostbasis); From 020dcfcd85ff3f442de0f4425d9faf1b77e9d41b Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 30 Apr 2019 16:15:02 +0500 Subject: [PATCH 183/242] changed gmp to essentials --- src/cc/prices.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 36acd753c..8d0453051 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -817,24 +817,28 @@ int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t mpz_t mpzProfits; mpz_t mpzCostbasis; mpz_t mpzPrice; + mpz_t mpzLeverage; mpz_init(mpzProfits); mpz_init(mpzCostbasis); mpz_init(mpzPrice); + mpz_init(mpzLeverage); mpz_set_ui(mpzCostbasis, costbasis); mpz_mul_ui(mpzCostbasis, mpzCostbasis, SATOSHIDEN); mpz_set_ui(mpzPrice, price); + mpz_set_si(mpzLeverage, leverage); - mpz_divexact(mpzProfits, mpzPrice, mpzCostbasis); // profits = (price*SATOSHIDEN)/costbasis // normalization + mpz_fdiv_q(mpzProfits, mpzPrice, mpzCostbasis); // profits = (price*SATOSHIDEN)/costbasis // normalization mpz_sub_ui(mpzProfits, mpzProfits, SATOSHIDEN); // profits -= SATOSHIDEN - mpz_mul_ui(mpzProfits, mpzProfits, leverage); // profits *= leverage + mpz_mul(mpzProfits, mpzProfits, mpzLeverage); // profits *= leverage mpz_mul_ui(mpzProfits, mpzProfits, positionsize); // profits *= positionsize - mpz_divexact_ui(mpzProfits, mpzPrice, SATOSHIDEN); // profits /= SATOSHIDEN // de-normalization + mpz_fdiv_q_ui(mpzProfits, mpzPrice, SATOSHIDEN); // profits /= SATOSHIDEN // de-normalization profits = mpz_get_ui(mpzProfits); + mpz_clear(mpzLeverage); mpz_clear(mpzProfits); mpz_clear(mpzCostbasis); mpz_clear(mpzPrice); From 67176b6a7145a4dd02cead14c5cbe7a62ecd7911 Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 30 Apr 2019 16:20:52 +0500 Subject: [PATCH 184/242] cdiv used --- src/cc/prices.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 8d0453051..4575e879e 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -829,12 +829,12 @@ int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t mpz_set_ui(mpzPrice, price); mpz_set_si(mpzLeverage, leverage); - mpz_fdiv_q(mpzProfits, mpzPrice, mpzCostbasis); // profits = (price*SATOSHIDEN)/costbasis // normalization + mpz_cdiv_q(mpzProfits, mpzPrice, mpzCostbasis); // profits = (price*SATOSHIDEN)/costbasis // normalization mpz_sub_ui(mpzProfits, mpzProfits, SATOSHIDEN); // profits -= SATOSHIDEN mpz_mul(mpzProfits, mpzProfits, mpzLeverage); // profits *= leverage mpz_mul_ui(mpzProfits, mpzProfits, positionsize); // profits *= positionsize - mpz_fdiv_q_ui(mpzProfits, mpzPrice, SATOSHIDEN); // profits /= SATOSHIDEN // de-normalization + mpz_cdiv_q_ui(mpzProfits, mpzPrice, SATOSHIDEN); // profits /= SATOSHIDEN // de-normalization profits = mpz_get_ui(mpzProfits); From 9c50f7a7e5073b9a25692b6dcc9052c736a04351 Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 30 Apr 2019 16:25:56 +0500 Subject: [PATCH 185/242] changed div funcs to essentials --- src/cc/prices.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 4575e879e..bf291618f 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -818,6 +818,7 @@ int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t mpz_t mpzCostbasis; mpz_t mpzPrice; mpz_t mpzLeverage; + mpz_t mpzRemainder; mpz_init(mpzProfits); mpz_init(mpzCostbasis); @@ -829,15 +830,16 @@ int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t mpz_set_ui(mpzPrice, price); mpz_set_si(mpzLeverage, leverage); - mpz_cdiv_q(mpzProfits, mpzPrice, mpzCostbasis); // profits = (price*SATOSHIDEN)/costbasis // normalization + mpz_tdiv_qr(mpzProfits, mpzRemainder, mpzPrice, mpzCostbasis); // profits = (price*SATOSHIDEN)/costbasis // normalization mpz_sub_ui(mpzProfits, mpzProfits, SATOSHIDEN); // profits -= SATOSHIDEN mpz_mul(mpzProfits, mpzProfits, mpzLeverage); // profits *= leverage mpz_mul_ui(mpzProfits, mpzProfits, positionsize); // profits *= positionsize - mpz_cdiv_q_ui(mpzProfits, mpzPrice, SATOSHIDEN); // profits /= SATOSHIDEN // de-normalization + mpz_tdiv_qr_ui(mpzProfits, mpzRemainder, mpzPrice, SATOSHIDEN); // profits /= SATOSHIDEN // de-normalization profits = mpz_get_ui(mpzProfits); + mpz_clear(mpzRemainder); mpz_clear(mpzLeverage); mpz_clear(mpzProfits); mpz_clear(mpzCostbasis); From 3f61f3c155c1090885352e64c8a58da843036de0 Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 30 Apr 2019 16:31:37 +0500 Subject: [PATCH 186/242] missed mpz_init added --- src/cc/prices.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index bf291618f..3a14bf440 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -824,6 +824,8 @@ int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t mpz_init(mpzCostbasis); mpz_init(mpzPrice); mpz_init(mpzLeverage); + mpz_init(mpzRemainder); + mpz_set_ui(mpzCostbasis, costbasis); mpz_mul_ui(mpzCostbasis, mpzCostbasis, SATOSHIDEN); From f4837d2b09320da18b774aa0d3834cbee44523cc Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 30 Apr 2019 18:27:26 +0500 Subject: [PATCH 187/242] changed to gmp.h --- src/cc/prices.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 3a14bf440..56911144f 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -16,7 +16,8 @@ #include "CCassets.h" #include "CCPrices.h" -#include "mini-gmp.h" +//#include "mini-gmp.h" +#include #define IS_CHARINSTR(c, str) (std::string(str).find((char)(c)) != std::string::npos) From 1e131efcbaca28379cb9561566d379298bb5d306 Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 30 Apr 2019 18:36:56 +0500 Subject: [PATCH 188/242] try use signed mpz_get_si --- src/cc/prices.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 56911144f..1992a40f1 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -840,7 +840,7 @@ int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t mpz_mul_ui(mpzProfits, mpzProfits, positionsize); // profits *= positionsize mpz_tdiv_qr_ui(mpzProfits, mpzRemainder, mpzPrice, SATOSHIDEN); // profits /= SATOSHIDEN // de-normalization - profits = mpz_get_ui(mpzProfits); + profits = mpz_get_si(mpzProfits); mpz_clear(mpzRemainder); mpz_clear(mpzLeverage); From c6d91b33c02fd94f2eb38cbd889490b4fc9a5cab Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 30 Apr 2019 19:11:24 +0500 Subject: [PATCH 189/242] test div --- src/cc/prices.cpp | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 1992a40f1..d27547a81 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -827,7 +827,6 @@ int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t mpz_init(mpzLeverage); mpz_init(mpzRemainder); - mpz_set_ui(mpzCostbasis, costbasis); mpz_mul_ui(mpzCostbasis, mpzCostbasis, SATOSHIDEN); mpz_set_ui(mpzPrice, price); @@ -842,11 +841,44 @@ int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t profits = mpz_get_si(mpzProfits); + + mpz_clear(mpzRemainder); mpz_clear(mpzLeverage); mpz_clear(mpzProfits); mpz_clear(mpzCostbasis); mpz_clear(mpzPrice); + + mpz_t mpzTest; + mpz_init(mpzTest); + + mpz_set_si(mpzTest, 5); + mpz_cdiv_qr_ui(mpzTest, mpzRemainder, mpzTest, 2); + std::cerr << "mpz_cdiv_qr_ui 5/2=" << mpz_get_si(mpzTest); + + mpz_set_si(mpzTest, 5); + mpz_tdiv_qr_ui(mpzTest, mpzRemainder, mpzTest, 2); + std::cerr << "mpz_tdiv_qr_ui 5/2=" << mpz_get_si(mpzTest); + + mpz_set_si(mpzTest, 5); + mpz_fdiv_qr_ui(mpzTest, mpzRemainder, mpzTest, 2); + std::cerr << "mpz_tdiv_qr_ui 5/2=" << mpz_get_si(mpzTest); + + mpz_set_si(mpzTest, -5); + mpz_cdiv_qr_ui(mpzTest, mpzRemainder, mpzTest, 2); + std::cerr << "mpz_cdiv_qr_ui -5/2=" << mpz_get_si(mpzTest); + + mpz_set_si(mpzTest, -5); + mpz_tdiv_qr_ui(mpzTest, mpzRemainder, mpzTest, 2); + std::cerr << "mpz_tdiv_qr_ui -5/2=" << mpz_get_si(mpzTest); + + mpz_set_si(mpzTest, -5); + mpz_fdiv_qr_ui(mpzTest, mpzRemainder, mpzTest, 2); + std::cerr << "mpz_fdiv_qr_ui -5/2=" << mpz_get_si(mpzTest); + std::cerr << std::endl; + + mpz_clear(mpzTest); + } else profits = 0; From 7ada2401e5d9ac4543af4ebf08ad464884ea959a Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 30 Apr 2019 19:20:27 +0500 Subject: [PATCH 190/242] mem alloc corr --- src/cc/prices.cpp | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index d27547a81..b5eb19dd3 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -843,12 +843,6 @@ int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t - mpz_clear(mpzRemainder); - mpz_clear(mpzLeverage); - mpz_clear(mpzProfits); - mpz_clear(mpzCostbasis); - mpz_clear(mpzPrice); - mpz_t mpzTest; mpz_init(mpzTest); @@ -858,25 +852,30 @@ int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t mpz_set_si(mpzTest, 5); mpz_tdiv_qr_ui(mpzTest, mpzRemainder, mpzTest, 2); - std::cerr << "mpz_tdiv_qr_ui 5/2=" << mpz_get_si(mpzTest); + std::cerr << " mpz_tdiv_qr_ui 5/2=" << mpz_get_si(mpzTest); mpz_set_si(mpzTest, 5); mpz_fdiv_qr_ui(mpzTest, mpzRemainder, mpzTest, 2); - std::cerr << "mpz_tdiv_qr_ui 5/2=" << mpz_get_si(mpzTest); + std::cerr << " mpz_tdiv_qr_ui 5/2=" << mpz_get_si(mpzTest); mpz_set_si(mpzTest, -5); mpz_cdiv_qr_ui(mpzTest, mpzRemainder, mpzTest, 2); - std::cerr << "mpz_cdiv_qr_ui -5/2=" << mpz_get_si(mpzTest); + std::cerr << " mpz_cdiv_qr_ui -5/2=" << mpz_get_si(mpzTest); mpz_set_si(mpzTest, -5); mpz_tdiv_qr_ui(mpzTest, mpzRemainder, mpzTest, 2); - std::cerr << "mpz_tdiv_qr_ui -5/2=" << mpz_get_si(mpzTest); + std::cerr << " mpz_tdiv_qr_ui -5/2=" << mpz_get_si(mpzTest); mpz_set_si(mpzTest, -5); mpz_fdiv_qr_ui(mpzTest, mpzRemainder, mpzTest, 2); - std::cerr << "mpz_fdiv_qr_ui -5/2=" << mpz_get_si(mpzTest); + std::cerr << " mpz_fdiv_qr_ui -5/2=" << mpz_get_si(mpzTest); std::cerr << std::endl; + mpz_clear(mpzRemainder); + mpz_clear(mpzLeverage); + mpz_clear(mpzProfits); + mpz_clear(mpzCostbasis); + mpz_clear(mpzPrice); mpz_clear(mpzTest); } From fe0f7ed57917f6f10234f13bef5a86467e54ac6d Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 30 Apr 2019 19:34:20 +0500 Subject: [PATCH 191/242] more test div --- src/cc/prices.cpp | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index b5eb19dd3..be1f5b897 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -856,7 +856,7 @@ int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t mpz_set_si(mpzTest, 5); mpz_fdiv_qr_ui(mpzTest, mpzRemainder, mpzTest, 2); - std::cerr << " mpz_tdiv_qr_ui 5/2=" << mpz_get_si(mpzTest); + std::cerr << " mpz_fdiv_qr_ui 5/2=" << mpz_get_si(mpzTest); mpz_set_si(mpzTest, -5); mpz_cdiv_qr_ui(mpzTest, mpzRemainder, mpzTest, 2); @@ -869,6 +869,32 @@ int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t mpz_set_si(mpzTest, -5); mpz_fdiv_qr_ui(mpzTest, mpzRemainder, mpzTest, 2); std::cerr << " mpz_fdiv_qr_ui -5/2=" << mpz_get_si(mpzTest); + + std::cerr << std::endl; + + mpz_set_si(mpzTest, 7); + mpz_cdiv_qr_ui(mpzTest, mpzRemainder, mpzTest, 3); + std::cerr << "mpz_cdiv_qr_ui 7/3=" << mpz_get_si(mpzTest); + + mpz_set_si(mpzTest, 7); + mpz_tdiv_qr_ui(mpzTest, mpzRemainder, mpzTest, 3); + std::cerr << " mpz_tdiv_qr_ui 7/3=" << mpz_get_si(mpzTest); + + mpz_set_si(mpzTest, 7); + mpz_fdiv_qr_ui(mpzTest, mpzRemainder, mpzTest, 3); + std::cerr << " mpz_fdiv_qr_ui 7/3=" << mpz_get_si(mpzTest); + + mpz_set_si(mpzTest, -7); + mpz_cdiv_qr_ui(mpzTest, mpzRemainder, mpzTest, 3); + std::cerr << " mpz_cdiv_qr_ui -7/3=" << mpz_get_si(mpzTest); + + mpz_set_si(mpzTest, -7); + mpz_tdiv_qr_ui(mpzTest, mpzRemainder, mpzTest, 3); + std::cerr << " mpz_tdiv_qr_ui -7/3=" << mpz_get_si(mpzTest); + + mpz_set_si(mpzTest, -7); + mpz_fdiv_qr_ui(mpzTest, mpzRemainder, mpzTest, 3); + std::cerr << " mpz_fdiv_qr_ui -7/3=" << mpz_get_si(mpzTest); std::cerr << std::endl; mpz_clear(mpzRemainder); From 802acc8c44d101b745c1c9f32595aab8152de29b Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 30 Apr 2019 20:39:49 +0500 Subject: [PATCH 192/242] change ave costbasis to gmp --- src/cc/prices.cpp | 125 +++++++++++++++++++--------------------------- 1 file changed, 52 insertions(+), 73 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index be1f5b897..96bacc83b 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -841,68 +841,11 @@ int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t profits = mpz_get_si(mpzProfits); - - - mpz_t mpzTest; - mpz_init(mpzTest); - - mpz_set_si(mpzTest, 5); - mpz_cdiv_qr_ui(mpzTest, mpzRemainder, mpzTest, 2); - std::cerr << "mpz_cdiv_qr_ui 5/2=" << mpz_get_si(mpzTest); - - mpz_set_si(mpzTest, 5); - mpz_tdiv_qr_ui(mpzTest, mpzRemainder, mpzTest, 2); - std::cerr << " mpz_tdiv_qr_ui 5/2=" << mpz_get_si(mpzTest); - - mpz_set_si(mpzTest, 5); - mpz_fdiv_qr_ui(mpzTest, mpzRemainder, mpzTest, 2); - std::cerr << " mpz_fdiv_qr_ui 5/2=" << mpz_get_si(mpzTest); - - mpz_set_si(mpzTest, -5); - mpz_cdiv_qr_ui(mpzTest, mpzRemainder, mpzTest, 2); - std::cerr << " mpz_cdiv_qr_ui -5/2=" << mpz_get_si(mpzTest); - - mpz_set_si(mpzTest, -5); - mpz_tdiv_qr_ui(mpzTest, mpzRemainder, mpzTest, 2); - std::cerr << " mpz_tdiv_qr_ui -5/2=" << mpz_get_si(mpzTest); - - mpz_set_si(mpzTest, -5); - mpz_fdiv_qr_ui(mpzTest, mpzRemainder, mpzTest, 2); - std::cerr << " mpz_fdiv_qr_ui -5/2=" << mpz_get_si(mpzTest); - - std::cerr << std::endl; - - mpz_set_si(mpzTest, 7); - mpz_cdiv_qr_ui(mpzTest, mpzRemainder, mpzTest, 3); - std::cerr << "mpz_cdiv_qr_ui 7/3=" << mpz_get_si(mpzTest); - - mpz_set_si(mpzTest, 7); - mpz_tdiv_qr_ui(mpzTest, mpzRemainder, mpzTest, 3); - std::cerr << " mpz_tdiv_qr_ui 7/3=" << mpz_get_si(mpzTest); - - mpz_set_si(mpzTest, 7); - mpz_fdiv_qr_ui(mpzTest, mpzRemainder, mpzTest, 3); - std::cerr << " mpz_fdiv_qr_ui 7/3=" << mpz_get_si(mpzTest); - - mpz_set_si(mpzTest, -7); - mpz_cdiv_qr_ui(mpzTest, mpzRemainder, mpzTest, 3); - std::cerr << " mpz_cdiv_qr_ui -7/3=" << mpz_get_si(mpzTest); - - mpz_set_si(mpzTest, -7); - mpz_tdiv_qr_ui(mpzTest, mpzRemainder, mpzTest, 3); - std::cerr << " mpz_tdiv_qr_ui -7/3=" << mpz_get_si(mpzTest); - - mpz_set_si(mpzTest, -7); - mpz_fdiv_qr_ui(mpzTest, mpzRemainder, mpzTest, 3); - std::cerr << " mpz_fdiv_qr_ui -7/3=" << mpz_get_si(mpzTest); - std::cerr << std::endl; - mpz_clear(mpzRemainder); mpz_clear(mpzLeverage); mpz_clear(mpzProfits); mpz_clear(mpzCostbasis); mpz_clear(mpzPrice); - mpz_clear(mpzTest); } else @@ -1434,34 +1377,66 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) result.push_back(Pair("error", "error scanning chain")); return(result); } - + + mpz_t mpzTotalbets; + mpz_t mpzTotalprofits; + mpz_t mpzTotalcostbasis; + + mpz_init(mpzTotalbets); + mpz_init(mpzTotalprofits); + mpz_init(mpzTotalcostbasis); + + int64_t totalbets = 0; int64_t totalprofits = 0; double dcostbasis = 0.0; + + for (auto b : bets) { - totalbets += b.amount; - totalprofits += b.profits; - dcostbasis += b.amount * (double)b.costbasis; + mpz_t mpzProduct; + mpz_t mpzProfits; + + mpz_init(mpzProduct); + mpz_init(mpzProfits); + + //totalprofits += b.profits; + //dcostbasis += b.amount * (double)b.costbasis; // costbasis += b.amount * (b.costbasis / PRICES_POINTFACTOR); // prevent int64 overflow (but we have underflow for 1/BTC) - std::cerr << "PricesInfo() acc dcostbasis=" << dcostbasis << " b.amount=" << b.amount << " b.costbasis/PRICES_POINTFACTOR=" << (b.costbasis / PRICES_POINTFACTOR) << std::endl; + // std::cerr << "PricesInfo() acc dcostbasis=" << dcostbasis << " b.amount=" << b.amount << " b.costbasis/PRICES_POINTFACTOR=" << (b.costbasis / PRICES_POINTFACTOR) << std::endl; + //std::cerr << "PricesInfo() acc dcostbasis=" << dcostbasis << " b.amount=" << b.amount << " b.costbasis/PRICES_POINTFACTOR=" << (b.costbasis / PRICES_POINTFACTOR) << std::endl; + mpz_set_ui(mpzProduct, b.costbasis); + mpz_mul_ui(mpzProduct, mpzProduct, (uint64_t)b.amount); // b.costbasis * b.amount + mpz_add(mpzTotalcostbasis, mpzTotalcostbasis, mpzProduct); //averageCostbasis += b.costbasis * b.amount; + + mpz_add_ui(mpzTotalbets, mpzTotalbets, (uint64_t)b.amount); //totalbets += b.amount; + mpz_add(mpzTotalprofits, mpzTotalprofits, mpzProfits); //totalprofits += b.profits; + + mpz_clear(mpzProduct); + mpz_clear(mpzProfits); } int64_t equity = totalbets + totalprofits; - int64_t costbasis; + int64_t averageCostbasis = 0; + if (totalbets != 0) { //prevent zero div // costbasis *= PRICES_POINTFACTOR; // save last 0.0000xxxx positions - costbasis = (int64_t) (dcostbasis / (double)totalbets); + //costbasis = (int64_t) (dcostbasis / (double)totalbets); + mpz_t mpzAverageCostbasis; + + mpz_init(mpzAverageCostbasis); + mpz_mul_ui(mpzTotalcostbasis, mpzTotalcostbasis, SATOSHIDEN); // normalization to prevent loss while div + mpz_tdiv_q(mpzAverageCostbasis, mpzTotalcostbasis, mpzTotalbets); // profits /= SATOSHIDEN // de-normalization + + mpz_tdiv_q_ui(mpzAverageCostbasis, mpzAverageCostbasis, SATOSHIDEN); // profits /= SATOSHIDEN // de-normalization + + averageCostbasis = mpz_get_ui(mpzAverageCostbasis); + mpz_clear(mpzAverageCostbasis); } - else - costbasis = 0; - int64_t liqprice; + + int64_t liqprice = 0; if (leverage != 0) {// prevent zero div - liqprice = costbasis - costbasis / leverage; - //liqprice /= PRICES_POINTFACTOR; - //liqprice *= PRICES_POINTFACTOR; // last posiitons should be == 0000 + liqprice = averageCostbasis - averageCostbasis / leverage; } - else - liqprice = 0; if (equity >= 0) result.push_back(Pair("rekt", 0)); @@ -1473,7 +1448,7 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) } result.push_back(Pair("batontxid", batontxid.GetHex())); - result.push_back(Pair("costbasis", ValueFromAmount(costbasis))); + result.push_back(Pair("costbasis", ValueFromAmount(averageCostbasis))); prices_betjson(result, bets, leverage, endheight, lastprice); @@ -1483,6 +1458,10 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) //#ifdef TESTMODE // result.push_back(Pair("test_daywindow", PRICES_DAYWINDOW)); //#endif + + mpz_clear(mpzTotalbets); + mpz_clear(mpzTotalprofits); + mpz_clear(mpzTotalcostbasis); return(result); } } From dba71a325e325c60d56f39fece6025236dfca193 Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 30 Apr 2019 21:07:56 +0500 Subject: [PATCH 193/242] corr ave costbasis --- src/cc/prices.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 96bacc83b..229723fc3 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1411,6 +1411,9 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) mpz_add_ui(mpzTotalbets, mpzTotalbets, (uint64_t)b.amount); //totalbets += b.amount; mpz_add(mpzTotalprofits, mpzTotalprofits, mpzProfits); //totalprofits += b.profits; + totalbets += b.amount; + totalprofits += b.profits; + mpz_clear(mpzProduct); mpz_clear(mpzProfits); } @@ -1418,7 +1421,7 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) int64_t equity = totalbets + totalprofits; int64_t averageCostbasis = 0; - if (totalbets != 0) { //prevent zero div + if (mpz_get_ui(mpzTotalbets) != 0) { //prevent zero div // costbasis *= PRICES_POINTFACTOR; // save last 0.0000xxxx positions //costbasis = (int64_t) (dcostbasis / (double)totalbets); mpz_t mpzAverageCostbasis; From bd2f5a6d41cf87e44f0677b76767eb09ea6b7604 Mon Sep 17 00:00:00 2001 From: dimxy Date: Wed, 1 May 2019 00:47:29 +0500 Subject: [PATCH 194/242] corr costbasis calc (prices norm) --- src/cc/prices.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 229723fc3..ce098146d 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -828,15 +828,16 @@ int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t mpz_init(mpzRemainder); mpz_set_ui(mpzCostbasis, costbasis); - mpz_mul_ui(mpzCostbasis, mpzCostbasis, SATOSHIDEN); mpz_set_ui(mpzPrice, price); + mpz_mul_ui(mpzPrice, mpzPrice, SATOSHIDEN); // (price*SATOSHIDEN) + mpz_set_si(mpzLeverage, leverage); mpz_tdiv_qr(mpzProfits, mpzRemainder, mpzPrice, mpzCostbasis); // profits = (price*SATOSHIDEN)/costbasis // normalization - mpz_sub_ui(mpzProfits, mpzProfits, SATOSHIDEN); // profits -= SATOSHIDEN + mpz_sub_ui(mpzProfits, mpzProfits, SATOSHIDEN); // profits -= SATOSHIDEN - mpz_mul(mpzProfits, mpzProfits, mpzLeverage); // profits *= leverage - mpz_mul_ui(mpzProfits, mpzProfits, positionsize); // profits *= positionsize + mpz_mul(mpzProfits, mpzProfits, mpzLeverage); // profits *= leverage + mpz_mul_ui(mpzProfits, mpzProfits, positionsize); // profits *= positionsize mpz_tdiv_qr_ui(mpzProfits, mpzRemainder, mpzPrice, SATOSHIDEN); // profits /= SATOSHIDEN // de-normalization profits = mpz_get_si(mpzProfits); From c6dab1decac596f66a974c01044524a751a352bb Mon Sep 17 00:00:00 2001 From: dimxy Date: Wed, 1 May 2019 01:01:22 +0500 Subject: [PATCH 195/242] corr costbasis gmp calc (incorrect prices op) --- src/cc/prices.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index ce098146d..cc8340fb4 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -831,14 +831,13 @@ int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t mpz_set_ui(mpzPrice, price); mpz_mul_ui(mpzPrice, mpzPrice, SATOSHIDEN); // (price*SATOSHIDEN) - mpz_set_si(mpzLeverage, leverage); - mpz_tdiv_qr(mpzProfits, mpzRemainder, mpzPrice, mpzCostbasis); // profits = (price*SATOSHIDEN)/costbasis // normalization mpz_sub_ui(mpzProfits, mpzProfits, SATOSHIDEN); // profits -= SATOSHIDEN + mpz_set_si(mpzLeverage, leverage); mpz_mul(mpzProfits, mpzProfits, mpzLeverage); // profits *= leverage mpz_mul_ui(mpzProfits, mpzProfits, positionsize); // profits *= positionsize - mpz_tdiv_qr_ui(mpzProfits, mpzRemainder, mpzPrice, SATOSHIDEN); // profits /= SATOSHIDEN // de-normalization + mpz_tdiv_qr_ui(mpzProfits, mpzRemainder, mpzProfits, SATOSHIDEN); // profits /= SATOSHIDEN // de-normalization profits = mpz_get_si(mpzProfits); From 7d7f0a08e4b804465d11faa0e785a8f0e68b5357 Mon Sep 17 00:00:00 2001 From: dimxy Date: Wed, 1 May 2019 12:30:41 +0500 Subject: [PATCH 196/242] added gmp for prices_syntheticprice --- src/cc/prices.cpp | 125 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 99 insertions(+), 26 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index cc8340fb4..8ab0d1875 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -592,6 +592,13 @@ int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t uint16_t opcode; int64_t *pricedata, pricestack[4], price, den, a, b, c; + mpz_t mpzA, mpzB, mpzC, mpzResult; + + mpz_init(mpzA); + mpz_init(mpzB); + mpz_init(mpzC); + mpz_init(mpzResult); + pricedata = (int64_t *)calloc(sizeof(*pricedata) * 3, 1 + PRICES_DAYWINDOW * 2 + PRICES_SMOOTHWIDTH); price = den = depth = errcode = 0; @@ -599,7 +606,10 @@ int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t { opcode = vec[i]; value = (opcode & (KOMODO_MAXPRICES - 1)); // index or weight - std::cerr << "prices_syntheticprice" << " i=" << i << " price=" << price << " value=" << value << " depth=" << depth << std::endl; + + mpz_set_ui(mpzResult, 0); // clear result to test overflow (see below) + + std::cerr << "prices_syntheticprice" << " i=" << i << " price=" << price << " value=" << value << " depth=" << depth << " opcode&KOMODO_PRICEMASK=" << (opcode & KOMODO_PRICEMASK) < vec, int32_t height, int32_t errcode = -2; break; - case PRICES_MULT: + case PRICES_MULT: // "*" if (depth >= 2) { b = pricestack[--depth]; a = pricestack[--depth]; - pricestack[depth++] = (a * b) / PRICES_NORMFACTOR; + // pricestack[depth++] = (a * b) / SATOSHIDEN; + mpz_set_si(mpzA, a); + mpz_set_si(mpzB, b); + mpz_mul(mpzResult, mpzA, mpzB); + mpz_tdiv_q_ui(mpzResult, mpzResult, SATOSHIDEN); + pricestack[depth++] = mpz_get_si(mpzResult); + } else errcode = -3; break; - case PRICES_DIV: + case PRICES_DIV: // "/" if (depth >= 2) { b = pricestack[--depth]; a = pricestack[--depth]; - pricestack[depth++] = (a * PRICES_NORMFACTOR) / b; + // pricestack[depth++] = (a * SATOSHIDEN) / b; + mpz_set_si(mpzA, a); + mpz_set_si(mpzB, b); + mpz_mul_ui(mpzResult, mpzA, SATOSHIDEN); + mpz_tdiv_q(mpzResult, mpzResult, mpzB); + pricestack[depth++] = mpz_get_si(mpzResult); } else errcode = -4; break; - case PRICES_INV: + case PRICES_INV: // "1/price" if (depth >= 1) { a = pricestack[--depth]; - pricestack[depth++] = (PRICES_NORMFACTOR * PRICES_NORMFACTOR) / a; + // pricestack[depth++] = (SATOSHIDEN * SATOSHIDEN) / a; + mpz_set_si(mpzA, a); + mpz_set_ui(mpzResult, SATOSHIDEN); + mpz_mul_ui(mpzResult, mpzResult, SATOSHIDEN); + mpz_tdiv_q(mpzResult, mpzResult, mpzA); + pricestack[depth++] = mpz_get_si(mpzResult); } else errcode = -5; break; - case PRICES_MDD: + case PRICES_MDD: // "*//" if (depth >= 3) { c = pricestack[--depth]; b = pricestack[--depth]; a = pricestack[--depth]; - pricestack[depth++] = (((a * PRICES_NORMFACTOR) / b) * PRICES_NORMFACTOR) / c; + // pricestack[depth++] = (((a * SATOSHIDEN) / b) * SATOSHIDEN) / c; + mpz_set_si(mpzA, a); + mpz_set_si(mpzB, b); + mpz_set_si(mpzC, c); + mpz_mul_ui(mpzResult, mpzA, SATOSHIDEN); + mpz_tdiv_q(mpzResult, mpzResult, mpzB); + mpz_mul_ui(mpzResult, mpzA, SATOSHIDEN); + mpz_tdiv_q(mpzResult, mpzResult, mpzC); + pricestack[depth++] = mpz_get_si(mpzResult); } else errcode = -6; break; - case PRICES_MMD: + case PRICES_MMD: // "**/" if (depth >= 3) { c = pricestack[--depth]; b = pricestack[--depth]; a = pricestack[--depth]; - pricestack[depth++] = (a * b) / c; + // pricestack[depth++] = (a * b) / c; + mpz_set_si(mpzA, a); + mpz_set_si(mpzB, b); + mpz_set_si(mpzC, c); + mpz_mul(mpzResult, mpzA, mpzB); + mpz_tdiv_q(mpzResult, mpzResult, mpzC); + pricestack[depth++] = mpz_get_si(mpzResult); } else errcode = -7; break; - case PRICES_MMM: + case PRICES_MMM: // "***" if (depth >= 3) { c = pricestack[--depth]; b = pricestack[--depth]; a = pricestack[--depth]; - pricestack[depth++] = ((a * b) / PRICES_NORMFACTOR) * c; + // pricestack[depth++] = ((a * b) / SATOSHIDEN) * c; + mpz_set_si(mpzA, a); + mpz_set_si(mpzB, b); + mpz_set_si(mpzC, c); + mpz_mul(mpzResult, mpzA, mpzB); + mpz_tdiv_q_ui(mpzResult, mpzResult, SATOSHIDEN); + mpz_mul(mpzResult, mpzResult, mpzC); + pricestack[depth++] = mpz_get_si(mpzResult); } else errcode = -8; break; - - case PRICES_DDD: + + case PRICES_DDD: // "///" if (depth >= 3) { c = pricestack[--depth]; b = pricestack[--depth]; a = pricestack[--depth]; - pricestack[depth++] = (((((PRICES_NORMFACTOR * PRICES_NORMFACTOR) / a) * PRICES_NORMFACTOR) / b) * PRICES_NORMFACTOR) / c; + //pricestack[depth++] = (((((SATOSHIDEN * SATOSHIDEN) / a) * SATOSHIDEN) / b) * SATOSHIDEN) / c; + mpz_set_si(mpzA, a); + mpz_set_si(mpzB, b); + mpz_set_si(mpzC, c); + mpz_set_ui(mpzResult, SATOSHIDEN); + mpz_mul_ui(mpzResult, mpzResult, SATOSHIDEN); + mpz_tdiv_q(mpzResult, mpzResult, mpzA); + mpz_mul_ui(mpzResult, mpzResult, SATOSHIDEN); + mpz_tdiv_q(mpzResult, mpzResult, mpzB); + mpz_mul_ui(mpzResult, mpzResult, SATOSHIDEN); + mpz_tdiv_q(mpzResult, mpzResult, mpzC); + pricestack[depth++] = mpz_get_si(mpzResult); } else errcode = -9; @@ -716,19 +774,36 @@ int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t errcode = -10; break; } + + std::cerr << "prices_syntheticprice test mpzResult=" << mpz_get_si(mpzResult) << std::endl; + // check overflow: + if (mpz_cmp_si(mpzResult, std::numeric_limits::max()) > 0) { + errcode = -13; + break; + } + if (errcode != 0) break; if( depth > 0 ) - std::cerr << "top pricestack[depth-1=" << depth-1 << "]=" << pricestack[depth-1] << std::endl; + std::cerr << "prices_syntheticprice top pricestack[depth-1=" << depth-1 << "]=" << pricestack[depth-1] << std::endl; else - std::cerr << "pricestack empty" << std::endl; + std::cerr << "prices_syntheticprice pricestack empty" << std::endl; } free(pricedata); + mpz_clear(mpzResult); + mpz_clear(mpzA); + mpz_clear(mpzB); + mpz_clear(mpzC); if (errcode != 0) - std::cerr << "prices_syntheticprice warning: errcode in switch=" << errcode << std::endl; + std::cerr << "prices_syntheticprice errcode in switch=" << errcode << std::endl; + + if (errcode == -13) { + std::cerr << "prices_syntheticprice overflow in price" << std::endl; + return errcode; + } if (den == 0) { std::cerr << "prices_syntheticprice den==0 return err=-11" << std::endl; @@ -819,29 +894,26 @@ int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t mpz_t mpzCostbasis; mpz_t mpzPrice; mpz_t mpzLeverage; - mpz_t mpzRemainder; mpz_init(mpzProfits); mpz_init(mpzCostbasis); mpz_init(mpzPrice); mpz_init(mpzLeverage); - mpz_init(mpzRemainder); - mpz_set_ui(mpzCostbasis, costbasis); - mpz_set_ui(mpzPrice, price); + mpz_set_si(mpzCostbasis, costbasis); + mpz_set_si(mpzPrice, price); mpz_mul_ui(mpzPrice, mpzPrice, SATOSHIDEN); // (price*SATOSHIDEN) - mpz_tdiv_qr(mpzProfits, mpzRemainder, mpzPrice, mpzCostbasis); // profits = (price*SATOSHIDEN)/costbasis // normalization + mpz_tdiv_q(mpzProfits, mpzPrice, mpzCostbasis); // profits = (price*SATOSHIDEN)/costbasis // normalization mpz_sub_ui(mpzProfits, mpzProfits, SATOSHIDEN); // profits -= SATOSHIDEN mpz_set_si(mpzLeverage, leverage); mpz_mul(mpzProfits, mpzProfits, mpzLeverage); // profits *= leverage mpz_mul_ui(mpzProfits, mpzProfits, positionsize); // profits *= positionsize - mpz_tdiv_qr_ui(mpzProfits, mpzRemainder, mpzProfits, SATOSHIDEN); // profits /= SATOSHIDEN // de-normalization + mpz_tdiv_q_ui(mpzProfits, mpzProfits, SATOSHIDEN); // profits /= SATOSHIDEN // de-normalization profits = mpz_get_si(mpzProfits); - mpz_clear(mpzRemainder); mpz_clear(mpzLeverage); mpz_clear(mpzProfits); mpz_clear(mpzCostbasis); @@ -988,6 +1060,7 @@ UniValue PricesBet(int64_t txfee, int64_t amount, int16_t leverage, std::vector< //GetCCaddress(cp, myaddr, mypk); if (prices_syntheticvec(vec, synthetic) < 0 || (firstprice = prices_syntheticprice(vec, nextheight - 1, 1, leverage)) < 0 || vec.size() == 0 || vec.size() > 4096) { + std::cerr << "PricesBet() firstprice=" << firstprice << (firstprice < 0 ? "error or overflow" : "") << std::endl; result.push_back(Pair("result", "error")); result.push_back(Pair("error", "invalid synthetic")); return(result); From 7a3858ab6edca8da140db94072a5002967b0a9da Mon Sep 17 00:00:00 2001 From: dimxy Date: Wed, 1 May 2019 19:37:20 +0500 Subject: [PATCH 197/242] added getting source exp --- src/cc/prices.cpp | 79 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 70 insertions(+), 9 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 8ab0d1875..965c88e80 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -525,6 +525,69 @@ UniValue prices_rawtxresult(UniValue &result, std::string rawtx, int32_t broadca return(result); } +std::string prices_getsourceexpression(std::vector &vec) { + + std::string exp; + + for (int32_t i = 0; i < vec.size(); i++) + { + char name[65]; + std::string operand; + uint16_t opcode = vec[i]; + int32_t value = (opcode & (KOMODO_MAXPRICES - 1)); // index or weight + + switch (opcode & KOMODO_PRICEMASK) + { + case 0: // indices + komodo_pricename(name, value); + operand = std::string(name); + break; + + case PRICES_WEIGHT: // multiply by weight and consume top of stack by updating price + operand = std::to_string(value); + break; + + case PRICES_MULT: // "*" + operand = std::string("*"); + break; + + case PRICES_DIV: // "/" + operand = std::string("/"); + break; + + case PRICES_INV: // "1/price" + operand = std::string("!"); + break; + + case PRICES_MDD: // "*//" + operand = std::string("*//"); + break; + + case PRICES_MMD: // "**/" + operand = std::string("**/"); + break; + + case PRICES_MMM: // "***" + operand = std::string("***"); + break; + + case PRICES_DDD: // "///" + operand = std::string("///"); + break; + + default: + return "invalid opcode"; + break; + } + + if (exp.size() > 0) + exp += std::string(", "); + exp += operand; + } + return exp; +} + + int32_t prices_syntheticvec(std::vector &vec, std::vector synthetic) { int32_t i, need, ind, depth = 0; std::string opstr; uint16_t opcode, weight; @@ -1462,8 +1525,6 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) int64_t totalbets = 0; int64_t totalprofits = 0; - double dcostbasis = 0.0; - for (auto b : bets) { mpz_t mpzProduct; @@ -1495,15 +1556,14 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) int64_t averageCostbasis = 0; if (mpz_get_ui(mpzTotalbets) != 0) { //prevent zero div - // costbasis *= PRICES_POINTFACTOR; // save last 0.0000xxxx positions - //costbasis = (int64_t) (dcostbasis / (double)totalbets); mpz_t mpzAverageCostbasis; - mpz_init(mpzAverageCostbasis); - mpz_mul_ui(mpzTotalcostbasis, mpzTotalcostbasis, SATOSHIDEN); // normalization to prevent loss while div - mpz_tdiv_q(mpzAverageCostbasis, mpzTotalcostbasis, mpzTotalbets); // profits /= SATOSHIDEN // de-normalization - mpz_tdiv_q_ui(mpzAverageCostbasis, mpzAverageCostbasis, SATOSHIDEN); // profits /= SATOSHIDEN // de-normalization + //averageCostbasis = totalcostbasis / totalbets; + 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_ui(mpzAverageCostbasis, mpzAverageCostbasis, SATOSHIDEN); // profits /= SATOSHIDEN de-normalization averageCostbasis = mpz_get_ui(mpzAverageCostbasis); mpz_clear(mpzAverageCostbasis); @@ -1522,7 +1582,8 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) result.push_back(Pair("rektfee", totalbets / 500)); result.push_back(Pair("rektheight", (int64_t)endheight)); } - + + result.push_back(Pair("expression", prices_getsourceexpression(vec))); result.push_back(Pair("batontxid", batontxid.GetHex())); result.push_back(Pair("costbasis", ValueFromAmount(averageCostbasis))); From e587d489c956766c2d9e801175a2f4b30b9e167b Mon Sep 17 00:00:00 2001 From: dimxy Date: Thu, 2 May 2019 11:37:53 +0500 Subject: [PATCH 198/242] corr *// and *** price calc --- src/cc/prices.cpp | 90 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 76 insertions(+), 14 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 965c88e80..5fccd8774 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -525,9 +525,9 @@ UniValue prices_rawtxresult(UniValue &result, std::string rawtx, int32_t broadca return(result); } -std::string prices_getsourceexpression(std::vector &vec) { +static std::string prices_getsourceexpression(const std::vector &vec) { - std::string exp; + std::string expr; for (int32_t i = 0; i < vec.size(); i++) { @@ -555,7 +555,7 @@ std::string prices_getsourceexpression(std::vector &vec) { operand = std::string("/"); break; - case PRICES_INV: // "1/price" + case PRICES_INV: // "!" operand = std::string("!"); break; @@ -580,13 +580,75 @@ std::string prices_getsourceexpression(std::vector &vec) { break; } - if (exp.size() > 0) - exp += std::string(", "); - exp += operand; + if (expr.size() > 0) + expr += std::string(", "); + expr += operand; } - return exp; + return expr; } +static void prices_splitpair(const std::string &pair, std::string &upperquote, std::string &bottomquote) +{ + size_t pos = pair.find('_'); // like BTC_USD + if (pos != std::string::npos) { + upperquote = pair.substr(0, pos); + bottomquote = pair.substr(pos); + } + else { + upperquote = pair; + bottomquote = ""; + } +} + +// search for an upper or bottom quote in the vectored expression, remove it from the vector with its weight and with operation correction +static bool prices_tryextractpair(const std::vector &vexpr, size_t istart, const std::string "e, bool isSearchUpper, std::string &foundpair, int32_t &weight) { + +/* for (size_t i = istart; i < vexpr.size(); i++) { + if (komodo_priceind(vexpr[i].c_str()) >= 0) { + std::string upperquote, bottomquote; + prices_splitpair(vexpr[i], upperquote, bottomquote); + + if (quote == upperquote) { + if( ) + + } + + + } + }*/ + return true; +} + +// try to reduce synthetic expression by substituting "BTC_USD, 20, BTC_EUR, 30, *" with "EUR_USD, 30/20" +static std::string prices_reduceexp(const std::vector &vec) +{ + std::string reduced; + + + return reduced; +/* + std::vector vexpr; + SplitStr(expr, vexpr); + + for (size_t i = 0; i < vexpr.size(); i ++) { + if (komodo_priceind(vexpr[i].c_str()) >= 0) { + std::string upperquote, bottomquote; + std::string foundpair1, foundpair2; + int32_t weight1, weight2; + + prices_splitpair(vexpr[i], upperquote, bottomquote); + if (prices_tryextractpair(vexpr, i+1, upperquote, false, foundpair1, weight1)) { + + } + if (prices_tryextractpair(vexpr, i+1, bottomquote, true, foundpair2, weight2)) { + + } + } + } +*/ +} + + int32_t prices_syntheticvec(std::vector &vec, std::vector synthetic) { @@ -629,13 +691,13 @@ int32_t prices_syntheticvec(std::vector &vec, std::vector return(-3); } depth -= need; - std::cerr << "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; } if (depth > 3) { - std::cerr << "prices_syntheticvec() to many operands, last=" << opstr << std::endl; + std::cerr << "prices_syntheticvec() too many operands, last=" << opstr << std::endl; return(-4); } vec.push_back(opcode); @@ -743,7 +805,7 @@ int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t errcode = -4; break; - case PRICES_INV: // "1/price" + case PRICES_INV: // "!" if (depth >= 1) { a = pricestack[--depth]; // pricestack[depth++] = (SATOSHIDEN * SATOSHIDEN) / a; @@ -768,7 +830,7 @@ int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t mpz_set_si(mpzC, c); mpz_mul_ui(mpzResult, mpzA, SATOSHIDEN); mpz_tdiv_q(mpzResult, mpzResult, mpzB); - mpz_mul_ui(mpzResult, mpzA, SATOSHIDEN); + mpz_mul_ui(mpzResult, mpzResult, SATOSHIDEN); mpz_tdiv_q(mpzResult, mpzResult, mpzC); pricestack[depth++] = mpz_get_si(mpzResult); } @@ -798,13 +860,14 @@ int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t c = pricestack[--depth]; b = pricestack[--depth]; a = pricestack[--depth]; - // pricestack[depth++] = ((a * b) / SATOSHIDEN) * c; + // pricestack[depth++] = (((a * b) / SATOSHIDEN ) * c) / SATOSHIDEN; mpz_set_si(mpzA, a); mpz_set_si(mpzB, b); mpz_set_si(mpzC, c); mpz_mul(mpzResult, mpzA, mpzB); mpz_tdiv_q_ui(mpzResult, mpzResult, SATOSHIDEN); mpz_mul(mpzResult, mpzResult, mpzC); + mpz_tdiv_q_ui(mpzResult, mpzResult, SATOSHIDEN); pricestack[depth++] = mpz_get_si(mpzResult); } else @@ -1104,7 +1167,7 @@ UniValue PricesBet(int64_t txfee, int64_t amount, int16_t leverage, std::vector< CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nextheight); UniValue result(UniValue::VOBJ); struct CCcontract_info *cp, C; CPubKey pricespk, mypk; - int64_t betamount, firstprice; + int64_t betamount, firstprice = 0; std::vector vec; //char myaddr[64]; std::string rawtx; @@ -1123,7 +1186,6 @@ UniValue PricesBet(int64_t txfee, int64_t amount, int16_t leverage, std::vector< //GetCCaddress(cp, myaddr, mypk); if (prices_syntheticvec(vec, synthetic) < 0 || (firstprice = prices_syntheticprice(vec, nextheight - 1, 1, leverage)) < 0 || vec.size() == 0 || vec.size() > 4096) { - std::cerr << "PricesBet() firstprice=" << firstprice << (firstprice < 0 ? "error or overflow" : "") << std::endl; result.push_back(Pair("result", "error")); result.push_back(Pair("error", "invalid synthetic")); return(result); From 3ab22eb5ec79fa0a163f1128333cfdc84595d2d5 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Thu, 2 May 2019 16:07:27 +0800 Subject: [PATCH 199/242] add test chain exception. --- src/notaries_staked.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/notaries_staked.cpp b/src/notaries_staked.cpp index 0b7c97ceb..bb1518262 100644 --- a/src/notaries_staked.cpp +++ b/src/notaries_staked.cpp @@ -18,7 +18,7 @@ int8_t is_STAKED(const char *chain_name) if (doneinit == 1 && ASSETCHAINS_SYMBOL[0] != 0) return(STAKED); else STAKED = 0; - if ( (strcmp(chain_name, "LABS") == 0) || (strcmp(chain_name, "LABSTH") == 0) ) + if ( (strcmp(chain_name, "LABS") == 0) || (strcmp(chain_name, "LABSRCTEST") == 0) ) STAKED = 1; // These chains are allowed coin emissions. else if ( (strncmp(chain_name, "LABS", 4) == 0) ) STAKED = 2; // These chains have no coin emission, block subsidy is always 0, and comission is 0. Notary pay is allowed. From 8703305e7aa51801b165ca0358636634158059a5 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Thu, 2 May 2019 18:42:40 +0800 Subject: [PATCH 200/242] game commit --- src/cc/CCPayments.h | 1 + src/cc/payments.cpp | 341 +++++++++++++++++++++++++-------------- src/init.cpp | 13 ++ src/komodo_defs.h | 3 +- src/komodo_globals.h | 2 +- src/komodo_utils.h | 8 +- src/main.cpp | 16 +- src/miner.cpp | 6 +- src/wallet/rpcwallet.cpp | 2 +- 9 files changed, 250 insertions(+), 142 deletions(-) diff --git a/src/cc/CCPayments.h b/src/cc/CCPayments.h index cff304a2e..c45fbab9e 100644 --- a/src/cc/CCPayments.h +++ b/src/cc/CCPayments.h @@ -22,6 +22,7 @@ #define PAYMENTS_TXFEE 10000 extern std::vector > vAddressSnapshot; +extern int32_t lastSnapShotHeight; bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn); diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index e72184719..7ab3e8202 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -16,27 +16,6 @@ #include "CCPayments.h" /* -192.168.0.139: RH side screen. - ./komodod -ac_name=TESTDP -ac_supply=10000000 -ac_reward=1000000000 -ac_nk=96,5 -ac_blocktime=20 -ac_cc=2 -addndoe=192.168.0.112 - - TESTDP.tar saved after distributing funds randomly. approx block 120. -LH screen: - ./komodod -ac_name=TESTDP -ac_supply=10000000 -ac_reward=1000000000 -ac_nk=96,5 -ac_blocktime=20 -ac_cc=2 -pubkey=0244a96824fa317433f0eaa6d5b1faf68e802b1958df273c24cb82bce1ef8e1aec -gen -genproclimit=1 - -./komodo-cli -ac_name=TESTDP paymentsairdrop '[10,2000,500,"76a9149758abb81ee168dd3824cb55e94df509b35462d788ac",76a9144cfd873dadbfbb4b9c03e77ecaa6cfb74a484f4888ac"]' - -use notarizations DB to scan back from the correct height, then undo ALL blocks back to this notarized height! -payments airdrop: - - extra RPC to merge all payments inputs to a single utxo, this must be called first and be confirmed before payments release, - or tx will be too big, we can check add payments inputs is only 1 input, at RPC and in validation very early on. - - do getsnapshot2 every 1440 blocks and save the result into some global sorted vector. - -this allows any address balance to be calculated by only iterating each 1439 blocks maximum. - - calculate scriptpubkey to pay from each address, set allocations from balance of each address. allocation = balance? - -payments airdrop paying a token: - - tokenid, top number of tokens to pay, list of pubkeys to exclude as optional param - - token airdrop code should be the same as normal snapshot, but call a diffrent snapshot function that only fetches the info for a specific tokenid given. - this should be fine to work in validation/rpc level rather than a global saved result, as a single token id doesnt require iterating the whole DB. - 0) txidopret <- allocation, scriptPubKey, opret 1) create <- locked_blocks, minrelease, list of txidopret @@ -138,6 +117,26 @@ uint8_t DecodePaymentsFundOpRet(CScript scriptPubKey,uint256 &checktxid) return(0); } +CScript EncodePaymentsMergeOpRet(uint256 checktxid) +{ + CScript opret; uint8_t evalcode = EVAL_PAYMENTS; + opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'M' << checktxid); + return(opret); +} + +uint8_t DecodePaymentsMergeOpRet(CScript scriptPubKey,uint256 &checktxid) +{ + std::vector vopret; uint8_t *script,e,f; + GetOpReturnData(scriptPubKey, vopret); + script = (uint8_t *)vopret.data(); + if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> checktxid) != 0 ) + { + if ( e == EVAL_PAYMENTS && f == 'M' ) + return(f); + } + return(0); +} + CScript EncodePaymentsOpRet(int32_t lockedblocks,int32_t minrelease,int64_t totalallocations,std::vector txidoprets) { CScript opret; uint8_t evalcode = EVAL_PAYMENTS; @@ -158,20 +157,19 @@ uint8_t DecodePaymentsOpRet(CScript scriptPubKey,int32_t &lockedblocks,int32_t & return(0); } - -CScript EncodePaymentsSnapsShotOpRet(int32_t lockedblocks,int32_t minrelease,int32_t top,std::vector> excludeScriptPubKeys) +CScript EncodePaymentsSnapsShotOpRet(int32_t lockedblocks,int32_t minrelease,int32_t top,int32_t bottom,int8_t fixedAmount,std::vector> excludeScriptPubKeys) { CScript opret; uint8_t evalcode = EVAL_PAYMENTS; - opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'S' << lockedblocks << minrelease << top << excludeScriptPubKeys); + opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'S' << lockedblocks << minrelease << top << bottom << fixedAmount << excludeScriptPubKeys); return(opret); } -uint8_t DecodePaymentsSnapsShotOpRet(CScript scriptPubKey,int32_t &lockedblocks,int32_t &minrelease,int32_t &top,std::vector> &excludeScriptPubKeys) +uint8_t DecodePaymentsSnapsShotOpRet(CScript scriptPubKey,int32_t &lockedblocks,int32_t &minrelease,int32_t &top,int32_t &bottom,int8_t &fixedAmount,std::vector> &excludeScriptPubKeys) { std::vector vopret; uint8_t *script,e,f; GetOpReturnData(scriptPubKey, vopret); script = (uint8_t *)vopret.data(); - if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> lockedblocks; ss >> minrelease; ss >> top; ss >> excludeScriptPubKeys) != 0 ) + if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> lockedblocks; ss >> minrelease; ss >> top; ; ss >> bottom; ss >> fixedAmount; ss >> excludeScriptPubKeys) != 0 ) { if ( e == EVAL_PAYMENTS && f == 'S' ) return(f); @@ -233,9 +231,9 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & // change is/must be in vout[0] // only 'F' or 1of2 txidaddr can be spent // all vouts must match exactly - char temp[128], coinaddr[64], txidaddr[64]; std::string scriptpubkey; uint256 createtxid, blockhash, tokenid; CTransaction plantx; uint8_t funcid = 0; + char temp[128], coinaddr[64], txidaddr[64]; std::string scriptpubkey; uint256 createtxid, blockhash, tokenid; CTransaction plantx; int8_t funcid=0, fixedAmount=0; int32_t i,lockedblocks,minrelease; int64_t change,totalallocations; std::vector txidoprets; bool fHasOpret = false; CPubKey txidpk,Paymentspk; - int32_t top; std::vector> excludeScriptPubKeys; + int32_t top,bottom=0; std::vector> excludeScriptPubKeys; bool fFixedAmount = false; mpz_t mpzTotalAllocations, mpzAllocation;; mpz_init(mpzTotalAllocations); // user marker vout to get the createtxid if ( tx.vout.size() < 2 ) @@ -253,9 +251,9 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & // use the createtxid to fetch the tx and all of the plans info. if ( myGetTransaction(createtxid,plantx,blockhash) != 0 && plantx.vout.size() > 0 ) { - if ( ((funcid= DecodePaymentsOpRet(plantx.vout[plantx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets)) == 'C' || (funcid= DecodePaymentsSnapsShotOpRet(plantx.vout[plantx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys)) == 'S' || (funcid= DecodePaymentsTokensOpRet(plantx.vout[plantx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys,tokenid)) == 'O') ) + if ( ((funcid= DecodePaymentsOpRet(plantx.vout[plantx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets)) == 'C' || (funcid= DecodePaymentsSnapsShotOpRet(plantx.vout[plantx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,bottom,fixedAmount,excludeScriptPubKeys)) == 'S' || (funcid= DecodePaymentsTokensOpRet(plantx.vout[plantx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys,tokenid)) == 'O') ) { - if ( lockedblocks < 0 || minrelease < 0 || totalallocations <= 0 ) + if ( lockedblocks < 0 || minrelease < 0 || (totalallocations <= 0 && top <= 0 ) ) return(eval->Invalid("negative values")); Paymentspk = GetUnspendable(cp,0); txidpk = CCtxidaddr(txidaddr,createtxid); @@ -301,32 +299,60 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & } else if ( funcid == 'S' ) { + if ( KOMODO_SNAPSHOT_INTERVAL == 0 ) + return(eval->Invalid("snapshots not activated on this chain")); + if ( vAddressSnapshot.size() == 0 ) + return(eval->Invalid("need first snapshot")); // need time for TX to me mined before the next snapshot. - if ( top > 5000 ) + if ( top > 3999 ) return(eval->Invalid("transaction too big")); - for ( auto address : vAddressSnapshot ) + if ( fixedAmount == 7 ) { - CScript scriptPubKey = GetScriptForDestination(address.second); - for ( auto skipkey : excludeScriptPubKeys ) + // game setting, randomise bottom and top values + uint64_t x; + uint256 tmphash = chainActive[lastSnapShotHeight]->GetBlockHash(); + memcpy(&x,&tmphash,sizeof(x)); + bottom = ((x & 0xff) % 50); + if ( bottom == 0 ) bottom = 1; + top = (((x>>8) & 0xff) % 100); + if ( top < 50 ) top += 50; + bottom = (vAddressSnapshot.size()*bottom)/100; + top = (vAddressSnapshot.size()*top)/100; + fprintf(stderr, "bottom.%i top.%i\n",bottom,top); + fFixedAmount = true; + } + else if ( fixedAmount != 0 ) + { + fFixedAmount = true; + } + for (int32_t j = bottom; j < vAddressSnapshot.size(); j++) + { + auto &address = vAddressSnapshot[j]; + CScript scriptPubKey = GetScriptForDestination(address.second); bool skip = false; + for ( auto skipkey : excludeScriptPubKeys ) { - //fprintf(stderr, "scriptpubkey.%s\n skipkey.%s", HexStr(scriptPubKey).c_str(), HexStr(CScript(skipkey.begin(), skipkey.end())).c_str()); - if ( scriptPubKey != CScript(skipkey.begin(), skipkey.end()) ) + if ( scriptPubKey == CScript(skipkey.begin(), skipkey.end()) ) { - mpz_init(mpzAllocation); - i++; - scriptPubKeys.push_back(scriptPubKey); - allocations.push_back(address.first); - mpz_set_si(mpzAllocation,address.first); - mpz_add(mpzTotalAllocations,mpzTotalAllocations,mpzAllocation); - mpz_clear(mpzAllocation); - } + skip = true; + //fprintf(stderr, "SKIPPED::: %s\n", CBitcoinAddress(address.second).ToString().c_str()); + } } - if ( i == top ) // we reached top amount to pay, it can be less than this! + if ( !skip ) + { + mpz_init(mpzAllocation); + i++; + scriptPubKeys.push_back(scriptPubKey); + allocations.push_back(address.first); + mpz_set_si(mpzAllocation,address.first); + mpz_add(mpzTotalAllocations,mpzTotalAllocations,mpzAllocation); + mpz_clear(mpzAllocation); + } + if ( i+bottom == top ) // we reached top amount to pay, it can be less than this! break; } if ( i != tx.vout.size()-2 ) return(eval->Invalid("pays wrong amount of recipients")); - } + } else if ( funcid == 'O' ) { // tokens snapshot. @@ -355,12 +381,20 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & fprintf(stderr, "pays wrong destination destscriptPubKey.%s voutscriptPubKey.%s\n", HexStr(scriptPubKeys[n].begin(),scriptPubKeys[n].end()).c_str(), HexStr(tx.vout[i].scriptPubKey.begin(),tx.vout[i].scriptPubKey.end()).c_str()); return(eval->Invalid("pays wrong address")); } - mpz_init(mpzAllocation); - mpz_set_si(mpzAllocation,allocations[n]); - mpz_mul(mpzAllocation,mpzAllocation,mpzCheckamount); - mpz_cdiv_q(mpzAllocation,mpzAllocation,mpzTotalAllocations); - int64_t test = mpz_get_si(mpzAllocation); - mpz_clear(mpzAllocation); + int64_t test; + if ( fFixedAmount ) + { + test = checkamount / (top-bottom); + } + else + { + mpz_init(mpzAllocation); + mpz_set_si(mpzAllocation,allocations[n]); + mpz_mul(mpzAllocation,mpzAllocation,mpzCheckamount); + mpz_cdiv_q(mpzAllocation,mpzAllocation,mpzTotalAllocations); + test = mpz_get_si(mpzAllocation); + mpz_clear(mpzAllocation); + } // Vairance of 1 sat is allowed, for rounding errors. if ( test >= tx.vout[i].nValue+1 && test <= tx.vout[i].nValue-1 ) { @@ -571,7 +605,7 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) int32_t latestheight,nextheight = komodo_nextheight(); CMutableTransaction tmpmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(),nextheight); UniValue result(UniValue::VOBJ); uint256 createtxid,hashBlock,tokenid; CTransaction tx,txO; CPubKey mypk,txidpk,Paymentspk; int32_t i,n,m,numoprets=0,lockedblocks,minrelease; int64_t newamount,inputsum,amount,CCchange=0,totalallocations=0,checkallocations=0,allocation; CTxOut vout; CScript onlyopret; char txidaddr[64],destaddr[64]; std::vector txidoprets; - int32_t top; std::vector> excludeScriptPubKeys; int8_t funcid; + int32_t top,bottom=0; std::vector> excludeScriptPubKeys; int8_t funcid,fixedAmount=0; bool fFixedAmount = false; mpz_t mpzTotalAllocations; mpz_init(mpzTotalAllocations); cJSON *params = payments_reparse(&n,jsonstr); mypk = pubkey2pk(Mypubkey()); @@ -582,9 +616,9 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) amount = jdouble(jitem(params,1),0) * SATOSHIDEN + 0.0000000049; if ( myGetTransaction(createtxid,tx,hashBlock) != 0 && tx.vout.size() > 0 ) { - if ( ((funcid= DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets)) == 'C' || (funcid= DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys)) == 'S' || (funcid= DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys,tokenid)) == 'O') ) + if ( ((funcid= DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets)) == 'C' || (funcid= DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,bottom,fixedAmount,excludeScriptPubKeys)) == 'S' || (funcid= DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys,tokenid)) == 'O') ) { - if ( lockedblocks < 0 || minrelease < 0 || totalallocations <= 0 ) + if ( lockedblocks < 0 || minrelease < 0 || (totalallocations <= 0 && top <= 0 ) ) { result.push_back(Pair("result","error")); result.push_back(Pair("error","negative parameter")); @@ -605,7 +639,8 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) } txidpk = CCtxidaddr(txidaddr,createtxid); mtx.vout.push_back(MakeCC1of2vout(EVAL_PAYMENTS,0,Paymentspk,txidpk)); - if ( funcid = 'C' ) + //fprintf(stderr, "funcid.%i\n", funcid); + if ( funcid == 'C' ) { // normal payments for (i=0; i 5000 ) + if ( vAddressSnapshot.size() == 0 ) { - // need to test the maximum number, this is an estimate. result.push_back(Pair("result","error")); - result.push_back(Pair("error","cannot pay more than 5000 addresses")); + result.push_back(Pair("error","first snapshot has not happened yet")); if ( params != 0 ) free_json(params); return(result); } - for ( auto address : vAddressSnapshot ) + if ( top > 3999 ) { - CScript scriptPubKey = GetScriptForDestination(address.second); - for ( auto skipkey : excludeScriptPubKeys ) + result.push_back(Pair("result","error")); + result.push_back(Pair("error","cannot pay more than 3999 addresses")); + if ( params != 0 ) + free_json(params); + return(result); + } + i = 0; + //for ( auto address : vAddressSnapshot ) + if ( fixedAmount == 7 ) + { + // game setting, randomise bottom and top values + uint64_t x; + uint256 tmphash = chainActive[lastSnapShotHeight]->GetBlockHash(); + memcpy(&x,&tmphash,sizeof(x)); + bottom = ((x & 0xff) % 50); + if ( bottom == 0 ) bottom = 1; + top = (((x>>8) & 0xff) % 100); + if ( top < 50 ) top += 50; + bottom = (vAddressSnapshot.size()*bottom)/100; + top = (vAddressSnapshot.size()*top)/100; + fprintf(stderr, "bottom.%i top.%i\n",bottom,top); + fFixedAmount = true; + } + else if ( fixedAmount != 0 ) + { + fFixedAmount = true; + } + for (int32_t j = bottom; j < vAddressSnapshot.size(); j++) + { + auto &address = vAddressSnapshot[j]; + CScript scriptPubKey = GetScriptForDestination(address.second); bool skip = false; + for ( auto skipkey : excludeScriptPubKeys ) { - if ( scriptPubKey != CScript(skipkey.begin(), skipkey.end()) ) + if ( scriptPubKey == CScript(skipkey.begin(), skipkey.end()) ) { - mpz_t mpzAllocation; mpz_init(mpzAllocation); - i++; - //fprintf(stderr, "address: %s nValue.%li \n", CBitcoinAddress(address.second).ToString().c_str(), address.first); - vout.nValue = address.first; - vout.scriptPubKey = scriptPubKey; - mpz_set_si(mpzAllocation,address.first); - mpz_add(mpzTotalAllocations,mpzTotalAllocations,mpzAllocation); //totalallocations += address.first; - mtx.vout.push_back(vout); - mpz_clear(mpzAllocation); - } else fprintf(stderr, "SKIPPED::: %s\n", CBitcoinAddress(address.second).ToString().c_str()); + skip = true; + //fprintf(stderr, "SKIPPED::: %s\n", CBitcoinAddress(address.second).ToString().c_str()); + } } - if ( i == top ) // we reached top amount to pay, it can be less than this! + if ( !skip ) + { + mpz_t mpzAllocation; mpz_init(mpzAllocation); + i++; + //fprintf(stderr, "address: %s nValue.%li \n", CBitcoinAddress(address.second).ToString().c_str(), address.first); + vout.nValue = address.first; + vout.scriptPubKey = scriptPubKey; + mpz_set_si(mpzAllocation,address.first); + mpz_add(mpzTotalAllocations,mpzTotalAllocations,mpzAllocation); + mtx.vout.push_back(vout); + mpz_clear(mpzAllocation); + } + if ( i+bottom == top ) // we reached top amount to pay, it can be less than this! break; } m = i; // this is the amount we got, either top, or all of the address on the chain. } - else if ( funcid = 'O' ) + else if ( funcid == 'O' ) { // token snapshot } newamount = amount; int64_t totalamountsent = 0; mpz_t mpzAmount; mpz_init(mpzAmount); mpz_set_si(mpzAmount,amount); + fprintf(stderr, "m.%i\n",m); for (i=0; i txidoprets; - int32_t top; std::vector> excludeScriptPubKeys; // snapshot - uint256 tokenid; + int32_t top,bottom; std::vector> excludeScriptPubKeys; // snapshot + uint256 tokenid; int8_t fixedAmount; cJSON *params = payments_reparse(&n,jsonstr); mypk = pubkey2pk(Mypubkey()); Paymentspk = GetUnspendable(cp,0); @@ -789,14 +869,14 @@ UniValue PaymentsFund(struct CCcontract_info *cp,char *jsonstr) amount = jdouble(jitem(params,1),0) * SATOSHIDEN + 0.0000000049; if ( n == 3 ) useopret = jint(jitem(params,2),0) != 0; - if ( myGetTransaction(txid,tx,hashBlock) == 0 || tx.vout.size() == 1 || (DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) == 0 && DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys) == 0 && DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys,tokenid) == 0) ) + if ( myGetTransaction(txid,tx,hashBlock) == 0 || tx.vout.size() == 1 || (DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) == 0 && DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,bottom,fixedAmount,excludeScriptPubKeys) == 0 && DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys,tokenid) == 0) ) { result.push_back(Pair("result","error")); result.push_back(Pair("error","invalid createtxid")); } else if ( AddNormalinputs(mtx,mypk,amount+PAYMENTS_TXFEE,60) > 0 ) { - if ( lockedblocks < 0 || minrelease < 0 || totalallocations <= 0 ) + if ( lockedblocks < 0 || minrelease < 0 || (totalallocations <= 0 && top <= 0 ) ) { result.push_back(Pair("result","error")); result.push_back(Pair("error","negative parameter")); @@ -961,43 +1041,54 @@ UniValue PaymentsAirdrop(struct CCcontract_info *cp,char *jsonstr) CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); UniValue result(UniValue::VOBJ); uint256 hashBlock; CTransaction tx; CPubKey Paymentspk,mypk; char markeraddr[64]; std::string rawtx; - int32_t lockedblocks,minrelease,top,n,i; std::vector> excludeScriptPubKeys; + int32_t lockedblocks,minrelease,top,bottom,n,i; std::vector> excludeScriptPubKeys; int8_t fixedAmount; + if ( KOMODO_SNAPSHOT_INTERVAL == 0 ) + { + result.push_back(Pair("result","error")); + result.push_back(Pair("error","cannot use airdrop wihtout -ac_snapshot set.")); + return(result); + } cJSON *params = payments_reparse(&n,jsonstr); - if ( params != 0 && n >= 4 ) + if ( params != 0 && n >= 5 ) { lockedblocks = juint(jitem(params,0),0); minrelease = juint(jitem(params,1),0); top = juint(jitem(params,2),0); - if ( lockedblocks < 0 || minrelease < 0 || top < 0 ) + bottom = juint(jitem(params,3),0); + fixedAmount = juint(jitem(params,4),0); // fixed amount is a flag set to 0 or 1. It means allocations are equal rather than weighted by address balance. + if ( lockedblocks < 0 || minrelease < 0 || top <= 0 || bottom < 0 || fixedAmount < 0 || top > 3999 ) { result.push_back(Pair("result","error")); - result.push_back(Pair("error","negative parameter")); + result.push_back(Pair("error","negative parameter, or top over 3999")); if ( params != 0 ) free_json(params); return(result); } - for (i=0; i 5 ) { - /* TODO: Change this RPC to take an address. Because a tokens airdrop needs its own RPC anyway. - CTxDestination destination = DecodeDestination(name_); - CScript scriptPubKey = GetScriptForDestination(destination); - */ - char *inputhex = jstri(params,3+i); - std::vector scriptPubKey; - int32_t len = strlen(inputhex)/2; - scriptPubKey.resize(len); - decode_hex((uint8_t *)scriptPubKey.data(),len,(char *)inputhex); - excludeScriptPubKeys.push_back(scriptPubKey); + for (i=0; i scriptPubKey; + int32_t len = strlen(inputhex)/2; + scriptPubKey.resize(len); + decode_hex((uint8_t *)scriptPubKey.data(),len,(char *)inputhex); + excludeScriptPubKeys.push_back(scriptPubKey); + } } mypk = pubkey2pk(Mypubkey()); Paymentspk = GetUnspendable(cp,0); if ( AddNormalinputs(mtx,mypk,2*PAYMENTS_TXFEE,60) > 0 ) { mtx.vout.push_back(MakeCC1of2vout(cp->evalcode,PAYMENTS_TXFEE,Paymentspk,Paymentspk)); - rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,EncodePaymentsSnapsShotOpRet(lockedblocks,minrelease,top,excludeScriptPubKeys)); + rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,EncodePaymentsSnapsShotOpRet(lockedblocks,minrelease,top,bottom,fixedAmount,excludeScriptPubKeys)); 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","not enough normal funds")); @@ -1015,8 +1106,8 @@ UniValue PaymentsAirdrop(struct CCcontract_info *cp,char *jsonstr) UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr) { UniValue result(UniValue::VOBJ),a(UniValue::VARR); CTransaction tx,txO; CPubKey Paymentspk,txidpk; int32_t i,j,n,flag=0,numoprets=0,lockedblocks,minrelease; std::vector txidoprets; int64_t funds,fundsopret,totalallocations=0,allocation; char fundsaddr[64],fundsopretaddr[64],txidaddr[64],*outstr; uint256 createtxid,hashBlock; - int32_t top; std::vector> excludeScriptPubKeys; // snapshot - uint256 tokenid; + int32_t top,bottom; std::vector> excludeScriptPubKeys; // snapshot + uint256 tokenid; int8_t fixedAmount; cJSON *params = payments_reparse(&n,jsonstr); if ( params != 0 && n == 1 ) { @@ -1071,9 +1162,9 @@ UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr) result.push_back(Pair("error","too many opreturns")); } else result.push_back(Pair("txidoprets",a)); } - else if ( DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys) != 0 ) + else if ( DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,bottom,fixedAmount,excludeScriptPubKeys) != 0 ) { - if ( lockedblocks < 0 || minrelease < 0 || top <= 0 ) + if ( lockedblocks < 0 || minrelease < 0 || top <= 0 || bottom < 0 || fixedAmount < 0 || top > 3999 ) { result.push_back(Pair("result","error")); result.push_back(Pair("error","negative parameter")); @@ -1085,6 +1176,9 @@ UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr) result.push_back(Pair("lockedblocks",(int64_t)lockedblocks)); result.push_back(Pair("minrelease",(int64_t)minrelease)); result.push_back(Pair("top",(int64_t)top)); + result.push_back(Pair("bottom",(int64_t)bottom)); + result.push_back(Pair("fixedFlag",(int64_t)fixedAmount)); + // TODO: convert to show addresses instead of scriptpubkey. for ( auto scriptPubKey : excludeScriptPubKeys ) a.push_back(HexStr(scriptPubKey.begin(),scriptPubKey.end())); result.push_back(Pair("excludeScriptPubkeys",a)); @@ -1104,6 +1198,7 @@ UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr) result.push_back(Pair("minrelease",(int64_t)minrelease)); result.push_back(Pair("top",(int64_t)top)); result.push_back(Pair("tokenid",tokenid.ToString())); + // TODO: show pubkeys instead of scriptpubkeys for ( auto scriptPubKey : excludeScriptPubKeys ) a.push_back(HexStr(scriptPubKey.begin(),scriptPubKey.end())); result.push_back(Pair("excludeScriptPubkeys",a)); @@ -1146,8 +1241,8 @@ UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr) UniValue PaymentsList(struct CCcontract_info *cp,char *jsonstr) { std::vector > addressIndex; uint256 txid,hashBlock,tokenid; - UniValue result(UniValue::VOBJ),a(UniValue::VARR); char markeraddr[64],str[65]; CPubKey Paymentspk; CTransaction tx; int32_t lockedblocks,minrelease; std::vector txidoprets; int64_t totalallocations; - int32_t top; std::vector> excludeScriptPubKeys; + UniValue result(UniValue::VOBJ),a(UniValue::VARR); char markeraddr[64],str[65]; CPubKey Paymentspk; CTransaction tx; int32_t lockedblocks,minrelease; std::vector txidoprets; int64_t totalallocations=0; + int32_t top=0,bottom=0; std::vector> excludeScriptPubKeys; int8_t fixedAmount = 0; Paymentspk = GetUnspendable(cp,0); GetCCaddress1of2(cp,markeraddr,Paymentspk,Paymentspk); SetCCtxids(addressIndex,markeraddr,true); @@ -1156,9 +1251,9 @@ UniValue PaymentsList(struct CCcontract_info *cp,char *jsonstr) txid = it->first.txhash; if ( it->first.index == 0 && myGetTransaction(txid,tx,hashBlock) != 0 ) { - if ( tx.vout.size() > 0 && (DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) == 'C' || DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys) == 'S' || DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys,tokenid) == 'O') ) + if ( tx.vout.size() > 0 && (DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) == 'C' || DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,bottom,fixedAmount,excludeScriptPubKeys) == 'S' || DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys,tokenid) == 'O') ) { - if ( lockedblocks < 0 || minrelease < 0 || totalallocations <= 0 || txidoprets.size() < 2 ) + if ( lockedblocks < 0 || minrelease < 0 || (totalallocations <= 0 && top <= 0 ) || bottom < 0 || fixedAmount < 0 ) { result.push_back(Pair("result","error")); result.push_back(Pair("error","negative parameter")); @@ -1169,6 +1264,6 @@ UniValue PaymentsList(struct CCcontract_info *cp,char *jsonstr) } } result.push_back(Pair("result","success")); - result.push_back(Pair("createtxids",a)); - return(result); + result.push_back(Pair("createtxids",a)); + return(result); } diff --git a/src/init.cpp b/src/init.cpp index 4003f9ced..bab2aba77 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -35,6 +35,7 @@ #include "httprpc.h" #include "key.h" #include "notarisationdb.h" + #ifdef ENABLE_MINING #include "key_io.h" #endif @@ -55,6 +56,7 @@ #ifdef ENABLE_WALLET #include "wallet/wallet.h" #include "wallet/walletdb.h" + #endif #include #include @@ -89,9 +91,11 @@ using namespace std; extern void ThreadSendAlert(); +extern bool komodo_dailysnapshot(int32_t height); extern int32_t KOMODO_LOADINGBLOCKS; extern bool VERUS_MINTBLOCKS; extern char ASSETCHAINS_SYMBOL[]; +extern int32_t KOMODO_SNAPSHOT_INTERVAL; ZCJoinSplit* pzcashParams = NULL; @@ -1622,6 +1626,15 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) strLoadError = _("You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain"); break; } + + if ( ASSETCHAINS_CC != 0 && KOMODO_SNAPSHOT_INTERVAL != 0 && chainActive.Height() > KOMODO_SNAPSHOT_INTERVAL ) + { + if ( !komodo_dailysnapshot(chainActive.Height()) ) + { + strLoadError = _("daily snapshot failed, please reindex your chain."); + break; + } + } if (!fReindex) { uiInterface.InitMessage(_("Rewinding blocks if needed...")); diff --git a/src/komodo_defs.h b/src/komodo_defs.h index a9df99c0e..a3bde708b 100644 --- a/src/komodo_defs.h +++ b/src/komodo_defs.h @@ -20,7 +20,6 @@ #define ASSETCHAINS_MINHEIGHT 128 #define ASSETCHAINS_MAX_ERAS 3 #define KOMODO_ELECTION_GAP 2000 -#define KOMODO_SNAPSHOT_INTERVAL 1440 // 1440 is approx 1 day. Maybe this can be -ac param to allow for diffrent block times etc.? #define ROUNDROBIN_DELAY 61 #define KOMODO_ASSETCHAIN_MAXLEN 65 #define KOMODO_LIMITED_NETWORKSIZE 4 @@ -79,7 +78,7 @@ extern std::string DONATION_PUBKEY; extern uint8_t ASSETCHAINS_PRIVATE; extern int32_t USE_EXTERNAL_PUBKEY; extern char NOTARYADDRS[64][64]; -extern int32_t KOMODO_TESTNODE; +extern int32_t KOMODO_TESTNODE, KOMODO_SNAPSHOT_INTERVAL; int tx_height( const uint256 &hash ); extern std::vector vWhiteListAddress; void komodo_netevent(std::vector payload); diff --git a/src/komodo_globals.h b/src/komodo_globals.h index dc8cbda35..8d440cbaf 100644 --- a/src/komodo_globals.h +++ b/src/komodo_globals.h @@ -109,7 +109,7 @@ uint64_t PENDING_KOMODO_TX; extern int32_t KOMODO_LOADINGBLOCKS; unsigned int MAX_BLOCK_SIGOPS = 20000; -int32_t KOMODO_TESTNODE; +int32_t KOMODO_TESTNODE, KOMODO_SNAPSHOT_INTERVAL; struct komodo_kv *KOMODO_KV; pthread_mutex_t KOMODO_KV_mutex,KOMODO_CC_mutex; diff --git a/src/komodo_utils.h b/src/komodo_utils.h index cfb133a9d..137bace4c 100644 --- a/src/komodo_utils.h +++ b/src/komodo_utils.h @@ -1752,6 +1752,7 @@ void komodo_args(char *argv0) ASSETCHAINS_BLOCKTIME = GetArg("-ac_blocktime",60); ASSETCHAINS_PUBLIC = GetArg("-ac_public",0); ASSETCHAINS_PRIVATE = GetArg("-ac_private",0); + KOMODO_SNAPSHOT_INTERVAL = GetArg("-ac_snapshot",0); Split(GetArg("-ac_nk",""), ASSETCHAINS_NK, 0); if ( (KOMODO_REWIND= GetArg("-rewind",0)) != 0 ) { @@ -2012,7 +2013,7 @@ void komodo_args(char *argv0) fprintf(stderr,"-ac_script and -ac_marmara are mutually exclusive\n"); StartShutdown(); } - if ( ASSETCHAINS_ENDSUBSIDY[0] != 0 || ASSETCHAINS_REWARD[0] != 0 || ASSETCHAINS_HALVING[0] != 0 || ASSETCHAINS_DECAY[0] != 0 || ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_PUBLIC != 0 || ASSETCHAINS_PRIVATE != 0 || ASSETCHAINS_TXPOW != 0 || ASSETCHAINS_FOUNDERS != 0 || ASSETCHAINS_SCRIPTPUB.size() > 1 || ASSETCHAINS_SELFIMPORT.size() > 0 || ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 || ASSETCHAINS_TIMELOCKGTE != _ASSETCHAINS_TIMELOCKOFF|| ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH || ASSETCHAINS_LWMAPOS != 0 || ASSETCHAINS_LASTERA > 0 || ASSETCHAINS_BEAMPORT != 0 || ASSETCHAINS_CODAPORT != 0 || ASSETCHAINS_MARMARA != 0 || nonz > 0 || ASSETCHAINS_CCLIB.size() > 0 || ASSETCHAINS_FOUNDERS_REWARD != 0 || ASSETCHAINS_NOTARY_PAY[0] != 0 || ASSETCHAINS_BLOCKTIME != 60 || ASSETCHAINS_CBOPRET != 0 || Mineropret.size() != 0 || (ASSETCHAINS_NK[0] != 0 && ASSETCHAINS_NK[1] != 0) ) + if ( ASSETCHAINS_ENDSUBSIDY[0] != 0 || ASSETCHAINS_REWARD[0] != 0 || ASSETCHAINS_HALVING[0] != 0 || ASSETCHAINS_DECAY[0] != 0 || ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_PUBLIC != 0 || ASSETCHAINS_PRIVATE != 0 || ASSETCHAINS_TXPOW != 0 || ASSETCHAINS_FOUNDERS != 0 || ASSETCHAINS_SCRIPTPUB.size() > 1 || ASSETCHAINS_SELFIMPORT.size() > 0 || ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 || ASSETCHAINS_TIMELOCKGTE != _ASSETCHAINS_TIMELOCKOFF|| ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH || ASSETCHAINS_LWMAPOS != 0 || ASSETCHAINS_LASTERA > 0 || ASSETCHAINS_BEAMPORT != 0 || ASSETCHAINS_CODAPORT != 0 || ASSETCHAINS_MARMARA != 0 || nonz > 0 || ASSETCHAINS_CCLIB.size() > 0 || ASSETCHAINS_FOUNDERS_REWARD != 0 || ASSETCHAINS_NOTARY_PAY[0] != 0 || ASSETCHAINS_BLOCKTIME != 60 || ASSETCHAINS_CBOPRET != 0 || Mineropret.size() != 0 || (ASSETCHAINS_NK[0] != 0 && ASSETCHAINS_NK[1] != 0) || KOMODO_SNAPSHOT_INTERVAL != 0 ) { fprintf(stderr,"perc %.4f%% ac_pub=[%02x%02x%02x...] acsize.%d\n",dstr(ASSETCHAINS_COMMISSION)*100,ASSETCHAINS_OVERRIDE_PUBKEY33[0],ASSETCHAINS_OVERRIDE_PUBKEY33[1],ASSETCHAINS_OVERRIDE_PUBKEY33[2],(int32_t)ASSETCHAINS_SCRIPTPUB.size()); extraptr = extrabuf; @@ -2148,6 +2149,11 @@ void komodo_args(char *argv0) extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_NK[0]),(void *)&ASSETCHAINS_NK[0]); extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_NK[1]),(void *)&ASSETCHAINS_NK[1]); } + if ( KOMODO_SNAPSHOT_INTERVAL != 0 ) + { + extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(KOMODO_SNAPSHOT_INTERVAL),(void *)&KOMODO_SNAPSHOT_INTERVAL); + fprintf(stderr, "snapshot interval.%i\n",KOMODO_SNAPSHOT_INTERVAL); + } } addn = GetArg("-seednode",""); diff --git a/src/main.cpp b/src/main.cpp index 3168b773c..ef1a1a40b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -673,7 +673,7 @@ bool komodo_dailysnapshot(int32_t height) { // we are at the right height in connect block to scan back to last notarized height. notarized_height = komodo_notarized_height(&prevMoMheight,¬arized_hash,¬arized_desttxid); - notarized_height > height-100 ? undo_height = notarized_height : undo_height = height-reorglimit; + notarized_height > height-reorglimit ? undo_height = notarized_height : undo_height = height-reorglimit; } fprintf(stderr, "doing snapshot for height.%i undo_height.%i\n", height, undo_height); // if we already did this height dont bother doing it again, this is just a reorg. The actual snapshot height cannot be reorged. @@ -732,7 +732,7 @@ bool komodo_dailysnapshot(int32_t height) //for (int j = 0; j < 50; j++) // fprintf(stderr, "j.%i address.%s nValue.%li\n",j, CBitcoinAddress(vAddressSnapshot[j].second).ToString().c_str(), vAddressSnapshot[j].first ); // include only top 5000 address. - if ( vAddressSnapshot.size() > 5000 ) vAddressSnapshot.resize(5000); + if ( vAddressSnapshot.size() > 3999 ) vAddressSnapshot.resize(3999); lastSnapShotHeight = undo_height; fprintf(stderr, "vAddressSnapshot.size.%li\n", vAddressSnapshot.size()); return true; @@ -3592,8 +3592,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin fprintf(stderr,"valueout %.8f too big\n",(double)valueout/COIN); return state.DoS(100, error("ConnectBlock(): GetValueOut too big"),REJECT_INVALID,"tx valueout is too big"); } - prevsum = voutsum; - voutsum += valueout; + //prevsum = voutsum; + //voutsum += valueout; /*if ( KOMODO_VALUETOOBIG(voutsum) != 0 ) { fprintf(stderr,"voutsum %.8f too big\n",(double)voutsum/COIN); @@ -4251,7 +4251,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * komodo_pricesupdate(pindexNew->GetHeight(),pblock); if ( ASSETCHAINS_SAPLING <= 0 && pindexNew->nTime > KOMODO_SAPLING_ACTIVATION - 24*3600 ) komodo_activate_sapling(pindexNew); - if ( ASSETCHAINS_CC != 0 && (pindexNew->GetHeight() % KOMODO_SNAPSHOT_INTERVAL) == 0 ) + if ( ASSETCHAINS_CC != 0 && KOMODO_SNAPSHOT_INTERVAL != 0 && (pindexNew->GetHeight() % KOMODO_SNAPSHOT_INTERVAL) == 0 && pindexNew->GetHeight() > KOMODO_SNAPSHOT_INTERVAL ) { uint64_t start = time(NULL); if ( !komodo_dailysnapshot(pindexNew->GetHeight()) ) @@ -6198,12 +6198,6 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth LogPrintf("No coin database inconsistencies in last %i blocks (%i transactions)\n", chainActive.Height() - pindexState->GetHeight(), nGoodTransactions); - if ( ASSETCHAINS_CC != 0 && chainActive.Height() > KOMODO_SNAPSHOT_INTERVAL ) - { - if ( !komodo_dailysnapshot(chainActive.Height()) ) - fprintf(stderr, "daily snapshot failed, please reindex your chain\n"); // maybe force shutdown here? - } - return true; } diff --git a/src/miner.cpp b/src/miner.cpp index a2ff8c933..810607d5a 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -291,9 +291,9 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 txvalue = tx.GetValueOut(); if ( KOMODO_VALUETOOBIG(txvalue) != 0 ) continue; - if ( KOMODO_VALUETOOBIG(txvalue + voutsum) != 0 ) - continue; - voutsum += txvalue; + //if ( KOMODO_VALUETOOBIG(txvalue + voutsum) != 0 ) // has been commented from main.cpp ? + // continue; + //voutsum += txvalue; if ( ASSETCHAINS_SYMBOL[0] == 0 && komodo_validate_interest(tx,nHeight,(uint32_t)pblock->nTime,0) < 0 ) { //fprintf(stderr,"CreateNewBlock: komodo_validate_interest failure nHeight.%d nTime.%u vs locktime.%u\n",nHeight,(uint32_t)pblock->nTime,(uint32_t)tx.nLockTime); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 8733b2894..8a671b322 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5633,7 +5633,7 @@ UniValue payments_airdrop(const UniValue& params, bool fHelp) { struct CCcontract_info *cp,C; if ( fHelp || params.size() != 1 ) - throw runtime_error("paymentsairdrop \"[lockedblocks,minamount,top,%22paytxid0%22,...,%22paytxidN%22]\"\n"); + throw runtime_error("paymentsairdrop \"[lockedblocks,minamount,top,bottom,fixedFlag,%22excludeAddress%22,...,%22excludeAddressN%22]\"\n"); if ( ensure_CCrequirements(EVAL_PAYMENTS) < 0 ) throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); const CKeyStore& keystore = *pwalletMain; From 52474518352482b5e6385d774b8660e855d8eef7 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Thu, 2 May 2019 20:16:21 +0800 Subject: [PATCH 201/242] disable token imports on LABS. fix getimports RPC --- src/cc/import.cpp | 2 ++ src/rpc/crosschain.cpp | 42 ++++++++++++++++++++++++++---------------- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/src/cc/import.cpp b/src/cc/import.cpp index ded10abd5..35b4f5405 100644 --- a/src/cc/import.cpp +++ b/src/cc/import.cpp @@ -535,6 +535,8 @@ bool CheckMigration(Eval *eval, const CTransaction &importTx, const CTransaction uint256 tokenid = zeroid; if (vimportOpret.begin()[0] == EVAL_TOKENS) { // for tokens (new opret with tokens) + if ( is_STAKED(ASSETCHAINS_SYMBOL) == 1 ) + return eval->Invalid("no-tokens-migrate-on-LABS"); struct CCcontract_info *cpTokens, CCtokens_info; std::vector> oprets; uint8_t evalCodeInOpret; diff --git a/src/rpc/crosschain.cpp b/src/rpc/crosschain.cpp index 2ac53f788..35409323d 100644 --- a/src/rpc/crosschain.cpp +++ b/src/rpc/crosschain.cpp @@ -300,6 +300,9 @@ UniValue migrate_createburntransaction(const UniValue& params, bool fHelp) uint256 tokenid = zeroid; if( params.size() == 4 ) tokenid = Parseuint256(params[3].get_str().c_str()); + + if ( tokenid != zeroid && strcmp("LABS", targetSymbol.c_str())) + throw JSONRPCError(RPC_TYPE_ERROR, "There is no tokens support on LABS."); CPubKey myPubKey = Mypubkey(); struct CCcontract_info *cpTokens, C; @@ -312,8 +315,8 @@ UniValue migrate_createburntransaction(const UniValue& params, bool fHelp) if (tokenid.IsNull()) { // coins int64_t inputs; - if ((inputs = AddNormalinputs(mtx, myPubKey, burnAmount + txfee, 60)) == 0) { - throw runtime_error("Cannot find normal inputs\n"); + if ((inputs = AddNormalinputs(mtx, myPubKey, burnAmount + txfee, 10)) == 0) { + throw runtime_error("not enough funds, or need to merge utxos first\n"); } CTxDestination txdest = DecodeDestination(dest_addr_or_pubkey.c_str()); @@ -1145,36 +1148,43 @@ UniValue getNotarisationsForBlock(const UniValue& params, bool fHelp) //out.push_back(make_pair("blocktime",(int))); UniValue labs(UniValue::VARR); UniValue kmd(UniValue::VARR); - // Gets KMD notaries on KMD... but LABS notaries on labs chains needs to be fixed so LABS are identified on KMD. - int8_t numNN = 0; uint8_t notarypubkeys[64][33] = {0}; + int8_t numNN = 0, numSN = 0; uint8_t notarypubkeys[64][33] = {0}; uint8_t LABSpubkeys[64][33] = {0}; numNN = komodo_notaries(notarypubkeys, height, chainActive[height]->nTime); - + numSN = numStakedNotaries(LABSpubkeys,STAKED_era(chainActive[height]->nTime)); + BOOST_FOREACH(const Notarisation& n, nibs) { UniValue item(UniValue::VOBJ); UniValue notaryarr(UniValue::VARR); std::vector NotarisationNotaries; - if ( is_STAKED(n.second.symbol) != 0 ) - continue; // for now just skip this... need to fetch diff pubkeys for these chains. labs.push_back(item); uint256 hash; CTransaction tx; if ( GetTransaction(n.first,tx,hash,false) ) { - if ( !GetNotarisationNotaries(notarypubkeys, numNN, tx.vin, NotarisationNotaries) ) - continue; - if ( NotarisationNotaries.size() < numNN/5 ) - continue; + if ( is_STAKED(n.second.symbol) != 0 ) + { + if ( !GetNotarisationNotaries(LABSpubkeys, numSN, tx.vin, NotarisationNotaries) ) + continue; + } + else + { + if ( !GetNotarisationNotaries(notarypubkeys, numNN, tx.vin, NotarisationNotaries) ) + continue; + } } item.push_back(make_pair("txid", n.first.GetHex())); item.push_back(make_pair("chain", n.second.symbol)); item.push_back(make_pair("height", (int)n.second.height)); item.push_back(make_pair("blockhash", n.second.blockHash.GetHex())); - item.push_back(make_pair("KMD_height", height)); // for when timstamp input is used. + //item.push_back(make_pair("KMD_height", height)); // for when timstamp input is used. for ( auto notary : NotarisationNotaries ) notaryarr.push_back(notary); item.push_back(make_pair("notaries",notaryarr)); - kmd.push_back(item); + if ( is_STAKED(n.second.symbol) != 0 ) + labs.push_back(item); + else + kmd.push_back(item); } out.push_back(make_pair("KMD", kmd)); - //out.push_back(make_pair("LABS", labs)); + out.push_back(make_pair("LABS", labs)); return out; } @@ -1308,7 +1318,7 @@ UniValue getimports(const UniValue& params, bool fHelp) UniValue objTx(UniValue::VOBJ); objTx.push_back(Pair("txid",tx.GetHash().ToString())); ImportProof proof; CTransaction burnTx; std::vector payouts; CTxDestination importaddress; - TotalImported += tx.vout[1].nValue; + TotalImported += tx.vout[0].nValue; // were vouts swapped? objTx.push_back(Pair("amount", ValueFromAmount(tx.vout[1].nValue))); if (ExtractDestination(tx.vout[1].scriptPubKey, importaddress)) { @@ -1481,4 +1491,4 @@ UniValue getwalletburntransactions(const UniValue& params, bool fHelp) ret.push_backV(arrTmp); return ret; -} \ No newline at end of file +} From 6623acf4db95a31e13cbab6f84e37bae96770b58 Mon Sep 17 00:00:00 2001 From: dimxy Date: Thu, 2 May 2019 18:21:51 +0500 Subject: [PATCH 202/242] added reduced expr --- src/cc/prices.cpp | 202 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 169 insertions(+), 33 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 5fccd8774..fd1f5b4ef 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -587,69 +587,199 @@ static std::string prices_getsourceexpression(const std::vector &vec) return expr; } +// helper functions to get synthetic expression reduced: + +// return s true and needed operand count if string is opcode +static bool prices_isopcode(const std::string &s, int &need) +{ + if (s == "!") { + need = 1; + return true; + } + else if (s == "*" || s == "/") { + need = 2; + return true; + } + else if (s == "***" || s == "///" || s == "*//" || s == "**/") { + need = 3; + return true; + } + else + return false; +} + +// split pair onto two quotes divided by "_" static void prices_splitpair(const std::string &pair, std::string &upperquote, std::string &bottomquote) { size_t pos = pair.find('_'); // like BTC_USD if (pos != std::string::npos) { upperquote = pair.substr(0, pos); - bottomquote = pair.substr(pos); + bottomquote = pair.substr(pos + 1); } else { upperquote = pair; bottomquote = ""; } + std::cerr << "prices_splitpair: upperquote=" << upperquote << " bottomquote=" << bottomquote << std::endl; } -// search for an upper or bottom quote in the vectored expression, remove it from the vector with its weight and with operation correction -static bool prices_tryextractpair(const std::vector &vexpr, size_t istart, const std::string "e, bool isSearchUpper, std::string &foundpair, int32_t &weight) { +// invert pair like BTS_USD -> USD_BTC +static std::string prices_invertpair(const std::string &pair) +{ + std::string upperquote, bottomquote; + prices_splitpair(pair, upperquote, bottomquote); + return bottomquote + std::string("_") + upperquote; +} -/* for (size_t i = istart; i < vexpr.size(); i++) { - if (komodo_priceind(vexpr[i].c_str()) >= 0) { +// invert pairs in operation accordingly to "/" operator +static void prices_invertoperation(const std::vector &vexpr, int p, std::vector &voperation) +{ + int32_t need; + + voperation.clear(); + if (prices_isopcode(vexpr[p], need) && need > 1) { + if (need == 2) { + voperation.push_back(vexpr[p - 2]); + if (vexpr[p] == "/") + voperation.push_back(prices_invertpair(vexpr[p - 1])); + else + voperation.push_back(vexpr[p - 1]); + voperation.push_back("*"); + } + + if (need == 3) { + int i; + std::string::const_iterator c; + for (c = vexpr[p].begin(), i = -3; c != vexpr[p].end(); c++, i++) { + if (*c == '/') + voperation.push_back(prices_invertpair(vexpr[p + i])); + else + voperation.push_back(vexpr[p + i]); + } + voperation.push_back("***"); + } + } + + //std::cerr << "prices_invert inverted="; + for (auto v : voperation) std::cerr << v << " "; + std::cerr << std::endl; +} + +// reduce pair in operation, change or remove opcode if reduced +static int prices_reduceoperands(std::vector &voperation) +{ + int opcount = voperation.size() - 1; + int need = opcount; + //std::cerr << "prices_reduceoperands begin need=" << need << std::endl; + + while (true) { + int i; + //std::cerr << "prices_reduceoperands opcount=" << opcount << std::endl; + for (i = 0; i < opcount; i++) { std::string upperquote, bottomquote; - prices_splitpair(vexpr[i], upperquote, bottomquote); + bool breaktostart = false; - if (quote == upperquote) { - if( ) + //std::cerr << "prices_reduceoperands voperation[i]=" << voperation[i] << " i=" << i << std::endl; + prices_splitpair(voperation[i], upperquote, bottomquote); + if (upperquote == bottomquote) { + std::cerr << "prices_reduceoperands erasing i=" << i << std::endl; + voperation.erase(voperation.begin() + i); + opcount--; + //std::cerr << "prices_reduceoperands erased, size=" << voperation.size() << std::endl; + + if (voperation.size() > 0 && voperation.back() == "*") + voperation.pop_back(); + breaktostart = true; + break; } + int j; + for (j = i + 1; j < opcount; j++) { + + //std::cerr << "prices_reduceoperands voperation[j]=" << voperation[j] << " j=" << j << std::endl; + + std::string upperquotej, bottomquotej; + prices_splitpair(voperation[j], upperquotej, bottomquotej); + if (upperquote == bottomquotej || bottomquote == upperquotej) { + if (upperquote == bottomquotej) + voperation[i] = upperquotej + "_" + bottomquote; + else + voperation[i] = upperquote + "_" + bottomquotej; + //std::cerr << "prices_reduceoperands erasing j=" << j << std::endl; + voperation.erase(voperation.begin() + j); + opcount--; + //std::cerr << "prices_reduceoperands erased, size=" << voperation.size() << std::endl; + + need--; + if (voperation.back() == "***") { + voperation.pop_back(); + voperation.push_back("*"); + } + else if (voperation.back() == "*") { + voperation.pop_back(); + } + breaktostart = true; + break; + } + + + } + //if (j < voperation.size() - 1) + if (breaktostart) + break; } - }*/ - return true; + if (i >= opcount) // all seen + break; + } + + //std::cerr << "prices_reduceoperands end need=" << need << std::endl; + return need; } -// try to reduce synthetic expression by substituting "BTC_USD, 20, BTC_EUR, 30, *" with "EUR_USD, 30/20" -static std::string prices_reduceexp(const std::vector &vec) +// substitute reduced operation in vectored expr +static void prices_substitutereduced(std::vector &vexpr, int p, std::vector voperation) +{ + int need; + prices_isopcode(vexpr[p], need); + + vexpr.erase(vexpr.begin() + p - need, vexpr.begin() + p + 1); + vexpr.insert(vexpr.begin() + p - need, voperation.begin(), voperation.end()); +} + +// try to reduce synthetic expression by substituting "BTC_USD, BTC_EUR, 30, /" with "EUR_USD, 30" +static std::string prices_getreducedexpr(const std::string &expr) { std::string reduced; - - return reduced; -/* std::vector vexpr; SplitStr(expr, vexpr); - for (size_t i = 0; i < vexpr.size(); i ++) { - if (komodo_priceind(vexpr[i].c_str()) >= 0) { - std::string upperquote, bottomquote; - std::string foundpair1, foundpair2; - int32_t weight1, weight2; - - prices_splitpair(vexpr[i], upperquote, bottomquote); - if (prices_tryextractpair(vexpr, i+1, upperquote, false, foundpair1, weight1)) { - - } - if (prices_tryextractpair(vexpr, i+1, bottomquote, true, foundpair2, weight2)) { + for (size_t i = 0; i < vexpr.size(); i++) { + int need; + if (prices_isopcode(vexpr[i], need)) { + std::vector voperation; + prices_invertoperation(vexpr, i, voperation); + int reducedneed = prices_reduceoperands(voperation); + if (reducedneed < need) { + prices_substitutereduced(vexpr, i, voperation); } } } -*/ + + for (size_t i = 0; i < vexpr.size(); i++) { + if (reduced.size() > 0) + reduced += std::string(", "); + reduced += vexpr[i]; + } + + //std::cerr << "reduced=" << reduced << std::endl; + return reduced; } - - +// parse synthetic expression into vector of codes int32_t prices_syntheticvec(std::vector &vec, std::vector synthetic) { int32_t i, need, ind, depth = 0; std::string opstr; uint16_t opcode, weight; @@ -1013,8 +1143,6 @@ int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t // profits = dprofits; //std::cerr << "prices_syntheticprofits() dprofits=" << dprofits << std::endl; - - if (costbasis > 0) { mpz_t mpzProfits; mpz_t mpzCostbasis; @@ -1161,6 +1289,7 @@ int64_t prices_enumaddedbets(uint256 &batontxid, std::vector &bets, uin return(addedBetsTotal); } +// pricesbet rpc impl: make betting tx UniValue PricesBet(int64_t txfee, int64_t amount, int16_t leverage, std::vector synthetic) { int32_t nextheight = komodo_nextheight(); @@ -1206,6 +1335,7 @@ UniValue PricesBet(int64_t txfee, int64_t amount, int16_t leverage, std::vector< return(result); } +// pricesaddfunding rpc impl: add yet another bet UniValue PricesAddFunding(int64_t txfee, uint256 bettxid, int64_t amount) { int32_t nextheight = komodo_nextheight(); @@ -1289,7 +1419,7 @@ int32_t prices_scanchain(std::vector &bets, int16_t leverage, std::vect return 0; } -// set cost basis (open price) for the bet +// pricescostbasis rpc impl: set cost basis (open price) for the bet (deprecated) UniValue PricesSetcostbasis(int64_t txfee, uint256 bettxid) { int32_t nextheight = komodo_nextheight(); @@ -1360,6 +1490,7 @@ UniValue PricesSetcostbasis(int64_t txfee, uint256 bettxid) return(result); } +// pricesrekt rpc: anyone can rekt a bet at some block where losses reached limit, collecting fee UniValue PricesRekt(int64_t txfee, uint256 bettxid, int32_t rektheight) { int32_t nextheight = komodo_nextheight(); @@ -1448,6 +1579,7 @@ UniValue PricesRekt(int64_t txfee, uint256 bettxid, int32_t rektheight) return(result); } +// pricescashout rpc impl: bettor can cashout hit bet if it is not rekt UniValue PricesCashout(int64_t txfee, uint256 bettxid) { int32_t nextheight = komodo_nextheight(); @@ -1533,6 +1665,7 @@ UniValue PricesCashout(int64_t txfee, uint256 bettxid) return(result); } +// pricesinfo rpc impl UniValue PricesInfo(uint256 bettxid, int32_t refheight) { UniValue result(UniValue::VOBJ); @@ -1645,7 +1778,9 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) result.push_back(Pair("rektheight", (int64_t)endheight)); } - result.push_back(Pair("expression", prices_getsourceexpression(vec))); + std::string expr = prices_getsourceexpression(vec); + result.push_back(Pair("expression", expr)); + result.push_back(Pair("reduced", prices_getreducedexpr(expr))); result.push_back(Pair("batontxid", batontxid.GetHex())); result.push_back(Pair("costbasis", ValueFromAmount(averageCostbasis))); @@ -1669,6 +1804,7 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) return(result); } +// priceslist rpc impl UniValue PricesList(uint32_t filter, CPubKey mypk) { UniValue result(UniValue::VARR); From c5b7b4aae48d2b0f8b1a6ae02893152ff1a457fc Mon Sep 17 00:00:00 2001 From: dimxy Date: Thu, 2 May 2019 18:37:53 +0500 Subject: [PATCH 203/242] corr reduced calc for op=! --- src/cc/prices.cpp | 50 ++++++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index fd1f5b4ef..123bd142d 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -632,37 +632,43 @@ static std::string prices_invertpair(const std::string &pair) } // invert pairs in operation accordingly to "/" operator -static void prices_invertoperation(const std::vector &vexpr, int p, std::vector &voperation) +static void prices_invert(const std::vector &vexpr, int p, std::vector &voperation) { - int32_t need; + int need; voperation.clear(); - if (prices_isopcode(vexpr[p], need) && need > 1) { - if (need == 2) { - voperation.push_back(vexpr[p - 2]); - if (vexpr[p] == "/") - voperation.push_back(prices_invertpair(vexpr[p - 1])); - else - voperation.push_back(vexpr[p - 1]); - voperation.push_back("*"); - } - - if (need == 3) { - int i; - std::string::const_iterator c; - for (c = vexpr[p].begin(), i = -3; c != vexpr[p].end(); c++, i++) { - if (*c == '/') - voperation.push_back(prices_invertpair(vexpr[p + i])); + if (prices_isopcode(vexpr[p], need)) { + if (need > 1) { + if (need == 2) { + voperation.push_back(vexpr[p - 2]); + if (vexpr[p] == "/") + voperation.push_back(prices_invertpair(vexpr[p - 1])); else - voperation.push_back(vexpr[p + i]); + voperation.push_back(vexpr[p - 1]); + voperation.push_back("*"); } - voperation.push_back("***"); + + if (need == 3) { + int i; + std::string::const_iterator c; + for (c = vexpr[p].begin(), i = -3; c != vexpr[p].end(); c++, i++) { + if (*c == '/') + voperation.push_back(prices_invertpair(vexpr[p + i])); + else + voperation.push_back(vexpr[p + i]); + } + voperation.push_back("***"); + } + } + else if (vexpr[p] == "!") { + voperation.push_back(prices_invertpair(vexpr[p - 1])); + // do not add operator } } //std::cerr << "prices_invert inverted="; - for (auto v : voperation) std::cerr << v << " "; - std::cerr << std::endl; + //for (auto v : voperation) std::cerr << v << " "; + //std::cerr << std::endl; } // reduce pair in operation, change or remove opcode if reduced From af82537ec1784cf8d3318a3415a7cef35aa6deaf Mon Sep 17 00:00:00 2001 From: dimxy Date: Thu, 2 May 2019 18:39:37 +0500 Subject: [PATCH 204/242] corr func name --- src/cc/prices.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 123bd142d..61d188af2 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -632,7 +632,7 @@ static std::string prices_invertpair(const std::string &pair) } // invert pairs in operation accordingly to "/" operator -static void prices_invert(const std::vector &vexpr, int p, std::vector &voperation) +static void prices_invertoperation(const std::vector &vexpr, int p, std::vector &voperation) { int need; From e2f1fe60280a7af2d9a4ae4e6d4f947b0ca07058 Mon Sep 17 00:00:00 2001 From: dimxy Date: Thu, 2 May 2019 18:46:19 +0500 Subject: [PATCH 205/242] added check to do nothing if empty inverted --- src/cc/prices.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 61d188af2..7254c8217 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -768,9 +768,11 @@ static std::string prices_getreducedexpr(const std::string &expr) if (prices_isopcode(vexpr[i], need)) { std::vector voperation; prices_invertoperation(vexpr, i, voperation); - int reducedneed = prices_reduceoperands(voperation); - if (reducedneed < need) { - prices_substitutereduced(vexpr, i, voperation); + if (voperation.size() > 0) { + int reducedneed = prices_reduceoperands(voperation); + if (reducedneed < need) { + prices_substitutereduced(vexpr, i, voperation); + } } } } From b5910e55c71dc13b8c1a33ed07854a3bfce1428a Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Thu, 2 May 2019 23:35:22 +0800 Subject: [PATCH 206/242] . --- src/cc/payments.cpp | 12 ++++++------ src/init.cpp | 2 +- src/main.cpp | 2 +- src/wallet/rpcwallet.cpp | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index 7ab3e8202..814d6823c 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -894,16 +894,16 @@ UniValue PaymentsFund(struct CCcontract_info *cp,char *jsonstr) mtx.vout.push_back(MakeCC1vout(EVAL_PAYMENTS,amount,Paymentspk)); opret = EncodePaymentsFundOpRet(txid); // Use the below one along with other FinalizeCCTx/return, to get the ccvout scriptpubkey - /*std::vector> vData = std::vector>(); + std::vector> vData = std::vector>(); if ( makeCCopret(opret, vData) ) - mtx.vout.push_back(MakeCC1vout(EVAL_PAYMENTS,amount,Paymentspk,&vData)); */ + mtx.vout.push_back(MakeCC1vout(EVAL_PAYMENTS,amount,Paymentspk,&vData)); } - rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,opret); - //rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,CScript()); // use this one to get ccvout scriptpubkey. + //rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,opret); + rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,CScript()); // use this one to get ccvout scriptpubkey. if ( params != 0 ) free_json(params); - //return(payments_rawtxresult(result,rawtx,0)); // disable sending for CCvout, as we only need to decode the tx. - return(payments_rawtxresult(result,rawtx,1)); + return(payments_rawtxresult(result,rawtx,0)); // disable sending for CCvout, as we only need to decode the tx. + //return(payments_rawtxresult(result,rawtx,1)); } else { diff --git a/src/init.cpp b/src/init.cpp index bab2aba77..107e3e476 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1627,7 +1627,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) break; } - if ( ASSETCHAINS_CC != 0 && KOMODO_SNAPSHOT_INTERVAL != 0 && chainActive.Height() > KOMODO_SNAPSHOT_INTERVAL ) + if ( ASSETCHAINS_CC != 0 && KOMODO_SNAPSHOT_INTERVAL != 0 && chainActive.Height() >= KOMODO_SNAPSHOT_INTERVAL ) { if ( !komodo_dailysnapshot(chainActive.Height()) ) { diff --git a/src/main.cpp b/src/main.cpp index ef1a1a40b..2e57f419e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4251,7 +4251,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * komodo_pricesupdate(pindexNew->GetHeight(),pblock); if ( ASSETCHAINS_SAPLING <= 0 && pindexNew->nTime > KOMODO_SAPLING_ACTIVATION - 24*3600 ) komodo_activate_sapling(pindexNew); - if ( ASSETCHAINS_CC != 0 && KOMODO_SNAPSHOT_INTERVAL != 0 && (pindexNew->GetHeight() % KOMODO_SNAPSHOT_INTERVAL) == 0 && pindexNew->GetHeight() > KOMODO_SNAPSHOT_INTERVAL ) + if ( ASSETCHAINS_CC != 0 && KOMODO_SNAPSHOT_INTERVAL != 0 && (pindexNew->GetHeight() % KOMODO_SNAPSHOT_INTERVAL) == 0 && pindexNew->GetHeight() >= KOMODO_SNAPSHOT_INTERVAL ) { uint64_t start = time(NULL); if ( !komodo_dailysnapshot(pindexNew->GetHeight()) ) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 8a671b322..754ec5318 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -8047,10 +8047,10 @@ UniValue opreturn_burn(const UniValue& params, bool fHelp) throw runtime_error("not enough normals\n"); CScript opret; uint8_t *ptr; - opret << OP_RETURN; + opret << OP_RETURN << 0; int32_t len = strlen(strHex.c_str()); len >>=1; - opret.resize(len+1); + opret.resize(len+2); ptr = (uint8_t *)&opret[1]; decode_hex(ptr,len,(char *)strHex.c_str()); mtx.vout.push_back(CTxOut(nAmount,opret)); From 4d8a0547b317457e594d62b18e459b9fddbd7ff5 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Thu, 2 May 2019 23:39:07 +0800 Subject: [PATCH 207/242] revert RPC --- src/komodo_bitcoind.h | 2 +- src/wallet/rpcwallet.cpp | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/komodo_bitcoind.h b/src/komodo_bitcoind.h index a1510a34e..292d5f8df 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -2063,7 +2063,7 @@ bool komodo_appendACscriptpub() ASSETCHAINS_SCRIPTPUB.pop_back(); ASSETCHAINS_SCRIPTPUB.pop_back(); // remove last 2 chars. // get OP_RETURN from txid and append the HexStr of it to scriptpub // encoded opreturn incorrectly on TESTHC chain, once we no longer need this it can be changed to a straight +1 to drop OP_RETURN opcode. - ASSETCHAINS_SCRIPTPUB.append(HexStr(tx.vout[i].scriptPubKey.begin()+(strcmp("TESTHC",ASSETCHAINS_SYMBOL) == 0 ? 3 : 1), tx.vout[i].scriptPubKey.end())); + ASSETCHAINS_SCRIPTPUB.append(HexStr(tx.vout[i].scriptPubKey.begin()+3, tx.vout[i].scriptPubKey.end())); //fprintf(stderr, "ac_script.%s\n",ASSETCHAINS_SCRIPTPUB.c_str()); didinit = true; return true; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 754ec5318..888c60e0e 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -8045,14 +8045,21 @@ UniValue opreturn_burn(const UniValue& params, bool fHelp) int64_t normalInputs = AddNormalinputs(mtx, myPubkey, nAmount, 60); if (normalInputs < nAmount) throw runtime_error("not enough normals\n"); - - CScript opret; uint8_t *ptr; + + CScript opret; uint8_t scripthex[8192]; + + decode_hex(scripthex,strHex.size()/2,(char *)strHex.c_str()); + std::string test; + test.append((char*)scripthex); + std::vector opretdata(test.begin(), test.end()); + opret << OP_RETURN << E_MARSHAL(ss << opretdata); + /*CScript opret; uint8_t *ptr; opret << OP_RETURN << 0; int32_t len = strlen(strHex.c_str()); len >>=1; opret.resize(len+2); ptr = (uint8_t *)&opret[1]; - decode_hex(ptr,len,(char *)strHex.c_str()); + decode_hex(ptr,len,(char *)strHex.c_str()); */ mtx.vout.push_back(CTxOut(nAmount,opret)); ret.push_back(Pair("hex",FinalizeCCTx(0, cp, mtx, myPubkey, 10000, CScript()))); return(ret); From 7fc288161e8c90114f69759c52528106d458f730 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Fri, 3 May 2019 00:03:19 +0800 Subject: [PATCH 208/242] recomment paymentsfund --- src/cc/payments.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index 814d6823c..7ab3e8202 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -894,16 +894,16 @@ UniValue PaymentsFund(struct CCcontract_info *cp,char *jsonstr) mtx.vout.push_back(MakeCC1vout(EVAL_PAYMENTS,amount,Paymentspk)); opret = EncodePaymentsFundOpRet(txid); // Use the below one along with other FinalizeCCTx/return, to get the ccvout scriptpubkey - std::vector> vData = std::vector>(); + /*std::vector> vData = std::vector>(); if ( makeCCopret(opret, vData) ) - mtx.vout.push_back(MakeCC1vout(EVAL_PAYMENTS,amount,Paymentspk,&vData)); + mtx.vout.push_back(MakeCC1vout(EVAL_PAYMENTS,amount,Paymentspk,&vData)); */ } - //rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,opret); - rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,CScript()); // use this one to get ccvout scriptpubkey. + rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,opret); + //rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,CScript()); // use this one to get ccvout scriptpubkey. if ( params != 0 ) free_json(params); - return(payments_rawtxresult(result,rawtx,0)); // disable sending for CCvout, as we only need to decode the tx. - //return(payments_rawtxresult(result,rawtx,1)); + //return(payments_rawtxresult(result,rawtx,0)); // disable sending for CCvout, as we only need to decode the tx. + return(payments_rawtxresult(result,rawtx,1)); } else { From aea85abb39af7beaa15f55d403af8d21712d281e Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Fri, 3 May 2019 01:54:42 +0800 Subject: [PATCH 209/242] fix build --- src/cc/makecustom | 6 +++--- zcutil/build.sh | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cc/makecustom b/src/cc/makecustom index 61b251e6e..06f2f6fb1 100755 --- a/src/cc/makecustom +++ b/src/cc/makecustom @@ -1,7 +1,7 @@ #!/bin/sh gcc -O3 -DBUILD_CUSTOMCC -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 customcc.so cclib.cpp cp customcc.so ../libcc.so -cd .. -make -cd cc +#cd .. +#make +#cd cc diff --git a/zcutil/build.sh b/zcutil/build.sh index df3dfa234..96e0b7c2c 100755 --- a/zcutil/build.sh +++ b/zcutil/build.sh @@ -106,7 +106,7 @@ CONFIG_SITE="$PWD/depends/$HOST/share/config.site" ./configure "$HARDENING_ARG" WD=$PWD cd src/cc echo $PWD -./makerogue +./makecustom cd $WD "$MAKE" "$@" V=1 From 74b0cbb6566866f28eba98eac21afd6ca4fb819a Mon Sep 17 00:00:00 2001 From: dimxy Date: Thu, 2 May 2019 23:13:39 +0500 Subject: [PATCH 210/242] commented out extra log in reduced exp calc --- src/cc/prices.cpp | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 7254c8217..afa4f6e56 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -620,7 +620,7 @@ static void prices_splitpair(const std::string &pair, std::string &upperquote, s upperquote = pair; bottomquote = ""; } - std::cerr << "prices_splitpair: upperquote=" << upperquote << " bottomquote=" << bottomquote << std::endl; + //std::cerr << "prices_splitpair: upperquote=" << upperquote << " bottomquote=" << bottomquote << std::endl; } // invert pair like BTS_USD -> USD_BTC @@ -631,7 +631,7 @@ static std::string prices_invertpair(const std::string &pair) return bottomquote + std::string("_") + upperquote; } -// invert pairs in operation accordingly to "/" operator +// invert pairs in operation accordingly to "/" operator, convert operator to * or *** static void prices_invertoperation(const std::vector &vexpr, int p, std::vector &voperation) { int need; @@ -671,7 +671,7 @@ static void prices_invertoperation(const std::vector &vexpr, int p, //std::cerr << std::endl; } -// reduce pair in operation, change or remove opcode if reduced +// reduce pairs in the operation, change or remove opcode if reduced static int prices_reduceoperands(std::vector &voperation) { int opcount = voperation.size() - 1; @@ -686,7 +686,6 @@ static int prices_reduceoperands(std::vector &voperation) bool breaktostart = false; //std::cerr << "prices_reduceoperands voperation[i]=" << voperation[i] << " i=" << i << std::endl; - prices_splitpair(voperation[i], upperquote, bottomquote); if (upperquote == bottomquote) { std::cerr << "prices_reduceoperands erasing i=" << i << std::endl; @@ -721,18 +720,15 @@ static int prices_reduceoperands(std::vector &voperation) need--; if (voperation.back() == "***") { voperation.pop_back(); - voperation.push_back("*"); + voperation.push_back("*"); // convert *** to * } else if (voperation.back() == "*") { - voperation.pop_back(); + voperation.pop_back(); // convert * to nothing } breaktostart = true; break; } - - } - //if (j < voperation.size() - 1) if (breaktostart) break; } @@ -748,13 +744,13 @@ static int prices_reduceoperands(std::vector &voperation) static void prices_substitutereduced(std::vector &vexpr, int p, std::vector voperation) { int need; - prices_isopcode(vexpr[p], need); - - vexpr.erase(vexpr.begin() + p - need, vexpr.begin() + p + 1); - vexpr.insert(vexpr.begin() + p - need, voperation.begin(), voperation.end()); + if (prices_isopcode(vexpr[p], need)) { + vexpr.erase(vexpr.begin() + p - need, vexpr.begin() + p + 1); + vexpr.insert(vexpr.begin() + p - need, voperation.begin(), voperation.end()); + } } -// try to reduce synthetic expression by substituting "BTC_USD, BTC_EUR, 30, /" with "EUR_USD, 30" +// try to reduce synthetic expression by substituting "BTC_USD, BTC_EUR, 30, /" with "EUR_USD, 30" etc static std::string prices_getreducedexpr(const std::string &expr) { std::string reduced; From 2a8a02e5733e4401bb7724718eb723b324905f06 Mon Sep 17 00:00:00 2001 From: dimxy Date: Thu, 2 May 2019 23:56:56 +0500 Subject: [PATCH 211/242] corr rekt tx --- src/cc/prices.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index afa4f6e56..0344e983f 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1508,12 +1508,15 @@ UniValue PricesRekt(int64_t txfee, uint256 bettxid, int32_t rektheight) std::vector vec; CPubKey pk, mypk, pricespk; std::string rawtx; + char destaddr[64]; cp = CCinit(&C, EVAL_PRICES); if (txfee == 0) txfee = PRICES_TXFEE; mypk = pubkey2pk(Mypubkey()); pricespk = GetUnspendable(cp, 0); + GetCCaddress(cp, destaddr, pricespk); + if (myGetTransaction(bettxid, bettx, hashBlock) != 0 && bettx.vout.size() > 3) { if (prices_betopretdecode(bettx.vout.back().scriptPubKey, pk, firstheight, positionsize, leverage, firstprice, vec, tokenid) == 'B') @@ -1558,9 +1561,16 @@ UniValue PricesRekt(int64_t txfee, uint256 bettxid, int32_t rektheight) } if (myfee != 0) { + int64_t CCchange = 0, inputsum; + mtx.vin.push_back(CTxIn(bettxid, 1, CScript())); // spend cc marker + if ((inputsum = AddPricesInputs(cp, mtx, destaddr, myfee + txfee, 64)) > myfee + txfee) // TODO: why do we take txfee from global addr and not from user's addr? + CCchange = (inputsum - myfee); mtx.vout.push_back(CTxOut(myfee, CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); - mtx.vout.push_back(MakeCC1vout(cp->evalcode, bettx.vout[2].nValue - myfee - txfee, pricespk)); // change + if (CCchange >= txfee) + 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, firstprice, 0, totalbets - positionsize, positionsize, leverage)); return(prices_rawtxresult(result, rawtx, 0)); } From 2f3c8e31420631f6711b402ee1f5d82041d8f362 Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 3 May 2019 00:42:49 +0500 Subject: [PATCH 212/242] corr open/close status on cc marker --- src/cc/prices.cpp | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 0344e983f..27c4367e4 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -16,11 +16,12 @@ #include "CCassets.h" #include "CCPrices.h" -//#include "mini-gmp.h" #include #define IS_CHARINSTR(c, str) (std::string(str).find((char)(c)) != std::string::npos) +#define N_CCMARKER 1 + typedef struct BetInfo { int64_t amount; int32_t firstheight; @@ -1214,7 +1215,7 @@ void prices_betjson(UniValue &result, std::vector bets, int16_t leverag result.push_back(Pair("LastHeight", endheight)); } -// retrives costbasis from a tx spending bettx vout1 +// retrieves costbasis from a tx spending bettx vout1 (deprecated) int64_t prices_costbasis(CTransaction bettx, uint256 &txidCostbasis) { int64_t costbasis = 0; @@ -1224,7 +1225,7 @@ int64_t prices_costbasis(CTransaction bettx, uint256 &txidCostbasis) int32_t vini; int32_t height; txidCostbasis = zeroid; - +/* if (CCgetspenttxid(txidCostbasis, vini, height, bettx.GetHash(), 1) < 0) { std::cerr << "prices_costbasis() no costbasis txid found" << std::endl; return 0; @@ -1243,7 +1244,7 @@ int64_t prices_costbasis(CTransaction bettx, uint256 &txidCostbasis) return costbasis; } - std::cerr << "prices_costbasis() cannot load costbasis tx or decode opret" << " isLoaded=" << isLoaded << " funcId=" << (int)funcId << std::endl; + std::cerr << "prices_costbasis() cannot load costbasis tx or decode opret" << " isLoaded=" << isLoaded << " funcId=" << (int)funcId << std::endl; */ return 0; } @@ -1327,10 +1328,10 @@ UniValue PricesBet(int64_t txfee, int64_t amount, int16_t leverage, std::vector< { betamount = (amount * 199) / 200; 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 + // 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 (N_CCMARKER) mtx.vout.push_back(MakeCC1vout(cp->evalcode, betamount, pricespk)); // vout2 betamount - mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(HexStr(pricespk)) << OP_CHECKSIG)); // vout3 normal marker + mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(HexStr(pricespk)) << OP_CHECKSIG)); // vout3 normal marker - may remove it as we have cc marker now rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_betopret(mypk, nextheight - 1, amount, leverage, firstprice, vec, zeroid)); return(prices_rawtxresult(result, rawtx, 0)); } @@ -1527,7 +1528,7 @@ UniValue PricesRekt(int64_t txfee, uint256 bettxid, int32_t rektheight) std::vector bets; BetInfo bet1; - if (CCgetspenttxid(finaltxid, vini, finalheight, bettxid, 2) == 0) { + if (CCgetspenttxid(finaltxid, vini, finalheight, bettxid, N_CCMARKER) == 0) { result.push_back(Pair("result", "error")); result.push_back(Pair("error", "position closed")); return result; @@ -1563,7 +1564,7 @@ UniValue PricesRekt(int64_t txfee, uint256 bettxid, int32_t rektheight) { int64_t CCchange = 0, inputsum; - mtx.vin.push_back(CTxIn(bettxid, 1, CScript())); // spend cc marker + mtx.vin.push_back(CTxIn(bettxid, N_CCMARKER, CScript())); // spend cc marker if ((inputsum = AddPricesInputs(cp, mtx, destaddr, myfee + txfee, 64)) > myfee + txfee) // TODO: why do we take txfee from global addr and not from user's addr? CCchange = (inputsum - myfee); mtx.vout.push_back(CTxOut(myfee, CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); @@ -1625,7 +1626,7 @@ UniValue PricesCashout(int64_t txfee, uint256 bettxid) std::vector bets; BetInfo bet1; - if (CCgetspenttxid(finaltxid, vini, finalheight, bettxid, 2) == 0) { + if (CCgetspenttxid(finaltxid, vini, finalheight, bettxid, N_CCMARKER) == 0) { result.push_back(Pair("result", "error")); result.push_back(Pair("error", "position closed")); return result; @@ -1658,7 +1659,7 @@ UniValue PricesCashout(int64_t txfee, uint256 bettxid) return(result); } - mtx.vin.push_back(CTxIn(bettxid, 1, CScript())); // spend cc marker + mtx.vin.push_back(CTxIn(bettxid, N_CCMARKER, CScript())); // spend cc marker if ((inputsum = AddPricesInputs(cp, mtx, destaddr, equity + txfee, 64)) > equity + txfee) CCchange = (inputsum - equity); mtx.vout.push_back(CTxOut(equity, CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); @@ -1706,7 +1707,7 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) std::vector bets; BetInfo bet1; - if (CCgetspenttxid(finaltxid, vini, finalheight, bettxid, 2) == 0) + if (CCgetspenttxid(finaltxid, vini, finalheight, bettxid, N_CCMARKER) == 0) result.push_back(Pair("status", "closed")); else result.push_back(Pair("status", "open")); @@ -1857,7 +1858,7 @@ UniValue PricesList(uint32_t filter, CPubKey mypk) int32_t height; uint256 finaltxid; - int32_t spent = CCgetspenttxid(finaltxid, vini, height, txid, 2); + int32_t spent = CCgetspenttxid(finaltxid, vini, height, txid, N_CCMARKER); if (filter == 1 && spent < 0 || // open positions filter == 2 && spent == 0) // closed positions bAppend = true; From 2d1d8d253285547a41774fd802d7f3a134c9b996 Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 3 May 2019 00:56:55 +0500 Subject: [PATCH 213/242] added todo comment to remove normal marker --- src/cc/prices.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 27c4367e4..cfc308680 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1331,7 +1331,7 @@ UniValue PricesBet(int64_t txfee, int64_t amount, int16_t leverage, std::vector< // 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 (N_CCMARKER) mtx.vout.push_back(MakeCC1vout(cp->evalcode, betamount, pricespk)); // vout2 betamount - mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(HexStr(pricespk)) << OP_CHECKSIG)); // vout3 normal marker - may remove it as we have cc marker now + mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(HexStr(pricespk)) << OP_CHECKSIG)); // vout3 normal marker - TODO: remove it as we have cc marker now, when move to the new chain rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_betopret(mypk, nextheight - 1, amount, leverage, firstprice, vec, zeroid)); return(prices_rawtxresult(result, rawtx, 0)); } From b750ac018f4000570683b9fe2f9961d1219fad4a Mon Sep 17 00:00:00 2001 From: blackjok3rtt <30971146+blackjok3rtt@users.noreply.github.com> Date: Fri, 3 May 2019 13:08:29 +0800 Subject: [PATCH 214/242] revert back to rogue --- zcutil/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zcutil/build.sh b/zcutil/build.sh index 96e0b7c2c..df3dfa234 100755 --- a/zcutil/build.sh +++ b/zcutil/build.sh @@ -106,7 +106,7 @@ CONFIG_SITE="$PWD/depends/$HOST/share/config.site" ./configure "$HARDENING_ARG" WD=$PWD cd src/cc echo $PWD -./makecustom +./makerogue cd $WD "$MAKE" "$@" V=1 From eeaa0176eb83fb3db2c36bfcf6ebce1481d48579 Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 3 May 2019 10:29:24 +0500 Subject: [PATCH 215/242] added costbasis testmode period = 7 --- src/cc/prices.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index cfc308680..37186e987 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1091,8 +1091,11 @@ int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t fprintf(stderr, "requested height is lower than bet firstheight.%d\n", height); return -1; } - +#ifndef TESTMODE int32_t minmax = (height < firstheight + PRICES_DAYWINDOW); // if we are within 24h then use min or max value +#else + int32_t minmax = (height < firstheight + 7); // if we are within 24h then use min or max value +#endif if ((price = prices_syntheticprice(vec, height, minmax, leverage)) < 0) { @@ -1803,11 +1806,6 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) result.push_back(Pair("LiquidationPrice", ValueFromAmount(liqprice))); - //result.push_back(Pair("height", (int64_t)endheight)); -//#ifdef TESTMODE -// result.push_back(Pair("test_daywindow", PRICES_DAYWINDOW)); -//#endif - mpz_clear(mpzTotalbets); mpz_clear(mpzTotalprofits); mpz_clear(mpzTotalcostbasis); From dec5613c96d5441df33bbcf2f40e32eea325182d Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 3 May 2019 10:32:26 +0500 Subject: [PATCH 216/242] costbasis test period info in json --- src/cc/prices.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 37186e987..0b7c8a873 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1801,6 +1801,9 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) result.push_back(Pair("reduced", prices_getreducedexpr(expr))); result.push_back(Pair("batontxid", batontxid.GetHex())); result.push_back(Pair("costbasis", ValueFromAmount(averageCostbasis))); +#ifdef TESTMODE + result.push_back(Pair("costbasis_test_period", 7)); +#endif prices_betjson(result, bets, leverage, endheight, lastprice); From 9ae73e9219fac7bfbfd35860503faf2b52143aeb Mon Sep 17 00:00:00 2001 From: dimxy Date: Fri, 3 May 2019 10:43:07 +0500 Subject: [PATCH 217/242] added COSTBASIS_PERIOD var --- src/cc/prices.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 0b7c8a873..cefc8c4e0 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1086,16 +1086,19 @@ int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t 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) { int64_t price; +#ifndef TESTMODE + const int32_t COSTBASIS_PERIOD = PRICES_DAYWINDOW; +#else + const int32_t COSTBASIS_PERIOD = 7; +#endif + if (height < firstheight) { fprintf(stderr, "requested height is lower than bet firstheight.%d\n", height); return -1; } -#ifndef TESTMODE - int32_t minmax = (height < firstheight + PRICES_DAYWINDOW); // if we are within 24h then use min or max value -#else - int32_t minmax = (height < firstheight + 7); // if we are within 24h then use min or max value -#endif + + int32_t minmax = (height < firstheight + COSTBASIS_PERIOD); // if we are within 24h then use min or max value if ((price = prices_syntheticprice(vec, height, minmax, leverage)) < 0) { @@ -1122,12 +1125,12 @@ int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t //} } else { - if (height == firstheight + PRICES_DAYWINDOW) { + 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 << " height=" << height << std::endl; + std::cerr << "prices_syntheticprofits() use permanent costbasis=" << costbasis << " at height=" << height << std::endl; } } From 8d1583de80568a3175d628768e47d47439e20a73 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Fri, 3 May 2019 14:11:56 +0800 Subject: [PATCH 218/242] PLEASE BE WORKING --- src/cc/makecclib | 19 ++++++++++--------- src/wallet/db.h | 4 +++- zcutil/build.sh | 2 +- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/cc/makecclib b/src/cc/makecclib index b2f8e2ee1..256d50995 100755 --- a/src/cc/makecclib +++ b/src/cc/makecclib @@ -4,16 +4,17 @@ rm *.so rogue/rogue games/tetris games/prices echo rogue make -f Makefile_rogue ./makerogue +rm ../libcc.so +cp librogue.so ../libcc.so -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 +#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 -echo games tetris -./maketetris +#echo games tetris +#./maketetris -echo games prices -./makeprices - -echo customcc stub -gcc -O3 -DBUILD_CUSTOMCC -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 customcc.so cclib.cpp +#echo games prices +#./makeprices +#echo customcc stub +#gcc -O3 -DBUILD_CUSTOMCC -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 customcc.so cclib.cpp diff --git a/src/wallet/db.h b/src/wallet/db.h index 19b9b6079..4af25c698 100644 --- a/src/wallet/db.h +++ b/src/wallet/db.h @@ -33,7 +33,9 @@ #include -#include +// CCLIB fails to compile with this! +//#include +#include "../depends/x86_64-unknown-linux-gnu/include/db_cxx.h" extern unsigned int nWalletDBUpdated; diff --git a/zcutil/build.sh b/zcutil/build.sh index df3dfa234..dc4d027b1 100755 --- a/zcutil/build.sh +++ b/zcutil/build.sh @@ -106,7 +106,7 @@ CONFIG_SITE="$PWD/depends/$HOST/share/config.site" ./configure "$HARDENING_ARG" WD=$PWD cd src/cc echo $PWD -./makerogue +./makecclib cd $WD "$MAKE" "$@" V=1 From ec185b7226942182f2174b76878b352a25b34951 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Fri, 3 May 2019 22:36:58 +0800 Subject: [PATCH 219/242] add daily snapshot address to getsnapshot (top = -1) --- src/rpc/misc.cpp | 3 ++- src/txdb.cpp | 19 +++++++++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 4e21ab9e9..7c00ae7ad 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -1282,7 +1282,8 @@ UniValue getsnapshot(const UniValue& params, bool fHelp) if (params.size() > 0 && !params[0].isNull()) { top = atoi(params[0].get_str().c_str()); if (top <= 0) - throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, top must be a positive integer"); + //throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, top must be a positive integer"); + top = -1; } if ( fHelp || params.size() > 1) diff --git a/src/txdb.cpp b/src/txdb.cpp index a7415834c..4f813097b 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -555,6 +555,8 @@ bool CBlockTreeDB::Snapshot2(std::map &addressAmounts, Un return true; } +extern std::vector > vAddressSnapshot; + UniValue CBlockTreeDB::Snapshot(int top) { int topN = 0; @@ -564,11 +566,20 @@ UniValue CBlockTreeDB::Snapshot(int top) UniValue result(UniValue::VOBJ); UniValue addressesSorted(UniValue::VARR); result.push_back(Pair("start_time", (int) time(NULL))); - if ( Snapshot2(addressAmounts,&result) ) + if ( (vAddressSnapshot.size() > 0 && top < 0) || (Snapshot2(addressAmounts,&result) && top > 0) ) { - for (std::pair element : addressAmounts) - vaddr.push_back( make_pair(element.second, element.first) ); - std::sort(vaddr.rbegin(), vaddr.rend()); + if ( top > 0 ) + { + for (std::pair element : addressAmounts) + vaddr.push_back( make_pair(element.second, element.first) ); + std::sort(vaddr.rbegin(), vaddr.rend()); + } + else + { + for ( auto address : vAddressSnapshot ) + vaddr.push_back(make_pair(address.first, CBitcoinAddress(address.second).ToString())); + top = vAddressSnapshot.size(); + } int topN = 0; for (std::vector>::iterator it = vaddr.begin(); it!=vaddr.end(); ++it) { From 9802d350aa77767caffa06af09cd25db796af300 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Sat, 4 May 2019 01:55:33 +0800 Subject: [PATCH 220/242] bug fix --- src/rpc/misc.cpp | 2 +- src/txdb.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 7cb9b6664..4ea6e94e3 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -1383,7 +1383,7 @@ UniValue getsnapshot(const UniValue& params, bool fHelp) if (params.size() > 0 && !params[0].isNull()) { top = atoi(params[0].get_str().c_str()); - if (top <= 0) + if (top < 0) //throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, top must be a positive integer"); top = -1; } diff --git a/src/txdb.cpp b/src/txdb.cpp index 4638633ed..82885044e 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -481,6 +481,8 @@ bool CBlockTreeDB::Snapshot2(std::map &addressAmounts, Un try { CAmount nValue; iter->GetValue(nValue); + if ( nValue == 0 ) + continue; getAddressFromIndex(indexKey.type, indexKey.hashBytes, address); if ( indexKey.type == 3 ) { @@ -566,9 +568,9 @@ UniValue CBlockTreeDB::Snapshot(int top) UniValue result(UniValue::VOBJ); UniValue addressesSorted(UniValue::VARR); result.push_back(Pair("start_time", (int) time(NULL))); - if ( (vAddressSnapshot.size() > 0 && top < 0) || (Snapshot2(addressAmounts,&result) && top > 0) ) + if ( (vAddressSnapshot.size() > 0 && top < 0) || (Snapshot2(addressAmounts,&result) && top >= 0) ) { - if ( top > 0 ) + if ( top > -1 ) { for (std::pair element : addressAmounts) vaddr.push_back( make_pair(element.second, element.first) ); From 6e9fea30bbecd30901c403e683638c7115fc35a4 Mon Sep 17 00:00:00 2001 From: SHossain Date: Sat, 4 May 2019 16:09:25 +0100 Subject: [PATCH 221/242] Update assetchains.old --- src/assetchains.old | 1 + 1 file changed, 1 insertion(+) diff --git a/src/assetchains.old b/src/assetchains.old index a0cbd3b9c..fd472eff9 100755 --- a/src/assetchains.old +++ b/src/assetchains.old @@ -51,3 +51,4 @@ 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 & From 650e55084d63fc715a5be97bb8ba5b7fd93d46d9 Mon Sep 17 00:00:00 2001 From: Alrighttt Date: Sat, 4 May 2019 23:19:33 +0200 Subject: [PATCH 222/242] Change oraclessamples rpc to show txid for each --- src/cc/oracles.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/cc/oracles.cpp b/src/cc/oracles.cpp index ef457fe82..53148bba9 100644 --- a/src/cc/oracles.cpp +++ b/src/cc/oracles.cpp @@ -935,13 +935,13 @@ UniValue OracleFormat(uint8_t *data,int32_t datalen,char *format,int32_t formatl if ( j >= datalen ) break; } - return(obj); + return(str); } UniValue OracleDataSamples(uint256 reforacletxid,uint256 batontxid,int32_t num) { - UniValue result(UniValue::VOBJ),a(UniValue::VARR); CTransaction tx,oracletx; uint256 hashBlock,btxid,oracletxid; - CPubKey pk; std::string name,description,format; int32_t numvouts,n=0; std::vector data; char *formatstr = 0; + UniValue result(UniValue::VOBJ),b(UniValue::VARR); CTransaction tx,oracletx; uint256 hashBlock,btxid,oracletxid; + CPubKey pk; std::string name,description,format; int32_t numvouts,n=0; std::vector data; char str[67], *formatstr = 0; result.push_back(Pair("result","success")); if ( GetTransaction(reforacletxid,oracletx,hashBlock,false) != 0 && (numvouts=oracletx.vout.size()) > 0 ) @@ -954,7 +954,10 @@ 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)); + b.push_back(a); batontxid = btxid; if ( ++n >= num ) break; @@ -962,7 +965,7 @@ UniValue OracleDataSamples(uint256 reforacletxid,uint256 batontxid,int32_t num) } } } - result.push_back(Pair("samples",a)); + result.push_back(Pair("samples",b)); return(result); } From c1cc66d1d48498edd061c9bfa546edc853625b94 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Sun, 5 May 2019 11:28:13 +0800 Subject: [PATCH 223/242] add range paid to paymentsinfo for game. --- src/cc/payments.cpp | 48 ++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index 7ab3e8202..40f0b6e92 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -224,6 +224,21 @@ void pub2createtxid(char *str) free(rev); } +bool payments_game(int32_t &top, int32_t &bottom) +{ + uint64_t x; + uint256 tmphash = chainActive[lastSnapShotHeight]->GetBlockHash(); + memcpy(&x,&tmphash,sizeof(x)); + bottom = ((x & 0xff) % 50); + if ( bottom == 0 ) bottom = 1; + top = (((x>>8) & 0xff) % 100); + if ( top < 50 ) top += 50; + bottom = (vAddressSnapshot.size()*bottom)/100; + top = (vAddressSnapshot.size()*top)/100; + fprintf(stderr, "bottom.%i top.%i\n",bottom,top); + return true; +} + bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn) { // one of two addresses @@ -309,17 +324,7 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & if ( fixedAmount == 7 ) { // game setting, randomise bottom and top values - uint64_t x; - uint256 tmphash = chainActive[lastSnapShotHeight]->GetBlockHash(); - memcpy(&x,&tmphash,sizeof(x)); - bottom = ((x & 0xff) % 50); - if ( bottom == 0 ) bottom = 1; - top = (((x>>8) & 0xff) % 100); - if ( top < 50 ) top += 50; - bottom = (vAddressSnapshot.size()*bottom)/100; - top = (vAddressSnapshot.size()*top)/100; - fprintf(stderr, "bottom.%i top.%i\n",bottom,top); - fFixedAmount = true; + fFixedAmount = payments_game(top,bottom); } else if ( fixedAmount != 0 ) { @@ -717,17 +722,7 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) if ( fixedAmount == 7 ) { // game setting, randomise bottom and top values - uint64_t x; - uint256 tmphash = chainActive[lastSnapShotHeight]->GetBlockHash(); - memcpy(&x,&tmphash,sizeof(x)); - bottom = ((x & 0xff) % 50); - if ( bottom == 0 ) bottom = 1; - top = (((x>>8) & 0xff) % 100); - if ( top < 50 ) top += 50; - bottom = (vAddressSnapshot.size()*bottom)/100; - top = (vAddressSnapshot.size()*top)/100; - fprintf(stderr, "bottom.%i top.%i\n",bottom,top); - fFixedAmount = true; + fFixedAmount = payments_game(top,bottom); } else if ( fixedAmount != 0 ) { @@ -1172,11 +1167,14 @@ UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr) free_json(params); return(result); } - result.push_back(Pair("plan_type","snapshot")); + if ( fixedAmount == 7 && payments_game(top,bottom)) + result.push_back(Pair("plan_type","payments_game")); + else + result.push_back(Pair("plan_type","snapshot")); result.push_back(Pair("lockedblocks",(int64_t)lockedblocks)); - result.push_back(Pair("minrelease",(int64_t)minrelease)); - result.push_back(Pair("top",(int64_t)top)); + result.push_back(Pair("minrelease",(int64_t)minrelease)); result.push_back(Pair("bottom",(int64_t)bottom)); + result.push_back(Pair("top",(int64_t)top)); result.push_back(Pair("fixedFlag",(int64_t)fixedAmount)); // TODO: convert to show addresses instead of scriptpubkey. for ( auto scriptPubKey : excludeScriptPubKeys ) From 0e49cd4afe1001a31eb30f497e02fb6e3de3dcfd Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Sun, 5 May 2019 13:16:30 +0800 Subject: [PATCH 224/242] more RPC additions. --- src/cc/payments.cpp | 108 ++++++++++++++++++++++++++++---------------- 1 file changed, 70 insertions(+), 38 deletions(-) diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index 40f0b6e92..0b69f79fc 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -239,6 +239,19 @@ bool payments_game(int32_t &top, int32_t &bottom) return true; } +bool payments_lockedblocks(uint256 blockhash,int32_t lockedblocks,int32_t &blocksleft) +{ + int32_t ht = chainActive.Height(); + CBlockIndex* pblockindex = komodo_blockindex(blockhash); + if ( pblockindex == 0 || pblockindex->GetHeight()+lockedblocks > ht) + { + blocksleft = pblockindex->GetHeight()+lockedblocks - ht; + fprintf(stderr, "not elegible to be spent yet height.%i vs elegible_ht.%i blocksleft.%i\n",ht,(pblockindex!=0?pblockindex->GetHeight():0)+lockedblocks,blocksleft); + return false; + } + return true; +} + bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn) { // one of two addresses @@ -422,7 +435,7 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & // Check vins i = 0; - int32_t ht = chainActive.LastTip()->GetHeight(); + int32_t blocksleft; BOOST_FOREACH(const CTxIn& vin, tx.vin) { CTransaction txin; @@ -446,12 +459,8 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & } } // check the chain depth vs locked blocks requirement. - CBlockIndex* pblockindex = komodo_blockindex(blockhash); - if ( pblockindex == 0 || pblockindex->GetHeight() > ht-lockedblocks ) - { - fprintf(stderr, "vin.%i is not elegible to be spent yet height.%i vs elegible_ht.%i\n", i, pblockindex!=0?pblockindex->GetHeight():0, ht-lockedblocks); + if ( !payments_lockedblocks(blockhash, lockedblocks, blocksleft) ) return(eval->Invalid("vin not elegible")); - } } else return(eval->Invalid("cant get vin transaction")); i++; } @@ -462,19 +471,27 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & // end of consensus code // helper functions for rpc calls in rpcwallet.cpp - -int64_t AddPaymentsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey txidpk,int64_t total,int32_t maxinputs,uint256 createtxid,int32_t latestheight) +int64_t AddPaymentsInputs(bool fLockedBlocks,int8_t GetBalance,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey txidpk,int64_t total,int32_t maxinputs,uint256 createtxid,int32_t lockedblocks,int64_t minrelease,int32_t &blocksleft) { char coinaddr[64]; CPubKey Paymentspk; int64_t nValue,threshold,price,totalinputs = 0; uint256 txid,checktxid,hashBlock; std::vector origpubkey; CTransaction vintx; int32_t iter,vout,ht,n = 0; std::vector > unspentOutputs; - if ( maxinputs > CC_MAXVINS ) - maxinputs = CC_MAXVINS; - if ( maxinputs > 0 ) - threshold = total/maxinputs; - else threshold = total; + std::vector > blocksleft_balance; + if ( GetBalance == 0 ) + { + if ( maxinputs > CC_MAXVINS ) + maxinputs = CC_MAXVINS; + if ( maxinputs > 0 ) + threshold = total/maxinputs; + else threshold = total; + } + else threshold = 0; Paymentspk = GetUnspendable(cp,0); for (iter=0; iter<2; iter++) { + if ( GetBalance == 1 && iter == 1 ) + continue; // getbalance of global paymentsCC address. + if ( GetBalance == 2 && iter == 0 ) + continue; // get balance of txidpk address. if ( iter == 0 ) GetCCaddress(cp,coinaddr,Paymentspk); else GetCCaddress1of2(cp,coinaddr,Paymentspk,txidpk); @@ -486,19 +503,6 @@ int64_t AddPaymentsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CP //fprintf(stderr,"iter.%d %s/v%d %s\n",iter,txid.GetHex().c_str(),vout,coinaddr); if ( (vout == 0 || vout == 1) && GetTransaction(txid,vintx,hashBlock,false) != 0 ) { - if ( latestheight != 0 ) - { - if ( (ht= komodo_blockheight(hashBlock)) == 0 ) - { - fprintf(stderr,"null ht\n"); - continue; - } - else if ( ht > latestheight ) - { - fprintf(stderr,"ht.%d > lastheight.%d\n",ht,latestheight); - continue; - } - } if ( iter == 0 ) { CScript opret; uint256 checktxid; int32_t opret_ind; @@ -520,16 +524,37 @@ int64_t AddPaymentsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CP } if ( (nValue= IsPaymentsvout(cp,vintx,vout,coinaddr)) > PAYMENTS_TXFEE && nValue >= threshold && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 ) { - if ( total != 0 && maxinputs != 0 ) + int32_t tmpblocksleft = 0; + if ( GetBalance == 0 && total != 0 && maxinputs != 0 ) mtx.vin.push_back(CTxIn(txid,vout,CScript())); nValue = it->second.satoshis; + if ( fLockedBlocks && !payments_lockedblocks(hashBlock, lockedblocks, tmpblocksleft) ) + { + blocksleft_balance.push_back(std::make_pair(tmpblocksleft,nValue)); + continue; + } totalinputs += nValue; n++; //fprintf(stderr,"iter.%d %s/v%d %s %.8f\n",iter,txid.GetHex().c_str(),vout,coinaddr,(double)nValue/COIN); - if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) ) - break; + if ( GetBalance == 0 && ((total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs)) ) + break; // create tx. We have ebnough inputs to make it. } //else fprintf(stderr,"nValue %.8f vs threshold %.8f\n",(double)nValue/COIN,(double)threshold/COIN); - iter++; + } + } + } + if ( GetBalance == 3 ) // return elegible balance to be spent, and blocks left until min release can be released. + { + int64_t lockedblocks_balance = totalinputs; // inputs that can be spent already. + // sort utxos by blocks until able to be spent, smallest at top. + std::sort(blocksleft_balance.begin(), blocksleft_balance.end()); + // iterate the utxos blocks left vector, to get block height min release is able to be released. + for ( auto utxo : blocksleft_balance ) + { + lockedblocks_balance += utxo.second; + if ( lockedblocks_balance >= minrelease ) + { + blocksleft = utxo.first; + break; } } } @@ -607,10 +632,11 @@ int32_t payments_parsehexdata(std::vector &hexdata,cJSON *item,int32_t UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) { - int32_t latestheight,nextheight = komodo_nextheight(); + int32_t nextheight = komodo_nextheight(); + //int32_t latestheight,nextheight = komodo_nextheight(); CMutableTransaction tmpmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(),nextheight); UniValue result(UniValue::VOBJ); uint256 createtxid,hashBlock,tokenid; CTransaction tx,txO; CPubKey mypk,txidpk,Paymentspk; int32_t i,n,m,numoprets=0,lockedblocks,minrelease; int64_t newamount,inputsum,amount,CCchange=0,totalallocations=0,checkallocations=0,allocation; CTxOut vout; CScript onlyopret; char txidaddr[64],destaddr[64]; std::vector txidoprets; - int32_t top,bottom=0; std::vector> excludeScriptPubKeys; int8_t funcid,fixedAmount=0; bool fFixedAmount = false; + int32_t top,bottom=0,blocksleft=0; std::vector> excludeScriptPubKeys; int8_t funcid,fixedAmount=0; bool fFixedAmount = false; mpz_t mpzTotalAllocations; mpz_init(mpzTotalAllocations); cJSON *params = payments_reparse(&n,jsonstr); mypk = pubkey2pk(Mypubkey()); @@ -631,7 +657,7 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) free_json(params); return(result); } - latestheight = (nextheight - lockedblocks - 1); + //latestheight = (nextheight - lockedblocks - 1); if ( amount < minrelease*COIN ) { result.push_back(Pair("result","error")); @@ -812,7 +838,7 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) free_json(params); return(result); } - if ( (inputsum= AddPaymentsInputs(cp,mtx,txidpk,newamount+2*PAYMENTS_TXFEE,CC_MAXVINS/2,createtxid,latestheight)) >= newamount+2*PAYMENTS_TXFEE ) + if ( (inputsum= AddPaymentsInputs(true,0,cp,mtx,txidpk,newamount+2*PAYMENTS_TXFEE,CC_MAXVINS/2,createtxid,lockedblocks,minrelease,blocksleft)) >= newamount+2*PAYMENTS_TXFEE ) { std::string rawtx; if ( (CCchange= (inputsum - newamount - 2*PAYMENTS_TXFEE)) >= PAYMENTS_TXFEE ) @@ -1100,9 +1126,9 @@ UniValue PaymentsAirdrop(struct CCcontract_info *cp,char *jsonstr) UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr) { - UniValue result(UniValue::VOBJ),a(UniValue::VARR); CTransaction tx,txO; CPubKey Paymentspk,txidpk; int32_t i,j,n,flag=0,numoprets=0,lockedblocks,minrelease; std::vector txidoprets; int64_t funds,fundsopret,totalallocations=0,allocation; char fundsaddr[64],fundsopretaddr[64],txidaddr[64],*outstr; uint256 createtxid,hashBlock; + UniValue result(UniValue::VOBJ),a(UniValue::VARR); CTransaction tx,txO; CPubKey Paymentspk,txidpk; int32_t i,j,n,flag=0,numoprets=0,lockedblocks,minrelease,blocksleft=0; std::vector txidoprets; int64_t funds,fundsopret,elegiblefunds,totalallocations=0,allocation; char fundsaddr[64],fundsopretaddr[64],txidaddr[64],*outstr; uint256 createtxid,hashBlock; int32_t top,bottom; std::vector> excludeScriptPubKeys; // snapshot - uint256 tokenid; int8_t fixedAmount; + uint256 tokenid; int8_t fixedAmount; CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(),komodo_nextheight()); cJSON *params = payments_reparse(&n,jsonstr); if ( params != 0 && n == 1 ) { @@ -1210,13 +1236,19 @@ UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr) { txidpk = CCtxidaddr(txidaddr,createtxid); GetCCaddress1of2(cp,fundsaddr,Paymentspk,txidpk); - funds = CCaddress_balance(fundsaddr,1); + funds = AddPaymentsInputs(false,2,cp,mtx,txidpk,0,CC_MAXVINS,createtxid,lockedblocks,minrelease,blocksleft); + //CCaddress_balance(fundsaddr,1); result.push_back(Pair(fundsaddr,ValueFromAmount(funds))); GetCCaddress(cp,fundsopretaddr,Paymentspk); // TODO: Shows balance for ALL payments plans, not just the one asked for! Needs to be reworked. - fundsopret = CCaddress_balance(fundsopretaddr,1); + fundsopret = AddPaymentsInputs(false,1,cp,mtx,txidpk,0,CC_MAXVINS,createtxid,lockedblocks,minrelease,blocksleft); + //CCaddress_balance(fundsopretaddr,1); result.push_back(Pair(fundsopretaddr,ValueFromAmount(fundsopret))); result.push_back(Pair("totalfunds",ValueFromAmount(funds+fundsopret))); + // Blocks until minrelease can be released. + elegiblefunds = AddPaymentsInputs(true,3,cp,mtx,txidpk,0,CC_MAXVINS,createtxid,lockedblocks,minrelease,blocksleft); + result.push_back(Pair("elegiblefunds",ValueFromAmount(elegiblefunds))); + result.push_back(Pair("min_release_height",chainActive.Height()+blocksleft)); result.push_back(Pair("result","success")); } } From 0d47cda1451e48f1bab746e10f6a3e2cfac9030a Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Mon, 6 May 2019 00:57:06 +0800 Subject: [PATCH 225/242] initial commit for payments merge RPC --- src/cc/CCPayments.h | 2 + src/cc/CCinclude.h | 2 +- src/cc/CCtx.cpp | 2 +- src/cc/CCutils.cpp | 16 +- src/cc/customcc.cpp | 6 +- src/cc/payments.cpp | 502 ++++++++++++++++++++++++--------------- src/main.h | 2 +- src/rpc/server.cpp | 1 + src/rpc/server.h | 1 + src/wallet/rpcwallet.cpp | 15 +- 10 files changed, 348 insertions(+), 201 deletions(-) diff --git a/src/cc/CCPayments.h b/src/cc/CCPayments.h index c45fbab9e..13c66d358 100644 --- a/src/cc/CCPayments.h +++ b/src/cc/CCPayments.h @@ -21,6 +21,7 @@ #include #define PAYMENTS_TXFEE 10000 +#define PAYMENTS_MERGEOFSET 10 // 100? extern std::vector > vAddressSnapshot; extern int32_t lastSnapShotHeight; @@ -29,6 +30,7 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & // CCcustom UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr); UniValue PaymentsFund(struct CCcontract_info *cp,char *jsonstr); +UniValue PaymentsMerge(struct CCcontract_info *cp,char *jsonstr); UniValue PaymentsTxidopret(struct CCcontract_info *cp,char *jsonstr); UniValue PaymentsCreate(struct CCcontract_info *cp,char *jsonstr); UniValue PaymentsAirdrop(struct CCcontract_info *cp,char *jsonstr); diff --git a/src/cc/CCinclude.h b/src/cc/CCinclude.h index db1ee7475..4ca73b6d7 100644 --- a/src/cc/CCinclude.h +++ b/src/cc/CCinclude.h @@ -229,7 +229,7 @@ uint256 DiceHashEntropy(uint256 &entropy,uint256 _txidpriv,int32_t entropyvout,i CTxOut MakeCC1vout(uint8_t evalcode,CAmount nValue,CPubKey pk, std::vector>* vData = NULL); CTxOut MakeCC1of2vout(uint8_t evalcode,CAmount nValue,CPubKey pk,CPubKey pk2, std::vector>* vData = NULL); int32_t has_opret(const CTransaction &tx, uint8_t evalcode); -CScript getCCopret(const CScript &scriptPubKey); +bool getCCopret(const CScript &scriptPubKey, CScript &opret); bool makeCCopret(CScript &opret, std::vector> &vData); CC *MakeCCcond1(uint8_t evalcode,CPubKey pk); CC *MakeCCcond1of2(uint8_t evalcode,CPubKey pk1,CPubKey pk2); diff --git a/src/cc/CCtx.cpp b/src/cc/CCtx.cpp index 7435defbf..fe5fade71 100644 --- a/src/cc/CCtx.cpp +++ b/src/cc/CCtx.cpp @@ -241,7 +241,7 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran { char coinaddr[64]; GetCCaddress1of2(cp,coinaddr,globalpk,pubkeys[i]); - //fprintf(stderr,"%s + %s -> %s vs %s\n",HexStr(globalpk).c_str(),HexStr(pubkeys[i]).c_str(),coinaddr,destaddr); + fprintf(stderr,"%s + %s -> %s vs %s\n",HexStr(globalpk).c_str(),HexStr(pubkeys[i]).c_str(),coinaddr,destaddr); if ( strcmp(destaddr,coinaddr) == 0 ) { privkey = cp->CCpriv; diff --git a/src/cc/CCutils.cpp b/src/cc/CCutils.cpp index acf0da766..5fe7d662b 100644 --- a/src/cc/CCutils.cpp +++ b/src/cc/CCutils.cpp @@ -70,16 +70,20 @@ int32_t has_opret(const CTransaction &tx, uint8_t evalcode) return 0; } -CScript getCCopret(const CScript &scriptPubKey) +bool getCCopret(const CScript &scriptPubKey, CScript &opret) { std::vector> vParams = std::vector>(); - CScript dummy; CScript opret; - if ( scriptPubKey.IsPayToCryptoCondition(&dummy, vParams) && vParams.size() == 1 ) + CScript dummy; bool ret = false; + if ( scriptPubKey.IsPayToCryptoCondition(&dummy, vParams) != 0 ) { - //fprintf(stderr, "vparams.%s\n", HexStr(vParams[0].begin(), vParams[0].end()).c_str()); - opret = CScript(vParams[0].begin()+6, vParams[0].end()); + ret = true; + if ( vParams.size() == 1) + { + opret = CScript(vParams[0].begin()+6, vParams[0].end()); + //fprintf(stderr, "vparams.%s\n", HexStr(vParams[0].begin(), vParams[0].end()).c_str()); + } } - return opret; + return ret; } bool makeCCopret(CScript &opret, std::vector> &vData) diff --git a/src/cc/customcc.cpp b/src/cc/customcc.cpp index a8b0bf871..f7e8e6407 100644 --- a/src/cc/customcc.cpp +++ b/src/cc/customcc.cpp @@ -82,12 +82,12 @@ UniValue custom_func1(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) bool custom_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx) { char expectedaddress[64]; CPubKey pk; - CScript opret; int32_t numvout; + CScript opret; int32_t numvout = 0; if ( has_opret(tx, EVAL_CUSTOM) == 0 ) { std::vector> vParams = std::vector>(); - opret = getCCopret(tx.vout[0].scriptPubKey); - numvout = 1; + if ( getCCopret(tx.vout[0].scriptPubKey,opret) ) + numvout = 1; } else { diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index 0b69f79fc..e42da664f 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -157,22 +157,41 @@ uint8_t DecodePaymentsOpRet(CScript scriptPubKey,int32_t &lockedblocks,int32_t & return(0); } -CScript EncodePaymentsSnapsShotOpRet(int32_t lockedblocks,int32_t minrelease,int32_t top,int32_t bottom,int8_t fixedAmount,std::vector> excludeScriptPubKeys) +CScript EncodePaymentsSnapsShotOpRet(int32_t lockedblocks,int32_t minrelease,int32_t minimum,int32_t top,int32_t bottom,int8_t fixedAmount,std::vector> excludeScriptPubKeys) { CScript opret; uint8_t evalcode = EVAL_PAYMENTS; - opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'S' << lockedblocks << minrelease << top << bottom << fixedAmount << excludeScriptPubKeys); + if ( (strcmp(ASSETCHAINS_SYMBOL, "CFEKPAY") == 0) ) // exempt for now, remove this after game completed. + { + minimum = 10000; + opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'S' << lockedblocks << minrelease << top << bottom << fixedAmount << excludeScriptPubKeys); + } + else + opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'S' << lockedblocks << minrelease << minimum << top << bottom << fixedAmount << excludeScriptPubKeys); return(opret); } -uint8_t DecodePaymentsSnapsShotOpRet(CScript scriptPubKey,int32_t &lockedblocks,int32_t &minrelease,int32_t &top,int32_t &bottom,int8_t &fixedAmount,std::vector> &excludeScriptPubKeys) +uint8_t DecodePaymentsSnapsShotOpRet(CScript scriptPubKey,int32_t &lockedblocks,int32_t &minrelease,int32_t &minimum,int32_t &top,int32_t &bottom,int8_t &fixedAmount,std::vector> &excludeScriptPubKeys) { std::vector vopret; uint8_t *script,e,f; GetOpReturnData(scriptPubKey, vopret); script = (uint8_t *)vopret.data(); - if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> lockedblocks; ss >> minrelease; ss >> top; ; ss >> bottom; ss >> fixedAmount; ss >> excludeScriptPubKeys) != 0 ) + if ( (strcmp(ASSETCHAINS_SYMBOL, "CFEKPAY") == 0) ) // exempt for now, remove this after game completed. { - if ( e == EVAL_PAYMENTS && f == 'S' ) - return(f); + minimum = 10000; + if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> lockedblocks; ss >> minrelease; ss >> top; ; ss >> bottom; ss >> fixedAmount; ss >> excludeScriptPubKeys) != 0 ) + { + if ( e == EVAL_PAYMENTS && f == 'S' ) + return(f); + } + } + else + { + + if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> lockedblocks; ss >> minrelease; ss >> minimum; ss >> top; ; ss >> bottom; ss >> fixedAmount; ss >> excludeScriptPubKeys) != 0 ) + { + if ( e == EVAL_PAYMENTS && f == 'S' ) + return(f); + } } return(0); } @@ -197,10 +216,11 @@ uint8_t DecodePaymentsTokensOpRet(CScript scriptPubKey,int32_t &lockedblocks,int return(0); } -int64_t IsPaymentsvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v,char *cmpaddr) +int64_t IsPaymentsvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v,char *cmpaddr, CScript &ccopret) { char destaddr[64]; - if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 ) + //if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 ) + if ( getCCopret(tx.vout[v].scriptPubKey, ccopret) ) { if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && (cmpaddr[0] == 0 || strcmp(destaddr,cmpaddr) == 0) ) return(tx.vout[v].nValue); @@ -259,197 +279,216 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & // change is/must be in vout[0] // only 'F' or 1of2 txidaddr can be spent // all vouts must match exactly - char temp[128], coinaddr[64], txidaddr[64]; std::string scriptpubkey; uint256 createtxid, blockhash, tokenid; CTransaction plantx; int8_t funcid=0, fixedAmount=0; - int32_t i,lockedblocks,minrelease; int64_t change,totalallocations; std::vector txidoprets; bool fHasOpret = false; CPubKey txidpk,Paymentspk; - int32_t top,bottom=0; std::vector> excludeScriptPubKeys; bool fFixedAmount = false; + char temp[128], coinaddr[64]={0}, txidaddr[64]; std::string scriptpubkey; uint256 createtxid, blockhash, tokenid; CTransaction plantx; int8_t funcid=0, fixedAmount=0; + int32_t i,lockedblocks,minrelease; int64_t change,totalallocations; std::vector txidoprets; bool fHasOpret = false,fIsMerge = false; CPubKey txidpk,Paymentspk; + int32_t top,bottom=0,minimum=10000; std::vector> excludeScriptPubKeys; bool fFixedAmount = false; CScript ccopret; mpz_t mpzTotalAllocations, mpzAllocation;; mpz_init(mpzTotalAllocations); // user marker vout to get the createtxid - if ( tx.vout.size() < 2 ) - return(eval->Invalid("not enough vouts")); - if ( tx.vout.back().scriptPubKey[0] == OP_RETURN ) + if ( tx.vout.size() == 1 ) + { + if ( IsPaymentsvout(cp,tx,0,coinaddr,ccopret) != 0 && ccopret.size() > 2 && DecodePaymentsMergeOpRet(ccopret,createtxid) ) + { + fIsMerge = true; + } else return(eval->Invalid("not enough vouts")); + } + else if ( tx.vout.back().scriptPubKey[0] == OP_RETURN ) { scriptpubkey = HexStr(tx.vout[tx.vout.size()-2].scriptPubKey.begin()+2, tx.vout[tx.vout.size()-2].scriptPubKey.end()-1); fHasOpret = true; - } else scriptpubkey = HexStr(tx.vout[tx.vout.size()-1].scriptPubKey.begin()+2,tx.vout[tx.vout.size()-1].scriptPubKey.end()-1); - strcpy(temp, scriptpubkey.c_str()); - pub2createtxid(temp); - createtxid = Parseuint256(temp); + } + else scriptpubkey = HexStr(tx.vout[tx.vout.size()-1].scriptPubKey.begin()+2,tx.vout[tx.vout.size()-1].scriptPubKey.end()-1); + if ( !fIsMerge ) + { + strcpy(temp, scriptpubkey.c_str()); + pub2createtxid(temp); + createtxid = Parseuint256(temp); + } //printf("createtxid.%s\n",createtxid.ToString().c_str()); // use the createtxid to fetch the tx and all of the plans info. if ( myGetTransaction(createtxid,plantx,blockhash) != 0 && plantx.vout.size() > 0 ) { - if ( ((funcid= DecodePaymentsOpRet(plantx.vout[plantx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets)) == 'C' || (funcid= DecodePaymentsSnapsShotOpRet(plantx.vout[plantx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,bottom,fixedAmount,excludeScriptPubKeys)) == 'S' || (funcid= DecodePaymentsTokensOpRet(plantx.vout[plantx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys,tokenid)) == 'O') ) + if ( ((funcid= DecodePaymentsOpRet(plantx.vout[plantx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets)) == 'C' || (funcid= DecodePaymentsSnapsShotOpRet(plantx.vout[plantx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys)) == 'S' || (funcid= DecodePaymentsTokensOpRet(plantx.vout[plantx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys,tokenid)) == 'O') ) { if ( lockedblocks < 0 || minrelease < 0 || (totalallocations <= 0 && top <= 0 ) ) - return(eval->Invalid("negative values")); + return(eval->Invalid("negative values")); + if ( minimum < 10000 ) + return(eval->Invalid("minimum must be over 10000")); Paymentspk = GetUnspendable(cp,0); txidpk = CCtxidaddr(txidaddr,createtxid); GetCCaddress1of2(cp,coinaddr,Paymentspk,txidpk); //fprintf(stderr, "lockedblocks.%i minrelease.%i totalallocations.%i txidopret1.%s txidopret2.%s\n",lockedblocks, minrelease, totalallocations, txidoprets[0].ToString().c_str(), txidoprets[1].ToString().c_str() ); if ( !CheckTxFee(tx, PAYMENTS_TXFEE+1, chainActive.LastTip()->GetHeight(), chainActive.LastTip()->nTime) ) return eval->Invalid("txfee is too high"); - // Get all the script pubkeys and allocations - std::vector allocations; - std::vector scriptPubKeys; - int64_t checkallocations = 0; - i = 0; - if ( funcid == 'C' ) - { - // normal payment - for (const uint256& txidopret : txidoprets) - { - CTransaction tx0; std::vector scriptPubKey,opret; int64_t allocation; - if ( myGetTransaction(txidopret,tx0,blockhash) != 0 && tx0.vout.size() > 1 && DecodePaymentsTxidOpRet(tx0.vout[tx0.vout.size()-1].scriptPubKey,allocation,scriptPubKey,opret) == 'T' ) - { - scriptPubKeys.push_back(CScript(scriptPubKey.begin(), scriptPubKey.end())); - allocations.push_back(allocation); - //fprintf(stderr, "i.%i scriptpubkey.%s allocation.%li\n",i,scriptPubKeys[i].ToString().c_str(),allocation); - checkallocations += allocation; - // if we have an op_return to pay to need to check it exists and is paying the correct opret. - if ( !opret.empty() ) - { - if ( !fHasOpret ) - { - fprintf(stderr, "missing opret.%s in payments release.\n",HexStr(opret.begin(), opret.end()).c_str()); - return(eval->Invalid("missing opret in payments release")); - } - else if ( CScript(opret.begin(),opret.end()) != tx.vout[tx.vout.size()-1].scriptPubKey ) - { - fprintf(stderr, "opret.%s vs opret.%s\n",HexStr(opret.begin(), opret.end()).c_str(), HexStr(tx.vout[tx.vout.size()-1].scriptPubKey.begin(), tx.vout[tx.vout.size()-1].scriptPubKey.end()).c_str()); - return(eval->Invalid("pays incorrect opret")); - } - } - } - i++; - } - mpz_set_si(mpzTotalAllocations,totalallocations); - } - else if ( funcid == 'S' ) - { - if ( KOMODO_SNAPSHOT_INTERVAL == 0 ) - return(eval->Invalid("snapshots not activated on this chain")); - if ( vAddressSnapshot.size() == 0 ) - return(eval->Invalid("need first snapshot")); - // need time for TX to me mined before the next snapshot. - if ( top > 3999 ) - return(eval->Invalid("transaction too big")); - if ( fixedAmount == 7 ) - { - // game setting, randomise bottom and top values - fFixedAmount = payments_game(top,bottom); - } - else if ( fixedAmount != 0 ) - { - fFixedAmount = true; - } - for (int32_t j = bottom; j < vAddressSnapshot.size(); j++) - { - auto &address = vAddressSnapshot[j]; - CScript scriptPubKey = GetScriptForDestination(address.second); bool skip = false; - for ( auto skipkey : excludeScriptPubKeys ) - { - if ( scriptPubKey == CScript(skipkey.begin(), skipkey.end()) ) - { - skip = true; - //fprintf(stderr, "SKIPPED::: %s\n", CBitcoinAddress(address.second).ToString().c_str()); - } - } - if ( !skip ) - { - mpz_init(mpzAllocation); - i++; - scriptPubKeys.push_back(scriptPubKey); - allocations.push_back(address.first); - mpz_set_si(mpzAllocation,address.first); - mpz_add(mpzTotalAllocations,mpzTotalAllocations,mpzAllocation); - mpz_clear(mpzAllocation); - } - if ( i+bottom == top ) // we reached top amount to pay, it can be less than this! - break; - } - if ( i != tx.vout.size()-2 ) - return(eval->Invalid("pays wrong amount of recipients")); - } - else if ( funcid == 'O' ) - { - // tokens snapshot. - } - // sanity check to make sure we got all the required info - //fprintf(stderr, " allocations.size().%li scriptPubKeys.size.%li\n",allocations.size(), scriptPubKeys.size()); - if ( allocations.size() == 0 || scriptPubKeys.size() == 0 || allocations.size() != scriptPubKeys.size() ) - return(eval->Invalid("missing data cannot validate")); - - //fprintf(stderr, "totalallocations.%li checkallocations.%li\n",totalallocations, checkallocations); - if ( funcid == 'C' && totalallocations != checkallocations ) // only check for normal payments release. - return(eval->Invalid("allocation missmatch")); - // make sure change is in vout 0 and is paying to the contract address. - if ( (change= IsPaymentsvout(cp,tx,0,coinaddr)) == 0 ) + if ( (change= IsPaymentsvout(cp,tx,0,coinaddr,ccopret)) == 0 ) return(eval->Invalid("change is in wrong vout or is wrong tx type")); - // Check vouts go to the right place and pay the right amounts. - int64_t amount = 0, checkamount; int32_t n = 0; - checkamount = tx.GetValueOut() - change - PAYMENTS_TXFEE; - mpz_t mpzCheckamount; mpz_init(mpzCheckamount); mpz_set_si(mpzCheckamount,checkamount); - for (i = 1; i < (fHasOpret ? tx.vout.size()-2 : tx.vout.size()-1); i++) + if ( !fIsMerge ) { - if ( scriptPubKeys[n] != tx.vout[i].scriptPubKey ) + // Get all the script pubkeys and allocations + std::vector allocations; + std::vector scriptPubKeys; + int64_t checkallocations = 0; + i = 0; + if ( funcid == 'C' ) { - fprintf(stderr, "pays wrong destination destscriptPubKey.%s voutscriptPubKey.%s\n", HexStr(scriptPubKeys[n].begin(),scriptPubKeys[n].end()).c_str(), HexStr(tx.vout[i].scriptPubKey.begin(),tx.vout[i].scriptPubKey.end()).c_str()); - return(eval->Invalid("pays wrong address")); + // normal payment + for (const uint256& txidopret : txidoprets) + { + CTransaction tx0; std::vector scriptPubKey,opret; int64_t allocation; + if ( myGetTransaction(txidopret,tx0,blockhash) != 0 && tx0.vout.size() > 1 && DecodePaymentsTxidOpRet(tx0.vout[tx0.vout.size()-1].scriptPubKey,allocation,scriptPubKey,opret) == 'T' ) + { + scriptPubKeys.push_back(CScript(scriptPubKey.begin(), scriptPubKey.end())); + allocations.push_back(allocation); + //fprintf(stderr, "i.%i scriptpubkey.%s allocation.%li\n",i,scriptPubKeys[i].ToString().c_str(),allocation); + checkallocations += allocation; + // if we have an op_return to pay to need to check it exists and is paying the correct opret. + if ( !opret.empty() ) + { + if ( !fHasOpret ) + { + fprintf(stderr, "missing opret.%s in payments release.\n",HexStr(opret.begin(), opret.end()).c_str()); + return(eval->Invalid("missing opret in payments release")); + } + else if ( CScript(opret.begin(),opret.end()) != tx.vout[tx.vout.size()-1].scriptPubKey ) + { + fprintf(stderr, "opret.%s vs opret.%s\n",HexStr(opret.begin(), opret.end()).c_str(), HexStr(tx.vout[tx.vout.size()-1].scriptPubKey.begin(), tx.vout[tx.vout.size()-1].scriptPubKey.end()).c_str()); + return(eval->Invalid("pays incorrect opret")); + } + } + } + i++; + } + mpz_set_si(mpzTotalAllocations,totalallocations); } - int64_t test; - if ( fFixedAmount ) + else if ( funcid == 'S' ) { - test = checkamount / (top-bottom); + if ( KOMODO_SNAPSHOT_INTERVAL == 0 ) + return(eval->Invalid("snapshots not activated on this chain")); + if ( vAddressSnapshot.size() == 0 ) + return(eval->Invalid("need first snapshot")); + if ( top > 3999 ) + return(eval->Invalid("transaction too big")); + if ( fixedAmount == 7 ) + { + // game setting, randomise bottom and top values + fFixedAmount = payments_game(top,bottom); + } + else if ( fixedAmount != 0 ) + { + fFixedAmount = true; + } + for (int32_t j = bottom; j < vAddressSnapshot.size(); j++) + { + auto &address = vAddressSnapshot[j]; + CScript scriptPubKey = GetScriptForDestination(address.second); bool skip = false; + for ( auto skipkey : excludeScriptPubKeys ) + { + if ( scriptPubKey == CScript(skipkey.begin(), skipkey.end()) ) + { + skip = true; + //fprintf(stderr, "SKIPPED::: %s\n", CBitcoinAddress(address.second).ToString().c_str()); + } + } + if ( !skip ) + { + mpz_init(mpzAllocation); + i++; + scriptPubKeys.push_back(scriptPubKey); + allocations.push_back(address.first); + mpz_set_si(mpzAllocation,address.first); + mpz_add(mpzTotalAllocations,mpzTotalAllocations,mpzAllocation); + mpz_clear(mpzAllocation); + } + if ( i+bottom == top ) // we reached top amount to pay, it can be less than this! + break; + } + if ( i != tx.vout.size()-2 ) + return(eval->Invalid("pays wrong amount of recipients")); } - else + else if ( funcid == 'O' ) { - mpz_init(mpzAllocation); - mpz_set_si(mpzAllocation,allocations[n]); - mpz_mul(mpzAllocation,mpzAllocation,mpzCheckamount); - mpz_cdiv_q(mpzAllocation,mpzAllocation,mpzTotalAllocations); - test = mpz_get_si(mpzAllocation); - mpz_clear(mpzAllocation); + // tokens snapshot. } - // Vairance of 1 sat is allowed, for rounding errors. - if ( test >= tx.vout[i].nValue+1 && test <= tx.vout[i].nValue-1 ) + // sanity check to make sure we got all the required info, skip for merge type tx + //fprintf(stderr, " allocations.size().%li scriptPubKeys.size.%li\n",allocations.size(), scriptPubKeys.size()); + if ( (allocations.size() == 0 || scriptPubKeys.size() == 0 || allocations.size() != scriptPubKeys.size()) ) + return(eval->Invalid("missing data cannot validate")); + + //fprintf(stderr, "totalallocations.%li checkallocations.%li\n",totalallocations, checkallocations); + if ( funcid == 'C' && totalallocations != checkallocations ) // only check for normal payments release. + return(eval->Invalid("allocation missmatch")); + + // Check vouts go to the right place and pay the right amounts. + int64_t amount = 0, checkamount; int32_t n = 0; + checkamount = tx.GetValueOut() - change - PAYMENTS_TXFEE; + mpz_t mpzCheckamount; mpz_init(mpzCheckamount); mpz_set_si(mpzCheckamount,checkamount); + for (i = 1; i < (fHasOpret ? tx.vout.size()-2 : tx.vout.size()-1); i++) { - fprintf(stderr, "vout.%i test.%li vs nVlaue.%li\n",i, test, tx.vout[i].nValue); + if ( scriptPubKeys[n] != tx.vout[i].scriptPubKey ) + { + fprintf(stderr, "pays wrong destination destscriptPubKey.%s voutscriptPubKey.%s\n", HexStr(scriptPubKeys[n].begin(),scriptPubKeys[n].end()).c_str(), HexStr(tx.vout[i].scriptPubKey.begin(),tx.vout[i].scriptPubKey.end()).c_str()); + return(eval->Invalid("pays wrong address")); + } + int64_t test; + if ( fFixedAmount ) + { + test = checkamount / (top-bottom); + } + else + { + mpz_init(mpzAllocation); + mpz_set_si(mpzAllocation,allocations[n]); + mpz_mul(mpzAllocation,mpzAllocation,mpzCheckamount); + mpz_cdiv_q(mpzAllocation,mpzAllocation,mpzTotalAllocations); + test = mpz_get_si(mpzAllocation); + mpz_clear(mpzAllocation); + } + // Vairance of 1 sat is allowed, for rounding errors. + if ( test >= tx.vout[i].nValue+1 && test <= tx.vout[i].nValue-1 ) + { + fprintf(stderr, "vout.%i test.%li vs nVlaue.%li\n",i, test, tx.vout[i].nValue); + return(eval->Invalid("amounts do not match")); + } + if ( test < minimum ) + { + fprintf(stderr, "vout.%i test.%li vs minimum.%i\n",i, test, minimum); + return(eval->Invalid("under minimum size")); + } + amount += tx.vout[i].nValue; + n++; + } + mpz_clear(mpzTotalAllocations); + // This is a backup check to make sure there are no extra vouts paying something else! + if ( checkamount != amount ) return(eval->Invalid("amounts do not match")); + + if ( amount < minrelease*COIN ) + { + fprintf(stderr, "does not meet minrelease amount.%li minrelease.%li\n",amount, (int64_t)minrelease*COIN ); + return(eval->Invalid("amount is too small")); } - amount += tx.vout[i].nValue; - n++; } - mpz_clear(mpzTotalAllocations); - // This is a backup check to make sure there are no extra vouts paying something else! - if ( checkamount != amount ) - return(eval->Invalid("amounts do not match")); - - if ( amount < minrelease*COIN ) - { - fprintf(stderr, "does not meet minrelease amount.%li minrelease.%li\n",amount, (int64_t)minrelease*COIN ); - return(eval->Invalid("amount is too small")); - } - // Check vins - i = 0; + i = 0; int32_t dust = 0; int32_t blocksleft; BOOST_FOREACH(const CTxIn& vin, tx.vin) { - CTransaction txin; + CTransaction txin; if ( myGetTransaction(vin.prevout.hash,txin,blockhash) ) { // check the vin comes from the CC address's - char destaddr[64]; + char destaddr[64]; int32_t mergeoffset = 0; CScript opret; uint256 checktxid; Getscriptaddress(destaddr,txin.vout[vin.prevout.n].scriptPubKey); + if ( fIsMerge && txin.vout[vin.prevout.n].nValue < COIN ) + dust++; if ( strcmp(destaddr,coinaddr) != 0 ) { // if does not come from address its in the global payments adddress and we need to check the opreturn. - CScript opret; uint256 checktxid; int32_t opret_ind; + uint256 checktxid; int32_t opret_ind; if ( (opret_ind= has_opret(txin, EVAL_PAYMENTS)) == 0 ) - opret = getCCopret(txin.vout[vin.prevout.n].scriptPubKey); // get op_return from CCvout, + getCCopret(txin.vout[vin.prevout.n].scriptPubKey,opret); // get op_return from CCvout, else opret = txin.vout[opret_ind].scriptPubKey; if ( DecodePaymentsFundOpRet(opret,checktxid) != 'F' || checktxid != createtxid ) @@ -457,13 +496,25 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & fprintf(stderr, "vin.%i is not a payments CC vout: txid.%s\n", i, txin.GetHash().ToString().c_str()); return(eval->Invalid("vin is not paymentsCC type")); } + } + else if ( fIsMerge && getCCopret(txin.vout[vin.prevout.n].scriptPubKey,opret) && opret.size() > 2 && DecodePaymentsMergeOpRet(opret,checktxid) == 'M' ) + { + mergeoffset = PAYMENTS_MERGEOFSET; } + fprintf(stderr, "mergeoffset.%i\n", mergeoffset); // check the chain depth vs locked blocks requirement. - if ( !payments_lockedblocks(blockhash, lockedblocks, blocksleft) ) + if ( !payments_lockedblocks(blockhash, lockedblocks+mergeoffset, blocksleft) ) return(eval->Invalid("vin not elegible")); + i++; } else return(eval->Invalid("cant get vin transaction")); - i++; } + if ( fIsMerge ) + { + if ( i < 2 ) + return(eval->Invalid("must have at least 2 vins to carry out merge")); + 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")); return(true); @@ -474,7 +525,7 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & int64_t AddPaymentsInputs(bool fLockedBlocks,int8_t GetBalance,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey txidpk,int64_t total,int32_t maxinputs,uint256 createtxid,int32_t lockedblocks,int64_t minrelease,int32_t &blocksleft) { char coinaddr[64]; CPubKey Paymentspk; int64_t nValue,threshold,price,totalinputs = 0; uint256 txid,checktxid,hashBlock; std::vector origpubkey; CTransaction vintx; int32_t iter,vout,ht,n = 0; - std::vector > unspentOutputs; + std::vector > unspentOutputs; CScript ccopret; std::vector > blocksleft_balance; if ( GetBalance == 0 ) { @@ -509,7 +560,7 @@ int64_t AddPaymentsInputs(bool fLockedBlocks,int8_t GetBalance,struct CCcontract if ( (opret_ind= has_opret(vintx, EVAL_PAYMENTS)) == 0 ) { // get op_return from CCvout - opret = getCCopret(vintx.vout[vout].scriptPubKey); + getCCopret(vintx.vout[vout].scriptPubKey,opret); } else { @@ -522,13 +573,15 @@ int64_t AddPaymentsInputs(bool fLockedBlocks,int8_t GetBalance,struct CCcontract continue; } } - if ( (nValue= IsPaymentsvout(cp,vintx,vout,coinaddr)) > PAYMENTS_TXFEE && nValue >= threshold && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 ) + if ( (nValue= IsPaymentsvout(cp,vintx,vout,coinaddr,ccopret)) > PAYMENTS_TXFEE && nValue >= threshold && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 ) { int32_t tmpblocksleft = 0; - if ( GetBalance == 0 && total != 0 && maxinputs != 0 ) + if ( (GetBalance == 0 && total != 0 && maxinputs != 0) || GetBalance == 4 ) mtx.vin.push_back(CTxIn(txid,vout,CScript())); nValue = it->second.satoshis; - if ( fLockedBlocks && !payments_lockedblocks(hashBlock, lockedblocks, tmpblocksleft) ) + if ( nValue < COIN ) + blocksleft++; // count dust with unused variable. + if ( fLockedBlocks && !payments_lockedblocks(hashBlock, lockedblocks+(GetBalance == 4 ? PAYMENTS_MERGEOFSET : 0), tmpblocksleft) ) { blocksleft_balance.push_back(std::make_pair(tmpblocksleft,nValue)); continue; @@ -636,7 +689,7 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) //int32_t latestheight,nextheight = komodo_nextheight(); CMutableTransaction tmpmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(),nextheight); UniValue result(UniValue::VOBJ); uint256 createtxid,hashBlock,tokenid; CTransaction tx,txO; CPubKey mypk,txidpk,Paymentspk; int32_t i,n,m,numoprets=0,lockedblocks,minrelease; int64_t newamount,inputsum,amount,CCchange=0,totalallocations=0,checkallocations=0,allocation; CTxOut vout; CScript onlyopret; char txidaddr[64],destaddr[64]; std::vector txidoprets; - int32_t top,bottom=0,blocksleft=0; std::vector> excludeScriptPubKeys; int8_t funcid,fixedAmount=0; bool fFixedAmount = false; + int32_t top,bottom=0,blocksleft=0,minimum=10000; std::vector> excludeScriptPubKeys; int8_t funcid,fixedAmount=0; bool fFixedAmount = false; mpz_t mpzTotalAllocations; mpz_init(mpzTotalAllocations); cJSON *params = payments_reparse(&n,jsonstr); mypk = pubkey2pk(Mypubkey()); @@ -647,7 +700,7 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) amount = jdouble(jitem(params,1),0) * SATOSHIDEN + 0.0000000049; if ( myGetTransaction(createtxid,tx,hashBlock) != 0 && tx.vout.size() > 0 ) { - if ( ((funcid= DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets)) == 'C' || (funcid= DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,bottom,fixedAmount,excludeScriptPubKeys)) == 'S' || (funcid= DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys,tokenid)) == 'O') ) + if ( ((funcid= DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets)) == 'C' || (funcid= DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys)) == 'S' || (funcid= DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys,tokenid)) == 'O') ) { if ( lockedblocks < 0 || minrelease < 0 || (totalallocations <= 0 && top <= 0 ) ) { @@ -657,6 +710,9 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) free_json(params); return(result); } + // set minimum size to 10k sat otherwise the tx will be invalid. + if ( minimum < 10000 ) + minimum = 10000; //latestheight = (nextheight - lockedblocks - 1); if ( amount < minrelease*COIN ) { @@ -817,13 +873,14 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) } //fprintf(stderr, "nValue.%li \n", mtx.vout[i+1].nValue); mpz_clear(mpzValue); - /* - replace this with default dust threshold of 10ksat - if ( mtx.vout[i+1].nValue < PAYMENTS_TXFEE ) + if ( mtx.vout[i+1].nValue < minimum ) { - newamount += (PAYMENTS_TXFEE - mtx.vout[i+1].nValue); - mtx.vout[i+1].nValue = PAYMENTS_TXFEE; - } */ + result.push_back(Pair("result","error")); + result.push_back(Pair("error","value too small, try releasing a larger amount")); + if ( params != 0 ) + free_json(params); + return(result); + } totalamountsent += mtx.vout[i+1].nValue; } if ( totalamountsent < amount ) newamount = totalamountsent; @@ -879,7 +936,7 @@ UniValue PaymentsFund(struct CCcontract_info *cp,char *jsonstr) { CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); UniValue result(UniValue::VOBJ); CPubKey Paymentspk,mypk,txidpk; uint256 txid,hashBlock; int64_t amount,totalallocations; CScript opret; CTransaction tx; char txidaddr[64]; std::string rawtx; int32_t n,useopret = 0,lockedblocks,minrelease; std::vector txidoprets; - int32_t top,bottom; std::vector> excludeScriptPubKeys; // snapshot + int32_t top,bottom,minimum=10000; std::vector> excludeScriptPubKeys; // snapshot uint256 tokenid; int8_t fixedAmount; cJSON *params = payments_reparse(&n,jsonstr); mypk = pubkey2pk(Mypubkey()); @@ -890,7 +947,7 @@ UniValue PaymentsFund(struct CCcontract_info *cp,char *jsonstr) amount = jdouble(jitem(params,1),0) * SATOSHIDEN + 0.0000000049; if ( n == 3 ) useopret = jint(jitem(params,2),0) != 0; - if ( myGetTransaction(txid,tx,hashBlock) == 0 || tx.vout.size() == 1 || (DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) == 0 && DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,bottom,fixedAmount,excludeScriptPubKeys) == 0 && DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys,tokenid) == 0) ) + if ( myGetTransaction(txid,tx,hashBlock) == 0 || tx.vout.size() == 1 || (DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) == 0 && DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys) == 0 && DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys,tokenid) == 0) ) { result.push_back(Pair("result","error")); result.push_back(Pair("error","invalid createtxid")); @@ -942,6 +999,64 @@ UniValue PaymentsFund(struct CCcontract_info *cp,char *jsonstr) return(result); } +UniValue PaymentsMerge(struct CCcontract_info *cp,char *jsonstr) +{ + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); UniValue result(UniValue::VOBJ); + CPubKey Paymentspk,mypk,txidpk; uint256 createtxid,hashBlock; int64_t totalallocations,inputsum; CScript opret; CTransaction tx; char txidaddr[64],destaddr[64]; std::string rawtx; + int32_t n,useopret = 0,lockedblocks,minrelease,top,bottom,minimum=10000,blocksleft; std::vector txidoprets; + std::vector> excludeScriptPubKeys; // snapshot + uint256 tokenid; int8_t fixedAmount; + cJSON *params = payments_reparse(&n,jsonstr); + mypk = pubkey2pk(Mypubkey()); + Paymentspk = GetUnspendable(cp,0); + if ( params != 0 && n == 1 ) + { + createtxid = payments_juint256(jitem(params,0)); + txidpk = CCtxidaddr(txidaddr,createtxid); + if ( myGetTransaction(createtxid,tx,hashBlock) == 0 || tx.vout.size() == 1 || (DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) == 0 && DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys) == 0 && DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys,tokenid) == 0) ) + { + result.push_back(Pair("result","error")); + result.push_back(Pair("error","invalid createtxid")); + } + else if ( (inputsum= AddPaymentsInputs(true,4,cp,mtx,txidpk,0,CC_MAXVINS,createtxid,lockedblocks,minrelease,blocksleft)) > 0 && mtx.vin.size() > 1 ) + { + int32_t dust = blocksleft; + if ( mtx.vin.size() != dust+1 ) + { + result.push_back(Pair("result","error")); + result.push_back(Pair("error","cannot merge only dust")); + } + else + { + // encode the checktxid into the end of the ccvout, along with 'M' to flag merge type tx. + opret = EncodePaymentsMergeOpRet(createtxid); + std::vector> vData = std::vector>(); + if ( makeCCopret(opret, vData) ) + mtx.vout.push_back(MakeCC1vout(EVAL_PAYMENTS,inputsum-PAYMENTS_TXFEE,Paymentspk,&vData)); + GetCCaddress1of2(cp,destaddr,Paymentspk,txidpk); + CCaddr1of2set(cp,Paymentspk,txidpk,cp->CCpriv,destaddr); + rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,CScript()); + if ( params != 0 ) + free_json(params); + return(payments_rawtxresult(result,rawtx,1)); + } + } + else + { + result.push_back(Pair("result","error")); + result.push_back(Pair("error","couldnt find enough funds")); + } + } + else + { + result.push_back(Pair("result","error")); + result.push_back(Pair("error","parameters error")); + } + if ( params != 0 ) + free_json(params); + return(result); +} + UniValue PaymentsTxidopret(struct CCcontract_info *cp,char *jsonstr) { CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); UniValue result(UniValue::VOBJ); CPubKey mypk; std::string rawtx; @@ -1062,7 +1177,7 @@ UniValue PaymentsAirdrop(struct CCcontract_info *cp,char *jsonstr) CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); UniValue result(UniValue::VOBJ); uint256 hashBlock; CTransaction tx; CPubKey Paymentspk,mypk; char markeraddr[64]; std::string rawtx; - int32_t lockedblocks,minrelease,top,bottom,n,i; std::vector> excludeScriptPubKeys; int8_t fixedAmount; + int32_t lockedblocks,minrelease,top,bottom,n,i,minimum=10000; std::vector> excludeScriptPubKeys; int8_t fixedAmount; if ( KOMODO_SNAPSHOT_INTERVAL == 0 ) { result.push_back(Pair("result","error")); @@ -1074,10 +1189,11 @@ UniValue PaymentsAirdrop(struct CCcontract_info *cp,char *jsonstr) { lockedblocks = juint(jitem(params,0),0); minrelease = juint(jitem(params,1),0); - top = juint(jitem(params,2),0); - bottom = juint(jitem(params,3),0); - fixedAmount = juint(jitem(params,4),0); // fixed amount is a flag set to 0 or 1. It means allocations are equal rather than weighted by address balance. - if ( lockedblocks < 0 || minrelease < 0 || top <= 0 || bottom < 0 || fixedAmount < 0 || top > 3999 ) + minimum = juint(jitem(params,2),0); + top = juint(jitem(params,3),0); + bottom = juint(jitem(params,4),0); + fixedAmount = juint(jitem(params,5),0); // fixed amount is a flag, set to 7 does game mode, 0 normal snapshot, anything else fixed allocations. + if ( lockedblocks < 0 || minrelease < 0 || top <= 0 || bottom < 0 || minimum < 0 || fixedAmount < 0 || top > 3999 ) { result.push_back(Pair("result","error")); result.push_back(Pair("error","negative parameter, or top over 3999")); @@ -1085,15 +1201,15 @@ UniValue PaymentsAirdrop(struct CCcontract_info *cp,char *jsonstr) free_json(params); return(result); } - if ( n > 5 ) + if ( n > 6 ) { - for (i=0; i scriptPubKey; int32_t len = strlen(inputhex)/2; scriptPubKey.resize(len); @@ -1106,7 +1222,16 @@ UniValue PaymentsAirdrop(struct CCcontract_info *cp,char *jsonstr) if ( AddNormalinputs(mtx,mypk,2*PAYMENTS_TXFEE,60) > 0 ) { mtx.vout.push_back(MakeCC1of2vout(cp->evalcode,PAYMENTS_TXFEE,Paymentspk,Paymentspk)); - rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,EncodePaymentsSnapsShotOpRet(lockedblocks,minrelease,top,bottom,fixedAmount,excludeScriptPubKeys)); + CScript tempopret = EncodePaymentsSnapsShotOpRet(lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys); + if ( tempopret.size() > 10000 ) // TODO: Check this! + { + result.push_back(Pair("result","error")); + result.push_back(Pair("error","op_return is too big, try with less exclude addresses.")); + if ( params != 0 ) + free_json(params); + return(result); + } + rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,tempopret); if ( params != 0 ) free_json(params); return(payments_rawtxresult(result,rawtx,1)); @@ -1127,7 +1252,7 @@ UniValue PaymentsAirdrop(struct CCcontract_info *cp,char *jsonstr) UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr) { UniValue result(UniValue::VOBJ),a(UniValue::VARR); CTransaction tx,txO; CPubKey Paymentspk,txidpk; int32_t i,j,n,flag=0,numoprets=0,lockedblocks,minrelease,blocksleft=0; std::vector txidoprets; int64_t funds,fundsopret,elegiblefunds,totalallocations=0,allocation; char fundsaddr[64],fundsopretaddr[64],txidaddr[64],*outstr; uint256 createtxid,hashBlock; - int32_t top,bottom; std::vector> excludeScriptPubKeys; // snapshot + int32_t top,bottom,minimum=10000; std::vector> excludeScriptPubKeys; // snapshot uint256 tokenid; int8_t fixedAmount; CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(),komodo_nextheight()); cJSON *params = payments_reparse(&n,jsonstr); if ( params != 0 && n == 1 ) @@ -1183,9 +1308,9 @@ UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr) result.push_back(Pair("error","too many opreturns")); } else result.push_back(Pair("txidoprets",a)); } - else if ( DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,bottom,fixedAmount,excludeScriptPubKeys) != 0 ) + else if ( DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys) != 0 ) { - if ( lockedblocks < 0 || minrelease < 0 || top <= 0 || bottom < 0 || fixedAmount < 0 || top > 3999 ) + if ( lockedblocks < 0 || minrelease < 0 || top <= 0 || bottom < 0 || fixedAmount < 0 || top > 3999 || minimum < 10000 ) { result.push_back(Pair("result","error")); result.push_back(Pair("error","negative parameter")); @@ -1198,7 +1323,8 @@ UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr) else result.push_back(Pair("plan_type","snapshot")); result.push_back(Pair("lockedblocks",(int64_t)lockedblocks)); - result.push_back(Pair("minrelease",(int64_t)minrelease)); + result.push_back(Pair("minrelease",(int64_t)minrelease)); + result.push_back(Pair("minimum",(int64_t)minimum)); result.push_back(Pair("bottom",(int64_t)bottom)); result.push_back(Pair("top",(int64_t)top)); result.push_back(Pair("fixedFlag",(int64_t)fixedAmount)); @@ -1272,7 +1398,7 @@ UniValue PaymentsList(struct CCcontract_info *cp,char *jsonstr) { std::vector > addressIndex; uint256 txid,hashBlock,tokenid; UniValue result(UniValue::VOBJ),a(UniValue::VARR); char markeraddr[64],str[65]; CPubKey Paymentspk; CTransaction tx; int32_t lockedblocks,minrelease; std::vector txidoprets; int64_t totalallocations=0; - int32_t top=0,bottom=0; std::vector> excludeScriptPubKeys; int8_t fixedAmount = 0; + int32_t top=0,bottom=0,minimum=10000; std::vector> excludeScriptPubKeys; int8_t fixedAmount = 0; Paymentspk = GetUnspendable(cp,0); GetCCaddress1of2(cp,markeraddr,Paymentspk,Paymentspk); SetCCtxids(addressIndex,markeraddr,true); @@ -1281,9 +1407,9 @@ UniValue PaymentsList(struct CCcontract_info *cp,char *jsonstr) txid = it->first.txhash; if ( it->first.index == 0 && myGetTransaction(txid,tx,hashBlock) != 0 ) { - if ( tx.vout.size() > 0 && (DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) == 'C' || DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,bottom,fixedAmount,excludeScriptPubKeys) == 'S' || DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys,tokenid) == 'O') ) + if ( tx.vout.size() > 0 && (DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) == 'C' || DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys) == 'S' || DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys,tokenid) == 'O') ) { - if ( lockedblocks < 0 || minrelease < 0 || (totalallocations <= 0 && top <= 0 ) || bottom < 0 || fixedAmount < 0 ) + if ( lockedblocks < 0 || minrelease < 0 || (totalallocations <= 0 && top <= 0 ) || bottom < 0 || fixedAmount < 0 || minimum < 10000 ) { result.push_back(Pair("result","error")); result.push_back(Pair("error","negative parameter")); diff --git a/src/main.h b/src/main.h index d507f9dd6..2592fc657 100644 --- a/src/main.h +++ b/src/main.h @@ -95,7 +95,7 @@ static const unsigned int MAX_TEMPFILE_SIZE = 0x1000000; // 16 MiB 0x8000000 /** The pre-allocation chunk size for blk?????.dat files (since 0.8) */ static const unsigned int BLOCKFILE_CHUNK_SIZE = 0x1000000; // 16 MiB /** The pre-allocation chunk size for rev?????.dat files (since 0.8) */ -static const unsigned int UNDOFILE_CHUNK_SIZE = 0x100000; // 1 MiB +static const unsigned int UNDOFILE_CHUNK_SIZE = 0x1000000; // 16 MiB /** Maximum number of script-checking threads allowed */ static const int MAX_SCRIPTCHECK_THREADS = 16; /** -par default (number of script-checking threads, 0 = auto) */ diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 414add201..b1359ef15 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -487,6 +487,7 @@ static const CRPCCommand vRPCCommands[] = { "payments", "paymentslist", &payments_list, true }, { "payments", "paymentsinfo", &payments_info, true }, { "payments", "paymentsfund", &payments_fund, true }, + { "payments", "paymentsmerge", &payments_merge, true }, { "payments", "paymentsrelease", &payments_release, true }, { "CClib", "cclibaddress", &cclibaddress, true }, diff --git a/src/rpc/server.h b/src/rpc/server.h index b674ee909..5ec7640f2 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -287,6 +287,7 @@ extern UniValue marmara_lock(const UniValue& params, bool fHelp); extern UniValue paymentsaddress(const UniValue& params, bool fHelp); extern UniValue payments_release(const UniValue& params, bool fHelp); extern UniValue payments_fund(const UniValue& params, bool fHelp); +extern UniValue payments_merge(const UniValue& params, bool fHelp); extern UniValue payments_txidopret(const UniValue& params, bool fHelp); extern UniValue payments_create(const UniValue& params, bool fHelp); extern UniValue payments_airdrop(const UniValue& params, bool fHelp); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 888c60e0e..aff740e31 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5603,6 +5603,19 @@ UniValue payments_fund(const UniValue& params, bool fHelp) return(PaymentsFund(cp,(char *)params[0].get_str().c_str())); } +UniValue payments_merge(const UniValue& params, bool fHelp) +{ + struct CCcontract_info *cp,C; + if ( fHelp || params.size() != 1 ) + throw runtime_error("paymentsmerge \"[%22createtxid%22]\"\n"); + if ( ensure_CCrequirements(EVAL_PAYMENTS) < 0 ) + throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + const CKeyStore& keystore = *pwalletMain; + LOCK2(cs_main, pwalletMain->cs_wallet); + cp = CCinit(&C,EVAL_PAYMENTS); + return(PaymentsMerge(cp,(char *)params[0].get_str().c_str())); +} + UniValue payments_txidopret(const UniValue& params, bool fHelp) { struct CCcontract_info *cp,C; @@ -5633,7 +5646,7 @@ UniValue payments_airdrop(const UniValue& params, bool fHelp) { struct CCcontract_info *cp,C; if ( fHelp || params.size() != 1 ) - throw runtime_error("paymentsairdrop \"[lockedblocks,minamount,top,bottom,fixedFlag,%22excludeAddress%22,...,%22excludeAddressN%22]\"\n"); + throw runtime_error("paymentsairdrop \"[lockedblocks,minamount,mintoaddress,top,bottom,fixedFlag,%22excludeAddress%22,...,%22excludeAddressN%22]\"\n"); if ( ensure_CCrequirements(EVAL_PAYMENTS) < 0 ) throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); const CKeyStore& keystore = *pwalletMain; From 4f03f020426120cec1a93337a9fa013747fab160 Mon Sep 17 00:00:00 2001 From: Alrighttt Date: Sun, 5 May 2019 22:16:19 +0200 Subject: [PATCH 226/242] oraclessamples 0 to return all samples --- src/cc/oracles.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/oracles.cpp b/src/cc/oracles.cpp index 53148bba9..a5d61d404 100644 --- a/src/cc/oracles.cpp +++ b/src/cc/oracles.cpp @@ -959,7 +959,7 @@ UniValue OracleDataSamples(uint256 reforacletxid,uint256 batontxid,int32_t num) a.push_back(uint256_str(str,batontxid)); b.push_back(a); batontxid = btxid; - if ( ++n >= num ) + if ( ++n >= num && num != 0) break; } else break; } From 0f6fe03990f79ec4ddb9acf763ea817ea57a7fb2 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Mon, 6 May 2019 12:08:53 +0800 Subject: [PATCH 227/242] fix --- src/cc/CCutils.cpp | 3 ++- src/cc/payments.cpp | 23 ++++++++++++----------- src/chain.h | 4 ++-- src/komodo_nk.h | 4 ++-- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/cc/CCutils.cpp b/src/cc/CCutils.cpp index 5fe7d662b..363b54ad5 100644 --- a/src/cc/CCutils.cpp +++ b/src/cc/CCutils.cpp @@ -63,7 +63,8 @@ int32_t has_opret(const CTransaction &tx, uint8_t evalcode) int i = 0; for ( auto vout : tx.vout ) { - if ( vout.scriptPubKey[0] == OP_RETURN && vout.scriptPubKey[1] == evalcode ) + //fprintf(stderr, "[txid.%s] 1.%i 2.%i 3.%i 4.%i\n",tx.GetHash().GetHex().c_str(), vout.scriptPubKey[0], vout.scriptPubKey[1], vout.scriptPubKey[2], vout.scriptPubKey[3]); + if ( vout.scriptPubKey[0] == OP_RETURN && vout.scriptPubKey[2] == evalcode ) return i; i++; } diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index e42da664f..eda1bdb41 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -303,7 +303,7 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & pub2createtxid(temp); createtxid = Parseuint256(temp); } - //printf("createtxid.%s\n",createtxid.ToString().c_str()); + printf("createtxid.%s\n",createtxid.ToString().c_str()); // use the createtxid to fetch the tx and all of the plans info. if ( myGetTransaction(createtxid,plantx,blockhash) != 0 && plantx.vout.size() > 0 ) @@ -501,7 +501,7 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & { mergeoffset = PAYMENTS_MERGEOFSET; } - fprintf(stderr, "mergeoffset.%i\n", mergeoffset); + //fprintf(stderr, "mergeoffset.%i\n", mergeoffset); // check the chain depth vs locked blocks requirement. if ( !payments_lockedblocks(blockhash, lockedblocks+mergeoffset, blocksleft) ) return(eval->Invalid("vin not elegible")); @@ -576,16 +576,16 @@ int64_t AddPaymentsInputs(bool fLockedBlocks,int8_t GetBalance,struct CCcontract if ( (nValue= IsPaymentsvout(cp,vintx,vout,coinaddr,ccopret)) > PAYMENTS_TXFEE && nValue >= threshold && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 ) { int32_t tmpblocksleft = 0; - if ( (GetBalance == 0 && total != 0 && maxinputs != 0) || GetBalance == 4 ) - mtx.vin.push_back(CTxIn(txid,vout,CScript())); - nValue = it->second.satoshis; - if ( nValue < COIN ) - blocksleft++; // count dust with unused variable. if ( fLockedBlocks && !payments_lockedblocks(hashBlock, lockedblocks+(GetBalance == 4 ? PAYMENTS_MERGEOFSET : 0), tmpblocksleft) ) { blocksleft_balance.push_back(std::make_pair(tmpblocksleft,nValue)); continue; } + if ( (GetBalance == 0 && total != 0 && maxinputs != 0) || GetBalance == 4 ) + mtx.vin.push_back(CTxIn(txid,vout,CScript())); + nValue = it->second.satoshis; + if ( nValue < COIN ) + blocksleft++; // count dust with unused variable. totalinputs += nValue; n++; //fprintf(stderr,"iter.%d %s/v%d %s %.8f\n",iter,txid.GetHex().c_str(),vout,coinaddr,(double)nValue/COIN); @@ -1021,24 +1021,25 @@ UniValue PaymentsMerge(struct CCcontract_info *cp,char *jsonstr) else if ( (inputsum= AddPaymentsInputs(true,4,cp,mtx,txidpk,0,CC_MAXVINS,createtxid,lockedblocks,minrelease,blocksleft)) > 0 && mtx.vin.size() > 1 ) { int32_t dust = blocksleft; - if ( mtx.vin.size() != dust+1 ) + if ( mtx.vin.size() == dust+1 ) { result.push_back(Pair("result","error")); result.push_back(Pair("error","cannot merge only dust")); } else - { + { // encode the checktxid into the end of the ccvout, along with 'M' to flag merge type tx. opret = EncodePaymentsMergeOpRet(createtxid); std::vector> vData = std::vector>(); if ( makeCCopret(opret, vData) ) - mtx.vout.push_back(MakeCC1vout(EVAL_PAYMENTS,inputsum-PAYMENTS_TXFEE,Paymentspk,&vData)); + mtx.vout.push_back(MakeCC1of2vout(EVAL_PAYMENTS,inputsum-PAYMENTS_TXFEE,Paymentspk,txidpk,&vData)); + //mtx.vout.push_back(MakeCC1vout(EVAL_PAYMENTS,inputsum-PAYMENTS_TXFEE,txidpk,&vData)); GetCCaddress1of2(cp,destaddr,Paymentspk,txidpk); CCaddr1of2set(cp,Paymentspk,txidpk,cp->CCpriv,destaddr); rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,CScript()); if ( params != 0 ) free_json(params); - return(payments_rawtxresult(result,rawtx,1)); + return(payments_rawtxresult(result,rawtx,0)); } } else diff --git a/src/chain.h b/src/chain.h index 4e5d7e48d..b893e3a06 100644 --- a/src/chain.h +++ b/src/chain.h @@ -38,7 +38,7 @@ static const int SPROUT_VALUE_VERSION = 1001400; static const int SAPLING_VALUE_VERSION = 1010100; extern int32_t ASSETCHAINS_LWMAPOS; extern char ASSETCHAINS_SYMBOL[65]; -//extern uint64_t ASSETCHAINS_NOTARY_PAY; +extern uint64_t ASSETCHAINS_NOTARY_PAY[]; struct CDiskBlockPos { @@ -547,7 +547,7 @@ public: if ((s.GetType() & SER_DISK) && (nVersion >= SAPLING_VALUE_VERSION)) { READWRITE(nSaplingValue); } - if ( (s.GetType() & SER_DISK) && (is_STAKED(ASSETCHAINS_SYMBOL) != 0) ) + if ( (s.GetType() & SER_DISK) && (is_STAKED(ASSETCHAINS_SYMBOL) != 0) && ASSETCHAINS_NOTARY_PAY[0] != 0 ) { READWRITE(nNotaryPay); READWRITE(segid); diff --git a/src/komodo_nk.h b/src/komodo_nk.h index ed994c13f..3c9034dde 100644 --- a/src/komodo_nk.h +++ b/src/komodo_nk.h @@ -1,7 +1,7 @@ #ifndef KOMODO_NK_H #define KOMODO_NK_H -#define ASSETCHAINS_N 77 -#define ASSETCHAINS_K 3 +#define ASSETCHAINS_N 96 +#define ASSETCHAINS_K 5 #endif From 891a2102ba2e11b41b018f1c4f16915c1576b6d8 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Mon, 6 May 2019 14:54:59 +0800 Subject: [PATCH 228/242] fixes --- src/cc/payments.cpp | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index eda1bdb41..12d5cff62 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -303,7 +303,7 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & pub2createtxid(temp); createtxid = Parseuint256(temp); } - printf("createtxid.%s\n",createtxid.ToString().c_str()); + //printf("createtxid.%s\n",createtxid.ToString().c_str()); // use the createtxid to fetch the tx and all of the plans info. if ( myGetTransaction(createtxid,plantx,blockhash) != 0 && plantx.vout.size() > 0 ) @@ -496,7 +496,7 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & fprintf(stderr, "vin.%i is not a payments CC vout: txid.%s\n", i, txin.GetHash().ToString().c_str()); return(eval->Invalid("vin is not paymentsCC type")); } - } + } else if ( fIsMerge && getCCopret(txin.vout[vin.prevout.n].scriptPubKey,opret) && opret.size() > 2 && DecodePaymentsMergeOpRet(opret,checktxid) == 'M' ) { mergeoffset = PAYMENTS_MERGEOFSET; @@ -514,7 +514,7 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & return(eval->Invalid("must have at least 2 vins to carry out merge")); 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")); return(true); @@ -595,7 +595,7 @@ int64_t AddPaymentsInputs(bool fLockedBlocks,int8_t GetBalance,struct CCcontract } } } - if ( GetBalance == 3 ) // return elegible balance to be spent, and blocks left until min release can be released. + if ( GetBalance == 3 && totalinputs < minrelease ) // return elegible balance to be spent, and blocks left until min release can be released. { int64_t lockedblocks_balance = totalinputs; // inputs that can be spent already. // sort utxos by blocks until able to be spent, smallest at top. @@ -800,7 +800,6 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) return(result); } i = 0; - //for ( auto address : vAddressSnapshot ) if ( fixedAmount == 7 ) { // game setting, randomise bottom and top values @@ -846,7 +845,6 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) newamount = amount; int64_t totalamountsent = 0; mpz_t mpzAmount; mpz_init(mpzAmount); mpz_set_si(mpzAmount,amount); - fprintf(stderr, "m.%i\n",m); for (i=0; i txidoprets; + CPubKey Paymentspk,mypk,txidpk; uint256 createtxid,hashBlock; int64_t inputsum,totalallocations=0; CScript opret; CTransaction tx; char txidaddr[64],destaddr[64]; std::string rawtx; + int32_t n,lockedblocks,minrelease,top,bottom,minimum=10000,blocksleft; std::vector txidoprets; std::vector> excludeScriptPubKeys; // snapshot uint256 tokenid; int8_t fixedAmount; cJSON *params = payments_reparse(&n,jsonstr); @@ -1033,7 +1031,6 @@ UniValue PaymentsMerge(struct CCcontract_info *cp,char *jsonstr) std::vector> vData = std::vector>(); if ( makeCCopret(opret, vData) ) mtx.vout.push_back(MakeCC1of2vout(EVAL_PAYMENTS,inputsum-PAYMENTS_TXFEE,Paymentspk,txidpk,&vData)); - //mtx.vout.push_back(MakeCC1vout(EVAL_PAYMENTS,inputsum-PAYMENTS_TXFEE,txidpk,&vData)); GetCCaddress1of2(cp,destaddr,Paymentspk,txidpk); CCaddr1of2set(cp,Paymentspk,txidpk,cp->CCpriv,destaddr); rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,CScript()); @@ -1364,12 +1361,9 @@ UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr) txidpk = CCtxidaddr(txidaddr,createtxid); GetCCaddress1of2(cp,fundsaddr,Paymentspk,txidpk); funds = AddPaymentsInputs(false,2,cp,mtx,txidpk,0,CC_MAXVINS,createtxid,lockedblocks,minrelease,blocksleft); - //CCaddress_balance(fundsaddr,1); result.push_back(Pair(fundsaddr,ValueFromAmount(funds))); GetCCaddress(cp,fundsopretaddr,Paymentspk); - // TODO: Shows balance for ALL payments plans, not just the one asked for! Needs to be reworked. fundsopret = AddPaymentsInputs(false,1,cp,mtx,txidpk,0,CC_MAXVINS,createtxid,lockedblocks,minrelease,blocksleft); - //CCaddress_balance(fundsopretaddr,1); result.push_back(Pair(fundsopretaddr,ValueFromAmount(fundsopret))); result.push_back(Pair("totalfunds",ValueFromAmount(funds+fundsopret))); // Blocks until minrelease can be released. From b2de7d1ae26b42fc2bbd3c7191dddf0c8a42b585 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Mon, 6 May 2019 15:35:25 +0800 Subject: [PATCH 229/242] remove some labs stuff --- src/cc/CCtx.cpp | 2 +- src/cc/makecclib | 16 ++++++++-------- src/cc/makecustom | 7 +++---- src/wallet/db.h | 6 +++--- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/cc/CCtx.cpp b/src/cc/CCtx.cpp index fe5fade71..7435defbf 100644 --- a/src/cc/CCtx.cpp +++ b/src/cc/CCtx.cpp @@ -241,7 +241,7 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran { char coinaddr[64]; GetCCaddress1of2(cp,coinaddr,globalpk,pubkeys[i]); - fprintf(stderr,"%s + %s -> %s vs %s\n",HexStr(globalpk).c_str(),HexStr(pubkeys[i]).c_str(),coinaddr,destaddr); + //fprintf(stderr,"%s + %s -> %s vs %s\n",HexStr(globalpk).c_str(),HexStr(pubkeys[i]).c_str(),coinaddr,destaddr); if ( strcmp(destaddr,coinaddr) == 0 ) { privkey = cp->CCpriv; diff --git a/src/cc/makecclib b/src/cc/makecclib index 256d50995..e4816c55c 100755 --- a/src/cc/makecclib +++ b/src/cc/makecclib @@ -7,14 +7,14 @@ make -f Makefile_rogue rm ../libcc.so cp librogue.so ../libcc.so -#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 +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 -#echo games tetris -#./maketetris +echo games tetris +./maketetris -#echo games prices -#./makeprices +echo games prices +./makeprices -#echo customcc stub -#gcc -O3 -DBUILD_CUSTOMCC -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 customcc.so cclib.cpp +echo customcc stub +gcc -O3 -DBUILD_CUSTOMCC -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 customcc.so cclib.cpp diff --git a/src/cc/makecustom b/src/cc/makecustom index 06f2f6fb1..154be4f31 100755 --- a/src/cc/makecustom +++ b/src/cc/makecustom @@ -1,7 +1,6 @@ #!/bin/sh gcc -O3 -DBUILD_CUSTOMCC -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 customcc.so cclib.cpp cp customcc.so ../libcc.so -#cd .. -#make -#cd cc - +cd .. +make +cd cc diff --git a/src/wallet/db.h b/src/wallet/db.h index 4af25c698..e1ae52909 100644 --- a/src/wallet/db.h +++ b/src/wallet/db.h @@ -33,9 +33,9 @@ #include -// CCLIB fails to compile with this! -//#include -#include "../depends/x86_64-unknown-linux-gnu/include/db_cxx.h" +// If CCLIB fails to compile with this, use the one below. +#include +//#include "../depends/x86_64-unknown-linux-gnu/include/db_cxx.h" extern unsigned int nWalletDBUpdated; From 69626ff68d078b25568d1f2b365431f1eb4a4871 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Mon, 6 May 2019 16:38:22 +0800 Subject: [PATCH 230/242] revert undo file size --- src/main.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.h b/src/main.h index 2592fc657..d507f9dd6 100644 --- a/src/main.h +++ b/src/main.h @@ -95,7 +95,7 @@ static const unsigned int MAX_TEMPFILE_SIZE = 0x1000000; // 16 MiB 0x8000000 /** The pre-allocation chunk size for blk?????.dat files (since 0.8) */ static const unsigned int BLOCKFILE_CHUNK_SIZE = 0x1000000; // 16 MiB /** The pre-allocation chunk size for rev?????.dat files (since 0.8) */ -static const unsigned int UNDOFILE_CHUNK_SIZE = 0x1000000; // 16 MiB +static const unsigned int UNDOFILE_CHUNK_SIZE = 0x100000; // 1 MiB /** Maximum number of script-checking threads allowed */ static const int MAX_SCRIPTCHECK_THREADS = 16; /** -par default (number of script-checking threads, 0 = auto) */ From 12b1040aaa839bb671030622740fa3ff43a2badb Mon Sep 17 00:00:00 2001 From: dimxy Date: Mon, 6 May 2019 15:21:21 +0500 Subject: [PATCH 231/242] changed total price index calc to big num --- src/cc/prices.cpp | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index cefc8c4e0..b1947a9b5 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -850,9 +850,13 @@ int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t { int32_t i, value, errcode, depth, retval = -1; uint16_t opcode; - int64_t *pricedata, pricestack[4], price, den, a, b, c; + int64_t *pricedata, pricestack[4], a, b, c; - mpz_t mpzA, mpzB, mpzC, mpzResult; + mpz_t mpzTotalPrice, mpzPriceValue, mpzDen, mpzA, mpzB, mpzC, mpzResult; + + mpz_init(mpzTotalPrice); + mpz_init(mpzPriceValue); + mpz_init(mpzDen); mpz_init(mpzA); mpz_init(mpzB); @@ -860,7 +864,7 @@ int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t mpz_init(mpzResult); pricedata = (int64_t *)calloc(sizeof(*pricedata) * 3, 1 + PRICES_DAYWINDOW * 2 + PRICES_SMOOTHWIDTH); - price = den = depth = errcode = 0; + depth = errcode = 0; for (i = 0; i < vec.size(); i++) { @@ -869,7 +873,7 @@ 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 << " price=" << price << " value=" << value << " depth=" << depth << " opcode&KOMODO_PRICEMASK=" << (opcode & KOMODO_PRICEMASK) < 3 && vout.scriptPubKey[0] == OP_RETURN && vout.scriptPubKey[2] == evalcode ) return i; i++; } From cb346ffa448c99b129fb83bda3b2c7947323d0b2 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Tue, 7 May 2019 21:52:16 +0800 Subject: [PATCH 236/242] 1 --- src/cc/payments.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index 12d5cff62..35eda45f3 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -1029,6 +1029,7 @@ UniValue PaymentsMerge(struct CCcontract_info *cp,char *jsonstr) // encode the checktxid into the end of the ccvout, along with 'M' to flag merge type tx. opret = EncodePaymentsMergeOpRet(createtxid); std::vector> vData = std::vector>(); + // try to pay to diffrent pubkey here... change txidpk. if ( makeCCopret(opret, vData) ) mtx.vout.push_back(MakeCC1of2vout(EVAL_PAYMENTS,inputsum-PAYMENTS_TXFEE,Paymentspk,txidpk,&vData)); GetCCaddress1of2(cp,destaddr,Paymentspk,txidpk); @@ -1036,7 +1037,7 @@ UniValue PaymentsMerge(struct CCcontract_info *cp,char *jsonstr) rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,CScript()); if ( params != 0 ) free_json(params); - return(payments_rawtxresult(result,rawtx,0)); + return(payments_rawtxresult(result,rawtx,1)); } } else From 38f16334c13e895cbb2bb09cdcdbbddcc732aa4c Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Tue, 7 May 2019 22:42:12 +0800 Subject: [PATCH 237/242] fix --- src/cc/payments.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index 35eda45f3..f78474e12 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -575,8 +575,11 @@ int64_t AddPaymentsInputs(bool fLockedBlocks,int8_t GetBalance,struct CCcontract } if ( (nValue= IsPaymentsvout(cp,vintx,vout,coinaddr,ccopret)) > PAYMENTS_TXFEE && nValue >= threshold && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 ) { + int32_t offset = 0; + if ( ccopret.size() > 2 && DecodePaymentsMergeOpRet(ccopret,checktxid) == 'M' ) + offset = PAYMENTS_MERGEOFSET; int32_t tmpblocksleft = 0; - if ( fLockedBlocks && !payments_lockedblocks(hashBlock, lockedblocks+(GetBalance == 4 ? PAYMENTS_MERGEOFSET : 0), tmpblocksleft) ) + if ( fLockedBlocks && !payments_lockedblocks(hashBlock, lockedblocks+offset, tmpblocksleft) ) { blocksleft_balance.push_back(std::make_pair(tmpblocksleft,nValue)); continue; From bac6d503af863fc9ce7c745ac9601fa7ddf50bd6 Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 7 May 2019 21:24:46 +0500 Subject: [PATCH 238/242] change to prices_getbetinfo() --- src/cc/CCPrices.h | 1 + src/cc/prices.cpp | 629 +++++++++++++++++++++++------------------ src/rpc/blockchain.cpp | 13 + src/rpc/server.cpp | 2 + src/rpc/server.h | 2 + 5 files changed, 370 insertions(+), 277 deletions(-) diff --git a/src/cc/CCPrices.h b/src/cc/CCPrices.h index 9bcae60b2..933f08e19 100644 --- a/src/cc/CCPrices.h +++ b/src/cc/CCPrices.h @@ -49,6 +49,7 @@ UniValue PricesRekt(int64_t txfee,uint256 bettxid,int32_t rektheight); UniValue PricesCashout(int64_t txfee,uint256 bettxid); UniValue PricesInfo(uint256 bettxid,int32_t refheight); UniValue PricesList(uint32_t filter, CPubKey mypk); +UniValue PricesGetOrderbook(); #endif diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 31a63f93d..2ac89613c 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -20,16 +20,38 @@ #define IS_CHARINSTR(c, str) (std::string(str).find((char)(c)) != std::string::npos) -#define N_CCMARKER 1 +#define NVOUT_CCMARKER 1 +#define NVOUT_NORMALMARKER 3 -typedef struct BetInfo { - int64_t amount; +typedef struct OneBetData { + int64_t positionsize; int32_t firstheight; int64_t costbasis; int64_t profits; - BetInfo() { amount = 0; firstheight = 0; costbasis = 0; profits = 0; } // it is important to clear costbasis as it will be calculated as minmax from inital value 0 -} betinfo; + OneBetData() { positionsize = 0; firstheight = 0; costbasis = 0; profits = 0; } // it is important to clear costbasis as it will be calculated as minmax from inital value 0 +} onebetdata; + +typedef struct BetInfo { + int64_t averageCostbasis, firstprice, lastprice, liquidationprice, equity; + int64_t rektfee; + int32_t lastheight; + int16_t leverage; + bool isOpen, isRekt; + uint256 tokenid; + + std::vector parsed; + std::vector bets; + CPubKey pk; + + BetInfo() { + averageCostbasis = firstprice = lastprice = liquidationprice = equity = 0; + lastheight = 0; + leverage = 0; + rektfee = 0; + isOpen = isRekt = false; + } +} BetInfo; /* CBOPRET creates trustless oracles, which can be used for making a synthetic cash settlement system based on real world prices; @@ -145,7 +167,7 @@ uint8_t prices_finalopretdecode(CScript scriptPubKey,uint256 &bettxid,int64_t &p } // price opret basic validation and retrieval -static uint8_t CheckPricesOpret(const CTransaction & tx, vscript_t &opret) +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")) return opret.begin()[1]; @@ -217,7 +239,7 @@ static bool ValidateAddFundingTx(struct CCcontract_info *cp, Eval *eval, const C return eval->Invalid("cannot decode opreturn for add funding tx"); pricespk = GetUnspendable(cp, 0); - uint8_t vintxFuncId = CheckPricesOpret(vintx, vintxOpret); + uint8_t vintxFuncId = PricesCheckOpret(vintx, vintxOpret); if (vintxFuncId != 'A' && vintxFuncId != 'B') { // if vintx is bettx return eval->Invalid("incorrect vintx funcid"); } @@ -352,7 +374,7 @@ bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx if (strcmp(ASSETCHAINS_SYMBOL, "REKT0") == 0 && chainActive.Height() < 2965) return true; // check basic opret rules: - if (CheckPricesOpret(tx, vopret) == 0) + if (PricesCheckOpret(tx, vopret) == 0) return eval->Invalid("tx has no prices opreturn"); uint8_t funcId = vopret.begin()[1]; @@ -375,7 +397,7 @@ bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx if (!myGetTransaction(vin.prevout.hash, vintx, hashBlock)) return eval->Invalid("cannot load vintx"); - if (CheckPricesOpret(vintx, vintxOpret) == 0) { + if (PricesCheckOpret(vintx, vintxOpret) == 0) { //return eval->Invalid("cannot find prices opret in vintx"); std::cerr << "PricesValidate() " << "cannot find prices opret in vintx" << std::endl; } @@ -486,7 +508,7 @@ int64_t AddPricesInputs(struct CCcontract_info *cp, CMutableTransaction &mtx, ch if (GetTransaction(txid, vintx, hashBlock, false) != 0 && vout < vintx.vout.size()) { vscript_t vopret; - uint8_t funcId = CheckPricesOpret(vintx, vopret); + uint8_t funcId = PricesCheckOpret(vintx, vopret); if (funcId == 'B' && vout == 1) // skip cc marker continue; @@ -1215,7 +1237,7 @@ int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t } // makes result json object -void prices_betjson(UniValue &result, std::vector bets, int16_t leverage, int32_t endheight, int64_t lastprice) +void prices_betjson(UniValue &result, std::vector bets, int16_t leverage, int32_t endheight, int64_t lastprice) { UniValue resultbets(UniValue::VARR); @@ -1224,12 +1246,12 @@ void prices_betjson(UniValue &result, std::vector bets, int16_t leverag for (auto b : bets) { UniValue entry(UniValue::VOBJ); - entry.push_back(Pair("positionsize", ValueFromAmount(b.amount))); + entry.push_back(Pair("positionsize", ValueFromAmount(b.positionsize))); entry.push_back(Pair("profits", ValueFromAmount(b.profits))); entry.push_back(Pair("costbasis", ValueFromAmount(b.costbasis))); entry.push_back(Pair("firstheight", b.firstheight)); resultbets.push_back(entry); - totalbets += b.amount; + totalbets += b.positionsize; totalprofits += b.profits; } int64_t equity = totalbets + totalprofits; @@ -1277,7 +1299,7 @@ int64_t prices_costbasis(CTransaction bettx, uint256 &txidCostbasis) } // enumerates and retrieves added bets, returns the last baton txid -int64_t prices_enumaddedbets(uint256 &batontxid, std::vector &bets, uint256 bettxid) +int64_t prices_enumaddedbets(uint256 &batontxid, std::vector &bets, uint256 bettxid) { int64_t addedBetsTotal = 0; int32_t vini; @@ -1304,10 +1326,10 @@ int64_t prices_enumaddedbets(uint256 &batontxid, std::vector &bets, uin txBaton.vout.size() > 0 && (funcId = prices_addopretdecode(txBaton.vout.back().scriptPubKey, bettxidInOpret, pk, amount)) != 0) { - BetInfo added; + OneBetData added; addedBetsTotal += amount; - added.amount = amount; + added.positionsize = amount; added.firstheight = blockIdx.GetHeight(); bets.push_back(added); std::cerr << "prices_batontxid() added amount=" << amount << std::endl; @@ -1357,9 +1379,9 @@ UniValue PricesBet(int64_t txfee, int64_t amount, int16_t leverage, std::vector< betamount = (amount * 199) / 200; 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 (N_CCMARKER) + mtx.vout.push_back(MakeCC1vout(cp->evalcode, txfee, pricespk)); // vout1 cc marker (NVOUT_CCMARKER) mtx.vout.push_back(MakeCC1vout(cp->evalcode, betamount, pricespk)); // vout2 betamount - mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(HexStr(pricespk)) << OP_CHECKSIG)); // vout3 normal marker - TODO: remove it as we have cc marker now, when move to the new chain + mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(HexStr(pricespk)) << OP_CHECKSIG)); // vout3 normal marker NVOUT_NORMALMARKER - TODO: remove it as we have cc marker now, when move to the new chain rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_betopret(mypk, nextheight - 1, amount, leverage, firstprice, vec, zeroid)); return(prices_rawtxresult(result, rawtx, 0)); } @@ -1389,7 +1411,7 @@ UniValue PricesAddFunding(int64_t txfee, uint256 bettxid, int64_t amount) //GetCCaddress(cp, myaddr, mypk); if (AddNormalinputs(mtx, mypk, amount + 2*txfee, 64) >= amount + 2*txfee) { - std::vector bets; + std::vector bets; if (prices_enumaddedbets(batontxid, bets, bettxid) >= 0) { mtx.vin.push_back(CTxIn(batontxid, 0, CScript())); @@ -1411,7 +1433,7 @@ UniValue PricesAddFunding(int64_t txfee, uint256 bettxid, int64_t amount) } // scan chain from the initial bet's first position upto the chain tip and calculate bet's costbasises and profits, breaks if rekt detected -int32_t prices_scanchain(std::vector &bets, int16_t leverage, std::vector vec, int64_t &lastprice, int32_t &endheight) { +int32_t prices_scanchain(std::vector &bets, int16_t leverage, std::vector vec, int64_t &lastprice, int32_t &endheight) { if (bets.size() == 0) return -1; @@ -1427,13 +1449,13 @@ int32_t prices_scanchain(std::vector &bets, int16_t leverage, std::vect if (height > bets[i].firstheight) { - int32_t retcode = prices_syntheticprofits(bets[i].costbasis, bets[i].firstheight, height, leverage, vec, bets[i].amount, bets[i].profits, lastprice); + 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; stop = true; break; } - totalbets += bets[i].amount; + totalbets += bets[i].positionsize; totalprofits += bets[i].profits; } } @@ -1523,233 +1545,39 @@ UniValue PricesSetcostbasis(int64_t txfee, uint256 bettxid) return(result); } -// pricesrekt rpc: anyone can rekt a bet at some block where losses reached limit, collecting fee -UniValue PricesRekt(int64_t txfee, uint256 bettxid, int32_t rektheight) + +int32_t prices_getbetinfo(uint256 bettxid, BetInfo &betinfo) { - int32_t nextheight = komodo_nextheight(); - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nextheight); UniValue result(UniValue::VOBJ); - struct CCcontract_info *cp, C; - CTransaction bettx; - uint256 hashBlock, tokenid, batontxid; - int64_t myfee = 0, firstprice, lastprice = 0, positionsize; - int32_t firstheight; - int16_t leverage; - std::vector vec; - CPubKey pk, mypk, pricespk; - std::string rawtx; - char destaddr[64]; - - cp = CCinit(&C, EVAL_PRICES); - if (txfee == 0) - txfee = PRICES_TXFEE; - mypk = pubkey2pk(Mypubkey()); - pricespk = GetUnspendable(cp, 0); - GetCCaddress(cp, destaddr, pricespk); - - if (myGetTransaction(bettxid, bettx, hashBlock) != 0 && bettx.vout.size() > 3) - { - if (prices_betopretdecode(bettx.vout.back().scriptPubKey, pk, firstheight, positionsize, leverage, firstprice, vec, tokenid) == 'B') - { - uint256 finaltxid; - int32_t vini; - int32_t finalheight, endheight; - std::vector bets; - BetInfo bet1; - - if (CCgetspenttxid(finaltxid, vini, finalheight, bettxid, N_CCMARKER) == 0) { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "position closed")); - return result; - } - - bet1.amount = positionsize; - bet1.firstheight = firstheight; - bets.push_back(bet1); - - prices_enumaddedbets(batontxid, bets, bettxid); - - if (prices_scanchain(bets, leverage, vec, lastprice, endheight) < 0) { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "error scanning chain")); - return(result); - } - - int64_t totalbets = 0; - int64_t totalprofits = 0; - for (auto b : bets) { - totalbets += b.amount; - totalprofits += b.profits; - } - - prices_betjson(result, bets, leverage, endheight, lastprice); // fill output json - - int64_t equity = totalbets + totalprofits; - if (equity < 0) - { - myfee = totalbets / 500; // consolation fee for loss - } - if (myfee != 0) - { - int64_t CCchange = 0, inputsum; - - mtx.vin.push_back(CTxIn(bettxid, N_CCMARKER, CScript())); // spend cc marker - if ((inputsum = AddPricesInputs(cp, mtx, destaddr, myfee + txfee, 64)) > myfee + txfee) // TODO: why do we take txfee from global addr and not from user's addr? - CCchange = (inputsum - myfee); - mtx.vout.push_back(CTxOut(myfee, CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); - if (CCchange >= txfee) - 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, firstprice, 0, totalbets - positionsize, positionsize, leverage)); - return(prices_rawtxresult(result, rawtx, 0)); - } - else - { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "position not rekt")); - return(result); - } - } - else - { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "cant decode opret")); - return(result); - } - } - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "cant load or incorrect bettx")); - return(result); -} - -// pricescashout rpc impl: bettor can cashout hit bet if it is not rekt -UniValue PricesCashout(int64_t txfee, uint256 bettxid) -{ - int32_t nextheight = komodo_nextheight(); - 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 CCchange = 0, positionsize, inputsum, firstprice, lastprice = 0; - int32_t firstheight; - int16_t leverage; - std::vector vec; - CPubKey pk, mypk, pricespk; - std::string rawtx; - - cp = CCinit(&C, EVAL_PRICES); - if (txfee == 0) - txfee = PRICES_TXFEE; - - mypk = pubkey2pk(Mypubkey()); - pricespk = GetUnspendable(cp, 0); - GetCCaddress(cp, destaddr, pricespk); - if (myGetTransaction(bettxid, bettx, hashBlock) != 0 && bettx.vout.size() > 3) - { - if (prices_betopretdecode(bettx.vout.back().scriptPubKey, pk, firstheight, positionsize, leverage, firstprice, vec, tokenid) == 'B') - { - uint256 finaltxid; - int32_t vini; - int32_t finalheight, endheight; - std::vector bets; - BetInfo bet1; - - if (CCgetspenttxid(finaltxid, vini, finalheight, bettxid, N_CCMARKER) == 0) { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "position closed")); - return result; - } - - bet1.amount = positionsize; - bet1.firstheight = firstheight; - bets.push_back(bet1); - prices_enumaddedbets(batontxid, bets, bettxid); - - if (prices_scanchain(bets, leverage, vec, lastprice, endheight) < 0) { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "error scanning chain")); - return(result); - } - - int64_t totalbets = 0; - int64_t totalprofits = 0; - for (auto b : bets) { - totalbets += b.amount; - totalprofits += b.profits; - } - prices_betjson(result, bets, leverage, endheight, lastprice); // fill output json - - int64_t equity = totalbets + totalprofits; - if (equity < 0) - { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "position rekt")); - return(result); - } - - mtx.vin.push_back(CTxIn(bettxid, N_CCMARKER, CScript())); // spend cc marker - if ((inputsum = AddPricesInputs(cp, mtx, destaddr, equity + txfee, 64)) > equity + txfee) - CCchange = (inputsum - equity); - mtx.vout.push_back(CTxOut(equity, CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); - if (CCchange >= txfee) - mtx.vout.push_back(MakeCC1vout(cp->evalcode, CCchange, pricespk)); - rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_finalopret(bettxid, totalprofits, nextheight - 1, mypk, firstprice, 0, totalbets-positionsize, positionsize, leverage)); - return(prices_rawtxresult(result, rawtx, 0)); - } - else - { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "cant decode opret")); - return(result); - } - } - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "cant load or incorrect bettx")); - return(result); -} - -// pricesinfo rpc impl -UniValue PricesInfo(uint256 bettxid, int32_t refheight) -{ - UniValue result(UniValue::VOBJ); CTransaction bettx; uint256 hashBlock, batontxid, tokenid; - int64_t positionsize = 0, firstprice = 0, lastprice = 0; - int32_t firstheight = 0, endheight; - int16_t leverage = 0; - std::vector vec; - CPubKey pk, mypk, pricespk; - std::string rawtx; - //uint256 costbasistxid; if (myGetTransaction(bettxid, bettx, hashBlock) && bettx.vout.size() > 3) { if (hashBlock.IsNull()) - throw std::runtime_error("tx still in mempool"); + return -2; - if (prices_betopretdecode(bettx.vout.back().scriptPubKey, pk, firstheight, positionsize, leverage, firstprice, vec, tokenid) == 'B') + OneBetData bet1; + if (prices_betopretdecode(bettx.vout.back().scriptPubKey, betinfo.pk, bet1.firstheight, bet1.positionsize, betinfo.leverage, betinfo.firstprice, betinfo.parsed, betinfo.tokenid) == 'B') { uint256 finaltxid; int32_t vini; - int32_t finalheight, endheight; - std::vector bets; - BetInfo bet1; + int32_t finaltxheight; //, endheight; + //std::vector bets; - if (CCgetspenttxid(finaltxid, vini, finalheight, bettxid, N_CCMARKER) == 0) - result.push_back(Pair("status", "closed")); + + if (CCgetspenttxid(finaltxid, vini, finaltxheight, bettxid, NVOUT_CCMARKER) == 0) + betinfo.isOpen = false; else - result.push_back(Pair("status", "open")); + betinfo.isOpen = true; - bet1.amount = positionsize; - bet1.firstheight = firstheight; - bets.push_back(bet1); + //bet1.amount = betinfo.positionsize; + //bet1.firstheight = firstheight; + betinfo.bets.push_back(bet1); - prices_enumaddedbets(batontxid, bets, bettxid); + prices_enumaddedbets(batontxid, betinfo.bets, bettxid); - if( prices_scanchain(bets, leverage, vec, lastprice, endheight) < 0 ) { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "error scanning chain")); - return(result); + if (prices_scanchain(betinfo.bets, betinfo.leverage, betinfo.parsed, betinfo.lastprice, betinfo.lastheight) < 0) { + return -4; } mpz_t mpzTotalbets; @@ -1760,38 +1588,37 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) mpz_init(mpzTotalprofits); mpz_init(mpzTotalcostbasis); - int64_t totalbets = 0; int64_t totalprofits = 0; - for (auto b : bets) { + for (auto b : betinfo.bets) { mpz_t mpzProduct; mpz_t mpzProfits; - + mpz_init(mpzProduct); mpz_init(mpzProfits); - + //totalprofits += b.profits; //dcostbasis += b.amount * (double)b.costbasis; // costbasis += b.amount * (b.costbasis / PRICES_POINTFACTOR); // prevent int64 overflow (but we have underflow for 1/BTC) // std::cerr << "PricesInfo() acc dcostbasis=" << dcostbasis << " b.amount=" << b.amount << " b.costbasis/PRICES_POINTFACTOR=" << (b.costbasis / PRICES_POINTFACTOR) << std::endl; //std::cerr << "PricesInfo() acc dcostbasis=" << dcostbasis << " b.amount=" << b.amount << " b.costbasis/PRICES_POINTFACTOR=" << (b.costbasis / PRICES_POINTFACTOR) << std::endl; mpz_set_ui(mpzProduct, b.costbasis); - mpz_mul_ui(mpzProduct, mpzProduct, (uint64_t)b.amount); // b.costbasis * b.amount + 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.amount); //totalbets += b.amount; + mpz_add_ui(mpzTotalbets, mpzTotalbets, (uint64_t)b.positionsize); //totalbets += b.amount; mpz_add(mpzTotalprofits, mpzTotalprofits, mpzProfits); //totalprofits += b.profits; - totalbets += b.amount; + totalbets += b.positionsize; totalprofits += b.profits; mpz_clear(mpzProduct); mpz_clear(mpzProfits); } - int64_t equity = totalbets + totalprofits; - int64_t averageCostbasis = 0; + betinfo.equity = totalbets + totalprofits; + //int64_t averageCostbasis = 0; if (mpz_get_ui(mpzTotalbets) != 0) { //prevent zero div mpz_t mpzAverageCostbasis; @@ -1799,49 +1626,272 @@ UniValue PricesInfo(uint256 bettxid, int32_t refheight) //averageCostbasis = totalcostbasis / totalbets; 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, mpzTotalbets); mpz_tdiv_q_ui(mpzAverageCostbasis, mpzAverageCostbasis, SATOSHIDEN); // profits /= SATOSHIDEN de-normalization - averageCostbasis = mpz_get_ui(mpzAverageCostbasis); + betinfo.averageCostbasis = mpz_get_ui(mpzAverageCostbasis); mpz_clear(mpzAverageCostbasis); } - int64_t liqprice = 0; - if (leverage != 0) {// prevent zero div - liqprice = averageCostbasis - averageCostbasis / leverage; + betinfo.liquidationprice = 0; + if (betinfo.leverage != 0) {// prevent zero div + betinfo.liquidationprice = betinfo.averageCostbasis - betinfo.averageCostbasis / betinfo.leverage; } - if (equity >= 0) - result.push_back(Pair("rekt", 0)); + if (betinfo.equity >= 0) + betinfo.isRekt = true; else { - result.push_back(Pair("rekt", (int64_t)1)); - result.push_back(Pair("rektfee", totalbets / 500)); - result.push_back(Pair("rektheight", (int64_t)endheight)); + betinfo.isRekt = false; + betinfo.rektfee = totalbets / 500; } - std::string expr = prices_getsourceexpression(vec); - result.push_back(Pair("expression", expr)); - result.push_back(Pair("reduced", prices_getreducedexpr(expr))); - result.push_back(Pair("batontxid", batontxid.GetHex())); - result.push_back(Pair("costbasis", ValueFromAmount(averageCostbasis))); -#ifdef TESTMODE - result.push_back(Pair("costbasis_test_period", 7)); -#endif - - prices_betjson(result, bets, leverage, endheight, lastprice); - - result.push_back(Pair("LiquidationPrice", ValueFromAmount(liqprice))); - mpz_clear(mpzTotalbets); mpz_clear(mpzTotalprofits); mpz_clear(mpzTotalcostbasis); + return 0; + } + return -3; + } + return (-1); +} + +// pricesrekt rpc: anyone can rekt a bet at some block where losses reached limit, collecting fee +UniValue PricesRekt(int64_t txfee, uint256 bettxid, int32_t rektheight) +{ + int32_t nextheight = komodo_nextheight(); + 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? + txfee = PRICES_TXFEE; + mypk = pubkey2pk(Mypubkey()); + pricespk = GetUnspendable(cp, 0); + GetCCaddress(cp, destaddr, pricespk); + + BetInfo betinfo; + int32_t retcode = prices_getbetinfo(bettxid, betinfo); + if (retcode < 0) { + if (retcode == -1) { + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "cant find bettxid or incorrect")); + } + else if (retcode == -2) { + throw std::runtime_error("tx still in mempool"); + } + else if (retcode == -3) + { + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "cant decode opret")); return(result); } + else if (retcode == -4) { + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "error scanning chain")); + } + return(result); } - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "cant find bettxid or incorrect")); + + int64_t totalbets = 0; + int64_t totalprofits = 0; + + for (auto b : betinfo.bets) { + totalbets += b.positionsize; + totalprofits += b.profits; + } + + + if (!betinfo.isOpen) { + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "position closed")); + return result; + } + + prices_betjson(result, betinfo.bets, betinfo.leverage, betinfo.lastheight, betinfo.lastprice); // fill output + if (betinfo.isRekt) + { + myfee = betinfo.rektfee; // consolation fee for loss + } + if (myfee != 0) + { + int64_t CCchange = 0, inputsum; + + mtx.vin.push_back(CTxIn(bettxid, NVOUT_CCMARKER, CScript())); // spend cc marker + if ((inputsum = AddPricesInputs(cp, mtx, destaddr, myfee + txfee, 64)) > myfee + txfee) // TODO: why do we take txfee from global addr and not from user's addr? + CCchange = (inputsum - myfee); + mtx.vout.push_back(CTxOut(myfee, CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); + if (CCchange >= txfee) + 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)); + } + else + { + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "position not rekt")); + return(result); + } +} + +// pricescashout rpc impl: bettor can cashout hit bet if it is not rekt +UniValue PricesCashout(int64_t txfee, uint256 bettxid) +{ + int32_t nextheight = komodo_nextheight(); + 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; + + cp = CCinit(&C, EVAL_PRICES); + if (txfee == 0) + txfee = PRICES_TXFEE; + + mypk = pubkey2pk(Mypubkey()); + pricespk = GetUnspendable(cp, 0); + GetCCaddress(cp, destaddr, pricespk); + + BetInfo betinfo; + int32_t retcode = prices_getbetinfo(bettxid, betinfo); + if (retcode < 0) { + if (retcode == -1) { + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "cant find bettxid or incorrect")); + } + else if (retcode == -2) { + throw std::runtime_error("tx still in mempool"); + } + else if (retcode == -3) + { + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "cant decode opret")); + return(result); + } + else if (retcode == -4) { + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "error scanning chain")); + } + return(result); + } + + int64_t totalbets = 0; + int64_t totalprofits = 0; + + for (auto b : betinfo.bets) { + totalbets += b.positionsize; + totalprofits += b.profits; + } + + + if (!betinfo.isOpen) { + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "position closed")); + return result; + } + + prices_betjson(result, betinfo.bets, betinfo.leverage, betinfo.lastheight, betinfo.lastprice); // fill output json + + if (betinfo.isRekt) + { + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "position rekt")); + return(result); + } + + 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) + 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)); + return(prices_rawtxresult(result, rawtx, 0)); + +} + + + + +// pricesinfo rpc impl +UniValue PricesInfo(uint256 bettxid, int32_t refheight) +{ + UniValue result(UniValue::VOBJ); +/* CTransaction bettx; + uint256 hashBlock, batontxid, tokenid; + int64_t positionsize = 0, firstprice = 0, lastprice = 0; + int32_t firstheight = 0, endheight; + int16_t leverage = 0; + std::vector vec; + CPubKey pk, mypk, pricespk; + std::string rawtx; */ + + BetInfo betinfo; + int32_t retcode = prices_getbetinfo(bettxid, betinfo); + if (retcode < 0) { + if( retcode == -1 ) { + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "cant find bettxid or incorrect")); + } + else if (retcode == -2) { + throw std::runtime_error("tx still in mempool"); + } + else if (retcode == -3) + { + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "cant decode opret")); + return(result); + } + else if (retcode == -4) { + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "error scanning chain")); + } + return(result); + } + + if (!betinfo.isRekt) + result.push_back(Pair("rekt", 0)); + else + { + result.push_back(Pair("rekt", (int64_t)1)); + result.push_back(Pair("rektfee", betinfo.rektfee)); + result.push_back(Pair("rektheight", betinfo.lastheight)); + } + + std::string expr = prices_getsourceexpression(betinfo.parsed); + result.push_back(Pair("expression", expr)); + result.push_back(Pair("reduced", prices_getreducedexpr(expr))); +// result.push_back(Pair("batontxid", batontxid.GetHex())); + result.push_back(Pair("costbasis", ValueFromAmount(betinfo.averageCostbasis))); +#ifdef TESTMODE + result.push_back(Pair("costbasis_test_period", 7)); +#endif + + prices_betjson(result, betinfo.bets, betinfo.leverage, betinfo.lastheight, betinfo.lastprice); + + result.push_back(Pair("LiquidationPrice", ValueFromAmount(betinfo.liquidationprice))); + return(result); } @@ -1852,25 +1902,20 @@ UniValue PricesList(uint32_t filter, CPubKey mypk) std::vector > addressIndex, addressIndexCC; struct CCcontract_info *cp, C; - cp = CCinit(&C, EVAL_PRICES); //pricespk = GetUnspendable(cp, 0); // filters and outputs prices bet txid - auto priceslist = [&](std::vector >::const_iterator it, int32_t nvout) + auto AddBetToList = [&](uint256 txid) { int64_t amount, firstprice; int32_t height; int16_t leverage; - uint256 txid, hashBlock, tokenid; + uint256 hashBlock, tokenid; CPubKey pk, pricespk; std::vector vec; CTransaction vintx; - txid = it->first.txhash; - if (nvout != it->first.index) // our marker vout - return; - if (GetTransaction(txid, vintx, hashBlock, false) != 0) { bool bAppend = false; @@ -1884,7 +1929,7 @@ UniValue PricesList(uint32_t filter, CPubKey mypk) int32_t height; uint256 finaltxid; - int32_t spent = CCgetspenttxid(finaltxid, vini, height, txid, N_CCMARKER); + int32_t spent = CCgetspenttxid(finaltxid, vini, height, txid, NVOUT_CCMARKER); if (filter == 1 && spent < 0 || // open positions filter == 2 && spent == 0) // closed positions bAppend = true; @@ -1892,7 +1937,7 @@ UniValue PricesList(uint32_t filter, CPubKey mypk) if (bAppend) result.push_back(txid.GetHex()); } - std::cerr << "PricesList() " << " bettxid=" << txid.GetHex() << " mypk=" << HexStr(mypk) << " opretpk=" << HexStr(pk) << " filter=" << filter << " bAppend=" << bAppend << " index=" << it->first.index << " txindex=" << it->first.txindex << std::endl; + std::cerr << "PricesList() " << " bettxid=" << txid.GetHex() << " mypk=" << HexStr(mypk) << " opretpk=" << HexStr(pk) << " filter=" << filter << " bAppend=" << bAppend << std::endl; } }; @@ -1900,7 +1945,8 @@ 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++) { - priceslist(it, 3); + if( it->first.txindex == NVOUT_NORMALMARKER ) + AddBetToList(it->first.txhash); } /* for future when switch to cc marker only @@ -1911,4 +1957,33 @@ UniValue PricesList(uint32_t filter, CPubKey mypk) } */ return(result); +} + + +void prices_addbookentry(uint256 txid) +{ + BetInfo betinfo; + //if( prices_getbetinfo(txid, betinfo) == 0 ) +} + +// walk through uxtos on the global address +// calculate the balance: +// + rekt positions +// = opposite positions +// - unbalanced positions +UniValue PricesGetOrderbook() +{ + UniValue result(UniValue::VARR); + std::vector > addressIndex, addressIndexCC; + struct CCcontract_info *cp, C; + + cp = CCinit(&C, EVAL_PRICES); + + 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); + } + return result; } \ No newline at end of file diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 1f6fcadcf..cb2cfce92 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1439,6 +1439,19 @@ UniValue pricesrekt(const UniValue& params, bool fHelp) return PricesRekt(txfee, bettxid, height); } +// pricesrekt rpc implementation +UniValue pricesgetorderbook(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error("pricesgetorderbook\n"); + LOCK(cs_main); + UniValue ret(UniValue::VOBJ); + + if (ASSETCHAINS_CBOPRET == 0) + throw JSONRPCError(RPC_INVALID_PARAMETER, "only -ac_cbopret chains have prices"); + + return PricesGetOrderbook(); +} UniValue gettxout(const UniValue& params, bool fHelp) { diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index d18f551e6..30258a6e0 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -470,6 +470,8 @@ static const CRPCCommand vRPCCommands[] = { "prices", "pricescashout", &pricescashout, true }, { "prices", "pricesrekt", &pricesrekt, true }, { "prices", "pricesaddfunding", &pricesaddfunding, true }, + { "prices", "pricesgetorderbook", &pricesgetorderbook, true }, + // Pegs { "pegs", "pegsaddress", &pegsaddress, true }, diff --git a/src/rpc/server.h b/src/rpc/server.h index a215f9bc3..d4942eb69 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -503,6 +503,8 @@ extern UniValue pricessetcostbasis(const UniValue& params, bool fHelp); 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); + #endif // BITCOIN_RPCSERVER_H From 0bb28987648240b3cd0123d942d539d364cd3391 Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 7 May 2019 21:34:16 +0500 Subject: [PATCH 239/242] corr isRekt set --- src/cc/prices.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 2ac89613c..1fd039dc0 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1640,10 +1640,10 @@ int32_t prices_getbetinfo(uint256 bettxid, BetInfo &betinfo) } if (betinfo.equity >= 0) - betinfo.isRekt = true; + betinfo.isRekt = false; else { - betinfo.isRekt = false; + betinfo.isRekt = true; betinfo.rektfee = totalbets / 500; } From f328bbcf2d9b7b584701c68b3fcec3e81dd1a67b Mon Sep 17 00:00:00 2001 From: dimxy Date: Wed, 8 May 2019 12:04:31 +0500 Subject: [PATCH 240/242] new line --- src/cc/prices.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 1fd039dc0..507047c27 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1382,6 +1382,8 @@ UniValue PricesBet(int64_t txfee, int64_t amount, int16_t leverage, std::vector< mtx.vout.push_back(MakeCC1vout(cp->evalcode, txfee, pricespk)); // vout1 cc marker (NVOUT_CCMARKER) mtx.vout.push_back(MakeCC1vout(cp->evalcode, betamount, pricespk)); // vout2 betamount mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(HexStr(pricespk)) << OP_CHECKSIG)); // vout3 normal marker NVOUT_NORMALMARKER - TODO: remove it as we have cc marker now, when move to the new chain + + rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_betopret(mypk, nextheight - 1, amount, leverage, firstprice, vec, zeroid)); return(prices_rawtxresult(result, rawtx, 0)); } From f8084d7231d2b60898718f9b8517c3ac192ee866 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Wed, 8 May 2019 19:38:14 +0800 Subject: [PATCH 241/242] Inital commit for prices fee to be paid to payments snapshot plan. --- src/cc/CCPrices.h | 2 ++ src/cc/payments.cpp | 1 + src/cc/prices.cpp | 42 ++++++++++++++++++++++++++++++----- src/komodo_bitcoind.h | 51 +++++++++++++++++++++++++++++++++++++++++++ src/komodo_globals.h | 1 + 5 files changed, 91 insertions(+), 6 deletions(-) diff --git a/src/cc/CCPrices.h b/src/cc/CCPrices.h index 933f08e19..e6238533f 100644 --- a/src/cc/CCPrices.h +++ b/src/cc/CCPrices.h @@ -20,6 +20,8 @@ #include "komodo_defs.h" #include "CCinclude.h" int32_t komodo_priceget(int64_t *buf64,int32_t ind,int32_t height,int32_t numblocks); +extern void GetFeeAddress(); +extern CScript KOMODO_PRICES_FEE_SCRIPTPUB; // #define PRICES_DAYWINDOW ((3600*24/ASSETCHAINS_BLOCKTIME) + 1) // defined in komodo_defs.h #define PRICES_TXFEE 10000 diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index f78474e12..6311e393d 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -1192,6 +1192,7 @@ UniValue PaymentsAirdrop(struct CCcontract_info *cp,char *jsonstr) lockedblocks = juint(jitem(params,0),0); minrelease = juint(jitem(params,1),0); minimum = juint(jitem(params,2),0); + if ( minimum < 10000 ) minimum = 10000; top = juint(jitem(params,3),0); bottom = juint(jitem(params,4),0); fixedAmount = juint(jitem(params,5),0); // fixed amount is a flag, set to 7 does game mode, 0 normal snapshot, anything else fixed allocations. diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 507047c27..781483e5d 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -11,7 +11,25 @@ * * * Removal or modification of this copyright notice is prohibited. * * * - ******************************************************************************/ + ***************************************************************************** + To create payments plan start a chain with -ac_snapshot=1440 (or for test something shorter, if you like.) + then in very early block < 10 or so, do paymentsairdrop eg. + `./komodo-cli -ac_name=TESTDP paymentsairdrop '[10,10,0,3999,0,0]' + copy the txid of this transaction after it is confirmed, then do: + './komodo-cli -ac_name=TESTDP opreturn_burn 1 4a8f6469f713251a0381170e275d68899d481270a5e48586276dbbbadff91b57' +copy the hex, and sendrawtransaction, copy the txid returned. +this places the txid that locates the plan into an op_return before block 100, allowing us to retreive it. +Restart the daemon with -earlytxid= +mine the chain past block 100, preventing anyone else, creating another payments plan on chain before block 100. + +We call the following in Validation and RPC where the address is needed. +if ( KOMODO_PRICES_FEE_SCRIPTPUB.size() == 0 ) + GetFeeAddress(); + +This will fetch the op_return, calculate the scriptPubKey and save it to the global. +On daemon restart as soon as validation for BETTX happens the global will be filled, afte this the transaction never needs to be looked up again. +GetFeeAddress is on line #2080 of komodo_bitcoind.h + */ #include "CCassets.h" #include "CCPrices.h" @@ -184,7 +202,8 @@ static bool ValidateBetTx(struct CCcontract_info *cp, Eval *eval, const CTransac int16_t leverage; CPubKey pk, pricespk; std::vector vec; - + if ( KOMODO_PRICES_FEE_SCRIPTPUB.size() == 0 ) + GetFeeAddress(); if (bettx.vout.size() < 5 || bettx.vout.size() > 6) return eval->Invalid("incorrect vout number for bet tx"); @@ -198,8 +217,11 @@ static bool ValidateBetTx(struct CCcontract_info *cp, Eval *eval, const CTransac return eval->Invalid("cannot validate vout0 in bet tx with pk from opreturn"); if (MakeCC1vout(cp->evalcode, bettx.vout[1].nValue, pricespk) != bettx.vout[1]) return eval->Invalid("cannot validate vout1 in bet tx with global pk"); - if( MakeCC1vout(cp->evalcode, bettx.vout[2].nValue, pricespk) != bettx.vout[2] ) + if (MakeCC1vout(cp->evalcode, bettx.vout[2].nValue, pricespk) != bettx.vout[2] ) return eval->Invalid("cannot validate vout2 in bet tx with pk from opreturn"); + // This should be all you need to verify it, maybe also check amount? + if ( bettx.vout[4].scriptPubKey != KOMODO_PRICES_FEE_SCRIPTPUB ) + return eval->Invalid("the fee was paid to wrong address."); int64_t betamount = bettx.vout[2].nValue; if (betamount != (positionsize * 199) / 200) { @@ -1382,14 +1404,22 @@ UniValue PricesBet(int64_t txfee, int64_t amount, int16_t leverage, std::vector< mtx.vout.push_back(MakeCC1vout(cp->evalcode, txfee, pricespk)); // vout1 cc marker (NVOUT_CCMARKER) mtx.vout.push_back(MakeCC1vout(cp->evalcode, betamount, pricespk)); // vout2 betamount mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(HexStr(pricespk)) << OP_CHECKSIG)); // vout3 normal marker NVOUT_NORMALMARKER - TODO: remove it as we have cc marker now, when move to the new chain - + if ( KOMODO_PRICES_FEE_SCRIPTPUB.size() == 0 ) + { + // Lock here, as in validation we cannot call lock in the function itself. + // may not be needed as the validation call to update the global, is called in a LOCK already, and it can only update there and here. + LOCK(cs_main); + GetFeeAddress(); + } + mtx.vout.push_back(CTxOut(amount-betamount, KOMODO_PRICES_FEE_SCRIPTPUB)); + rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_betopret(mypk, nextheight - 1, amount, leverage, firstprice, vec, zeroid)); return(prices_rawtxresult(result, rawtx, 0)); } result.push_back(Pair("result", "error")); result.push_back(Pair("error", "not enough funds")); - return(result); + return(result); } // pricesaddfunding rpc impl: add yet another bet @@ -1988,4 +2018,4 @@ UniValue PricesGetOrderbook() prices_addbookentry(it->first.txhash); } return result; -} \ No newline at end of file +} diff --git a/src/komodo_bitcoind.h b/src/komodo_bitcoind.h index 292d5f8df..e827ea78f 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -29,6 +29,7 @@ int32_t komodo_voutupdate(bool fJustCheck,int32_t *isratificationp,int32_t notar unsigned int lwmaGetNextPOSRequired(const CBlockIndex* pindexLast, const Consensus::Params& params); bool EnsureWalletIsAvailable(bool avoidException); extern bool fRequestShutdown; +extern CScript KOMODO_PRICES_FEE_SCRIPTPUB; int32_t MarmaraSignature(uint8_t *utxosig,CMutableTransaction &txNew); uint8_t DecodeMaramaraCoinbaseOpRet(const CScript scriptPubKey,CPubKey &pk,int32_t &height,int32_t &unlockht); @@ -2076,6 +2077,56 @@ bool komodo_appendACscriptpub() return false; } +void GetFeeAddress() +{ + if ( KOMODO_EARLYTXID == zeroid ) + { + fprintf(stderr, "PLEASE RESTART DAEMON WITH -earlytxid.\n"); + StartShutdown(); + return; + } + if ( KOMODO_SNAPSHOT_INTERVAL == 0 ) + { + fprintf(stderr, "PRICES FEE ADDRESS MUST HAVE -ac_snapshot enabled to pay out.\n"); + StartShutdown(); + return; + } + if ( chainActive.Height() < 100 ) + { + fprintf(stderr, "Cannot fetch -earlytxid before block 100.\n"); + StartShutdown(); + return; + } + CTransaction tx; uint256 blockhash, txid = zeroid; char txidaddr[64]; + // get transaction and check that it occured before height 100. + if ( myGetTransaction(KOMODO_EARLYTXID,tx,blockhash) && mapBlockIndex[blockhash]->GetHeight() < 100 ) + { + for (int i = 0; i < tx.vout.size(); i++) + if ( tx.vout[i].scriptPubKey[0] == OP_RETURN ) + txid = uint256S(HexStr(tx.vout[i].scriptPubKey.begin()+3, tx.vout[i].scriptPubKey.end())); + if ( txid == zeroid ) + { + fprintf(stderr, "INVALID -earlytxid, restart daemon with correct txid.\n"); + StartShutdown(); + } + fprintf(stderr, "txid.%s\n", txid.GetHex().c_str()); + struct CCcontract_info *cp, C; CPubKey Paymentspk,txidpk; + cp = CCinit(&C, EVAL_PAYMENTS); + Paymentspk = GetUnspendable(cp,0); + txidpk = CCtxidaddr(txidaddr,txid); + GetCCaddress1of2(cp,txidaddr,Paymentspk,txidpk); + CC *payoutCond = MakeCCcond1of2(EVAL_PAYMENTS,Paymentspk,txidpk); + KOMODO_PRICES_FEE_SCRIPTPUB = CCPubKey(payoutCond); + cc_free(payoutCond); + fprintf(stderr, "KOMODO_PRICES_FEE_SCRIPTPUB.%s address.%s\n", HexStr(KOMODO_PRICES_FEE_SCRIPTPUB.begin(),KOMODO_PRICES_FEE_SCRIPTPUB.end()).c_str(),txidaddr); + } + else + { + fprintf(stderr, "INVALID -earlytxid, restart daemon with correct txid.\n"); + StartShutdown(); + } +} + int64_t komodo_checkcommission(CBlock *pblock,int32_t height) { int64_t checktoshis=0; uint8_t *script,scripthex[8192]; int32_t scriptlen,matched = 0; static bool didinit = false; diff --git a/src/komodo_globals.h b/src/komodo_globals.h index 8d440cbaf..bc21bab10 100644 --- a/src/komodo_globals.h +++ b/src/komodo_globals.h @@ -110,6 +110,7 @@ extern int32_t KOMODO_LOADINGBLOCKS; unsigned int MAX_BLOCK_SIGOPS = 20000; int32_t KOMODO_TESTNODE, KOMODO_SNAPSHOT_INTERVAL; +CScript KOMODO_PRICES_FEE_SCRIPTPUB; struct komodo_kv *KOMODO_KV; pthread_mutex_t KOMODO_KV_mutex,KOMODO_CC_mutex; From 460033ad0571b8c4d4fe24c9fabb6cccb9b1916c Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Thu, 9 May 2019 01:25:07 +0800 Subject: [PATCH 242/242] change to work for all contracts --- src/cc/CCPrices.h | 4 +-- src/cc/prices.cpp | 56 +++++++++++++++++++++++++++------------- src/komodo_bitcoind.h | 41 ++++++++++------------------- src/komodo_defs.h | 3 ++- src/komodo_globals.h | 3 ++- src/komodo_utils.h | 9 +++++-- src/wallet/rpcwallet.cpp | 31 +++++++++------------- 7 files changed, 77 insertions(+), 70 deletions(-) diff --git a/src/cc/CCPrices.h b/src/cc/CCPrices.h index e6238533f..238131d59 100644 --- a/src/cc/CCPrices.h +++ b/src/cc/CCPrices.h @@ -20,8 +20,8 @@ #include "komodo_defs.h" #include "CCinclude.h" int32_t komodo_priceget(int64_t *buf64,int32_t ind,int32_t height,int32_t numblocks); -extern void GetFeeAddress(); -extern CScript KOMODO_PRICES_FEE_SCRIPTPUB; +extern void GetKomodoEarlytxidScriptPub(); +extern CScript KOMODO_EARLYTXID_SCRIPTPUB; // #define PRICES_DAYWINDOW ((3600*24/ASSETCHAINS_BLOCKTIME) + 1) // defined in komodo_defs.h #define PRICES_TXFEE 10000 diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 781483e5d..27529bca4 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -12,23 +12,34 @@ * Removal or modification of this copyright notice is prohibited. * * * ***************************************************************************** - To create payments plan start a chain with -ac_snapshot=1440 (or for test something shorter, if you like.) - then in very early block < 10 or so, do paymentsairdrop eg. - `./komodo-cli -ac_name=TESTDP paymentsairdrop '[10,10,0,3999,0,0]' - copy the txid of this transaction after it is confirmed, then do: - './komodo-cli -ac_name=TESTDP opreturn_burn 1 4a8f6469f713251a0381170e275d68899d481270a5e48586276dbbbadff91b57' +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. + -ac_earlytxidcontract=237 (Eval code for prices cc.) + - this allows to know what contract this chain is paying with the scriptpubkey in the earlytxid op_return. + +./komodod -ac_name=TESTPRC -ac_supply=100000000 -ac_reward=1000000000 -ac_nk=96,5 -ac_blocktime=20 -ac_cc=2 -ac_snapshot=50 -ac_sapling=1 -ac_earlytxidcontract=237 -testnode=1 -gen -genproclimit=1 + +Then in very early block < 10 or so, do paymentsairdrop eg. + `./komodo-cli -ac_name=TESTPRC paymentsairdrop '[10,10,0,3999,0,0]' +Once this tx is confirmed, do `paymentsfund` and decode the raw hex. You can edit the source to not send the tx if requried. +Get the full `hex` of the vout[0] that pays to CryptoCondition. then place it on chain with the following command: with the hex you got in place of the hex below. + './komodo-cli -ac_name=TESTPRC opreturn_burn 1 2ea22c8020292ba5c8fd9cc89b12b35bf8f5d00196990ecbb06102b84d9748d11d883ef01e81031210008203000401cc' copy the hex, and sendrawtransaction, copy the txid returned. -this places the txid that locates the plan into an op_return before block 100, allowing us to retreive it. -Restart the daemon with -earlytxid= +this places the scriptpubkey that pays the plan into an op_return before block 100, allowing us to retreive it, and nobody to change it. +Restart the daemon with -earlytxid= eg: + +./komodod -ac_name=TESTPRC -ac_supply=100000000 -ac_reward=1000000000 -ac_nk=96,5 -ac_blocktime=20 -ac_cc=2 -ac_snapshot=50 -ac_sapling=1 -ac_earlytxidcontract=237 -earlytxid=cf89d17fb11037f65c160d0749dddd74dc44d9893b0bb67fe1f96c1f59786496 -testnode=1 -gen -genproclimit=1 + mine the chain past block 100, preventing anyone else, creating another payments plan on chain before block 100. We call the following in Validation and RPC where the address is needed. -if ( KOMODO_PRICES_FEE_SCRIPTPUB.size() == 0 ) - GetFeeAddress(); +if ( ASSETCHAINS_EARLYTXIDCONTRACT == EVAL_PRICES && KOMODO_EARLYTXID_SCRIPTPUB.size() == 0 ) + GetKomodoEarlytxidScriptPub(); This will fetch the op_return, calculate the scriptPubKey and save it to the global. -On daemon restart as soon as validation for BETTX happens the global will be filled, afte this the transaction never needs to be looked up again. -GetFeeAddress is on line #2080 of komodo_bitcoind.h +On daemon restart as soon as validation for BETTX happens the global will be filled, after this the transaction never needs to be looked up again. +GetKomodoEarlytxidScriptPub is on line #2080 of komodo_bitcoind.h */ #include "CCassets.h" @@ -202,8 +213,8 @@ static bool ValidateBetTx(struct CCcontract_info *cp, Eval *eval, const CTransac int16_t leverage; CPubKey pk, pricespk; std::vector vec; - if ( KOMODO_PRICES_FEE_SCRIPTPUB.size() == 0 ) - GetFeeAddress(); + if ( ASSETCHAINS_EARLYTXIDCONTRACT == EVAL_PRICES && KOMODO_EARLYTXID_SCRIPTPUB.size() == 0 ) + GetKomodoEarlytxidScriptPub(); if (bettx.vout.size() < 5 || bettx.vout.size() > 6) return eval->Invalid("incorrect vout number for bet tx"); @@ -220,7 +231,7 @@ static bool ValidateBetTx(struct CCcontract_info *cp, Eval *eval, const CTransac if (MakeCC1vout(cp->evalcode, bettx.vout[2].nValue, pricespk) != bettx.vout[2] ) return eval->Invalid("cannot validate vout2 in bet tx with pk from opreturn"); // This should be all you need to verify it, maybe also check amount? - if ( bettx.vout[4].scriptPubKey != KOMODO_PRICES_FEE_SCRIPTPUB ) + if ( bettx.vout[4].scriptPubKey != KOMODO_EARLYTXID_SCRIPTPUB ) return eval->Invalid("the fee was paid to wrong address."); int64_t betamount = bettx.vout[2].nValue; @@ -1369,6 +1380,15 @@ int64_t prices_enumaddedbets(uint256 &batontxid, std::vector &bets, // pricesbet rpc impl: make betting tx UniValue PricesBet(int64_t txfee, int64_t amount, int16_t leverage, std::vector synthetic) { + fprintf(stderr, "assetchains_contract.%i vs eval_prices.%i\n",ASSETCHAINS_EARLYTXIDCONTRACT, EVAL_PRICES); + 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(); + } + /* int32_t nextheight = komodo_nextheight(); CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nextheight); UniValue result(UniValue::VOBJ); struct CCcontract_info *cp, C; @@ -1404,15 +1424,14 @@ UniValue PricesBet(int64_t txfee, int64_t amount, int16_t leverage, std::vector< mtx.vout.push_back(MakeCC1vout(cp->evalcode, txfee, pricespk)); // vout1 cc marker (NVOUT_CCMARKER) mtx.vout.push_back(MakeCC1vout(cp->evalcode, betamount, pricespk)); // vout2 betamount mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(HexStr(pricespk)) << OP_CHECKSIG)); // vout3 normal marker NVOUT_NORMALMARKER - TODO: remove it as we have cc marker now, when move to the new chain - if ( KOMODO_PRICES_FEE_SCRIPTPUB.size() == 0 ) + 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); - GetFeeAddress(); + GetKomodoEarlytxidScriptPub(); } - mtx.vout.push_back(CTxOut(amount-betamount, KOMODO_PRICES_FEE_SCRIPTPUB)); - + mtx.vout.push_back(CTxOut(amount-betamount, KOMODO_EARLYTXID_SCRIPTPUB)); rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_betopret(mypk, nextheight - 1, amount, leverage, firstprice, vec, zeroid)); return(prices_rawtxresult(result, rawtx, 0)); @@ -1420,6 +1439,7 @@ UniValue PricesBet(int64_t txfee, int64_t amount, int16_t leverage, std::vector< result.push_back(Pair("result", "error")); result.push_back(Pair("error", "not enough funds")); return(result); + */ } // pricesaddfunding rpc impl: add yet another bet diff --git a/src/komodo_bitcoind.h b/src/komodo_bitcoind.h index e827ea78f..e616fb179 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -29,7 +29,7 @@ int32_t komodo_voutupdate(bool fJustCheck,int32_t *isratificationp,int32_t notar unsigned int lwmaGetNextPOSRequired(const CBlockIndex* pindexLast, const Consensus::Params& params); bool EnsureWalletIsAvailable(bool avoidException); extern bool fRequestShutdown; -extern CScript KOMODO_PRICES_FEE_SCRIPTPUB; +extern CScript KOMODO_EARLYTXID_SCRIPTPUB; int32_t MarmaraSignature(uint8_t *utxosig,CMutableTransaction &txNew); uint8_t DecodeMaramaraCoinbaseOpRet(const CScript scriptPubKey,CPubKey &pk,int32_t &height,int32_t &unlockht); @@ -2063,7 +2063,6 @@ bool komodo_appendACscriptpub() { ASSETCHAINS_SCRIPTPUB.pop_back(); ASSETCHAINS_SCRIPTPUB.pop_back(); // remove last 2 chars. // get OP_RETURN from txid and append the HexStr of it to scriptpub - // encoded opreturn incorrectly on TESTHC chain, once we no longer need this it can be changed to a straight +1 to drop OP_RETURN opcode. ASSETCHAINS_SCRIPTPUB.append(HexStr(tx.vout[i].scriptPubKey.begin()+3, tx.vout[i].scriptPubKey.end())); //fprintf(stderr, "ac_script.%s\n",ASSETCHAINS_SCRIPTPUB.c_str()); didinit = true; @@ -2077,17 +2076,17 @@ bool komodo_appendACscriptpub() return false; } -void GetFeeAddress() +void GetKomodoEarlytxidScriptPub() { if ( KOMODO_EARLYTXID == zeroid ) { - fprintf(stderr, "PLEASE RESTART DAEMON WITH -earlytxid.\n"); + fprintf(stderr, "Restart deamon with -earlytxid.\n"); StartShutdown(); return; } - if ( KOMODO_SNAPSHOT_INTERVAL == 0 ) + if ( ASSETCHAINS_EARLYTXIDCONTRACT == EVAL_PRICES && KOMODO_SNAPSHOT_INTERVAL == 0 ) { - fprintf(stderr, "PRICES FEE ADDRESS MUST HAVE -ac_snapshot enabled to pay out.\n"); + fprintf(stderr, "Prices->paymentsCC contract must have -ac_snapshot enabled to pay out.\n"); StartShutdown(); return; } @@ -2097,34 +2096,22 @@ void GetFeeAddress() StartShutdown(); return; } - CTransaction tx; uint256 blockhash, txid = zeroid; char txidaddr[64]; + CTransaction tx; uint256 blockhash; int32_t i; // get transaction and check that it occured before height 100. if ( myGetTransaction(KOMODO_EARLYTXID,tx,blockhash) && mapBlockIndex[blockhash]->GetHeight() < 100 ) { - for (int i = 0; i < tx.vout.size(); i++) + for (i = 0; i < tx.vout.size(); i++) if ( tx.vout[i].scriptPubKey[0] == OP_RETURN ) - txid = uint256S(HexStr(tx.vout[i].scriptPubKey.begin()+3, tx.vout[i].scriptPubKey.end())); - if ( txid == zeroid ) + break; + if ( i < tx.vout.size() ) { - fprintf(stderr, "INVALID -earlytxid, restart daemon with correct txid.\n"); - StartShutdown(); + KOMODO_EARLYTXID_SCRIPTPUB = CScript(tx.vout[i].scriptPubKey.begin()+3, tx.vout[i].scriptPubKey.end()); + fprintf(stderr, "KOMODO_EARLYTXID_SCRIPTPUB.%s\n", HexStr(KOMODO_EARLYTXID_SCRIPTPUB.begin(),KOMODO_EARLYTXID_SCRIPTPUB.end()).c_str()); + return; } - fprintf(stderr, "txid.%s\n", txid.GetHex().c_str()); - struct CCcontract_info *cp, C; CPubKey Paymentspk,txidpk; - cp = CCinit(&C, EVAL_PAYMENTS); - Paymentspk = GetUnspendable(cp,0); - txidpk = CCtxidaddr(txidaddr,txid); - GetCCaddress1of2(cp,txidaddr,Paymentspk,txidpk); - CC *payoutCond = MakeCCcond1of2(EVAL_PAYMENTS,Paymentspk,txidpk); - KOMODO_PRICES_FEE_SCRIPTPUB = CCPubKey(payoutCond); - cc_free(payoutCond); - fprintf(stderr, "KOMODO_PRICES_FEE_SCRIPTPUB.%s address.%s\n", HexStr(KOMODO_PRICES_FEE_SCRIPTPUB.begin(),KOMODO_PRICES_FEE_SCRIPTPUB.end()).c_str(),txidaddr); - } - else - { - fprintf(stderr, "INVALID -earlytxid, restart daemon with correct txid.\n"); - StartShutdown(); } + fprintf(stderr, "INVALID -earlytxid, restart daemon with correct txid.\n"); + StartShutdown(); } int64_t komodo_checkcommission(CBlock *pblock,int32_t height) diff --git a/src/komodo_defs.h b/src/komodo_defs.h index 0737356df..5efbe58fb 100644 --- a/src/komodo_defs.h +++ b/src/komodo_defs.h @@ -84,6 +84,7 @@ extern uint8_t ASSETCHAINS_PRIVATE; extern int32_t USE_EXTERNAL_PUBKEY; extern char NOTARYADDRS[64][64]; extern int32_t KOMODO_TESTNODE, KOMODO_SNAPSHOT_INTERVAL; +extern int32_t ASSETCHAINS_EARLYTXIDCONTRACT; int tx_height( const uint256 &hash ); extern std::vector vWhiteListAddress; void komodo_netevent(std::vector payload); @@ -117,4 +118,4 @@ int32_t komodo_priceget(int64_t *buf64,int32_t ind,int32_t height,int32_t numblo uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue,int32_t tipheight); -#endif \ No newline at end of file +#endif diff --git a/src/komodo_globals.h b/src/komodo_globals.h index bc21bab10..08c633ee7 100644 --- a/src/komodo_globals.h +++ b/src/komodo_globals.h @@ -110,7 +110,8 @@ extern int32_t KOMODO_LOADINGBLOCKS; unsigned int MAX_BLOCK_SIGOPS = 20000; int32_t KOMODO_TESTNODE, KOMODO_SNAPSHOT_INTERVAL; -CScript KOMODO_PRICES_FEE_SCRIPTPUB; +CScript KOMODO_EARLYTXID_SCRIPTPUB; +int32_t ASSETCHAINS_EARLYTXIDCONTRACT; struct komodo_kv *KOMODO_KV; pthread_mutex_t KOMODO_KV_mutex,KOMODO_CC_mutex; diff --git a/src/komodo_utils.h b/src/komodo_utils.h index 52539e35d..857dfe4c8 100644 --- a/src/komodo_utils.h +++ b/src/komodo_utils.h @@ -1759,6 +1759,8 @@ void komodo_args(char *argv0) printf("KOMODO_REWIND %d\n",KOMODO_REWIND); } 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])); @@ -2013,7 +2015,7 @@ void komodo_args(char *argv0) fprintf(stderr,"-ac_script and -ac_marmara are mutually exclusive\n"); StartShutdown(); } - if ( ASSETCHAINS_ENDSUBSIDY[0] != 0 || ASSETCHAINS_REWARD[0] != 0 || ASSETCHAINS_HALVING[0] != 0 || ASSETCHAINS_DECAY[0] != 0 || ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_PUBLIC != 0 || ASSETCHAINS_PRIVATE != 0 || ASSETCHAINS_TXPOW != 0 || ASSETCHAINS_FOUNDERS != 0 || ASSETCHAINS_SCRIPTPUB.size() > 1 || ASSETCHAINS_SELFIMPORT.size() > 0 || ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 || ASSETCHAINS_TIMELOCKGTE != _ASSETCHAINS_TIMELOCKOFF|| ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH || ASSETCHAINS_LWMAPOS != 0 || ASSETCHAINS_LASTERA > 0 || ASSETCHAINS_BEAMPORT != 0 || ASSETCHAINS_CODAPORT != 0 || ASSETCHAINS_MARMARA != 0 || nonz > 0 || ASSETCHAINS_CCLIB.size() > 0 || ASSETCHAINS_FOUNDERS_REWARD != 0 || ASSETCHAINS_NOTARY_PAY[0] != 0 || ASSETCHAINS_BLOCKTIME != 60 || ASSETCHAINS_CBOPRET != 0 || Mineropret.size() != 0 || (ASSETCHAINS_NK[0] != 0 && ASSETCHAINS_NK[1] != 0) || KOMODO_SNAPSHOT_INTERVAL != 0 ) + if ( ASSETCHAINS_ENDSUBSIDY[0] != 0 || ASSETCHAINS_REWARD[0] != 0 || ASSETCHAINS_HALVING[0] != 0 || ASSETCHAINS_DECAY[0] != 0 || ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_PUBLIC != 0 || ASSETCHAINS_PRIVATE != 0 || ASSETCHAINS_TXPOW != 0 || ASSETCHAINS_FOUNDERS != 0 || ASSETCHAINS_SCRIPTPUB.size() > 1 || ASSETCHAINS_SELFIMPORT.size() > 0 || ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 || ASSETCHAINS_TIMELOCKGTE != _ASSETCHAINS_TIMELOCKOFF|| ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH || ASSETCHAINS_LWMAPOS != 0 || ASSETCHAINS_LASTERA > 0 || ASSETCHAINS_BEAMPORT != 0 || ASSETCHAINS_CODAPORT != 0 || ASSETCHAINS_MARMARA != 0 || nonz > 0 || ASSETCHAINS_CCLIB.size() > 0 || ASSETCHAINS_FOUNDERS_REWARD != 0 || ASSETCHAINS_NOTARY_PAY[0] != 0 || ASSETCHAINS_BLOCKTIME != 60 || ASSETCHAINS_CBOPRET != 0 || Mineropret.size() != 0 || (ASSETCHAINS_NK[0] != 0 && ASSETCHAINS_NK[1] != 0) || KOMODO_SNAPSHOT_INTERVAL != 0 || ASSETCHAINS_EARLYTXIDCONTRACT != 0 ) { fprintf(stderr,"perc %.4f%% ac_pub=[%02x%02x%02x...] acsize.%d\n",dstr(ASSETCHAINS_COMMISSION)*100,ASSETCHAINS_OVERRIDE_PUBKEY33[0],ASSETCHAINS_OVERRIDE_PUBKEY33[1],ASSETCHAINS_OVERRIDE_PUBKEY33[2],(int32_t)ASSETCHAINS_SCRIPTPUB.size()); extraptr = extrabuf; @@ -2152,7 +2154,10 @@ void komodo_args(char *argv0) if ( KOMODO_SNAPSHOT_INTERVAL != 0 ) { extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(KOMODO_SNAPSHOT_INTERVAL),(void *)&KOMODO_SNAPSHOT_INTERVAL); - fprintf(stderr, "snapshot interval.%i\n",KOMODO_SNAPSHOT_INTERVAL); + } + if ( ASSETCHAINS_EARLYTXIDCONTRACT != 0 ) + { + extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_EARLYTXIDCONTRACT),(void *)&ASSETCHAINS_EARLYTXIDCONTRACT); } } diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index dc3b07418..5ce7ae773 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -8000,6 +8000,7 @@ void RegisterWalletRPCCommands(CRPCTable &tableRPC) UniValue opreturn_burn(const UniValue& params, bool fHelp) { + std::vector vHexStr; CScript opret; int32_t txfee = 10000; if (fHelp || (params.size() != 2)) throw runtime_error("amount to burn, hexstring to send\n"); struct CCcontract_info *cp, C; UniValue ret(UniValue::VOBJ); @@ -8009,30 +8010,22 @@ UniValue opreturn_burn(const UniValue& params, bool fHelp) CAmount nAmount = AmountFromValue(params[0]); if (nAmount <= 10000) - throw JSONRPCError(RPC_TYPE_ERROR, "must send at least 10000 sat"); - std::string strHex = params[1].get_str(); + throw JSONRPCError(RPC_TYPE_ERROR, "must burn at least 10000 sat"); + vHexStr = ParseHex(params[1].get_str()); + if ( vHexStr.size() == 0 ) + throw JSONRPCError(RPC_TYPE_ERROR, "hexstring is not valid."); + CPubKey myPubkey = pubkey2pk(Mypubkey()); CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); int64_t normalInputs = AddNormalinputs(mtx, myPubkey, nAmount, 60); if (normalInputs < nAmount) throw runtime_error("not enough normals\n"); - - CScript opret; uint8_t scripthex[8192]; - - decode_hex(scripthex,strHex.size()/2,(char *)strHex.c_str()); - std::string test; - test.append((char*)scripthex); - std::vector opretdata(test.begin(), test.end()); - opret << OP_RETURN << E_MARSHAL(ss << opretdata); - /*CScript opret; uint8_t *ptr; - opret << OP_RETURN << 0; - int32_t len = strlen(strHex.c_str()); - len >>=1; - opret.resize(len+2); - ptr = (uint8_t *)&opret[1]; - decode_hex(ptr,len,(char *)strHex.c_str()); */ - mtx.vout.push_back(CTxOut(nAmount,opret)); - ret.push_back(Pair("hex",FinalizeCCTx(0, cp, mtx, myPubkey, 10000, CScript()))); + + opret << OP_RETURN << E_MARSHAL(ss << vHexStr); + + mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(myPubkey)) << OP_CHECKSIG)); + mtx.vout.push_back(CTxOut(nAmount,opret)); + ret.push_back(Pair("hex",FinalizeCCTx(0, cp, mtx, myPubkey, txfee, CScript()))); return(ret); }