diff --git a/qa/rpc-tests/cryptoconditions.py b/qa/rpc-tests/cryptoconditions.py index f133ae28a..dd6adba76 100755 --- a/qa/rpc-tests/cryptoconditions.py +++ b/qa/rpc-tests/cryptoconditions.py @@ -78,6 +78,12 @@ class CryptoConditionsTest (BitcoinTestFramework): for x in ['myCCaddress', 'FaucetCCaddress', 'Faucetmarker', 'myaddress']: assert_equal(faucet[x][0], 'R') + result = rpc.faucetaddress(self.pubkey) + assert_success(result) + # test that additional CCaddress key is returned + for x in ['myCCaddress', 'FaucetCCaddress', 'Faucetmarker', 'myaddress', 'CCaddress']: + assert_equal(result[x][0], 'R') + # no funds in the faucet yet result = rpc.faucetget() assert_error(result) @@ -134,12 +140,20 @@ class CryptoConditionsTest (BitcoinTestFramework): for x in ['myCCaddress', 'DiceCCaddress', 'Dicemarker', 'myaddress']: assert_equal(dice[x][0], 'R') + dice = rpc.diceaddress(self.pubkey) + assert_equal(dice['result'], 'success') + for x in ['myCCaddress', 'DiceCCaddress', 'Dicemarker', 'myaddress', 'CCaddress']: + assert_equal(dice[x][0], 'R') + # no dice created yet result = rpc.dicelist() assert_equal(result, []) - #result = rpc.dicefund("LUCKY",10000,1,10000,10,5) - #assert_equal(result, []) + result = rpc.diceinfo("invalid") + assert_error(result) + + result = rpc.dicefund("THISISTOOLONG", "10000", "10", "10000", "10", "5") + assert_error(result) def run_token_tests(self): rpc = self.nodes[0] @@ -156,8 +170,15 @@ class CryptoConditionsTest (BitcoinTestFramework): result = rpc.tokenlist() assert_equal(result, []) - result = rpc.tokencreate("DUKE", "1987.420", "duke") + result = rpc.tokencreate("NUKE", "-1987420", "no bueno supply") + assert_error(result) + + result = rpc.tokencreate("NUKE123456789012345678901234567890", "1987420", "name too long") + assert_error(result) + + result = rpc.tokencreate("DUKE", "1987.420", "Duke's custom token") assert_success(result) + tokenid = self.send_and_mine(result['hex']) result = rpc.tokenlist() @@ -197,7 +218,7 @@ class CryptoConditionsTest (BitcoinTestFramework): assert_equal(result['owner'], self.pubkey) assert_equal(result['name'], "DUKE") assert_equal(result['supply'], 198742000000) - assert_equal(result['description'], "duke") + assert_equal(result['description'], "Duke's custom token") # invalid numtokens ask result = rpc.tokenask("-1", tokenid, "1") @@ -253,25 +274,25 @@ class CryptoConditionsTest (BitcoinTestFramework): result = rpc.tokenorders() assert_equal(result, []) - # invalid numtokens bid (have to add status to CC code!) + # invalid numtokens bid result = rpc.tokenbid("-1", tokenid, "1") - assert_equal(result['error'], 'invalid parameter') + assert_error(result); - # invalid numtokens bid (have to add status to CC code!) + # invalid numtokens bid result = rpc.tokenbid("0", tokenid, "1") - assert_equal(result['error'], 'invalid parameter') + assert_error(result); - # invalid price bid (have to add status to CC code!) + # invalid price bid result = rpc.tokenbid("1", tokenid, "-1") - assert_equal(result['error'], 'invalid parameter') + assert_error(result); - # invalid price bid (have to add status to CC code!) + # invalid price bid result = rpc.tokenbid("1", tokenid, "0") - assert_equal(result['error'], 'invalid parameter') + assert_error(result); - # invalid tokenid bid (have to add status to CC code!) + # invalid tokenid bid result = rpc.tokenbid("100", "deadbeef", "1") - assert_equal(result['error'], 'invalid parameter') + assert_error(result); # valid bid tokenbid = rpc.tokenbid("100", tokenid, "10") @@ -310,11 +331,11 @@ class CryptoConditionsTest (BitcoinTestFramework): # invalid token transfer amount (have to add status to CC code!) randompubkey = "021a559101e355c907d9c553671044d619769a6e71d624f68bfec7d0afa6bd6a96" result = rpc.tokentransfer(tokenid,randompubkey,"0") - assert_equal(result['error'], 'invalid parameter') + assert_error(result); # invalid token transfer amount (have to add status to CC code!) result = rpc.tokentransfer(tokenid,randompubkey,"-1") - assert_equal(result['error'], 'invalid parameter') + assert_error(result); # valid token transfer sendtokens = rpc.tokentransfer(tokenid,randompubkey,"1") diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 1012a0205..b99fffa59 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -55,6 +55,9 @@ std::string CCerror; // Private method: UniValue z_getoperationstatus_IMPL(const UniValue&, bool); +#define PLAN_NAME_MAX 8 +#define VALID_PLAN_NAME(x) (strlen(x) <= PLAN_NAME_MAX) + std::string HelpRequiringPassphrase() { return pwalletMain && pwalletMain->IsCrypted() @@ -5234,6 +5237,12 @@ UniValue dicefund(const UniValue& params, bool fHelp) maxbet = atof(params[3].get_str().c_str()) * COIN; maxodds = atol(params[4].get_str().c_str()); timeoutblocks = atol(params[5].get_str().c_str()); + + if (!VALID_PLAN_NAME(name)) { + ERR_RESULT(strprintf("Plan name can be at most %d ASCII characters",PLAN_NAME_MAX)); + return(result); + } + hex = DiceCreateFunding(0,name,funds,minbet,maxbet,maxodds,timeoutblocks); if (CCerror != "") { ERR_RESULT(CCerror); @@ -5258,6 +5267,10 @@ UniValue diceaddfunds(const UniValue& params, bool fHelp) name = (char *)params[0].get_str().c_str(); fundingtxid = Parseuint256((char *)params[1].get_str().c_str()); amount = atof(params[2].get_str().c_str()) * COIN; + if (!VALID_PLAN_NAME(name)) { + ERR_RESULT(strprintf("Plan name can be at most %d ASCII characters",PLAN_NAME_MAX)); + return(result); + } if ( amount > 0 ) { hex = DiceAddfunding(0,name,fundingtxid,amount); if (CCerror != "") { @@ -5283,6 +5296,11 @@ UniValue dicebet(const UniValue& params, bool fHelp) fundingtxid = Parseuint256((char *)params[1].get_str().c_str()); amount = atof(params[2].get_str().c_str()) * COIN; odds = atol(params[3].get_str().c_str()); + + if (!VALID_PLAN_NAME(name)) { + ERR_RESULT(strprintf("Plan name can be at most %d ASCII characters",PLAN_NAME_MAX)); + return(result); + } if (amount > 0 && odds > 0) { hex = DiceBet(0,name,fundingtxid,amount,odds); if ( hex.size() > 0 ) @@ -5306,6 +5324,10 @@ UniValue dicefinish(const UniValue& params, bool fHelp) const CKeyStore& keystore = *pwalletMain; LOCK2(cs_main, pwalletMain->cs_wallet); name = (char *)params[0].get_str().c_str(); + if (!VALID_PLAN_NAME(name)) { + ERR_RESULT(strprintf("Plan name can be at most %d ASCII characters",PLAN_NAME_MAX)); + return(result); + } fundingtxid = Parseuint256((char *)params[1].get_str().c_str()); bettxid = Parseuint256((char *)params[2].get_str().c_str()); hex = DiceBetFinish(&r,0,name,fundingtxid,bettxid,1); @@ -5330,6 +5352,10 @@ UniValue dicestatus(const UniValue& params, bool fHelp) const CKeyStore& keystore = *pwalletMain; LOCK2(cs_main, pwalletMain->cs_wallet); name = (char *)params[0].get_str().c_str(); + if (!VALID_PLAN_NAME(name)) { + ERR_RESULT(strprintf("Plan name can be at most %d ASCII characters",PLAN_NAME_MAX)); + return(result); + } fundingtxid = Parseuint256((char *)params[1].get_str().c_str()); memset(&bettxid,0,sizeof(bettxid)); if ( params.size() == 3 ) @@ -5453,9 +5479,14 @@ UniValue tokencreate(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); name = params[0].get_str(); supply = atof(params[1].get_str().c_str()) * COIN; - if ( name.size() == 0 || supply <= 0 ) + if ( name.size() == 0 || name.size() > 32) { - result.push_back(Pair("error", "invalid parameter")); + ERR_RESULT("Token name must not be empty and up to 32 characters"); + return(result); + } + if ( supply <= 0 ) + { + ERR_RESULT("Token supply must be positive"); return(result); } if ( params.size() == 3 ) @@ -5463,7 +5494,7 @@ UniValue tokencreate(const UniValue& params, bool fHelp) description = params[2].get_str(); if ( description.size() > 4096 ) { - result.push_back(Pair("error", "token description longer than 4096")); + ERR_RESULT("Token description must be <= 4096 characters"); return(result); } } @@ -5488,9 +5519,14 @@ UniValue tokentransfer(const UniValue& params, bool fHelp) tokenid = Parseuint256((char *)params[0].get_str().c_str()); std::vector pubkey(ParseHex(params[1].get_str().c_str())); amount = atol(params[2].get_str().c_str()); - if ( tokenid == zeroid || amount <= 0 ) + if ( tokenid == zeroid ) { - result.push_back(Pair("error", "invalid parameter")); + ERR_RESULT("invalid tokenid"); + return(result); + } + if ( amount <= 0 ) + { + ERR_RESULT("amount must be positive"); return(result); } hex = AssetTransfer(0,tokenid,pubkey,amount); @@ -5519,9 +5555,19 @@ UniValue tokenbid(const UniValue& params, bool fHelp) tokenid = Parseuint256((char *)params[1].get_str().c_str()); price = atof(params[2].get_str().c_str()); bidamount = (price * numtokens) * COIN + 0.0000000049999; - if ( tokenid == zeroid || tokenid == zeroid || price <= 0 || bidamount <= 0 ) + if ( price <= 0 ) { - result.push_back(Pair("error", "invalid parameter")); + ERR_RESULT("price must be positive"); + return(result); + } + if ( tokenid == zeroid ) + { + ERR_RESULT("invalid tokenid"); + return(result); + } + if ( bidamount <= 0 ) + { + ERR_RESULT("bid amount must be positive"); return(result); } hex = CreateBuyOffer(0,bidamount,tokenid,numtokens); @@ -5530,7 +5576,7 @@ UniValue tokenbid(const UniValue& params, bool fHelp) { result.push_back(Pair("result", "success")); result.push_back(Pair("hex", hex)); - } else result.push_back(Pair("error", "couldnt create bid")); + } else ERR_RESULT("couldnt create bid"); } else { ERR_RESULT("price and numtokens must be positive"); }