Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ BITCOIN_CORE_H = \
compat.h \
core.h \
mastercore.h \
mastercore_parse_string.h \
mastercore_tx.h \
mastercore_dex.h \
mastercore_sp.h \
Expand Down Expand Up @@ -131,6 +132,7 @@ libbitcoin_common_a_SOURCES = \
chainparams.cpp \
core.cpp \
mastercore.cpp \
mastercore_parse_string.cpp \
mastercore_tx.cpp \
mastercore_rpc.cpp \
mastercore_dex.cpp \
Expand Down
50 changes: 0 additions & 50 deletions src/mastercore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -328,56 +328,6 @@ std::string FormatMP(unsigned int property, int64_t n, bool fSign)
else return FormatIndivisibleMP(n);
}

int64_t mastercore::strToInt64(std::string strAmount, bool divisible)
{
int64_t Amount = 0;

//check for a negative (minus sign) and invalidate if present
size_t negSignPos = strAmount.find("-");
if (negSignPos!=std::string::npos) return 0;

//convert the string into a usable int64
if (divisible)
{
//check for existance of decimal point
size_t pos = strAmount.find(".");
if (pos==std::string::npos)
{ //no decimal point but divisible so pad 8 zeros on right
strAmount+="00000000";
}
else
{
size_t posSecond = strAmount.find(".", pos+1); //check for existence of second decimal point, if so invalidate amount
if (posSecond!=std::string::npos) return 0;
if ((strAmount.size()-pos)<9)
{ //there are decimals either exact or not enough, pad as needed
string strRightOfDecimal = strAmount.substr(pos+1);
unsigned int zerosToPad = 8-strRightOfDecimal.size();
if (zerosToPad>0) //do we need to pad?
{
for(unsigned int it = 0; it != zerosToPad; it++)
{
strAmount+="0";
}
}
}
else
{ //there are too many decimals, truncate after 8
strAmount = strAmount.substr(0,pos+9);
}
}
strAmount.erase(std::remove(strAmount.begin(), strAmount.end(), '.'), strAmount.end());
try { Amount = boost::lexical_cast<int64_t>(strAmount); } catch(const boost::bad_lexical_cast &e) { }
}
else
{
size_t pos = strAmount.find(".");
string newStrAmount = strAmount.substr(0,pos);
try { Amount = boost::lexical_cast<int64_t>(newStrAmount); } catch(const boost::bad_lexical_cast &e) { }
}
return Amount;
}

string const CMPSPInfo::watermarkKey("watermark");

CCriticalSection cs_tally;
Expand Down
1 change: 0 additions & 1 deletion src/mastercore.h
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,6 @@ uint256 send_INTERNAL_1packet(const string &FromAddress, const string &ToAddress
unsigned int TransactionType, int64_t additional, int *error_code = NULL);

bool isTestEcosystemProperty(unsigned int property);
int64_t strToInt64(std::string strAmount, bool divisible);

CMPTally *getTally(const string & address);

Expand Down
64 changes: 64 additions & 0 deletions src/mastercore_parse_string.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#include "mastercore_parse_string.h"

#include <stdint.h>
#include <algorithm>
#include <string>

#include <boost/lexical_cast.hpp>

namespace mastercore
{
int64_t StrToInt64(const std::string& str, bool divisible)
{
// copy original, so it remains unchanged
std::string strAmount (str);
int64_t nAmount = 0;

// check for a negative (minus sign) and invalidate if present
size_t negSignPos = strAmount.find("-");
if (negSignPos != std::string::npos) return 0;

// convert the string into a usable int64
if (divisible) {
// check for existance of decimal point
size_t pos = strAmount.find(".");
if (pos == std::string::npos) {
// no decimal point but divisible so pad 8 zeros on right
strAmount += "00000000";
} else {
// check for existence of second decimal point, if so invalidate amount
size_t posSecond = strAmount.find(".", pos + 1);
if (posSecond != std::string::npos) return 0;

if ((strAmount.size() - pos) < 9) {
// there are decimals either exact or not enough, pad as needed
std::string strRightOfDecimal = strAmount.substr(pos + 1);
unsigned int zerosToPad = 8 - strRightOfDecimal.size();

// do we need to pad?
if (zerosToPad > 0)
{
for (unsigned int it = 0; it != zerosToPad; it++) {
strAmount += "0";
}
}
} else {
// there are too many decimals, truncate after 8
strAmount = strAmount.substr(0, pos + 9);
}
}
strAmount.erase(std::remove(strAmount.begin(), strAmount.end(), '.'), strAmount.end());
try {
nAmount = boost::lexical_cast<int64_t>(strAmount);
} catch (const boost::bad_lexical_cast &e) {}
} else {
size_t pos = strAmount.find(".");
std::string newStrAmount = strAmount.substr(0, pos);
try {
nAmount = boost::lexical_cast<int64_t>(newStrAmount);
} catch (const boost::bad_lexical_cast &e) {}
}

return nAmount;
}
} // namespace mastercore
20 changes: 20 additions & 0 deletions src/mastercore_parse_string.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef _MASTERCOIN_PARSE_STRING
#define _MASTERCOIN_PARSE_STRING

#include <stdint.h>
#include <string>

namespace mastercore
{
// Converts strings to 64 bit wide interger.
// Divisible and indivisible amounts are accepted.
// 1 indivisible unit equals 0.00000001 divisible units.
// If input string is not a accepted number, 0 is returned.
// Divisible amounts are truncated after 8 decimal places.
// Characters after decimal mark are ignored for indivisible
// amounts.
// Any minus sign invalidates.
int64_t StrToInt64(const std::string& str, bool divisible);
}

#endif // _MASTERCOIN_PARSE_STRRING
13 changes: 7 additions & 6 deletions src/mastercore_rpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ using namespace json_spirit;
using namespace mastercore;

#include "mastercore_dex.h"
#include "mastercore_parse_string.h"
#include "mastercore_tx.h"
#include "mastercore_sp.h"
#include "mastercore_errors.h"
Expand Down Expand Up @@ -221,13 +222,13 @@ if (fHelp || params.size() < 4 || params.size() > 6)

string strAmount = params[3].get_str();
int64_t Amount = 0, additional = 0;
Amount = strToInt64(strAmount, divisible);
Amount = StrToInt64(strAmount, divisible);

if (0 >= Amount)
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount");

std::string strAdditional = (params.size() > 5) ? (params[5].get_str()): "0";
additional = strToInt64(strAdditional, true);
additional = StrToInt64(strAdditional, true);

int n = params.size();
printf("#: %d, additional= %ld\n", n, additional);
Expand Down Expand Up @@ -284,7 +285,7 @@ if (fHelp || params.size() < 3 || params.size() > 4)

string strAmount = params[2].get_str();
int64_t Amount = 0;
Amount = strToInt64(strAmount, divisible);
Amount = StrToInt64(strAmount, divisible);

if (0 >= Amount)
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount");
Expand Down Expand Up @@ -328,7 +329,7 @@ if (fHelp || params.size() < 2 || params.size() > 5)
int64_t referenceAmount = 0;

if (params.size() > 4)
referenceAmount = strToInt64(params[4].get_str(), true);
referenceAmount = StrToInt64(params[4].get_str(), true);

//some sanity checking of the data supplied?
uint256 newTX;
Expand Down Expand Up @@ -1092,11 +1093,11 @@ Value trade_MP(const Array& params, bool fHelp) {

std::string strAmountSale = params[1].get_str();
int64_t Amount_Sale = 0;
Amount_Sale = strToInt64(strAmountSale, divisible_sale);
Amount_Sale = StrToInt64(strAmountSale, divisible_sale);

std::string strAmountWant = params[3].get_str();
int64_t Amount_Want = 0;
Amount_Want = strToInt64(strAmountWant, divisible_want);
Amount_Want = StrToInt64(strAmountWant, divisible_want);

if (0 >= Amount_Sale)
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount (Sale)");
Expand Down
3 changes: 2 additions & 1 deletion src/qt/sendmpdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ using namespace leveldb;
// end potentially overzealous using

#include "mastercore_dex.h"
#include "mastercore_parse_string.h"
#include "mastercore_tx.h"
#include "mastercore_sp.h"

Expand Down Expand Up @@ -292,7 +293,7 @@ void SendMPDialog::sendMPTransaction()
}

// use strToInt64 function to get the amount, using divisibility of the property
int64_t sendAmount = strToInt64(strAmount, divisible);
int64_t sendAmount = StrToInt64(strAmount, divisible);
if (0>=sendAmount)
{
QMessageBox::critical( this, "Unable to send transaction",
Expand Down
1 change: 1 addition & 0 deletions src/test/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ test_bitcoin_SOURCES = \
getarg_tests.cpp \
key_tests.cpp \
main_tests.cpp \
mastercore_strtoint64_tests.cpp \
miner_tests.cpp \
mruset_tests.cpp \
multisig_tests.cpp \
Expand Down
77 changes: 77 additions & 0 deletions src/test/mastercore_strtoint64_tests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#include "mastercore_parse_string.h"

#include <string>

#include <boost/test/unit_test.hpp>

using namespace mastercore;

BOOST_AUTO_TEST_SUITE(mastercore_strtoint64_tests)

BOOST_AUTO_TEST_CASE(mastercore_strtoint64_invidisible)
{
// zero amount
BOOST_CHECK(StrToInt64("0", false) == 0);
// big num
BOOST_CHECK(StrToInt64("4000000000000000", false) == 4000000000000000);
// max int64
BOOST_CHECK(StrToInt64("9223372036854775807", false) == 9223372036854775807);
}

BOOST_AUTO_TEST_CASE(mastercore_strtoint64_invidisible_truncate)
{
// ignore any char after decimal mark
BOOST_CHECK(StrToInt64("8.76543210123456878901", false) == 8);
BOOST_CHECK(StrToInt64("8.765432101.2345687890", false) == 8);
BOOST_CHECK(StrToInt64("2345.AbCdEhf71z1.23", false) == 2345);
}

BOOST_AUTO_TEST_CASE(mastercore_strtoint64_invidisible_invalid)
{
// invalid, number is negative
BOOST_CHECK(StrToInt64("-4", false) == 0);
// invalid, number is over max int64
BOOST_CHECK(StrToInt64("9223372036854775808", false) == 0);
// invalid, minus sign in string
BOOST_CHECK(StrToInt64("2345.AbCdEFG71z88-1.23", false) == 0);
}

BOOST_AUTO_TEST_CASE(mastercore_strtoint64_divisible)
{
// range 0 to max int64
BOOST_CHECK(StrToInt64("0.000", true) == 0);
BOOST_CHECK(StrToInt64("92233720368.54775807", true) == 9223372036854775807);
// check padding
BOOST_CHECK(StrToInt64("0.00000004", true) == 4);
BOOST_CHECK(StrToInt64("0.0000004", true) == 40);
BOOST_CHECK(StrToInt64("0.0004", true) == 40000);
BOOST_CHECK(StrToInt64("0.4", true) == 40000000);
BOOST_CHECK(StrToInt64("4.0", true) == 400000000);
// truncate after 8 digits
BOOST_CHECK(StrToInt64("40.00000000000099", true) == 4000000000);
BOOST_CHECK(StrToInt64("92233720368.54775807000", true) == 9223372036854775807);
}

BOOST_AUTO_TEST_CASE(mastercore_strtoint64_divisible_truncate)
{
// truncate after 8 digits
BOOST_CHECK(StrToInt64("40.00000000000099", true) == 4000000000);
BOOST_CHECK(StrToInt64("92233720368.54775807000", true) == 9223372036854775807);
BOOST_CHECK(StrToInt64("92233720368.54775807000", true) == 9223372036854775807);
}

BOOST_AUTO_TEST_CASE(mastercore_strtoint64_divisible_invalid)
{
// invalid, number is over max int64
BOOST_CHECK(StrToInt64("92233720368.54775808", true) == 0);
// invalid, more than one decimal mark in string
BOOST_CHECK(StrToInt64("1234..12345678", true) == 0);
// invalid, alpha chars in string
BOOST_CHECK(StrToInt64("1234.12345A", true) == 0);
// invalid, number is negative
BOOST_CHECK(StrToInt64("-4.0", true) == 0);
// invalid, minus sign in string
BOOST_CHECK(StrToInt64("4.1234-5678", true) == 0);
}

BOOST_AUTO_TEST_SUITE_END()
Loading