Merge branch 'master' of github.com:jedmccaleb/NewCoin

This commit is contained in:
Arthur Britto
2013-01-16 15:05:55 -08:00
14 changed files with 150 additions and 84 deletions

2
.gitignore vendored
View File

@@ -28,7 +28,7 @@ tmp
# Ignore database directory. # Ignore database directory.
db/*.db db/*.db
db/*.db-journal db/*.db-*
# Ignore obj files # Ignore obj files
Debug/*.* Debug/*.*

View File

@@ -1,6 +1,7 @@
#include <cmath> #include <cmath>
#include <iomanip> #include <iomanip>
#include <algorithm> #include <algorithm>
#include <limits.h>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <boost/algorithm/string/split.hpp> #include <boost/algorithm/string/split.hpp>
@@ -15,8 +16,16 @@
SETUP_LOG(); SETUP_LOG();
uint64 STAmount::uRateOne = STAmount::getRate(STAmount(1), STAmount(1)); uint64 STAmount::uRateOne = STAmount::getRate(STAmount(1), STAmount(1));
static const uint64_t tenTo14 = 100000000000000ul; static const uint64 tenTo14 = 100000000000000ull;
static const uint64_t tenTo17 = 100000000000000000ul; static const uint64 tenTo17 = tenTo14 * 1000;
#if (ULONG_MAX > UINT_MAX)
#define BN_add_word64(bn, word) BN_add_word(bn, word)
#define BN_mul_word64(bn, word) BN_mul_word(bn, word)
#define BN_div_word64(bn, word) BN_div_word(bn, word)
#else
#include "BigNum64.h"
#endif
bool STAmount::issuerFromString(uint160& uDstIssuer, const std::string& sIssuer) bool STAmount::issuerFromString(uint160& uDstIssuer, const std::string& sIssuer)
{ {
@@ -901,9 +910,9 @@ STAmount STAmount::divide(const STAmount& num, const STAmount& den, const uint16
// Compute (numerator * 10^17) / denominator // Compute (numerator * 10^17) / denominator
CBigNum v; CBigNum v;
if ((BN_add_word(&v, numVal) != 1) || if ((BN_add_word64(&v, numVal) != 1) ||
(BN_mul_word(&v, tenTo17) != 1) || (BN_mul_word64(&v, tenTo17) != 1) ||
(BN_div_word(&v, denVal) == ((BN_ULONG) -1))) (BN_div_word64(&v, denVal) == ((uint64) -1)))
{ {
throw std::runtime_error("internal bn error"); throw std::runtime_error("internal bn error");
} }
@@ -911,7 +920,7 @@ STAmount STAmount::divide(const STAmount& num, const STAmount& den, const uint16
// 10^16 <= quotient <= 10^18 // 10^16 <= quotient <= 10^18
assert(BN_num_bytes(&v) <= 64); assert(BN_num_bytes(&v) <= 64);
return STAmount(uCurrencyID, uIssuerID, v.getulong() + 5, return STAmount(uCurrencyID, uIssuerID, v.getuint64() + 5,
numOffset - denOffset - 17, num.mIsNegative != den.mIsNegative); numOffset - denOffset - 17, num.mIsNegative != den.mIsNegative);
} }
@@ -924,9 +933,9 @@ STAmount STAmount::multiply(const STAmount& v1, const STAmount& v2, const uint16
{ {
uint64 minV = (v1.getSNValue() < v2.getSNValue()) ? v1.getSNValue() : v2.getSNValue(); uint64 minV = (v1.getSNValue() < v2.getSNValue()) ? v1.getSNValue() : v2.getSNValue();
uint64 maxV = (v1.getSNValue() < v2.getSNValue()) ? v2.getSNValue() : v1.getSNValue(); uint64 maxV = (v1.getSNValue() < v2.getSNValue()) ? v2.getSNValue() : v1.getSNValue();
if (minV > 3000000000) // sqrt(cMaxNative) if (minV > 3000000000ull) // sqrt(cMaxNative)
throw std::runtime_error("Native value overflow"); throw std::runtime_error("Native value overflow");
if (((maxV >> 32) * minV) > 2095475792) // cMaxNative / 2^32 if (((maxV >> 32) * minV) > 2095475792ull) // cMaxNative / 2^32
throw std::runtime_error("Native value overflow"); throw std::runtime_error("Native value overflow");
return STAmount(v1.getFName(), minV * maxV); return STAmount(v1.getFName(), minV * maxV);
} }
@@ -955,9 +964,9 @@ STAmount STAmount::multiply(const STAmount& v1, const STAmount& v2, const uint16
// Compute (numerator * denominator) / 10^14 with rounding // Compute (numerator * denominator) / 10^14 with rounding
// 10^16 <= result <= 10^18 // 10^16 <= result <= 10^18
CBigNum v; CBigNum v;
if ((BN_add_word(&v, value1) != 1) || if ((BN_add_word64(&v, value1) != 1) ||
(BN_mul_word(&v, value2) != 1) || (BN_mul_word64(&v, value2) != 1) ||
(BN_div_word(&v, tenTo14) == ((BN_ULONG) -1))) (BN_div_word64(&v, tenTo14) == ((uint64) -1)))
{ {
throw std::runtime_error("internal bn error"); throw std::runtime_error("internal bn error");
} }
@@ -965,7 +974,7 @@ STAmount STAmount::multiply(const STAmount& v1, const STAmount& v2, const uint16
// 10^16 <= product <= 10^18 // 10^16 <= product <= 10^18
assert(BN_num_bytes(&v) <= 64); assert(BN_num_bytes(&v) <= 64);
return STAmount(uCurrencyID, uIssuerID, v.getulong() + 7, offset1 + offset2 + 14, return STAmount(uCurrencyID, uIssuerID, v.getuint64() + 7, offset1 + offset2 + 14,
v1.mIsNegative != v2.mIsNegative); v1.mIsNegative != v2.mIsNegative);
} }
@@ -1119,13 +1128,13 @@ uint64 STAmount::muldiv(uint64 a, uint64 b, uint64 c)
if ((a == 0) || (b == 0)) return 0; if ((a == 0) || (b == 0)) return 0;
CBigNum v; CBigNum v;
if ((BN_add_word(&v, a * 10 + 5) != 1) || if ((BN_add_word64(&v, a * 10 + 5) != 1) ||
(BN_mul_word(&v, b * 10 + 5) != 1) || (BN_mul_word64(&v, b * 10 + 5) != 1) ||
(BN_div_word(&v, c) == ((BN_ULONG) -1)) || (BN_div_word64(&v, c) == ((uint64) -1)) ||
(BN_div_word(&v, 100) == ((BN_ULONG) -1))) (BN_div_word64(&v, 100) == ((uint64) -1)))
throw std::runtime_error("muldiv error"); throw std::runtime_error("muldiv error");
return v.getulong(); return v.getuint64();
} }
uint64 STAmount::convertToDisplayAmount(const STAmount& internalAmount, uint64 totalNow, uint64 totalInit) uint64 STAmount::convertToDisplayAmount(const STAmount& internalAmount, uint64 totalNow, uint64 totalInit)
@@ -1239,7 +1248,6 @@ BOOST_AUTO_TEST_CASE( NativeCurrency_test )
{ {
STAmount zero, one(1), hundred(100); STAmount zero, one(1), hundred(100);
if (sizeof(BN_ULONG) < (64 / 8)) BOOST_FAIL("BN too small");
if (serdes(zero) != zero) BOOST_FAIL("STAmount fail"); if (serdes(zero) != zero) BOOST_FAIL("STAmount fail");
if (serdes(one) != one) BOOST_FAIL("STAmount fail"); if (serdes(one) != one) BOOST_FAIL("STAmount fail");
if (serdes(hundred) != hundred) BOOST_FAIL("STAmount fail"); if (serdes(hundred) != hundred) BOOST_FAIL("STAmount fail");
@@ -1385,13 +1393,13 @@ BOOST_AUTO_TEST_CASE( CustomCurrency_test )
if (STAmount(CURRENCY_ONE, ACCOUNT_ONE, 31,-2).getText() != "0.31") BOOST_FAIL("STAmount fail"); if (STAmount(CURRENCY_ONE, ACCOUNT_ONE, 31,-2).getText() != "0.31") BOOST_FAIL("STAmount fail");
if (STAmount::multiply(STAmount(CURRENCY_ONE, ACCOUNT_ONE, 20), STAmount(3), CURRENCY_ONE, ACCOUNT_ONE).getText() != "60") if (STAmount::multiply(STAmount(CURRENCY_ONE, ACCOUNT_ONE, 20), STAmount(3), CURRENCY_ONE, ACCOUNT_ONE).getText() != "60")
BOOST_FAIL("STAmount multiply fail"); BOOST_FAIL("STAmount multiply fail 1");
if (STAmount::multiply(STAmount(CURRENCY_ONE, ACCOUNT_ONE, 20), STAmount(3), uint160(), ACCOUNT_XRP).getText() != "60") if (STAmount::multiply(STAmount(CURRENCY_ONE, ACCOUNT_ONE, 20), STAmount(3), uint160(), ACCOUNT_XRP).getText() != "60")
BOOST_FAIL("STAmount multiply fail"); BOOST_FAIL("STAmount multiply fail 2");
if (STAmount::multiply(STAmount(20), STAmount(3), CURRENCY_ONE, ACCOUNT_ONE).getText() != "60") if (STAmount::multiply(STAmount(20), STAmount(3), CURRENCY_ONE, ACCOUNT_ONE).getText() != "60")
BOOST_FAIL("STAmount multiply fail"); BOOST_FAIL("STAmount multiply fail 3");
if (STAmount::multiply(STAmount(20), STAmount(3), uint160(), ACCOUNT_XRP).getText() != "60") if (STAmount::multiply(STAmount(20), STAmount(3), uint160(), ACCOUNT_XRP).getText() != "60")
BOOST_FAIL("STAmount multiply fail"); BOOST_FAIL("STAmount multiply fail 4");
if (STAmount::divide(STAmount(CURRENCY_ONE, ACCOUNT_ONE, 60), STAmount(3), CURRENCY_ONE, ACCOUNT_ONE).getText() != "20") if (STAmount::divide(STAmount(CURRENCY_ONE, ACCOUNT_ONE, 60), STAmount(3), CURRENCY_ONE, ACCOUNT_ONE).getText() != "20")
{ {
cLog(lsFATAL) << "60/3 = " << cLog(lsFATAL) << "60/3 = " <<
@@ -1466,25 +1474,39 @@ static void mulTest(int a, int b)
BOOST_AUTO_TEST_CASE( CurrencyMulDivTests ) BOOST_AUTO_TEST_CASE( CurrencyMulDivTests )
{ {
CBigNum b;
for (int i = 0; i < 16; ++i)
{
uint64 r = rand();
r <<= 32;
r |= rand();
b.setuint64(r);
if (b.getuint64() != r)
{
cLog(lsFATAL) << r << " != " << b.getuint64() << " " << b.ToString(16);
BOOST_FAIL("setull64/getull64 failure");
}
}
// Test currency multiplication and division operations such as // Test currency multiplication and division operations such as
// convertToDisplayAmount, convertToInternalAmount, getRate, getClaimed, and getNeeded // convertToDisplayAmount, convertToInternalAmount, getRate, getClaimed, and getNeeded
if (STAmount::getRate(STAmount(1), STAmount(10)) != (((100ul-14)<<(64-8))|1000000000000000ul)) if (STAmount::getRate(STAmount(1), STAmount(10)) != (((100ull-14)<<(64-8))|1000000000000000ull))
BOOST_FAIL("STAmount getRate fail"); BOOST_FAIL("STAmount getRate fail 1");
if (STAmount::getRate(STAmount(10), STAmount(1)) != (((100ul-16)<<(64-8))|1000000000000000ul)) if (STAmount::getRate(STAmount(10), STAmount(1)) != (((100ull-16)<<(64-8))|1000000000000000ull))
BOOST_FAIL("STAmount getRate fail"); BOOST_FAIL("STAmount getRate fail 2");
if (STAmount::getRate(STAmount(CURRENCY_ONE, ACCOUNT_ONE, 1), STAmount(CURRENCY_ONE, ACCOUNT_ONE, 10)) != (((100ul-14)<<(64-8))|1000000000000000ul)) if (STAmount::getRate(STAmount(CURRENCY_ONE, ACCOUNT_ONE, 1), STAmount(CURRENCY_ONE, ACCOUNT_ONE, 10)) != (((100ull-14)<<(64-8))|1000000000000000ull))
BOOST_FAIL("STAmount getRate fail"); BOOST_FAIL("STAmount getRate fail 3");
if (STAmount::getRate(STAmount(CURRENCY_ONE, ACCOUNT_ONE, 10), STAmount(CURRENCY_ONE, ACCOUNT_ONE, 1)) != (((100ul-16)<<(64-8))|1000000000000000ul)) if (STAmount::getRate(STAmount(CURRENCY_ONE, ACCOUNT_ONE, 10), STAmount(CURRENCY_ONE, ACCOUNT_ONE, 1)) != (((100ull-16)<<(64-8))|1000000000000000ull))
BOOST_FAIL("STAmount getRate fail"); BOOST_FAIL("STAmount getRate fail 4");
if (STAmount::getRate(STAmount(CURRENCY_ONE, ACCOUNT_ONE, 1), STAmount(10)) != (((100ul-14)<<(64-8))|1000000000000000ul)) if (STAmount::getRate(STAmount(CURRENCY_ONE, ACCOUNT_ONE, 1), STAmount(10)) != (((100ull-14)<<(64-8))|1000000000000000ull))
BOOST_FAIL("STAmount getRate fail"); BOOST_FAIL("STAmount getRate fail 5");
if (STAmount::getRate(STAmount(CURRENCY_ONE, ACCOUNT_ONE, 10), STAmount(1)) != (((100ul-16)<<(64-8))|1000000000000000ul)) if (STAmount::getRate(STAmount(CURRENCY_ONE, ACCOUNT_ONE, 10), STAmount(1)) != (((100ull-16)<<(64-8))|1000000000000000ull))
BOOST_FAIL("STAmount getRate fail"); BOOST_FAIL("STAmount getRate fail 6");
if (STAmount::getRate(STAmount(1), STAmount(CURRENCY_ONE, ACCOUNT_ONE, 10)) != (((100ul-14)<<(64-8))|1000000000000000ul)) if (STAmount::getRate(STAmount(1), STAmount(CURRENCY_ONE, ACCOUNT_ONE, 10)) != (((100ull-14)<<(64-8))|1000000000000000ull))
BOOST_FAIL("STAmount getRate fail"); BOOST_FAIL("STAmount getRate fail 7");
if (STAmount::getRate(STAmount(10), STAmount(CURRENCY_ONE, ACCOUNT_ONE, 1)) != (((100ul-16)<<(64-8))|1000000000000000ul)) if (STAmount::getRate(STAmount(10), STAmount(CURRENCY_ONE, ACCOUNT_ONE, 1)) != (((100ull-16)<<(64-8))|1000000000000000ull))
BOOST_FAIL("STAmount getRate fail"); BOOST_FAIL("STAmount getRate fail 8");
roundTest(1, 3, 3); roundTest(2, 3, 9); roundTest(1, 7, 21); roundTest(1, 2, 4); roundTest(1, 3, 3); roundTest(2, 3, 9); roundTest(1, 7, 21); roundTest(1, 2, 4);
roundTest(3, 9, 18); roundTest(7, 11, 44); roundTest(3, 9, 18); roundTest(7, 11, 44);

22
src/cpp/ripple/BigNum64.h Normal file
View File

@@ -0,0 +1,22 @@
// Support 64-bit word operations on 32-bit platforms
static int BN_add_word64(BIGNUM *a, uint64 w)
{
CBigNum bn(w);
return BN_add(a, &bn, a);
}
static int BN_mul_word64(BIGNUM *a, uint64 w)
{
CBigNum bn(w);
CAutoBN_CTX ctx;
return BN_mul(a, &bn, a, ctx);
}
static uint64 BN_div_word64(BIGNUM *a, uint64 w)
{
CBigNum bn(w);
CAutoBN_CTX ctx;
return (BN_div(a, NULL, a, &bn, ctx) == 1) ? 0 : ((uint64)-1);
}

View File

@@ -539,7 +539,7 @@ Json::Value RPCParser::parseCommand(std::string strMethod, Json::Value jvParams)
if (i < 0) if (i < 0)
{ {
return rpcError(rpcBAD_SYNTAX); return rpcError(rpcUNKNOWN_COMMAND);
} }
else if ((commandsA[i].iMinParams >= 0 && jvParams.size() < commandsA[i].iMinParams) else if ((commandsA[i].iMinParams >= 0 && jvParams.size() < commandsA[i].iMinParams)
|| (commandsA[i].iMaxParams >= 0 && jvParams.size() > commandsA[i].iMaxParams)) || (commandsA[i].iMaxParams >= 0 && jvParams.size() > commandsA[i].iMaxParams))

View File

@@ -64,7 +64,7 @@ Json::Value rpcError(int iError, Json::Value jvResult)
{ rpcSRC_ISR_MALFORMED, "srcIsrMalformed", "Source issuer is malformed." }, { rpcSRC_ISR_MALFORMED, "srcIsrMalformed", "Source issuer is malformed." },
{ rpcSRC_UNCLAIMED, "srcUnclaimed", "Source account is not claimed." }, { rpcSRC_UNCLAIMED, "srcUnclaimed", "Source account is not claimed." },
{ rpcTXN_NOT_FOUND, "txnNotFound", "Transaction not found." }, { rpcTXN_NOT_FOUND, "txnNotFound", "Transaction not found." },
{ rpcUNKNOWN_COMMAND, "unknownCmd", "Unknown command." }, { rpcUNKNOWN_COMMAND, "unknownCmd", "Unknown method." },
{ rpcWRONG_SEED, "wrongSeed", "The regular key does not point as the master key." }, { rpcWRONG_SEED, "wrongSeed", "The regular key does not point as the master key." },
}; };

View File

@@ -3,7 +3,7 @@
SETUP_LOG(); SETUP_LOG();
uint64_t RegularKeySetTransactor::calculateBaseFee() uint64 RegularKeySetTransactor::calculateBaseFee()
{ {
if ( !(mTxnAccount->getFlags() & lsfPasswordSpent) if ( !(mTxnAccount->getFlags() & lsfPasswordSpent)
&& (mSigningPubKey.getAccountID() == mTxnAccountID)) && (mSigningPubKey.getAccountID() == mTxnAccountID))

View File

@@ -2,7 +2,7 @@
class RegularKeySetTransactor : public Transactor class RegularKeySetTransactor : public Transactor
{ {
uint64_t calculateBaseFee(); uint64 calculateBaseFee();
public: public:
RegularKeySetTransactor(const SerializedTransaction& txn,TransactionEngineParams params, TransactionEngine* engine) : Transactor(txn,params,engine) {} RegularKeySetTransactor(const SerializedTransaction& txn,TransactionEngineParams params, TransactionEngine* engine) : Transactor(txn,params,engine) {}
TER checkFee(); TER checkFee();

View File

@@ -1039,7 +1039,7 @@ std::auto_ptr<STObject> STObject::parseJson(const Json::Value& object, SField::r
if (value.isString()) if (value.isString())
data.push_back(new STUInt32(field, lexical_cast_st<uint32>(value.asString()))); data.push_back(new STUInt32(field, lexical_cast_st<uint32>(value.asString())));
else if (value.isInt()) else if (value.isInt())
data.push_back(new STUInt32(field, range_check_cast<uint32>(value.asInt(), 0, 4294967295))); data.push_back(new STUInt32(field, range_check_cast<uint32>(value.asInt(), 0, 4294967295u)));
else if (value.isUInt()) else if (value.isUInt())
data.push_back(new STUInt32(field, static_cast<uint32>(value.asUInt()))); data.push_back(new STUInt32(field, static_cast<uint32>(value.asUInt())));
else else

View File

@@ -45,7 +45,7 @@ void Transactor::calculateFee()
mFeeDue = STAmount(mEngine->getLedger()->scaleFeeLoad(calculateBaseFee())); mFeeDue = STAmount(mEngine->getLedger()->scaleFeeLoad(calculateBaseFee()));
} }
uint64_t Transactor::calculateBaseFee() uint64 Transactor::calculateBaseFee()
{ {
return theConfig.FEE_DEFAULT; return theConfig.FEE_DEFAULT;
} }

View File

@@ -27,7 +27,7 @@ protected:
void calculateFee(); void calculateFee();
// Returns the fee, not scaled for load (Should be in fee units. FIXME) // Returns the fee, not scaled for load (Should be in fee units. FIXME)
virtual uint64_t calculateBaseFee(); virtual uint64 calculateBaseFee();
virtual TER checkSig(); virtual TER checkSig();
virtual TER doApply()=0; virtual TER doApply()=0;

View File

@@ -51,7 +51,7 @@ inline std::string EncodeBase58(const unsigned char* pbegin, const unsigned char
if (!BN_div(&dv, &rem, &bn, &bn58, pctx)) if (!BN_div(&dv, &rem, &bn, &bn58, pctx))
throw bignum_error("EncodeBase58 : BN_div failed"); throw bignum_error("EncodeBase58 : BN_div failed");
bn = dv; bn = dv;
unsigned int c = rem.getulong(); unsigned int c = rem.getuint();
str += ALPHABET[c]; str += ALPHABET[c];
} }
@@ -91,7 +91,7 @@ inline bool DecodeBase58(const char* psz, std::vector<unsigned char>& vchRet)
return false; return false;
break; break;
} }
bnChar.setulong(p1 - ALPHABET); bnChar.setuint(p1 - ALPHABET);
if (!BN_mul(&bn, &bn, &bn58, pctx)) if (!BN_mul(&bn, &bn, &bn58, pctx))
throw bignum_error("DecodeBase58 : BN_mul failed"); throw bignum_error("DecodeBase58 : BN_mul failed");
bn += bnChar; bn += bnChar;

View File

@@ -89,7 +89,6 @@ public:
CBigNum(unsigned char n) { BN_init(this); setulong(n); } CBigNum(unsigned char n) { BN_init(this); setulong(n); }
CBigNum(unsigned short n) { BN_init(this); setulong(n); } CBigNum(unsigned short n) { BN_init(this); setulong(n); }
CBigNum(unsigned int n) { BN_init(this); setulong(n); } CBigNum(unsigned int n) { BN_init(this); setulong(n); }
CBigNum(unsigned long n) { BN_init(this); setulong(n); }
CBigNum(uint64 n) { BN_init(this); setuint64(n); } CBigNum(uint64 n) { BN_init(this); setuint64(n); }
explicit CBigNum(uint256 n) { BN_init(this); setuint256(n); } explicit CBigNum(uint256 n) { BN_init(this); setuint256(n); }
@@ -99,15 +98,9 @@ public:
setvch(vch); setvch(vch);
} }
void setulong(unsigned long n) void setuint(unsigned int n)
{ {
if (!BN_set_word(this, n)) setulong(static_cast<unsigned long>(n));
throw bignum_error("CBigNum conversion from unsigned long : BN_set_word failed");
}
unsigned long getulong() const
{
return BN_get_word(this);
} }
unsigned int getuint() const unsigned int getuint() const
@@ -159,31 +152,42 @@ public:
BN_mpi2bn(pch, p - pch, this); BN_mpi2bn(pch, p - pch, this);
} }
uint64 getuint64() const
{
#if (ULONG_MAX > UINT_MAX)
return static_cast<uint64>(getulong());
#else
int len = BN_num_bytes(this);
if (len > 8)
throw std::runtime_error("BN getuint64 overflow");
unsigned char buf[8];
memset(buf, 0, sizeof(buf));
BN_bn2bin(this, buf + 8 - len);
return
static_cast<uint64>(buf[0]) << 56 | static_cast<uint64>(buf[1]) << 48 |
static_cast<uint64>(buf[2]) << 40 | static_cast<uint64>(buf[3]) << 32 |
static_cast<uint64>(buf[4]) << 24 | static_cast<uint64>(buf[5]) << 16 |
static_cast<uint64>(buf[6]) << 8 | static_cast<uint64>(buf[7]);
#endif
}
void setuint64(uint64 n) void setuint64(uint64 n)
{ {
unsigned char pch[sizeof(n) + 6]; #if (ULONG_MAX > UINT_MAX)
unsigned char* p = pch + 4; setulong(static_cast<unsigned long>(n));
bool fLeadingZeroes = true; #else
for (int i = 0; i < 8; i++) unsigned char buf[8];
{ buf[0] = static_cast<unsigned char>((n >> 56) & 0xff);
unsigned char c = (n >> 56) & 0xff; buf[1] = static_cast<unsigned char>((n >> 48) & 0xff);
n <<= 8; buf[2] = static_cast<unsigned char>((n >> 40) & 0xff);
if (fLeadingZeroes) buf[3] = static_cast<unsigned char>((n >> 32) & 0xff);
{ buf[4] = static_cast<unsigned char>((n >> 24) & 0xff);
if (c == 0) buf[5] = static_cast<unsigned char>((n >> 16) & 0xff);
continue; buf[6] = static_cast<unsigned char>((n >> 8) & 0xff);
if (c & 0x80) buf[7] = static_cast<unsigned char>((n) & 0xff);
*p++ = 0; BN_bin2bn(buf, 8, this);
fLeadingZeroes = false; #endif
}
*p++ = c;
}
unsigned int nSize = p - (pch + 4);
pch[0] = (nSize >> 24) & 0xff;
pch[1] = (nSize >> 16) & 0xff;
pch[2] = (nSize >> 8) & 0xff;
pch[3] = (nSize) & 0xff;
BN_mpi2bn(pch, p - pch, this);
} }
void setuint256(const uint256& n) void setuint256(const uint256& n)
@@ -300,7 +304,7 @@ public:
if (!BN_div(&dv, &rem, &bn, &bnBase, pctx)) if (!BN_div(&dv, &rem, &bn, &bnBase, pctx))
throw bignum_error("CBigNum::ToString() : BN_div failed"); throw bignum_error("CBigNum::ToString() : BN_div failed");
bn = dv; bn = dv;
unsigned int c = rem.getulong(); unsigned int c = rem.getuint();
str += "0123456789abcdef"[c]; str += "0123456789abcdef"[c];
} }
if (BN_is_negative(this)) if (BN_is_negative(this))
@@ -435,6 +439,22 @@ public:
friend inline const CBigNum operator-(const CBigNum& a, const CBigNum& b); friend inline const CBigNum operator-(const CBigNum& a, const CBigNum& b);
friend inline const CBigNum operator/(const CBigNum& a, const CBigNum& b); friend inline const CBigNum operator/(const CBigNum& a, const CBigNum& b);
friend inline const CBigNum operator%(const CBigNum& a, const CBigNum& b); friend inline const CBigNum operator%(const CBigNum& a, const CBigNum& b);
private:
// private because the size of an unsigned long varies by platform
void setulong(unsigned long n)
{
if (!BN_set_word(this, n))
throw bignum_error("CBigNum conversion from unsigned long : BN_set_word failed");
}
unsigned long getulong() const
{
return BN_get_word(this);
}
}; };

View File

@@ -73,7 +73,7 @@ public:
zero(); zero();
// Put in least significant bits. // Put in least significant bits.
((uint64_t *) end())[-1] = htobe64(uHost); ((uint64*) end())[-1] = htobe64(uHost);
return *this; return *this;
} }
@@ -438,7 +438,7 @@ public:
zero(); zero();
// Put in least significant bits. // Put in least significant bits.
((uint64_t *) end())[-1] = htobe64(uHost); ((uint64*) end())[-1] = htobe64(uHost);
return *this; return *this;
} }
@@ -656,7 +656,7 @@ public:
zero(); zero();
// Put in least significant bits. // Put in least significant bits.
((uint64_t *) end())[-1] = htobe64(uHost); ((uint64*) end())[-1] = htobe64(uHost);
return *this; return *this;
} }

View File

@@ -778,6 +778,7 @@ Amount.prototype.ratio_human = function (denominator) {
if (denominator._is_native) { if (denominator._is_native) {
numerator = numerator.clone(); numerator = numerator.clone();
numerator._value = numerator._value.multiply(consts.bi_xns_unit); numerator._value = numerator._value.multiply(consts.bi_xns_unit);
numerator.canonicalize();
} }
return numerator.divide(denominator); return numerator.divide(denominator);
@@ -812,6 +813,7 @@ Amount.prototype.product_human = function (factor) {
// See also Amount#ratio_human. // See also Amount#ratio_human.
if (factor._is_native) { if (factor._is_native) {
product._value = product._value.divide(consts.bi_xns_unit); product._value = product._value.divide(consts.bi_xns_unit);
product.canonicalize();
} }
return product; return product;