mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-27 14:35:52 +00:00
Merge branch 'master' of github.com:jedmccaleb/NewCoin
This commit is contained in:
10
.dir-locals.el
Normal file
10
.dir-locals.el
Normal file
@@ -0,0 +1,10 @@
|
||||
;; Emacs - Code style and formatting settings
|
||||
|
||||
;; C++
|
||||
((c++-mode
|
||||
(indent-tabs-mode . t)
|
||||
(tab-width . 4)
|
||||
(c-basic-offset . 4)))
|
||||
|
||||
;; Headers should open in C++ mode
|
||||
((c-mode . ((mode . c++))))
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -25,6 +25,8 @@ tmp
|
||||
|
||||
# Ignore database directory.
|
||||
db/*.db
|
||||
db/*.db-journal
|
||||
|
||||
# Ignore customized test/config.js
|
||||
# Ignore customized configs
|
||||
rippled.cfg
|
||||
test/config.js
|
||||
|
||||
@@ -38,7 +38,7 @@ DatabaseCon::~DatabaseCon()
|
||||
}
|
||||
|
||||
Application::Application() :
|
||||
mIOWork(mIOService), mAuxWork(mAuxService), mUNL(mIOService), mNetOps(mIOService, &mMasterLedger),
|
||||
mIOWork(mIOService), mAuxWork(mAuxService), mUNL(mIOService), mNetOps(mIOService, &mLedgerMaster),
|
||||
mTempNodeCache("NodeCache", 16384, 90), mHashedObjectStore(16384, 300),
|
||||
mSNTPClient(mAuxService), mRPCHandler(&mNetOps),
|
||||
mRpcDB(NULL), mTxnDB(NULL), mLedgerDB(NULL), mWalletDB(NULL), mHashNodeDB(NULL), mNetNodeDB(NULL),
|
||||
@@ -122,7 +122,7 @@ void Application::run()
|
||||
{
|
||||
Ledger::pointer ledger = Ledger::getLastFullLedger();
|
||||
if (ledger)
|
||||
mMasterLedger.setLedgerRangePresent(0, ledger->getLedgerSeq());
|
||||
mLedgerMaster.setLedgerRangePresent(0, ledger->getLedgerSeq());
|
||||
}
|
||||
|
||||
//
|
||||
@@ -216,7 +216,7 @@ void Application::sweep()
|
||||
{
|
||||
mMasterTransaction.sweep();
|
||||
mHashedObjectStore.sweep();
|
||||
mMasterLedger.sweep();
|
||||
mLedgerMaster.sweep();
|
||||
mTempNodeCache.sweep();
|
||||
mValidations.sweep();
|
||||
mSweepTimer.expires_from_now(boost::posix_time::seconds(60));
|
||||
@@ -249,12 +249,12 @@ void Application::startNewLedger()
|
||||
firstLedger->updateHash();
|
||||
firstLedger->setClosed();
|
||||
firstLedger->setAccepted();
|
||||
mMasterLedger.pushLedger(firstLedger);
|
||||
mLedgerMaster.pushLedger(firstLedger);
|
||||
|
||||
Ledger::pointer secondLedger = boost::make_shared<Ledger>(true, boost::ref(*firstLedger));
|
||||
secondLedger->setClosed();
|
||||
secondLedger->setAccepted();
|
||||
mMasterLedger.pushLedger(secondLedger, boost::make_shared<Ledger>(true, boost::ref(*secondLedger)), false);
|
||||
mLedgerMaster.pushLedger(secondLedger, boost::make_shared<Ledger>(true, boost::ref(*secondLedger)), false);
|
||||
assert(!!secondLedger->getAccountState(rootAddress));
|
||||
mNetOps.setLastCloseTime(secondLedger->getCloseTimeNC());
|
||||
}
|
||||
@@ -293,10 +293,10 @@ void Application::loadOldLedger()
|
||||
cLog(lsFATAL) << "Ledger is not sane.";
|
||||
exit(-1);
|
||||
}
|
||||
mMasterLedger.setLedgerRangePresent(0, lastLedger->getLedgerSeq());
|
||||
mLedgerMaster.setLedgerRangePresent(0, lastLedger->getLedgerSeq());
|
||||
|
||||
Ledger::pointer openLedger = boost::make_shared<Ledger>(false, boost::ref(*lastLedger));
|
||||
mMasterLedger.switchLedgers(lastLedger, openLedger);
|
||||
mLedgerMaster.switchLedgers(lastLedger, openLedger);
|
||||
mNetOps.setLastCloseTime(lastLedger->getCloseTimeNC());
|
||||
}
|
||||
catch (SHAMapMissingNode& mn)
|
||||
|
||||
@@ -47,7 +47,7 @@ class Application
|
||||
|
||||
Wallet mWallet;
|
||||
UniqueNodeList mUNL;
|
||||
LedgerMaster mMasterLedger;
|
||||
LedgerMaster mLedgerMaster;
|
||||
LedgerAcquireMaster mMasterLedgerAcquire;
|
||||
TransactionMaster mMasterTransaction;
|
||||
NetworkOPs mNetOps;
|
||||
@@ -92,7 +92,7 @@ public:
|
||||
boost::asio::io_service& getIOService() { return mIOService; }
|
||||
boost::asio::io_service& getAuxService() { return mAuxService; }
|
||||
|
||||
LedgerMaster& getMasterLedger() { return mMasterLedger; }
|
||||
LedgerMaster& getLedgerMaster() { return mLedgerMaster; }
|
||||
LedgerAcquireMaster& getMasterLedgerAcquire() { return mMasterLedgerAcquire; }
|
||||
TransactionMaster& getMasterTransaction() { return mMasterTransaction; }
|
||||
NodeCache& getTempNodeCache() { return mTempNodeCache; }
|
||||
|
||||
@@ -438,7 +438,7 @@ void Ledger::saveAcceptedLedger(bool fromConsensus)
|
||||
return;
|
||||
}
|
||||
|
||||
theApp->getMasterLedger().setFullLedger(shared_from_this());
|
||||
theApp->getLedgerMaster().setFullLedger(shared_from_this());
|
||||
event = LoadEvent::pointer();
|
||||
|
||||
theApp->getOPs().pubLedger(shared_from_this());
|
||||
|
||||
@@ -176,7 +176,7 @@ void LedgerAcquire::done()
|
||||
{
|
||||
if (mAccept)
|
||||
mLedger->setAccepted();
|
||||
theApp->getMasterLedger().storeLedger(mLedger);
|
||||
theApp->getLedgerMaster().storeLedger(mLedger);
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < triggers.size(); ++i)
|
||||
|
||||
@@ -407,7 +407,7 @@ void LedgerConsensus::handleLCL(const uint256& lclHash)
|
||||
|
||||
if (mPreviousLedger->getHash() != mPrevLedgerHash)
|
||||
{ // we need to switch the ledger we're working from
|
||||
Ledger::pointer newLCL = theApp->getMasterLedger().getLedgerByHash(lclHash);
|
||||
Ledger::pointer newLCL = theApp->getLedgerMaster().getLedgerByHash(lclHash);
|
||||
if (newLCL)
|
||||
mPreviousLedger = newLCL;
|
||||
else if (!mAcquiringLedger || (mAcquiringLedger->getHash() != mPrevLedgerHash))
|
||||
@@ -578,7 +578,7 @@ int LedgerConsensus::startup()
|
||||
|
||||
void LedgerConsensus::statePreClose()
|
||||
{ // it is shortly before ledger close time
|
||||
bool anyTransactions = theApp->getMasterLedger().getCurrentLedger()->peekTransactionMap()->getHash().isNonZero();
|
||||
bool anyTransactions = theApp->getLedgerMaster().getCurrentLedger()->peekTransactionMap()->getHash().isNonZero();
|
||||
int proposersClosed = mPeerPositions.size();
|
||||
|
||||
// This ledger is open. This computes how long since the last ledger closed
|
||||
@@ -613,7 +613,7 @@ void LedgerConsensus::closeLedger()
|
||||
mCloseTime = theApp->getOPs().getCloseTimeNC();
|
||||
theApp->getOPs().setLastCloseTime(mCloseTime);
|
||||
statusChange(ripple::neCLOSING_LEDGER, *mPreviousLedger);
|
||||
takeInitialPosition(*theApp->getMasterLedger().closeLedger(true));
|
||||
takeInitialPosition(*theApp->getLedgerMaster().closeLedger(true));
|
||||
}
|
||||
|
||||
void LedgerConsensus::stateEstablish()
|
||||
@@ -813,7 +813,7 @@ SHAMap::pointer LedgerConsensus::getTransactionTree(const uint256& hash, bool do
|
||||
|
||||
if (mState == lcsPRE_CLOSE)
|
||||
{
|
||||
SHAMap::pointer currentMap = theApp->getMasterLedger().getCurrentLedger()->peekTransactionMap();
|
||||
SHAMap::pointer currentMap = theApp->getLedgerMaster().getCurrentLedger()->peekTransactionMap();
|
||||
if (currentMap->getHash() == hash)
|
||||
{
|
||||
cLog(lsINFO) << "node proposes our open transaction set";
|
||||
@@ -1251,7 +1251,7 @@ void LedgerConsensus::accept(SHAMap::ref set, LoadEvent::pointer)
|
||||
cLog(lsINFO) << "CNF newLCL " << newLCLHash;
|
||||
|
||||
Ledger::pointer newOL = boost::make_shared<Ledger>(true, boost::ref(*newLCL));
|
||||
ScopedLock sl = theApp->getMasterLedger().getLock();
|
||||
ScopedLock sl = theApp->getLedgerMaster().getLock();
|
||||
|
||||
// Apply disputed transactions that didn't get in
|
||||
TransactionEngine engine(newOL);
|
||||
@@ -1274,9 +1274,9 @@ void LedgerConsensus::accept(SHAMap::ref set, LoadEvent::pointer)
|
||||
}
|
||||
|
||||
cLog(lsINFO) << "Applying transactions from current ledger";
|
||||
applyTransactions(theApp->getMasterLedger().getCurrentLedger()->peekTransactionMap(), newOL, newLCL,
|
||||
applyTransactions(theApp->getLedgerMaster().getCurrentLedger()->peekTransactionMap(), newOL, newLCL,
|
||||
failedTransactions, true);
|
||||
theApp->getMasterLedger().pushLedger(newLCL, newOL, !mConsensusFail);
|
||||
theApp->getLedgerMaster().pushLedger(newLCL, newOL, !mConsensusFail);
|
||||
mNewLedgerHash = newLCL->getHash();
|
||||
mState = lcsACCEPTED;
|
||||
sl.unlock();
|
||||
|
||||
@@ -946,7 +946,7 @@ Json::Value NetworkOPs::getServerInfo()
|
||||
if (mNeedNetworkLedger)
|
||||
info["networkLedger"] = "waiting";
|
||||
|
||||
info["completeLedgers"] = theApp->getMasterLedger().getCompleteLedgers();
|
||||
info["completeLedgers"] = theApp->getLedgerMaster().getCompleteLedgers();
|
||||
info["peers"] = theApp->getConnectionPool().getPeerCount();
|
||||
|
||||
Json::Value lastClose = Json::objectValue;
|
||||
|
||||
@@ -80,9 +80,9 @@ PathOption::PathOption(PathOption::pointer other)
|
||||
// functionality is left to the future.
|
||||
//
|
||||
Pathfinder::Pathfinder(const RippleAddress& srcAccountID, const RippleAddress& dstAccountID, const uint160& srcCurrencyID, const uint160& srcIssuerID, const STAmount& dstAmount)
|
||||
: mSrcAccountID(srcAccountID.getAccountID()), mDstAccountID(dstAccountID.getAccountID()), mDstAmount(dstAmount), mSrcCurrencyID(srcCurrencyID), mSrcIssuerID(srcIssuerID), mOrderBook(theApp->getMasterLedger().getCurrentLedger())
|
||||
: mSrcAccountID(srcAccountID.getAccountID()), mDstAccountID(dstAccountID.getAccountID()), mDstAmount(dstAmount), mSrcCurrencyID(srcCurrencyID), mSrcIssuerID(srcIssuerID), mOrderBook(theApp->getLedgerMaster().getCurrentLedger())
|
||||
{
|
||||
mLedger=theApp->getMasterLedger().getCurrentLedger();
|
||||
mLedger=theApp->getLedgerMaster().getCurrentLedger();
|
||||
}
|
||||
|
||||
// If possible, returns a single path.
|
||||
|
||||
@@ -1237,7 +1237,7 @@ void Peer::recvGetLedger(ripple::TMGetLedger& packet)
|
||||
return;
|
||||
}
|
||||
memcpy(ledgerhash.begin(), packet.ledgerhash().data(), 32);
|
||||
ledger = theApp->getMasterLedger().getLedgerByHash(ledgerhash);
|
||||
ledger = theApp->getLedgerMaster().getLedgerByHash(ledgerhash);
|
||||
|
||||
tLog(!ledger, lsINFO) << "Don't have ledger " << ledgerhash;
|
||||
if (!ledger && (packet.has_querytype() && !packet.has_requestcookie()))
|
||||
@@ -1264,16 +1264,16 @@ void Peer::recvGetLedger(ripple::TMGetLedger& packet)
|
||||
}
|
||||
else if (packet.has_ledgerseq())
|
||||
{
|
||||
ledger = theApp->getMasterLedger().getLedgerBySeq(packet.ledgerseq());
|
||||
ledger = theApp->getLedgerMaster().getLedgerBySeq(packet.ledgerseq());
|
||||
tLog(!ledger, lsINFO) << "Don't have ledger " << packet.ledgerseq();
|
||||
}
|
||||
else if (packet.has_ltype() && (packet.ltype() == ripple::ltCURRENT))
|
||||
ledger = theApp->getMasterLedger().getCurrentLedger();
|
||||
ledger = theApp->getLedgerMaster().getCurrentLedger();
|
||||
else if (packet.has_ltype() && (packet.ltype() == ripple::ltCLOSED) )
|
||||
{
|
||||
ledger = theApp->getMasterLedger().getClosedLedger();
|
||||
ledger = theApp->getLedgerMaster().getClosedLedger();
|
||||
if (ledger && !ledger->isClosed())
|
||||
ledger = theApp->getMasterLedger().getLedgerBySeq(ledger->getLedgerSeq() - 1);
|
||||
ledger = theApp->getLedgerMaster().getLedgerBySeq(ledger->getLedgerSeq() - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1529,7 +1529,7 @@ void Peer::sendHello()
|
||||
h.set_ipv4port(theConfig.PEER_PORT);
|
||||
h.set_nodeprivate(theConfig.PEER_PRIVATE);
|
||||
|
||||
Ledger::pointer closedLedger = theApp->getMasterLedger().getClosedLedger();
|
||||
Ledger::pointer closedLedger = theApp->getLedgerMaster().getClosedLedger();
|
||||
if (closedLedger && closedLedger->isClosed())
|
||||
{
|
||||
uint256 hash = closedLedger->getHash();
|
||||
|
||||
@@ -1225,8 +1225,8 @@ Json::Value RPCHandler::doLedger(const Json::Value& params)
|
||||
if (getParamCount(params) == 0)
|
||||
{
|
||||
Json::Value ret(Json::objectValue), current(Json::objectValue), closed(Json::objectValue);
|
||||
theApp->getMasterLedger().getCurrentLedger()->addJson(current, 0);
|
||||
theApp->getMasterLedger().getClosedLedger()->addJson(closed, 0);
|
||||
theApp->getLedgerMaster().getCurrentLedger()->addJson(current, 0);
|
||||
theApp->getLedgerMaster().getClosedLedger()->addJson(closed, 0);
|
||||
ret["open"] = current;
|
||||
ret["closed"] = closed;
|
||||
return ret;
|
||||
@@ -1240,13 +1240,13 @@ Json::Value RPCHandler::doLedger(const Json::Value& params)
|
||||
|
||||
Ledger::pointer ledger;
|
||||
if (param == "current")
|
||||
ledger = theApp->getMasterLedger().getCurrentLedger();
|
||||
ledger = theApp->getLedgerMaster().getCurrentLedger();
|
||||
else if ((param == "lastclosed") || (param == "lastaccepted"))
|
||||
ledger = theApp->getMasterLedger().getClosedLedger();
|
||||
ledger = theApp->getLedgerMaster().getClosedLedger();
|
||||
else if (param.size() > 12)
|
||||
ledger = theApp->getMasterLedger().getLedgerByHash(uint256(param));
|
||||
ledger = theApp->getLedgerMaster().getLedgerByHash(uint256(param));
|
||||
else
|
||||
ledger = theApp->getMasterLedger().getLedgerBySeq(lexical_cast_s<uint32>(param));
|
||||
ledger = theApp->getLedgerMaster().getLedgerBySeq(lexical_cast_s<uint32>(param));
|
||||
|
||||
if (!ledger)
|
||||
return rpcError(rpcLGR_NOT_FOUND);
|
||||
@@ -1308,7 +1308,7 @@ Json::Value RPCHandler::doAccountTransactions(const Json::Value& params)
|
||||
else
|
||||
{
|
||||
txn->setLedger(it->first);
|
||||
ret["transactions"].append(txn->getJson(0));
|
||||
ret["transactions"].append(txn->getJson(1));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1854,7 +1854,7 @@ Json::Value RPCHandler::doTransactionEntry(const Json::Value& jvRequest)
|
||||
// XXX Relying on trusted WSS client. Would be better to have a strict routine, returning success or failure.
|
||||
uLedgerID.SetHex(jvRequest["ledger_hash"].asString());
|
||||
|
||||
Ledger::pointer lpLedger = theApp->getMasterLedger().getLedgerByHash(uLedgerID);
|
||||
Ledger::pointer lpLedger = theApp->getLedgerMaster().getLedgerByHash(uLedgerID);
|
||||
|
||||
if (!lpLedger) {
|
||||
jvResult["error"] = "ledgerNotFound";
|
||||
|
||||
@@ -22,7 +22,7 @@ void RippleLines::printRippleLines()
|
||||
|
||||
RippleLines::RippleLines(const uint160& accountID )
|
||||
{
|
||||
fillLines(accountID,theApp->getMasterLedger().getCurrentLedger());
|
||||
fillLines(accountID,theApp->getLedgerMaster().getCurrentLedger());
|
||||
}
|
||||
|
||||
void RippleLines::fillLines(const uint160& accountID, Ledger::ref ledger)
|
||||
|
||||
@@ -306,11 +306,25 @@ bool Transaction::convertToTransactions(uint32 firstLedgerSeq, uint32 secondLedg
|
||||
return true;
|
||||
}
|
||||
|
||||
// options 1 to include the date of the transaction
|
||||
Json::Value Transaction::getJson(int options) const
|
||||
{
|
||||
|
||||
Json::Value ret(mTransaction->getJson(0));
|
||||
|
||||
if (mInLedger) ret["inLedger"]=mInLedger;
|
||||
if (mInLedger)
|
||||
{
|
||||
ret["inLedger"]=mInLedger;
|
||||
|
||||
if(options==1)
|
||||
{
|
||||
Ledger::pointer ledger=theApp->getLedgerMaster().getLedgerBySeq(mInLedger);
|
||||
if(ledger)
|
||||
{
|
||||
ret["date"]=ledger->getCloseTimeNC();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (mStatus)
|
||||
{
|
||||
|
||||
130
src/js/amount.js
130
src/js/amount.js
@@ -14,6 +14,26 @@ var alphabets = {
|
||||
'bitcoin' : "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
|
||||
};
|
||||
|
||||
var consts = exports.consts = {
|
||||
'address_xns' : "rrrrrrrrrrrrrrrrrrrrrhoLvTp",
|
||||
'address_one' : "rrrrrrrrrrrrrrrrrrrrBZbvji",
|
||||
'currency_xns' : 0,
|
||||
'currency_one' : 1,
|
||||
'uint160_xns' : utils.hexToString("0000000000000000000000000000000000000000"),
|
||||
'uint160_one' : utils.hexToString("0000000000000000000000000000000000000001"),
|
||||
'hex_xns' : "0000000000000000000000000000000000000000",
|
||||
'hex_one' : "0000000000000000000000000000000000000001",
|
||||
'xns_precision' : 6,
|
||||
|
||||
// BigInteger values prefixed with bi_.
|
||||
'bi_10' : new BigInteger('10'),
|
||||
'bi_man_max_value' : new BigInteger('9999999999999999'),
|
||||
'bi_man_min_value' : new BigInteger('1000000000000000'),
|
||||
'bi_xns_max' : new BigInteger("9000000000000000000"), // Json wire limit.
|
||||
'bi_xns_min' : new BigInteger("-9000000000000000000"), // Json wire limit.
|
||||
'bi_xns_unit' : new BigInteger('1000000'),
|
||||
};
|
||||
|
||||
// --> input: big-endian array of bytes.
|
||||
// <-- string at least as long as input.
|
||||
var encode_base = function (input, alphabet) {
|
||||
@@ -137,6 +157,10 @@ UInt160.from_json = function (j) {
|
||||
: j.clone();
|
||||
};
|
||||
|
||||
UInt160.is_valid = function (j) {
|
||||
return UInt160.from_json(j).is_valid();
|
||||
};
|
||||
|
||||
UInt160.prototype.clone = function() {
|
||||
return this.copyTo(new UInt160());
|
||||
};
|
||||
@@ -161,16 +185,16 @@ UInt160.prototype.parse_json = function (j) {
|
||||
switch (j) {
|
||||
case undefined:
|
||||
case "0":
|
||||
case exports.consts.address_xns:
|
||||
case exports.consts.uint160_xns:
|
||||
case exports.consts.hex_xns:
|
||||
case consts.address_xns:
|
||||
case consts.uint160_xns:
|
||||
case consts.hex_xns:
|
||||
this._value = nbi();
|
||||
break;
|
||||
|
||||
case "1":
|
||||
case exports.consts.address_one:
|
||||
case exports.consts.uint160_one:
|
||||
case exports.consts.hex_one:
|
||||
case consts.address_one:
|
||||
case consts.uint160_one:
|
||||
case consts.hex_one:
|
||||
this._value = new BigInteger([1]);
|
||||
|
||||
break;
|
||||
@@ -217,6 +241,10 @@ UInt160.prototype.to_json = function () {
|
||||
return output;
|
||||
};
|
||||
|
||||
UInt160.prototype.is_valid = function () {
|
||||
return !isNaN(this._value);
|
||||
};
|
||||
|
||||
// XXX Internal form should be UInt160.
|
||||
var Currency = function () {
|
||||
// Internal form: 0 = XRP. 3 letter-code.
|
||||
@@ -241,6 +269,10 @@ Currency.from_json = function (j) {
|
||||
: j.clone();
|
||||
};
|
||||
|
||||
Currency.is_valid = function (j) {
|
||||
return currency.from_json(j).is_valid();
|
||||
};
|
||||
|
||||
Currency.prototype.clone = function() {
|
||||
return this.copyTo(new Currency());
|
||||
};
|
||||
@@ -272,6 +304,10 @@ Currency.prototype.parse_json = function(j) {
|
||||
return this;
|
||||
};
|
||||
|
||||
Currency.prototype.is_valid = function () {
|
||||
return !isNaN(this._value);
|
||||
};
|
||||
|
||||
Currency.prototype.to_json = function () {
|
||||
return this._value ? this._value : "XRP";
|
||||
};
|
||||
@@ -308,6 +344,14 @@ Amount.from_json = function(j) {
|
||||
return (new Amount()).parse_json(j);
|
||||
};
|
||||
|
||||
Amount.is_valid = function (j) {
|
||||
return Amount.from_json(j).is_valid();
|
||||
};
|
||||
|
||||
Amount.is_valid_full = function (j) {
|
||||
return Amount.from_json(j).is_valid_full();
|
||||
};
|
||||
|
||||
Amount.prototype.clone = function(negate) {
|
||||
return this.copyTo(new Amount(), negate);
|
||||
};
|
||||
@@ -344,11 +388,15 @@ Amount.prototype.currency = function() {
|
||||
return this._currency;
|
||||
};
|
||||
|
||||
// YYY Might also provide is_valid_json.
|
||||
// Only checks the value. Not the currency and issuer.
|
||||
Amount.prototype.is_valid = function() {
|
||||
return !isNaN(this._value);
|
||||
};
|
||||
|
||||
Amount.prototype.is_valid_full = function() {
|
||||
return this.is_valid() && this._currency.is_valid() && this._issuer.is_valid();
|
||||
};
|
||||
|
||||
Amount.prototype.issuer = function() {
|
||||
return this._issuer;
|
||||
};
|
||||
@@ -366,7 +414,7 @@ Amount.prototype.to_text = function(allow_nan) {
|
||||
return allow_nan ? NaN : "0";
|
||||
}
|
||||
else if (this._is_native) {
|
||||
if (this._value.compareTo(exports.consts.bi_xns_max) > 0 || this._value.compareTo(exports.consts.bi_xns_min) < 0)
|
||||
if (this._value.compareTo(consts.bi_xns_max) > 0 || this._value.compareTo(consts.bi_xns_min) < 0)
|
||||
{
|
||||
// Never should happen.
|
||||
return allow_nan ? NaN : "0";
|
||||
@@ -401,6 +449,36 @@ Amount.prototype.to_text = function(allow_nan) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Format only value in a human-readable format.
|
||||
*
|
||||
* @example
|
||||
* var pretty = amount.to_human({precision: 2});
|
||||
*
|
||||
* @param opts Options for formatter.
|
||||
* @param opts.precision {Number} Max. number of digits after decimal point.
|
||||
*/
|
||||
Amount.prototype.to_human = function (opts)
|
||||
{
|
||||
opts = opts || {};
|
||||
|
||||
var int_part = this._value.divide(consts.bi_xns_unit).toString(10);
|
||||
var fraction_part = this._value.mod(consts.bi_xns_unit).toString(10);
|
||||
|
||||
int_part = int_part.replace(/^0*/, '');
|
||||
fraction_part = fraction_part.replace(/0*$/, '');
|
||||
|
||||
if ("number" === typeof opts.precision) {
|
||||
fraction_part = fraction_part.slice(0, opts.precision);
|
||||
}
|
||||
|
||||
var formatted = '';
|
||||
formatted += int_part.length ? int_part : '0';
|
||||
formatted += fraction_part.length ? '.'+fraction_part : '';
|
||||
|
||||
return formatted;
|
||||
};
|
||||
|
||||
Amount.prototype.canonicalize = function() {
|
||||
if (isNaN(this._value) || !this._currency) {
|
||||
// nothing
|
||||
@@ -411,13 +489,13 @@ Amount.prototype.canonicalize = function() {
|
||||
}
|
||||
else
|
||||
{
|
||||
while (this._value.compareTo(exports.consts.bi_man_min_value) < 0) {
|
||||
this._value = this._value.multiply(exports.consts.bi_10);
|
||||
while (this._value.compareTo(consts.bi_man_min_value) < 0) {
|
||||
this._value = this._value.multiply(consts.bi_10);
|
||||
this._offset -= 1;
|
||||
}
|
||||
|
||||
while (this._value.compareTo(exports.consts.bi_man_max_value) > 0) {
|
||||
this._value = this._value.divide(exports.consts.bi_10);
|
||||
while (this._value.compareTo(consts.bi_man_max_value) > 0) {
|
||||
this._value = this._value.divide(consts.bi_10);
|
||||
this._offset += 1;
|
||||
}
|
||||
}
|
||||
@@ -475,8 +553,8 @@ Amount.prototype.parse_native = function(j) {
|
||||
else {
|
||||
// Float notation
|
||||
|
||||
var int_part = (new BigInteger(m[2])).multiply(exports.consts.bi_xns_unit);
|
||||
var fraction_part = (new BigInteger(m[3])).multiply(new BigInteger(String(Math.pow(10, 1+exports.consts.xns_precision-m[3].length))));
|
||||
var int_part = (new BigInteger(m[2])).multiply(consts.bi_xns_unit);
|
||||
var fraction_part = (new BigInteger(m[3])).multiply(new BigInteger(String(Math.pow(10, 1+consts.xns_precision-m[3].length))));
|
||||
|
||||
this._value = int_part.add(fraction_part);
|
||||
}
|
||||
@@ -488,7 +566,7 @@ Amount.prototype.parse_native = function(j) {
|
||||
this._offset = undefined;
|
||||
this._is_negative = undefined;
|
||||
|
||||
if (this._value.compareTo(exports.consts.bi_xns_max) > 0 || this._value.compareTo(exports.consts.bi_xns_min) < 0)
|
||||
if (this._value.compareTo(consts.bi_xns_max) > 0 || this._value.compareTo(consts.bi_xns_min) < 0)
|
||||
{
|
||||
this._value = NaN;
|
||||
}
|
||||
@@ -533,7 +611,7 @@ Amount.prototype.parse_value = function(j) {
|
||||
var fraction = new BigInteger(d[3]);
|
||||
var precision = d[3].length;
|
||||
|
||||
this._value = integer.multiply(exports.consts.bi_10.clone().pow(precision)).add(fraction);
|
||||
this._value = integer.multiply(consts.bi_10.clone().pow(precision)).add(fraction);
|
||||
this._offset = -precision;
|
||||
this._is_negative = !!d[1];
|
||||
|
||||
@@ -649,24 +727,4 @@ exports.UInt160 = UInt160;
|
||||
|
||||
exports.config = {};
|
||||
|
||||
exports.consts = {
|
||||
'address_xns' : "rrrrrrrrrrrrrrrrrrrrrhoLvTp",
|
||||
'address_one' : "rrrrrrrrrrrrrrrrrrrrBZbvji",
|
||||
'currency_xns' : 0,
|
||||
'currency_one' : 1,
|
||||
'uint160_xns' : utils.hexToString("0000000000000000000000000000000000000000"),
|
||||
'uint160_one' : utils.hexToString("0000000000000000000000000000000000000001"),
|
||||
'hex_xns' : "0000000000000000000000000000000000000000",
|
||||
'hex_one' : "0000000000000000000000000000000000000001",
|
||||
'xns_precision' : 6,
|
||||
|
||||
// BigInteger values prefixed with bi_.
|
||||
'bi_10' : new BigInteger('10'),
|
||||
'bi_man_max_value' : new BigInteger('9999999999999999'),
|
||||
'bi_man_min_value' : new BigInteger('1000000000000000'),
|
||||
'bi_xns_max' : new BigInteger("9000000000000000000"), // Json wire limit.
|
||||
'bi_xns_min' : new BigInteger("-9000000000000000000"), // Json wire limit.
|
||||
'bi_xns_unit' : new BigInteger('1000000'),
|
||||
};
|
||||
|
||||
// vim:sw=2:sts=2:ts=8
|
||||
|
||||
3
src/js/index.js
Normal file
3
src/js/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
exports.Remote = require('./remote').Remote;
|
||||
exports.Amount = require('./amount').Amount;
|
||||
exports.UInt160 = require('./amount').UInt160;
|
||||
@@ -34,7 +34,16 @@ buster.testCase("Amount", {
|
||||
"Parse mtgox export" : function () {
|
||||
buster.assert.equals(config.accounts["mtgox"].account, UInt160.from_json("mtgox").to_json());
|
||||
},
|
||||
|
||||
"is_valid('rrrrrrrrrrrrrrrrrrrrrhoLvTp')" : function () {
|
||||
buster.assert(UInt160.is_valid("rrrrrrrrrrrrrrrrrrrrrhoLvTp"));
|
||||
},
|
||||
|
||||
"!is_valid('rrrrrrrrrrrrrrrrrrrrrhoLvT')" : function () {
|
||||
buster.refute(UInt160.is_valid("rrrrrrrrrrrrrrrrrrrrrhoLvT"));
|
||||
},
|
||||
},
|
||||
|
||||
"Amount parsing" : {
|
||||
"Parse 800/USD/mtgox" : function () {
|
||||
buster.assert.equals("800/USD/"+config.accounts["mtgox"].account, Amount.from_json("800/USD/mtgox").to_text_full());
|
||||
|
||||
@@ -6,7 +6,7 @@ var extend = require("extend");
|
||||
var cfg = {
|
||||
// General settings
|
||||
baseName: pkg.name,
|
||||
programPath: __dirname + "/src/js/remote.js",
|
||||
programPath: __dirname + "/src/js/index.js",
|
||||
|
||||
// CLI-configurable options
|
||||
watch: false,
|
||||
|
||||
Reference in New Issue
Block a user