diff --git a/qa/rpc-tests/cryptoconditions.py b/qa/rpc-tests/cryptoconditions.py index e7d3065cc..1d2f68777 100755 --- a/qa/rpc-tests/cryptoconditions.py +++ b/qa/rpc-tests/cryptoconditions.py @@ -3,6 +3,7 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. + from test_framework.test_framework import BitcoinTestFramework from test_framework.authproxy import JSONRPCException from test_framework.util import assert_equal, assert_greater_than, \ @@ -11,6 +12,8 @@ from test_framework.util import assert_equal, assert_greater_than, \ import time from decimal import Decimal +from random import choice +from string import ascii_uppercase def assert_success(result): assert_equal(result['result'], 'success') @@ -18,6 +21,11 @@ def assert_success(result): def assert_error(result): assert_equal(result['result'], 'error') +def generate_random_string(length): + random_string = ''.join(choice(ascii_uppercase) for i in range(length)) + return random_string + + class CryptoConditionsTest (BitcoinTestFramework): def setup_chain(self): @@ -470,7 +478,6 @@ class CryptoConditionsTest (BitcoinTestFramework): result = rpc.tokenbalance(tokenid,randompubkey) assert_equal(result["balance"], 1) - def run_rewards_tests(self): rpc = self.nodes[0] result = rpc.rewardsaddress() @@ -581,6 +588,51 @@ class CryptoConditionsTest (BitcoinTestFramework): result = rpc.rewardsunlock("STUFF", fundingtxid, locktxid) assert_error(result) + def run_oracles_tests(self): + rpc = self.nodes[0] + result = rpc.oraclesaddress() + assert_success(result) + for x in ['OraclesCCaddress', 'Oraclesmarker', 'myCCaddress', 'myaddress']: + assert_equal(result[x][0], 'R') + + result = rpc.oraclesaddress(self.pubkey) + assert_success(result) + for x in ['OraclesCCaddress', 'Oraclesmarker', 'myCCaddress', 'myaddress']: + assert_equal(result[x][0], 'R') + + # there are no oracles created yet + result = rpc.oracleslist() + assert_equal(result, []) + + # looking up non-existent oracle should return error. + result = rpc.oraclesinfo("none") + assert_error(result) + + # attempt to create oracle with not valid data type should return error + result = rpc.oraclescreate("Test", "Test", "Test") + assert_error(result) + + # attempt to create oracle with description > 32 symbols should return error + too_long_name = generate_random_string(33) + result = rpc.oraclescreate(too_long_name, "Test", "s") + + + # attempt to create oracle with description > 4096 symbols should return error + too_long_description = generate_random_string(4100) + result = rpc.oraclescreate("Test", too_long_description, "s") + assert_error(result) + + # valid creating oracles of different types + # using such naming to re-use it for data publishing / reading (e.g. oracle_s for s type) + valid_formats = ["s", "S", "d", "D", "c", "C", "t", "T", "i", "I", "l", "L", "h", "Ihh"] + for f in valid_formats: + result = rpc.oraclescreate("Test", "Test", f) + assert_success(result) + globals()["oracle_{}".format(f)] = self.send_and_mine(result['hex']) + + + + def run_test (self): print("Mining blocks...") @@ -594,12 +646,13 @@ class CryptoConditionsTest (BitcoinTestFramework): print("Importing privkey") rpc.importprivkey(self.privkey) -# self.run_faucet_tests() + #self.run_faucet_tests() self.run_rewards_tests() self.run_dice_tests() self.run_token_tests() self.run_faucet_tests() + self.run_oracles_tests() if __name__ == '__main__': - CryptoConditionsTest ().main () + CryptoConditionsTest ().main() diff --git a/src/cc/gateways.cpp b/src/cc/gateways.cpp index b9c78a612..1db08532a 100644 --- a/src/cc/gateways.cpp +++ b/src/cc/gateways.cpp @@ -189,8 +189,11 @@ uint8_t DecodeGatewaysBindOpRet(char *depositaddr,const CScript &scriptPubKey,st if ( prefix == 60 ) { if ( N > 1 ) - Getscriptaddress(depositaddr,GetScriptForMultisig(M,pubkeys)); - else Getscriptaddress(depositaddr,CScript() << ParseHex(HexStr(pubkeys[0])) << OP_CHECKSIG); + { + strcpy(depositaddr,CBitcoinAddress(CScriptID(GetScriptForMultisig(M,pubkeys))).ToString().c_str()); + //Getscriptaddress(depositaddr,GetScriptForMultisig(M,pubkeys)); + fprintf(stderr,"f.%c M.%d of N.%d size.%d -> %s\n",f,M,N,(int32_t)pubkeys.size(),depositaddr); + } else Getscriptaddress(depositaddr,CScript() << ParseHex(HexStr(pubkeys[0])) << OP_CHECKSIG); } else { diff --git a/src/cc/oracles.cpp b/src/cc/oracles.cpp index 5a352afeb..7cccad0f6 100644 --- a/src/cc/oracles.cpp +++ b/src/cc/oracles.cpp @@ -854,11 +854,18 @@ UniValue OracleDataSamples(uint256 reforacletxid,uint256 batontxid,int32_t num) UniValue OracleInfo(uint256 origtxid) { - UniValue result(UniValue::VOBJ),a(UniValue::VARR),obj(UniValue::VOBJ); + UniValue result(UniValue::VOBJ),a(UniValue::VARR); std::vector > unspentOutputs; CMutableTransaction mtx; CTransaction regtx,tx; std::string name,description,format; uint256 hashBlock,txid,oracletxid,batontxid; CPubKey pk; struct CCcontract_info *cp,C; int64_t datafee,funding; char str[67],markeraddr[64],numstr[64],batonaddr[64]; std::vector data; cp = CCinit(&C,EVAL_ORACLES); CCtxidaddr(markeraddr,origtxid); + if ( GetTransaction(origtxid,tx,hashBlock,false) == 0 ) + { + fprintf(stderr,"cant find oracleid\n"); + result.push_back(Pair("result","error")); + result.push_back(Pair("error","cant find oracleid")); + return(result); + } if ( GetTransaction(origtxid,tx,hashBlock,false) != 0 ) { if ( tx.vout.size() > 0 && DecodeOraclesCreateOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,name,description,format) == 'C' ) @@ -877,6 +884,7 @@ UniValue OracleInfo(uint256 origtxid) { if ( regtx.vout.size() > 0 && DecodeOraclesOpRet(regtx.vout[regtx.vout.size()-1].scriptPubKey,oracletxid,pk,datafee) == 'R' && oracletxid == origtxid ) { + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("publisher",pubkey33_str(str,(uint8_t *)pk.begin()))); Getscriptaddress(batonaddr,regtx.vout[1].scriptPubKey); batontxid = OracleBatonUtxo(10000,cp,oracletxid,batonaddr,pk,data); diff --git a/src/komodo_utils.h b/src/komodo_utils.h index 7a729b2f5..a2ab9d8b3 100644 --- a/src/komodo_utils.h +++ b/src/komodo_utils.h @@ -1512,7 +1512,6 @@ void komodo_args(char *argv0) fprintf(stderr,"KOMODO_EXCHANGEWALLET mode active\n"); DONATION_PUBKEY = GetArg("-donation", ""); NOTARY_PUBKEY = GetArg("-pubkey", ""); - KOMODO_DPOWCONFS = GetArg("-dpowconfs",KOMODO_DPOWCONFS); if ( strlen(NOTARY_PUBKEY.c_str()) == 66 ) { USE_EXTERNAL_PUBKEY = 1; @@ -1701,6 +1700,7 @@ void komodo_args(char *argv0) break; } } + int32_t dpowconfs = KOMODO_DPOWCONFS; if ( ASSETCHAINS_SYMBOL[0] != 0 ) { BITCOIND_RPCPORT = GetArg("-rpcport", ASSETCHAINS_RPCPORT); @@ -1711,8 +1711,9 @@ void komodo_args(char *argv0) fprintf(stderr,"PIRATE halving changed to %d %.1f days\n",(int32_t)ASSETCHAINS_HALVING,(double)ASSETCHAINS_HALVING/1440); } else if ( strcmp("VRSC",ASSETCHAINS_SYMBOL) == 0 ) - KOMODO_DPOWCONFS = 0; + dpowconfs = 0; } else BITCOIND_RPCPORT = GetArg("-rpcport", BaseParams().RPCPort()); + KOMODO_DPOWCONFS = GetArg("-dpowconfs",dpowconfs); } void komodo_nameset(char *symbol,char *dest,char *source) diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 893c291b0..815860c7d 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -118,7 +118,8 @@ UniValue blockheaderToJSON(const CBlockIndex* blockindex) // Only report confirmations if the block is on the main chain if (chainActive.Contains(blockindex)) confirmations = chainActive.Height() - blockindex->nHeight + 1; - result.push_back(Pair("confirmations", confirmations)); + result.push_back(Pair("confirmations", komodo_dpowconfs(blockindex->nHeight,confirmations))); + result.push_back(Pair("rawconfirmations", confirmations)); result.push_back(Pair("height", blockindex->nHeight)); result.push_back(Pair("version", blockindex->nVersion)); result.push_back(Pair("merkleroot", blockindex->hashMerkleRoot.GetHex())); @@ -149,7 +150,8 @@ UniValue blockToDeltasJSON(const CBlock& block, const CBlockIndex* blockindex) } else { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block is an orphan"); } - result.push_back(Pair("confirmations", confirmations)); + result.push_back(Pair("confirmations", komodo_dpowconfs(blockindex->nHeight,confirmations))); + result.push_back(Pair("rawconfirmations", confirmations)); result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION))); result.push_back(Pair("height", blockindex->nHeight)); result.push_back(Pair("version", block.nVersion)); @@ -266,7 +268,8 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx // Only report confirmations if the block is on the main chain if (chainActive.Contains(blockindex)) confirmations = chainActive.Height() - blockindex->nHeight + 1; - result.push_back(Pair("confirmations", confirmations)); + result.push_back(Pair("confirmations", komodo_dpowconfs(blockindex->nHeight,confirmations))); + result.push_back(Pair("rawconfirmations", confirmations)); result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION))); result.push_back(Pair("height", blockindex->nHeight)); result.push_back(Pair("version", block.nVersion)); @@ -1151,7 +1154,11 @@ UniValue gettxout(const UniValue& params, bool fHelp) ret.push_back(Pair("bestblock", pindex->GetBlockHash().GetHex())); if ((unsigned int)coins.nHeight == MEMPOOL_HEIGHT) ret.push_back(Pair("confirmations", 0)); - else ret.push_back(Pair("confirmations", komodo_dpowconfs(coins.nHeight,pindex->nHeight - coins.nHeight + 1))); + else + { + ret.push_back(Pair("confirmations", komodo_dpowconfs(coins.nHeight,pindex->nHeight - coins.nHeight + 1))); + ret.push_back(Pair("rawconfirmations", pindex->nHeight - coins.nHeight + 1)); + } ret.push_back(Pair("value", ValueFromAmount(coins.vout[n].nValue))); uint64_t interest; int32_t txheight; uint32_t locktime; if ( (interest= komodo_accrued_interest(&txheight,&locktime,hash,n,coins.nHeight,coins.vout[n].nValue,(int32_t)pindex->nHeight)) != 0 ) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 83b4fc1ea..f81affb6f 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -90,7 +90,8 @@ void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry) { //int32_t i,n,txheight; uint32_t locktime; uint64_t interest = 0; int confirms = wtx.GetDepthInMainChain(); - entry.push_back(Pair("confirmations", confirms)); + entry.push_back(Pair("rawconfirmations", confirms)); + entry.push_back(Pair("confirmations", komodo_dpowconfs((int32_t)mapBlockIndex[wtx.hashBlock]->nHeight,confirms))); if (wtx.IsCoinBase()) entry.push_back(Pair("generated", true)); if (confirms > 0) @@ -5756,6 +5757,24 @@ 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); if ( hex.size() > 0 ) {