diff --git a/src/NicknameState.cpp b/src/NicknameState.cpp new file mode 100644 index 0000000000..9b2cb3e857 --- /dev/null +++ b/src/NicknameState.cpp @@ -0,0 +1,29 @@ +#include "NicknameState.h" + +NicknameState::NicknameState(SerializedLedgerEntry::pointer ledgerEntry) : + mLedgerEntry(ledgerEntry) +{ + if (!mLedgerEntry || mLedgerEntry->getType() != ltNICKNAME) return; +} + +bool NicknameState::haveMinimumOffer() const +{ + return mLedgerEntry->getIFieldPresent(sfMinimumOffer); +} + +STAmount NicknameState::getMinimumOffer() const +{ + return mLedgerEntry->getIFieldPresent(sfMinimumOffer) + ? mLedgerEntry->getIValueFieldAmount(sfMinimumOffer) + : STAmount(); +} + +NewcoinAddress NicknameState::getAccountID() const +{ + return mLedgerEntry->getIValueFieldAccount(sfAccount); +} + +void NicknameState::addJson(Json::Value& val) +{ + val = mLedgerEntry->getJson(0); +} diff --git a/src/NicknameState.h b/src/NicknameState.h new file mode 100644 index 0000000000..fe116f4c5d --- /dev/null +++ b/src/NicknameState.h @@ -0,0 +1,37 @@ +#ifndef _NICKNAMESTATE_ +#define _NICKNAMESTATE_ + +// +// State of a nickname node. +// - Isolate ledger entry format. +// + +#include "SerializedLedger.h" + +#include + +class NicknameState +{ +public: + typedef boost::shared_ptr pointer; + +private: + SerializedLedgerEntry::pointer mLedgerEntry; + +public: + NicknameState(SerializedLedgerEntry::pointer ledgerEntry); // For accounts in a ledger + + bool haveMinimumOffer() const; + STAmount getMinimumOffer() const; + NewcoinAddress getAccountID() const; + + SerializedLedgerEntry::pointer getSLE() { return mLedgerEntry; } + const SerializedLedgerEntry& peekSLE() const { return *mLedgerEntry; } + SerializedLedgerEntry& peekSLE() { return *mLedgerEntry; } + + std::vector getRaw() const; + void addJson(Json::Value& value); +}; + +#endif +// vim:ts=4 diff --git a/src/RPCServer.cpp b/src/RPCServer.cpp index 32faabb991..088c8f5c52 100644 --- a/src/RPCServer.cpp +++ b/src/RPCServer.cpp @@ -216,7 +216,7 @@ Json::Value RPCServer::getMasterGenerator(const uint256& uLedger, const NewcoinA Json::Value RPCServer::authorize(const uint256& uLedger, const NewcoinAddress& naRegularSeed, const NewcoinAddress& naSrcAccountID, NewcoinAddress& naAccountPublic, NewcoinAddress& naAccountPrivate, - STAmount& saSrcBalance, uint64 uFee, AccountState::pointer& asSrc, + STAmount& saSrcBalance, const STAmount& saFee, AccountState::pointer& asSrc, const NewcoinAddress& naVerifyGenerator) { // Source/paying account must exist. @@ -277,13 +277,13 @@ Json::Value RPCServer::authorize(const uint256& uLedger, saSrcBalance = asSrc->getBalance(); - if (saSrcBalance < uFee) + if (saSrcBalance < saFee) { return JSONRPCError(500, "insufficent funds"); } else { - saSrcBalance -= uFee; + saSrcBalance -= saFee; } return obj; @@ -780,7 +780,7 @@ Json::Value RPCServer::doCreditSet(Json::Value& params) } else if (!saLimitAmount.setValue(params[3u].asString(), params.size() >= 5 ? params[4u].asString() : "")) { - return JSONRPCError(500, "bad src amount/currency"); + return JSONRPCError(400, "bad src amount/currency"); } else if (!mNetOps->available()) { @@ -828,6 +828,7 @@ Json::Value RPCServer::doCreditSet(Json::Value& params) } // nickname_info +// Note: Nicknames are not automatically looked up by commands as they are advisory and can be changed. Json::Value RPCServer::doNicknameInfo(Json::Value& params) { uint256 uLedger; @@ -871,20 +872,38 @@ Json::Value RPCServer::doNicknameInfo(Json::Value& params) // nickname_set [] [] Json::Value RPCServer::doNicknameSet(Json::Value& params) { + NewcoinAddress naSrcAccountID; + NewcoinAddress naSeed; uint256 uLedger; if (params.size() < 2 || params.size() > 3) { return JSONRPCError(400, "invalid params"); } + else if (!naSeed.setFamilySeedGeneric(params[0u].asString())) + { + return "disallowed seed"; + } + else if (!naSrcAccountID.setAccountID(params[1u].asString())) + { + return "bad source account id needed"; + } - std::string strNickname = params[2u].asString(); - boost::trim(strNickname); + STAmount saMinimumOffer; + bool bSetOffer = params.size() >= 4; + std::string strOfferCurrency; + std::string strNickname = params[2u].asString(); + boost::trim(strNickname); + std::vector vucSignature; if (strNickname.empty()) { return JSONRPCError(400, "invalid nickname (zero length)"); } + else if (params.size() >= 4 && !saMinimumOffer.setValue(params[3u].asString(), strOfferCurrency)) + { + return JSONRPCError(400, "bad dst amount/currency"); + } else if (!mNetOps->available()) { return JSONRPCError(503, "network not available"); @@ -894,9 +913,56 @@ Json::Value RPCServer::doNicknameSet(Json::Value& params) return JSONRPCError(503, "no current ledger"); } + STAmount saFee; NicknameState::pointer nsSrc = mNetOps->getNicknameState(uLedger, strNickname); - return "not implemented"; + if (!nsSrc) + { + // Creating nickname. + saFee = theConfig.FEE_NICKNAME_CREATE; + } + else if (naSrcAccountID != nsSrc->getAccountID()) + { + // We don't own the nickname. + return JSONRPCError(400, "account does not control nickname"); + } + else + { + // Setting the minimum offer. + saFee = theConfig.FEE_DEFAULT; + } + + NewcoinAddress naMasterGenerator; + NewcoinAddress naAccountPublic; + NewcoinAddress naAccountPrivate; + AccountState::pointer asSrc; + STAmount saSrcBalance; + Json::Value obj = authorize(uLedger, naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate, + saSrcBalance, saFee, asSrc, naMasterGenerator); + + if (!obj.empty()) + return obj; + + // YYY Could verify nickname does not exist or points to paying account. + // XXX Adjust fee for nickname create. + + Transaction::pointer trans = Transaction::sharedNicknameSet( + naAccountPublic, naAccountPrivate, + naSrcAccountID, + asSrc->getSeq(), + saFee, + 0, // YYY No source tag + Ledger::getNicknameHash(strNickname), + bSetOffer, + saMinimumOffer, + vucSignature); + + (void) mNetOps->processTransaction(trans); + + obj["transaction"] = trans->getSTransaction()->getJson(0); + obj["status"] = trans->getStatus(); + + return obj; } // password_fund [] @@ -1106,11 +1172,11 @@ Json::Value RPCServer::doSend(Json::Value& params) } else if (!saDstAmount.setValue(params[3u].asString(), sDstCurrency)) { - return JSONRPCError(500, "bad dst amount/currency"); + return JSONRPCError(400, "bad dst amount/currency"); } else if (params.size() >= 6 && !saSrcAmount.setValue(params[5u].asString(), sSrcCurrency)) { - return JSONRPCError(500, "bad src amount/currency"); + return JSONRPCError(400, "bad src amount/currency"); } else if (!mNetOps->available()) { @@ -1474,7 +1540,7 @@ Json::Value RPCServer::doWalletAdd(Json::Value& params) } else if (params.size() >= 4 && !saAmount.setValue(params[3u].asString(), sDstCurrency)) { - return JSONRPCError(500, "bad dst amount/currency"); + return JSONRPCError(400, "bad dst amount/currency"); } else if (!mNetOps->available()) { @@ -1497,7 +1563,7 @@ Json::Value RPCServer::doWalletAdd(Json::Value& params) AccountState::pointer asSrc; STAmount saSrcBalance; Json::Value obj = authorize(uLedger, naRegularSeed, naSrcAccountID, naAccountPublic, naAccountPrivate, - saSrcBalance, theConfig.FEE_CREATE, asSrc, naMasterGenerator); + saSrcBalance, theConfig.FEE_ACCOUNT_CREATE, asSrc, naMasterGenerator); if (!obj.empty()) return obj; @@ -1544,7 +1610,7 @@ Json::Value RPCServer::doWalletAdd(Json::Value& params) naAccountPublic, naAccountPrivate, naSrcAccountID, asSrc->getSeq(), - theConfig.FEE_CREATE, + theConfig.FEE_ACCOUNT_CREATE, 0, // YYY No source tag saAmount, naAuthKeyID, @@ -1705,7 +1771,7 @@ Json::Value RPCServer::doWalletCreate(Json::Value& params) AccountState::pointer asSrc; STAmount saSrcBalance; Json::Value obj = authorize(uLedger, naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate, - saSrcBalance, theConfig.FEE_CREATE, asSrc, naMasterGenerator); + saSrcBalance, theConfig.FEE_ACCOUNT_CREATE, asSrc, naMasterGenerator); if (!obj.empty()) return obj; @@ -1719,7 +1785,7 @@ Json::Value RPCServer::doWalletCreate(Json::Value& params) naAccountPublic, naAccountPrivate, naSrcAccountID, asSrc->getSeq(), - theConfig.FEE_CREATE, + theConfig.FEE_ACCOUNT_CREATE, 0, // YYY No source tag naDstAccountID, saInitialFunds); // Initial funds in XNC. diff --git a/src/RPCServer.h b/src/RPCServer.h index a8358235c3..a972b05a6e 100644 --- a/src/RPCServer.h +++ b/src/RPCServer.h @@ -42,7 +42,7 @@ private: Json::Value getMasterGenerator(const uint256& uLedger, const NewcoinAddress& naRegularSeed, NewcoinAddress& naMasterGenerator); Json::Value authorize(const uint256& uLedger, const NewcoinAddress& naRegularSeed, const NewcoinAddress& naSrcAccountID, NewcoinAddress& naAccountPublic, NewcoinAddress& naAccountPrivate, - STAmount& saSrcBalance, uint64 uFee, AccountState::pointer& asSrc, + STAmount& saSrcBalance, const STAmount& saFee, AccountState::pointer& asSrc, const NewcoinAddress& naVerifyGenerator); Json::Value accounts(const uint256& uLedger, const NewcoinAddress& naMasterGenerator);