Better handling of full values for amounts.

This commit is contained in:
Arthur Britto
2012-07-20 14:16:34 -07:00
parent 1f02996e1d
commit a61cf78299
5 changed files with 56 additions and 48 deletions

View File

@@ -98,13 +98,32 @@ std::string STAmount::createHumanCurrency(const uint160& uCurrency)
// - Integer values are in base units. // - Integer values are in base units.
// - Float values are in float units. // - Float values are in float units.
// - To avoid a mistake float value for native are specified with a "^" in place of a "." // - To avoid a mistake float value for native are specified with a "^" in place of a "."
bool STAmount::setValue(const std::string& sAmount, const std::string& sCurrency) // <-- bValid: true = valid
bool STAmount::setFullValue(const std::string& sAmount, const std::string& sCurrency, const std::string& sIssuer)
{ {
//
// Figure out the currency.
//
if (!currencyFromString(mCurrency, sCurrency)) if (!currencyFromString(mCurrency, sCurrency))
return false; return false;
mIsNative = !mCurrency; mIsNative = !mCurrency;
//
// Figure out the issuer.
//
NewcoinAddress naIssuerID;
// Issuer must be "" or a valid account string.
if (!naIssuerID.setAccountID(sIssuer))
return false;
mIssuer = naIssuerID.getAccountID();
// Stamps not must have an issuer.
if (mIsNative && !mIssuer.isZero())
return false;
uint64 uValue; uint64 uValue;
int iOffset; int iOffset;
size_t uDecimal = sAmount.find_first_of(mIsNative ? "^" : "."); size_t uDecimal = sAmount.find_first_of(mIsNative ? "^" : ".");
@@ -910,13 +929,13 @@ BOOST_AUTO_TEST_CASE( setValue_test )
STAmount saTmp; STAmount saTmp;
// Check native floats // Check native floats
saTmp.setValue("1^0",""); BOOST_CHECK_MESSAGE(SYSTEM_CURRENCY_PARTS == saTmp.getNValue(), "float integer failed"); saTmp.setFullValue("1^0"); BOOST_CHECK_MESSAGE(SYSTEM_CURRENCY_PARTS == saTmp.getNValue(), "float integer failed");
saTmp.setValue("0^1",""); BOOST_CHECK_MESSAGE(SYSTEM_CURRENCY_PARTS/10 == saTmp.getNValue(), "float fraction failed"); saTmp.setFullValue("0^1"); BOOST_CHECK_MESSAGE(SYSTEM_CURRENCY_PARTS/10 == saTmp.getNValue(), "float fraction failed");
saTmp.setValue("0^12",""); BOOST_CHECK_MESSAGE(12*SYSTEM_CURRENCY_PARTS/100 == saTmp.getNValue(), "float fraction failed"); saTmp.setFullValue("0^12"); BOOST_CHECK_MESSAGE(12*SYSTEM_CURRENCY_PARTS/100 == saTmp.getNValue(), "float fraction failed");
saTmp.setValue("1^2",""); BOOST_CHECK_MESSAGE(SYSTEM_CURRENCY_PARTS+(2*SYSTEM_CURRENCY_PARTS/10) == saTmp.getNValue(), "float combined failed"); saTmp.setFullValue("1^2"); BOOST_CHECK_MESSAGE(SYSTEM_CURRENCY_PARTS+(2*SYSTEM_CURRENCY_PARTS/10) == saTmp.getNValue(), "float combined failed");
// Check native integer // Check native integer
saTmp.setValue("1",""); BOOST_CHECK_MESSAGE(1 == saTmp.getNValue(), "integer failed"); saTmp.setFullValue("1"); BOOST_CHECK_MESSAGE(1 == saTmp.getNValue(), "integer failed");
} }
BOOST_AUTO_TEST_CASE( NativeCurrency_test ) BOOST_AUTO_TEST_CASE( NativeCurrency_test )

View File

@@ -45,7 +45,7 @@ uint32 NetworkOPs::getCurrentLedgerID()
} }
// Sterilize transaction through serialization. // Sterilize transaction through serialization.
void NetworkOPs::submitTransaction(Transaction::pointer tpTrans) Transaction::pointer NetworkOPs::submitTransaction(Transaction::pointer tpTrans)
{ {
Serializer s; Serializer s;
@@ -60,6 +60,8 @@ void NetworkOPs::submitTransaction(Transaction::pointer tpTrans)
assert(tpTransNew); assert(tpTransNew);
(void) NetworkOPs::processTransaction(tpTransNew); (void) NetworkOPs::processTransaction(tpTransNew);
return tpTransNew;
} }
Transaction::pointer NetworkOPs::processTransaction(Transaction::pointer trans, uint32 tgtLedger, Peer* source) Transaction::pointer NetworkOPs::processTransaction(Transaction::pointer trans, uint32 tgtLedger, Peer* source)

View File

@@ -105,7 +105,7 @@ public:
// //
// Transaction operations // Transaction operations
// //
void submitTransaction(Transaction::pointer tpTrans); Transaction::pointer submitTransaction(Transaction::pointer tpTrans);
Transaction::pointer processTransaction(Transaction::pointer transaction, uint32 targetLedger = 0, Transaction::pointer processTransaction(Transaction::pointer transaction, uint32 targetLedger = 0,
Peer* source = NULL); Peer* source = NULL);

View File

@@ -463,7 +463,7 @@ Json::Value RPCServer::doAccountEmailSet(const Json::Value &params)
uint256(), uint256(),
NewcoinAddress()); NewcoinAddress());
(void) mNetOps->submitTransaction(trans); trans = mNetOps->submitTransaction(trans);
obj["transaction"] = trans->getSTransaction()->getJson(0); obj["transaction"] = trans->getSTransaction()->getJson(0);
obj["status"] = trans->getStatus(); obj["status"] = trans->getStatus();
@@ -572,7 +572,7 @@ Json::Value RPCServer::doAccountMessageSet(const Json::Value& params) {
uint256(), uint256(),
naMessagePubKey); naMessagePubKey);
(void) mNetOps->submitTransaction(trans); trans = mNetOps->submitTransaction(trans);
obj["transaction"] = trans->getSTransaction()->getJson(0); obj["transaction"] = trans->getSTransaction()->getJson(0);
obj["status"] = trans->getStatus(); obj["status"] = trans->getStatus();
@@ -624,7 +624,7 @@ Json::Value RPCServer::doAccountWalletSet(const Json::Value& params) {
uWalletLocator, uWalletLocator,
NewcoinAddress()); NewcoinAddress());
(void) mNetOps->submitTransaction(trans); trans = mNetOps->submitTransaction(trans);
obj["transaction"] = trans->getSTransaction()->getJson(0); obj["transaction"] = trans->getSTransaction()->getJson(0);
obj["status"] = trans->getStatus(); obj["status"] = trans->getStatus();
@@ -773,7 +773,7 @@ Json::Value RPCServer::doNicknameSet(const Json::Value& params)
{ {
return RPCError(rpcNICKNAME_MALFORMED); return RPCError(rpcNICKNAME_MALFORMED);
} }
else if (params.size() >= 4 && !saMinimumOffer.setValue(params[3u].asString(), strOfferCurrency)) else if (params.size() >= 4 && !saMinimumOffer.setFullValue(params[3u].asString(), strOfferCurrency))
{ {
return RPCError(rpcDST_AMT_MALFORMED); return RPCError(rpcDST_AMT_MALFORMED);
} }
@@ -822,7 +822,7 @@ Json::Value RPCServer::doNicknameSet(const Json::Value& params)
saMinimumOffer, saMinimumOffer,
vucSignature); vucSignature);
(void) mNetOps->submitTransaction(trans); trans = mNetOps->submitTransaction(trans);
obj["transaction"] = trans->getSTransaction()->getJson(0); obj["transaction"] = trans->getSTransaction()->getJson(0);
obj["status"] = trans->getStatus(); obj["status"] = trans->getStatus();
@@ -838,8 +838,6 @@ Json::Value RPCServer::doOfferCreate(const Json::Value &params)
NewcoinAddress naSrcAccountID; NewcoinAddress naSrcAccountID;
STAmount saTakerPays; STAmount saTakerPays;
STAmount saTakerGets; STAmount saTakerGets;
NewcoinAddress naTakerPaysID;
NewcoinAddress naTakerGetsID;
if (!naSeed.setSeedGeneric(params[0u].asString())) if (!naSeed.setSeedGeneric(params[0u].asString()))
{ {
@@ -849,22 +847,14 @@ Json::Value RPCServer::doOfferCreate(const Json::Value &params)
{ {
return RPCError(rpcSRC_ACT_MALFORMED); return RPCError(rpcSRC_ACT_MALFORMED);
} }
else if (!saTakerGets.setValue(params[2u].asString(), params[3u].asString())) else if (!saTakerGets.setFullValue(params[2u].asString(), params[3u].asString(), params[4u].asString()))
{ {
return RPCError(rpcGETS_AMT_MALFORMED); return RPCError(rpcGETS_AMT_MALFORMED);
} }
else if (!naTakerGetsID.setAccountID(params[4u].asString())) else if (!saTakerPays.setFullValue(params[5u].asString(), params[6u].asString(), params[7u].asString()))
{
return RPCError(rpcGETS_ACT_MALFORMED);
}
else if (!saTakerPays.setValue(params[5u].asString(), params[6u].asString()))
{ {
return RPCError(rpcPAYS_AMT_MALFORMED); return RPCError(rpcPAYS_AMT_MALFORMED);
} }
else if (!naTakerPaysID.setAccountID(params[7u].asString()))
{
return RPCError(rpcPAYS_ACT_MALFORMED);
}
else if (params.size() == 10 && params[9u].asString() != "passive") else if (params.size() == 10 && params[9u].asString() != "passive")
{ {
return RPCError(rpcINVALID_PARAMS); return RPCError(rpcINVALID_PARAMS);
@@ -873,9 +863,6 @@ Json::Value RPCServer::doOfferCreate(const Json::Value &params)
uint32 uExpiration = lexical_cast_s<int>(params[8u].asString()); uint32 uExpiration = lexical_cast_s<int>(params[8u].asString());
bool bPassive = params.size() == 10; bool bPassive = params.size() == 10;
saTakerPays.setIssuer(naTakerPaysID.getAccountID());
saTakerGets.setIssuer(naTakerGetsID.getAccountID());
NewcoinAddress naMasterGenerator; NewcoinAddress naMasterGenerator;
NewcoinAddress naAccountPublic; NewcoinAddress naAccountPublic;
NewcoinAddress naAccountPrivate; NewcoinAddress naAccountPrivate;
@@ -898,7 +885,7 @@ Json::Value RPCServer::doOfferCreate(const Json::Value &params)
saTakerGets, saTakerGets,
uExpiration); uExpiration);
(void) mNetOps->submitTransaction(trans); trans = mNetOps->submitTransaction(trans);
obj["transaction"] = trans->getSTransaction()->getJson(0); obj["transaction"] = trans->getSTransaction()->getJson(0);
obj["status"] = trans->getStatus(); obj["status"] = trans->getStatus();
@@ -941,7 +928,7 @@ Json::Value RPCServer::doOfferCancel(const Json::Value &params)
0, // YYY No source tag 0, // YYY No source tag
uSequence); uSequence);
(void) mNetOps->submitTransaction(trans); trans = mNetOps->submitTransaction(trans);
obj["transaction"] = trans->getSTransaction()->getJson(0); obj["transaction"] = trans->getSTransaction()->getJson(0);
obj["status"] = trans->getStatus(); obj["status"] = trans->getStatus();
@@ -1027,7 +1014,7 @@ Json::Value RPCServer::doPasswordFund(const Json::Value &params)
0, // YYY No source tag 0, // YYY No source tag
naDstAccountID); naDstAccountID);
(void) mNetOps->submitTransaction(trans); trans = mNetOps->submitTransaction(trans);
obj["transaction"] = trans->getSTransaction()->getJson(0); obj["transaction"] = trans->getSTransaction()->getJson(0);
obj["status"] = trans->getStatus(); obj["status"] = trans->getStatus();
@@ -1105,7 +1092,7 @@ Json::Value RPCServer::doPasswordSet(const Json::Value& params)
return RPCError(rpcACT_NOT_FOUND); return RPCError(rpcACT_NOT_FOUND);
} }
Transaction::pointer trns = Transaction::sharedPasswordSet( Transaction::pointer trans = Transaction::sharedPasswordSet(
naAccountPublic, naAccountPrivate, naAccountPublic, naAccountPrivate,
0, 0,
naRegularXPublic, naRegularXPublic,
@@ -1113,7 +1100,7 @@ Json::Value RPCServer::doPasswordSet(const Json::Value& params)
naRegular0Public.getAccountPublic(), naRegular0Public.getAccountPublic(),
vucGeneratorSig); vucGeneratorSig);
(void) mNetOps->submitTransaction(trns); trans = mNetOps->submitTransaction(trans);
Json::Value obj(Json::objectValue); Json::Value obj(Json::objectValue);
@@ -1123,8 +1110,8 @@ Json::Value RPCServer::doPasswordSet(const Json::Value& params)
obj["regular_seed"] = naRegularSeed.humanSeed(); obj["regular_seed"] = naRegularSeed.humanSeed();
obj["regular_key"] = naRegularSeed.humanSeed1751(); obj["regular_key"] = naRegularSeed.humanSeed1751();
obj["transaction"] = trns->getSTransaction()->getJson(0); obj["transaction"] = trans->getSTransaction()->getJson(0);
obj["status"] = trns->getStatus(); obj["status"] = trans->getStatus();
return obj; return obj;
} }
@@ -1160,7 +1147,7 @@ Json::Value RPCServer::doRippleLineSet(const Json::Value& params)
{ {
return RPCError(rpcDST_ACT_MALFORMED); return RPCError(rpcDST_ACT_MALFORMED);
} }
else if (!saLimitAmount.setValue(params[3u].asString(), params.size() >= 5 ? params[4u].asString() : "")) else if (!saLimitAmount.setFullValue(params[3u].asString(), params.size() >= 5 ? params[4u].asString() : ""))
{ {
return RPCError(rpcSRC_AMT_MALFORMED); return RPCError(rpcSRC_AMT_MALFORMED);
} }
@@ -1187,7 +1174,7 @@ Json::Value RPCServer::doRippleLineSet(const Json::Value& params)
saLimitAmount, saLimitAmount,
uAcceptRate); uAcceptRate);
(void) mNetOps->submitTransaction(trans); trans = mNetOps->submitTransaction(trans);
obj["transaction"] = trans->getSTransaction()->getJson(0); obj["transaction"] = trans->getSTransaction()->getJson(0);
obj["status"] = trans->getStatus(); obj["status"] = trans->getStatus();
@@ -1341,11 +1328,11 @@ Json::Value RPCServer::doSend(const Json::Value& params)
{ {
return RPCError(rpcDST_ACT_MALFORMED); return RPCError(rpcDST_ACT_MALFORMED);
} }
else if (!saDstAmount.setValue(params[3u].asString(), sDstCurrency)) else if (!saDstAmount.setFullValue(params[3u].asString(), sDstCurrency))
{ {
return RPCError(rpcDST_AMT_MALFORMED); return RPCError(rpcDST_AMT_MALFORMED);
} }
else if (params.size() >= 6 && !saSrcAmount.setValue(params[5u].asString(), sSrcCurrency)) else if (params.size() >= 6 && !saSrcAmount.setFullValue(params[5u].asString(), sSrcCurrency))
{ {
return RPCError(rpcSRC_AMT_MALFORMED); return RPCError(rpcSRC_AMT_MALFORMED);
} }
@@ -1425,7 +1412,7 @@ Json::Value RPCServer::doSend(const Json::Value& params)
saDstAmount); // Initial funds in XNS. saDstAmount); // Initial funds in XNS.
} }
(void) mNetOps->submitTransaction(trans); trans = mNetOps->submitTransaction(trans);
obj["transaction"] = trans->getSTransaction()->getJson(0); obj["transaction"] = trans->getSTransaction()->getJson(0);
obj["status"] = trans->getStatus(); obj["status"] = trans->getStatus();
@@ -1743,7 +1730,7 @@ Json::Value RPCServer::doWalletAdd(const Json::Value& params)
{ {
return RPCError(rpcBAD_SEED); return RPCError(rpcBAD_SEED);
} }
else if (params.size() >= 4 && !saAmount.setValue(params[3u].asString(), sDstCurrency)) else if (params.size() >= 4 && !saAmount.setFullValue(params[3u].asString(), sDstCurrency))
{ {
return RPCError(rpcDST_AMT_MALFORMED); return RPCError(rpcDST_AMT_MALFORMED);
} }
@@ -1811,7 +1798,7 @@ Json::Value RPCServer::doWalletAdd(const Json::Value& params)
naNewAccountPublic, naNewAccountPublic,
vucSignature); vucSignature);
(void) mNetOps->submitTransaction(trans); trans = mNetOps->submitTransaction(trans);
obj["transaction"] = trans->getSTransaction()->getJson(0); obj["transaction"] = trans->getSTransaction()->getJson(0);
obj["status"] = trans->getStatus(); obj["status"] = trans->getStatus();
@@ -1879,14 +1866,14 @@ Json::Value RPCServer::doWalletClaim(const Json::Value& params)
// XXX Check result. // XXX Check result.
naRegular0Private.accountPrivateSign(Serializer::getSHA512Half(vucGeneratorCipher), vucGeneratorSig); naRegular0Private.accountPrivateSign(Serializer::getSHA512Half(vucGeneratorCipher), vucGeneratorSig);
Transaction::pointer trns = Transaction::sharedClaim( Transaction::pointer trans = Transaction::sharedClaim(
naAccountPublic, naAccountPrivate, naAccountPublic, naAccountPrivate,
uSourceTag, uSourceTag,
vucGeneratorCipher, vucGeneratorCipher,
naRegular0Public.getAccountPublic(), naRegular0Public.getAccountPublic(),
vucGeneratorSig); vucGeneratorSig);
(void) mNetOps->submitTransaction(trns); trans = mNetOps->submitTransaction(trans);
Json::Value obj(Json::objectValue); Json::Value obj(Json::objectValue);
@@ -1901,8 +1888,8 @@ Json::Value RPCServer::doWalletClaim(const Json::Value& params)
obj["generator"] = strHex(vucGeneratorCipher); obj["generator"] = strHex(vucGeneratorCipher);
obj["annotation"] = strAnnotation; obj["annotation"] = strAnnotation;
obj["transaction"] = trns->getSTransaction()->getJson(0); obj["transaction"] = trans->getSTransaction()->getJson(0);
obj["status"] = trns->getStatus(); obj["status"] = trans->getStatus();
return obj; return obj;
} }
@@ -1964,7 +1951,7 @@ Json::Value RPCServer::doWalletCreate(const Json::Value& params)
naDstAccountID, naDstAccountID,
saInitialFunds); // Initial funds in XNC. saInitialFunds); // Initial funds in XNC.
(void) mNetOps->submitTransaction(trans); trans = mNetOps->submitTransaction(trans);
obj["transaction"] = trans->getSTransaction()->getJson(0); obj["transaction"] = trans->getSTransaction()->getJson(0);
obj["status"] = trans->getStatus(); obj["status"] = trans->getStatus();

View File

@@ -288,7 +288,7 @@ public:
void setIssuer(const uint160& uIssuer) { mIssuer = uIssuer; } void setIssuer(const uint160& uIssuer) { mIssuer = uIssuer; }
const uint160& getCurrency() const { return mCurrency; } const uint160& getCurrency() const { return mCurrency; }
bool setValue(const std::string& sAmount, const std::string& sCurrency); bool setFullValue(const std::string& sAmount, const std::string& sCurrency = "", const std::string& sIssuer = "");
void setValue(const STAmount &); void setValue(const STAmount &);
virtual bool isEquivalent(const SerializedType& t) const; virtual bool isEquivalent(const SerializedType& t) const;