diff --git a/src/cc/dapps/oraclefeed.c b/src/cc/dapps/oraclefeed.c index 33e6908fb..8a819a147 100644 --- a/src/cc/dapps/oraclefeed.c +++ b/src/cc/dapps/oraclefeed.c @@ -822,22 +822,6 @@ int32_t get_gatewaysinfo(char *refcoin,char *acname,char *depositaddr,int32_t *M else return(0); } -int32_t tx_notarizedconfirmed(char *refcoin,char *acname,bits256 txid) -{ - char *retstr,str[65]; cJSON *retjson; int32_t result; - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"txnotarizedconfirmed",bits256_str(str,txid),"","","")) != 0 ) - { - if (is_cJSON_True(jobj(retjson,"result")) != 0 ) result=1; - else result=0; - free_json(retjson); - } - else if ( retstr != 0 ) - { - printf("error parsing txnotarizedconfirmed.(%s)\n",retstr); - free(retstr); - } -} - int32_t tx_has_voutaddress(char *refcoin,char *acname,bits256 txid,char *coinaddr) { cJSON *txobj,*vouts,*vout,*vins,*vin,*sobj,*addresses; char *addr,str[65]; int32_t i,j,n,numarray,retval = 0, hasvout=0; diff --git a/src/cc/oracles.cpp b/src/cc/oracles.cpp index 8bcdf3860..66c0e1b9a 100644 --- a/src/cc/oracles.cpp +++ b/src/cc/oracles.cpp @@ -416,6 +416,42 @@ int32_t oracle_format(uint256 *hashp,int64_t *valp,char *str,uint8_t fmt,uint8_t return(offset); } +int32_t oracle_parse_data_format(std::vector data,std::string format) +{ + int64_t offset=0,len=0; char fmt; + + for (int i=0; idata.size()-offset) return (0); + if (fmt=='S' || fmt=='s') + { + for (int j=offset;j127) return (0); + } + offset+=len; + } + if (offset!=data.size()) return (0); + else return (offset); +} + int64_t _correlate_price(int64_t *prices,int32_t n,int64_t price) { int32_t i,count = 0; int64_t diff,threshold = (price >> 8); @@ -729,13 +765,29 @@ int64_t LifetimeOraclesFunds(struct CCcontract_info *cp,uint256 oracletxid,CPubK std::string OracleCreate(int64_t txfee,std::string name,std::string description,std::string format) { CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); - CPubKey mypk,Oraclespk; struct CCcontract_info *cp,C; + CPubKey mypk,Oraclespk; struct CCcontract_info *cp,C; char fmt; + cp = CCinit(&C,EVAL_ORACLES); if ( name.size() > 32 || description.size() > 4096 || format.size() > 4096 ) { - fprintf(stderr,"name.%d or description.%d is too big\n",(int32_t)name.size(),(int32_t)description.size()); + CCerror = strprintf("name.%d or description.%d is too big",(int32_t)name.size(),(int32_t)description.size()); + fprintf(stderr,"%s\n", CCerror.c_str() ); return(""); - } + } + for(int i = 0; i < format.size(); i++) + { + fmt=format[i]; + switch (fmt) + { + case 's': case 'S': case 'd': case 'D': + case 'c': case 'C': case 't': case 'T': + case 'i': case 'I': case 'l': case 'L': + case 'h': break; + default: CCerror = strprintf("invalid format type"); + fprintf(stderr,"%s\n", CCerror.c_str() ); + return(""); + } + } if ( txfee == 0 ) txfee = 10000; mypk = pubkey2pk(Mypubkey()); @@ -745,6 +797,8 @@ std::string OracleCreate(int64_t txfee,std::string name,std::string description, mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(Oraclespk)) << OP_CHECKSIG)); return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeOraclesCreateOpRet('C',name,description,format))); } + CCerror = strprintf("error adding normal inputs"); + fprintf(stderr,"%s\n", CCerror.c_str() ); return(""); } @@ -757,7 +811,8 @@ std::string OracleRegister(int64_t txfee,uint256 oracletxid,int64_t datafee) txfee = 10000; if ( datafee < txfee ) { - fprintf(stderr,"datafee must be txfee or more\n"); + CCerror = strprintf("datafee must be txfee or more"); + fprintf(stderr,"%s\n", CCerror.c_str() ); return(""); } mypk = pubkey2pk(Mypubkey()); @@ -769,6 +824,8 @@ std::string OracleRegister(int64_t txfee,uint256 oracletxid,int64_t datafee) mtx.vout.push_back(MakeCC1vout(cp->evalcode,txfee,batonpk)); return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeOraclesOpRet('R',oracletxid,mypk,datafee))); } + CCerror = strprintf("error adding normal inputs"); + fprintf(stderr,"%s\n", CCerror.c_str() ); return(""); } @@ -787,13 +844,17 @@ std::string OracleSubscribe(int64_t txfee,uint256 oracletxid,CPubKey publisher,i mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(markerpubkey)) << OP_CHECKSIG)); return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeOraclesOpRet('S',oracletxid,mypk,amount))); } + CCerror = strprintf("error adding normal inputs"); + fprintf(stderr,"%s\n", CCerror.c_str() ); return(""); } std::string OracleData(int64_t txfee,uint256 oracletxid,std::vector data) { CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); - CScript pubKey; CPubKey mypk,batonpk; int64_t datafee,inputs,CCchange = 0; struct CCcontract_info *cp,C; uint256 batontxid; char coinaddr[64],batonaddr[64]; std::vector prevdata; + CScript pubKey; CPubKey mypk,batonpk; int64_t offset,datafee,inputs,CCchange = 0; struct CCcontract_info *cp,C; uint256 batontxid,hashBlock; + char coinaddr[64],batonaddr[64]; std::vector prevdata; CTransaction tx; std::string name,description,format; int32_t len,numvouts; + cp = CCinit(&C,EVAL_ORACLES); mypk = pubkey2pk(Mypubkey()); if ( data.size() > 8192 ) @@ -808,6 +869,30 @@ std::string OracleData(int64_t txfee,uint256 oracletxid,std::vector da fprintf(stderr,"%s\n", CCerror.c_str() ); return(""); } + if ( GetTransaction(oracletxid,tx,hashBlock,false) != 0 && (numvouts=tx.vout.size()) > 0 ) + { + if ( DecodeOraclesCreateOpRet(tx.vout[numvouts-1].scriptPubKey,name,description,format) == 'C' ) + { + if (oracle_parse_data_format(data,format)==0) + { + CCerror = strprintf("data does not match length or content format specification"); + fprintf(stderr,"%s\n", CCerror.c_str() ); + return(""); + } + } + else + { + CCerror = strprintf("invalid oracle txid opret data"); + fprintf(stderr,"%s\n", CCerror.c_str() ); + return(""); + } + } + else + { + CCerror = strprintf("invalid oracle txid"); + fprintf(stderr,"%s\n", CCerror.c_str() ); + return(""); + } if ( txfee == 0 ) txfee = 10000; GetCCaddress(cp,coinaddr,mypk); @@ -831,7 +916,7 @@ std::string OracleData(int64_t txfee,uint256 oracletxid,std::vector da fprintf(stderr,"%s\n", CCerror.c_str() ); } } else { - CCerror = strprintf("couldnt add normal inputs\n"); + CCerror = strprintf("couldnt add normal inputs"); fprintf(stderr,"%s\n", CCerror.c_str() ); } return(""); @@ -855,7 +940,9 @@ UniValue OracleFormat(uint8_t *data,int32_t datalen,char *format,int32_t formatl 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),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; + result.push_back(Pair("result","success")); if ( GetTransaction(reforacletxid,oracletx,hashBlock,false) != 0 && (numvouts=oracletx.vout.size()) > 0 ) { diff --git a/src/main.cpp b/src/main.cpp index c8af01656..113fa4c03 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4809,6 +4809,7 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C if ( ASSETCHAINS_CC != 0 ) { + LOCK2(cs_main,mempool.cs); // here we add back all txs from the temp mempool to the main mempool. BOOST_FOREACH(const CTxMemPoolEntry& e, tmpmempool.mapTx) { diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 7aec551d4..20aaea1e2 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -29,6 +29,7 @@ #include "txmempool.h" #include "util.h" #include "notaries_staked.h" +#include "cc/eval.h" #ifdef ENABLE_WALLET #include "wallet/wallet.h" #include "wallet/walletdb.h" @@ -1420,6 +1421,52 @@ UniValue txnotarizedconfirmed(const UniValue& params, bool fHelp) return result; } +UniValue decodeccopret(const UniValue& params, bool fHelp) +{ + CTransaction tx; uint256 txid,hashBlock; + std::vector vopret; uint8_t *script; + UniValue result(UniValue::VOBJ); + + if (fHelp || params.size() < 1 || params.size() > 1) + { + string msg = "decodeccopret hex\n" + "\nReturns eval code and function id for CC OP RETURN data.\n" + + "\nArguments:\n" + "1. txid (string, required) Transaction id.\n" + + "\nResult:\n" + "{\n" + " eval_code, (string) Eval code name.\n" + " function, (char) Function id char.\n" + "}\n" + ; + throw runtime_error(msg); + } + txid = uint256S((char *)params[0].get_str().c_str()); + { + LOCK(cs_main); + if (!GetTransaction(txid, tx, hashBlock, true)) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction"); + } + GetOpReturnData(tx.vout[tx.vout.size()-1].scriptPubKey,vopret); + script = (uint8_t *)vopret.data(); + if ( vopret.size() > 1) + { + char func[5]; + sprintf(func,"%c",script[1]); + result.push_back(Pair("result", "success")); + result.push_back(Pair("eval_code", EvalToStr(script[0]))); + result.push_back(Pair("function", func)); + } + else + { + result.push_back(Pair("result", "error")); + result.push_back(Pair("error", "invalid or no CC opret data")); + } + return result; +} + static const CRPCCommand commands[] = { // category name actor (function) okSafeMode // --------------------- ------------------------ ----------------------- ---------- diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 7b2d770d8..265532557 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -506,6 +506,7 @@ static const CRPCCommand vRPCCommands[] = { "util", "validateaddress", &validateaddress, true }, /* uses wallet if enabled */ { "util", "verifymessage", &verifymessage, true }, { "util", "txnotarizedconfirmed", &txnotarizedconfirmed, true }, + { "util", "decodeccopret", &decodeccopret, true }, { "util", "estimatefee", &estimatefee, true }, { "util", "estimatepriority", &estimatepriority, true }, { "util", "z_validateaddress", &z_validateaddress, true }, /* uses wallet if enabled */ diff --git a/src/rpc/server.h b/src/rpc/server.h index 1a6144301..af1a0ea04 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -357,6 +357,7 @@ extern UniValue walletlock(const UniValue& params, bool fHelp); extern UniValue encryptwallet(const UniValue& params, bool fHelp); extern UniValue validateaddress(const UniValue& params, bool fHelp); extern UniValue txnotarizedconfirmed(const UniValue& params, bool fHelp); +extern UniValue decodeccopret(const UniValue& params, bool fHelp); extern UniValue getinfo(const UniValue& params, bool fHelp); extern UniValue getiguanajson(const UniValue& params, bool fHelp); extern UniValue getnotarysendmany(const UniValue& params, bool fHelp); diff --git a/src/script/standard.cpp b/src/script/standard.cpp index 6915a760c..d38c0a351 100644 --- a/src/script/standard.cpp +++ b/src/script/standard.cpp @@ -468,26 +468,27 @@ bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, vecto if (addressRet.empty()) return false; } - else if (IsCryptoConditionsEnabled() != 0 && typeRet == TX_CRYPTOCONDITION) - { - nRequiredRet = vSolutions.front()[0]; - for (unsigned int i = 1; i < vSolutions.size()-1; i++) - { - CTxDestination address; - if (vSolutions[i].size() == 20) - { - address = CKeyID(uint160(vSolutions[i])); - } - else - { - address = CPubKey(vSolutions[i]); - } - addressRet.push_back(address); - } + // Removed to get CC address printed in getrawtransaction and decoderawtransaction + // else if (IsCryptoConditionsEnabled() != 0 && typeRet == TX_CRYPTOCONDITION) + // { + // nRequiredRet = vSolutions.front()[0]; + // for (unsigned int i = 1; i < vSolutions.size()-1; i++) + // { + // CTxDestination address; + // if (vSolutions[i].size() == 20) + // { + // address = CKeyID(uint160(vSolutions[i])); + // } + // else + // { + // address = CPubKey(vSolutions[i]); + // } + // addressRet.push_back(address); + // } - if (addressRet.empty()) - return false; - } + // if (addressRet.empty()) + // return false; + // } else { nRequiredRet = 1; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 65063d942..1bb73b02f 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -6221,9 +6221,7 @@ UniValue oraclesdata(const UniValue& params, bool fHelp) txid = Parseuint256((char *)params[0].get_str().c_str()); data = ParseHex(params[1].get_str().c_str()); hex = OracleData(0,txid,data); - RETURN_IF_ERROR(CCerror); - if ( hex.size() > 0 ) { result.push_back(Pair("result", "success")); @@ -6259,24 +6257,6 @@ UniValue oraclescreate(const UniValue& params, bool fHelp) ERR_RESULT("oracles format must be <= 4096 characters"); return(result); } - // list of oracle valid formats from oracles.cpp -> oracle_format - const UniValue valid_formats[13] = {"s","S","d","D","c","C","t","T","i","I","l","L","h"}; - const UniValue header_type = "Ihh"; - // checking if oracle data type is valid - bool is_valid_format = false; - for ( int i = 0; i < 13; ++i ) { - if ( valid_formats[i].get_str() == format ) { - is_valid_format = true; - } - } - // additional check for special Ihh data type - if ( format == header_type.get_str() ) { - is_valid_format = true; - } - if ( !is_valid_format ) { - ERR_RESULT("oracles format not valid"); - return(result); - } hex = OracleCreate(0,name,description,format); RETURN_IF_ERROR(CCerror); if ( hex.size() > 0 )