From 0f02695f21d2cc9639fd647453560a7941c739c2 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Mon, 4 Jun 2012 15:25:01 -0700 Subject: [PATCH 01/12] Add NicknameSet to TransactionFormats. --- src/SerializedObject.h | 1 + src/TransactionFormats.cpp | 9 +++++++++ src/TransactionFormats.h | 1 + 3 files changed, 11 insertions(+) diff --git a/src/SerializedObject.h b/src/SerializedObject.h index 3c322486da..de9f3d2b7f 100644 --- a/src/SerializedObject.h +++ b/src/SerializedObject.h @@ -72,6 +72,7 @@ enum SOE_Field sfNextTransitStart, sfNickname, sfOfferCurrency, + sfOfferMin, sfPaths, sfPubKey, sfSendMax, diff --git a/src/TransactionFormats.cpp b/src/TransactionFormats.cpp index 66995e5a92..c0f2f73a51 100644 --- a/src/TransactionFormats.cpp +++ b/src/TransactionFormats.cpp @@ -44,6 +44,15 @@ TransactionFormat InnerTxnFormats[]= { S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x02000000 }, { sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } } }, + { "NicknameSet", ttNICKNAME_SET, { + { S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 }, + { S_FIELD(Nickname), STI_HASH256, SOE_IFFLAG, 8 }, + { S_FIELD(OfferMin), STI_AMOUNT, SOE_IFFLAG, 1 }, + { S_FIELD(Signature), STI_VL, SOE_IFFLAG, 2 }, + { S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 1 }, + { S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x02000000 }, + { sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } } + }, { "Offer", ttOFFER, { { S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 }, { S_FIELD(AmountIn), STI_AMOUNT, SOE_REQUIRED, 0 }, diff --git a/src/TransactionFormats.h b/src/TransactionFormats.h index 6833560696..3f053521f2 100644 --- a/src/TransactionFormats.h +++ b/src/TransactionFormats.h @@ -12,6 +12,7 @@ enum TransactionType ttACCOUNT_SET = 3, ttPASSWORD_FUND = 4, ttPASSWORD_SET = 5, + ttNICKNAME_SET = 6, ttCREDIT_SET = 20, ttTRANSIT_SET = 21, ttINVOICE = 10, From 189b11551351abca2da09530df13644768e4b035 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Tue, 5 Jun 2012 13:03:47 -0700 Subject: [PATCH 02/12] Fix serialized format for nicknames. --- src/LedgerFormats.cpp | 5 ++--- src/SerializedObject.h | 1 - src/TransactionFormats.cpp | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/LedgerFormats.cpp b/src/LedgerFormats.cpp index df6fb2350e..afee90b4c9 100644 --- a/src/LedgerFormats.cpp +++ b/src/LedgerFormats.cpp @@ -35,17 +35,16 @@ LedgerEntryFormat LedgerFormats[]= }, { "GeneratorMap", ltGENERATOR_MAP, { { S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 }, - { S_FIELD(GeneratorID), STI_HASH160, SOE_REQUIRED, 0 }, +// { S_FIELD(GeneratorID), STI_HASH160, SOE_REQUIRED, 0 }, { S_FIELD(Generator), STI_VL, SOE_REQUIRED, 0 }, { S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 }, { sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } } }, { "Nickname", ltNICKNAME, { { S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 }, - { S_FIELD(Nickname), STI_HASH256, SOE_REQUIRED, 0 }, +// { S_FIELD(Nickname), STI_HASH256, SOE_REQUIRED, 0 }, { S_FIELD(Account), STI_ACCOUNT, SOE_REQUIRED, 0 }, { S_FIELD(MinimumOffer), STI_AMOUNT, SOE_IFFLAG, 1 }, - { S_FIELD(OfferCurrency), STI_HASH160, SOE_IFFLAG, 2 }, { S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 }, { sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } } }, diff --git a/src/SerializedObject.h b/src/SerializedObject.h index de9f3d2b7f..3c322486da 100644 --- a/src/SerializedObject.h +++ b/src/SerializedObject.h @@ -72,7 +72,6 @@ enum SOE_Field sfNextTransitStart, sfNickname, sfOfferCurrency, - sfOfferMin, sfPaths, sfPubKey, sfSendMax, diff --git a/src/TransactionFormats.cpp b/src/TransactionFormats.cpp index c0f2f73a51..cddcafcf6c 100644 --- a/src/TransactionFormats.cpp +++ b/src/TransactionFormats.cpp @@ -47,7 +47,7 @@ TransactionFormat InnerTxnFormats[]= { "NicknameSet", ttNICKNAME_SET, { { S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 }, { S_FIELD(Nickname), STI_HASH256, SOE_IFFLAG, 8 }, - { S_FIELD(OfferMin), STI_AMOUNT, SOE_IFFLAG, 1 }, + { S_FIELD(MinimumOffer), STI_AMOUNT, SOE_IFFLAG, 1 }, { S_FIELD(Signature), STI_VL, SOE_IFFLAG, 2 }, { S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 1 }, { S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x02000000 }, From ea64ee3e5898160e731891f7559aa731d16e1e18 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Tue, 5 Jun 2012 13:04:42 -0700 Subject: [PATCH 03/12] Implement doNicknameSet. --- src/TransactionEngine.cpp | 62 +++++++++++++++++++++++++++++++++++++-- src/TransactionEngine.h | 2 ++ 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/src/TransactionEngine.cpp b/src/TransactionEngine.cpp index 39691b3d3d..6a39913884 100644 --- a/src/TransactionEngine.cpp +++ b/src/TransactionEngine.cpp @@ -259,7 +259,7 @@ TransactionEngineResult TransactionEngine::setAuthorized(const SerializedTransac sleGen = boost::make_shared(ltGENERATOR_MAP); sleGen->setIndex(Ledger::getGeneratorIndex(hGeneratorID)); - sleGen->setIFieldH160(sfGeneratorID, hGeneratorID); +// sleGen->setIFieldH160(sfGeneratorID, hGeneratorID); sleGen->setIFieldVL(sfGenerator, vucCipher); accounts.push_back(std::make_pair(taaCREATE, sleGen)); @@ -548,7 +548,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran { nothing(); } - else if (saCost) + else if (saCost.isZero()) { uint32 a_seq = sleSrc->getIFieldU32(sfSequence); @@ -622,6 +622,10 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran result = doOffer(txn, accounts); break; + case ttNICKNAME_SET: + result = doNicknameSet(txn, accounts, srcAccountID); + break; + case ttPASSWORD_FUND: result = doPasswordFund(txn, accounts, srcAccountID); break; @@ -869,6 +873,60 @@ TransactionEngineResult TransactionEngine::doCreditSet(const SerializedTransacti return terResult; } +TransactionEngineResult TransactionEngine::doNicknameSet(const SerializedTransaction& txn, std::vector& accounts, const uint160& uSrcAccountID) +{ + std::cerr << "doNicknameSet>" << std::endl; + + SLE::pointer sleSrc = accounts[0].second; + + uint256 uNickname = txn.getITFieldH256(sfWalletLocator); + bool bMinOffer = txn.getITFieldPresent(sfMinimumOffer); + STAmount saMinOffer = bMinOffer ? txn.getITFieldAmount(sfAmount) : STAmount(); + + LedgerStateParms qry = lepNONE; + SLE::pointer sleNickname = mLedger->getNickname(qry, uNickname); + + if (sleNickname) + { + // Edit old entry. + sleNickname->setIFieldAccount(sfAccount, uSrcAccountID); + + if (bMinOffer && !saMinOffer.isZero()) + { + sleNickname->setIFieldAmount(sfMinimumOffer, saMinOffer); + } + else + { + sleNickname->makeIFieldAbsent(sfMinimumOffer); + } + + accounts.push_back(std::make_pair(taaCREATE, sleNickname)); + } + else + { + // Make a new entry. + // XXX Need to include authorization limiting. + + sleNickname = boost::make_shared(ltNICKNAME); + + sleNickname->setIndex(Ledger::getNicknameIndex(uNickname)); + std::cerr << "doNicknameSet: Creating nickname node: " << sleNickname->getIndex().ToString() << std::endl; + + sleNickname->setIFieldAccount(sfAccount, uSrcAccountID); + + if (bMinOffer && !saMinOffer.isZero()) + sleNickname->setIFieldAmount(sfMinimumOffer, saMinOffer); + +// sleNickname->setIFieldH256(sfNickname, uNickname); + + accounts.push_back(std::make_pair(taaCREATE, sleNickname)); + } + + std::cerr << "doNicknameSet<" << std::endl; + + return terSUCCESS; +} + TransactionEngineResult TransactionEngine::doPasswordFund(const SerializedTransaction& txn, std::vector& accounts, const uint160& uSrcAccountID) { std::cerr << "doPasswordFund>" << std::endl; diff --git a/src/TransactionEngine.h b/src/TransactionEngine.h index 75b79aca07..9d79ff37f9 100644 --- a/src/TransactionEngine.h +++ b/src/TransactionEngine.h @@ -108,6 +108,8 @@ protected: TransactionEngineResult doDelete(const SerializedTransaction& txn, std::vector& accounts); TransactionEngineResult doInvoice(const SerializedTransaction& txn, std::vector& accounts); TransactionEngineResult doOffer(const SerializedTransaction& txn, std::vector& accounts); + TransactionEngineResult doNicknameSet(const SerializedTransaction& txn, std::vector& accounts, + const uint160& uSrcAccountID); TransactionEngineResult doPasswordFund(const SerializedTransaction& txn, std::vector& accounts, const uint160& uSrcAccountID); TransactionEngineResult doPasswordSet(const SerializedTransaction& txn, std::vector& accounts); From 26d7f0e1a45c5acd1fab2357fbbd5684ae70af30 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Tue, 5 Jun 2012 13:05:42 -0700 Subject: [PATCH 04/12] Add ledger fuctionality for NicknameState. --- src/Ledger.cpp | 15 +++++++++++ src/Ledger.h | 48 +++++++++++++++++++++++------------ src/LedgerIndex.cpp | 33 ++++++++++++++++-------- src/LedgerNode.cpp | 61 +++++++++++++++++++-------------------------- src/RippleState.h | 1 + 5 files changed, 96 insertions(+), 62 deletions(-) diff --git a/src/Ledger.cpp b/src/Ledger.cpp index 1fda2ca217..fd12a7979c 100644 --- a/src/Ledger.cpp +++ b/src/Ledger.cpp @@ -153,6 +153,21 @@ AccountState::pointer Ledger::getAccountState(const NewcoinAddress& accountID) return boost::make_shared(sle); } +NicknameState::pointer Ledger::getNicknameState(const uint256& uNickname) +{ + ScopedLock l(mAccountStateMap->Lock()); + SHAMapItem::pointer item = mAccountStateMap->peekItem(Ledger::getNicknameIndex(uNickname)); + if (!item) + { + return NicknameState::pointer(); + } + + SerializedLedgerEntry::pointer sle = + boost::make_shared(item->peekSerializer(), item->getTag()); + if (sle->getType() != ltNICKNAME) return NicknameState::pointer(); + return boost::make_shared(sle); +} + RippleState::pointer Ledger::getRippleState(const uint256& uNode) { ScopedLock l(mAccountStateMap->Lock()); diff --git a/src/Ledger.h b/src/Ledger.h index d4fe92f460..8d7c8f5831 100644 --- a/src/Ledger.h +++ b/src/Ledger.h @@ -13,6 +13,7 @@ #include "Transaction.h" #include "AccountState.h" #include "RippleState.h" +#include "NicknameState.h" #include "types.h" #include "BitcoinUtil.h" #include "SHAMap.h" @@ -137,8 +138,6 @@ public: LedgerStateParms writeBack(LedgerStateParms parms, SLE::pointer); SLE::pointer getAccountRoot(LedgerStateParms& parms, const uint160& accountID); SLE::pointer getAccountRoot(LedgerStateParms& parms, const NewcoinAddress& naAccountID); - SLE::pointer getNickname(LedgerStateParms& parms, const std::string& nickname); - SLE::pointer getNickname(LedgerStateParms& parms, const uint256& nickHash); // database functions static void saveAcceptedLedger(Ledger::pointer); @@ -160,25 +159,21 @@ public: static uint256 getGeneratorIndex(const uint160& uGeneratorID); // - // Ripple functions + // Nickname functions // - static uint256 getRippleStateIndex(const NewcoinAddress& naA, const NewcoinAddress& naB, const uint160& uCurrency); - static uint256 getRippleStateIndex(const uint160& uiA, const uint160& uiB, const uint160& uCurrency) - { return getRippleStateIndex(NewcoinAddress::createAccountID(uiA), NewcoinAddress::createAccountID(uiB), uCurrency); } + uint256 getNicknameHash(const std::string& strNickname) + { Serializer s(strNickname); return s.getSHA256(); } - static uint256 getRippleStateIndex(const NewcoinAddress& naA, const NewcoinAddress& naB) - { return getRippleStateIndex(naA, naB, uint160()); } - static uint256 getRippleDirIndex(const uint160& uAccountID); + NicknameState::pointer getNicknameState(const uint256& uNickname); + NicknameState::pointer getNicknameState(const std::string& strNickname) + { return getNicknameState(getNicknameHash(strNickname)); } - RippleState::pointer getRippleState(const uint256& uNode); - SLE::pointer getRippleState(LedgerStateParms& parms, const uint256& uNode); + SLE::pointer getNickname(LedgerStateParms& parms, const uint256& uNickname); + SLE::pointer getNickname(LedgerStateParms& parms, const std::string& strNickname) + { return getNickname(parms, getNicknameHash(strNickname)); } - SLE::pointer getRippleState(LedgerStateParms& parms, const NewcoinAddress& naA, const NewcoinAddress& naB, const uint160& uCurrency) - { return getRippleState(parms, getRippleStateIndex(naA, naB, uCurrency)); } - - SLE::pointer getRippleState(LedgerStateParms& parms, const uint160& uiA, const uint160& uiB, const uint160& uCurrency) - { return getRippleState(parms, getRippleStateIndex(NewcoinAddress::createAccountID(uiA), NewcoinAddress::createAccountID(uiB), uCurrency)); } + static uint256 getNicknameIndex(const uint256& uNickname); // // Offer functions @@ -200,6 +195,27 @@ public: SLE::pointer getDirRoot(LedgerStateParms& parms, const uint256& uRootIndex); SLE::pointer getDirNode(LedgerStateParms& parms, const uint256& uNodeIndex); + // + // Ripple functions + // + + static uint256 getRippleStateIndex(const NewcoinAddress& naA, const NewcoinAddress& naB, const uint160& uCurrency); + static uint256 getRippleStateIndex(const uint160& uiA, const uint160& uiB, const uint160& uCurrency) + { return getRippleStateIndex(NewcoinAddress::createAccountID(uiA), NewcoinAddress::createAccountID(uiB), uCurrency); } + + static uint256 getRippleStateIndex(const NewcoinAddress& naA, const NewcoinAddress& naB) + { return getRippleStateIndex(naA, naB, uint160()); } + static uint256 getRippleDirIndex(const uint160& uAccountID); + + RippleState::pointer getRippleState(const uint256& uNode); + SLE::pointer getRippleState(LedgerStateParms& parms, const uint256& uNode); + + SLE::pointer getRippleState(LedgerStateParms& parms, const NewcoinAddress& naA, const NewcoinAddress& naB, const uint160& uCurrency) + { return getRippleState(parms, getRippleStateIndex(naA, naB, uCurrency)); } + + SLE::pointer getRippleState(LedgerStateParms& parms, const uint160& uiA, const uint160& uiB, const uint160& uCurrency) + { return getRippleState(parms, getRippleStateIndex(NewcoinAddress::createAccountID(uiA), NewcoinAddress::createAccountID(uiB), uCurrency)); } + // // Misc // diff --git a/src/LedgerIndex.cpp b/src/LedgerIndex.cpp index 89d78ed2a3..0bf18f1c88 100644 --- a/src/LedgerIndex.cpp +++ b/src/LedgerIndex.cpp @@ -11,6 +11,29 @@ uint256 Ledger::getAccountRootIndex(const uint160& uAccountID) return s.getSHA512Half(); } +// What is important: +// --> uNickname: is a Sha256 +// <-- SHA512/2: for consistency and speed in generating indexes. +uint256 Ledger::getNicknameIndex(const uint256& uNickname) +{ + Serializer s; + + s.add16(spaceNickname); + s.add256(uNickname); + + return s.getSHA512Half(); +} + +uint256 Ledger::getGeneratorIndex(const uint160& uGeneratorID) +{ + Serializer s; + + s.add16(spaceGenerator); + s.add160(uGeneratorID); + + return s.getSHA512Half(); +} + uint256 Ledger::getRippleStateIndex(const NewcoinAddress& naA, const NewcoinAddress& naB, const uint160& uCurrency) { uint160 uAID = naA.getAccountID(); @@ -36,16 +59,6 @@ uint256 Ledger::getRippleDirIndex(const uint160& uAccountID) return s.getSHA512Half(); } -uint256 Ledger::getGeneratorIndex(const uint160& uGeneratorID) -{ - Serializer s; - - s.add16(spaceGenerator); - s.add160(uGeneratorID); - - return s.getSHA512Half(); -} - uint160 Ledger::getOfferBase(const uint160& currencyIn, const uint160& accountIn, const uint160& currencyOut, const uint160& accountOut) { diff --git a/src/LedgerNode.cpp b/src/LedgerNode.cpp index 9ae466834e..d059b9c3e7 100644 --- a/src/LedgerNode.cpp +++ b/src/LedgerNode.cpp @@ -6,7 +6,7 @@ #include "utils.h" #include "Log.h" -LedgerStateParms Ledger::writeBack(LedgerStateParms parms, SerializedLedgerEntry::pointer entry) +LedgerStateParms Ledger::writeBack(LedgerStateParms parms, SLE::pointer entry) { ScopedLock l(mAccountStateMap->Lock()); bool create = false; @@ -43,7 +43,7 @@ LedgerStateParms Ledger::writeBack(LedgerStateParms parms, SerializedLedgerEntry return lepOKAY; } -SerializedLedgerEntry::pointer Ledger::getASNode(LedgerStateParms& parms, const uint256& nodeID, +SLE::pointer Ledger::getASNode(LedgerStateParms& parms, const uint256& nodeID, LedgerEntryType let ) { SHAMapItem::pointer account = mAccountStateMap->peekItem(nodeID); @@ -53,23 +53,23 @@ SerializedLedgerEntry::pointer Ledger::getASNode(LedgerStateParms& parms, const if ( (parms & lepCREATE) == 0 ) { parms = lepMISSING; - return SerializedLedgerEntry::pointer(); + return SLE::pointer(); } parms = parms | lepCREATED | lepOKAY; - SerializedLedgerEntry::pointer sle=boost::make_shared(let); + SLE::pointer sle=boost::make_shared(let); sle->setIndex(nodeID); return sle; } - SerializedLedgerEntry::pointer sle = - boost::make_shared(account->peekSerializer(), nodeID); + SLE::pointer sle = + boost::make_shared(account->peekSerializer(), nodeID); if(sle->getType() != let) { // maybe it's a currency or something parms = parms | lepWRONGTYPE; - return SerializedLedgerEntry::pointer(); + return SLE::pointer(); } parms = parms | lepOKAY; @@ -78,56 +78,45 @@ SerializedLedgerEntry::pointer Ledger::getASNode(LedgerStateParms& parms, const } -SerializedLedgerEntry::pointer Ledger::getAccountRoot(LedgerStateParms& parms, const uint160& accountID) +SLE::pointer Ledger::getAccountRoot(LedgerStateParms& parms, const uint160& accountID) { uint256 nodeID=getAccountRootIndex(accountID); return getASNode(parms, nodeID, ltACCOUNT_ROOT); } -SerializedLedgerEntry::pointer Ledger::getAccountRoot(LedgerStateParms& parms, const NewcoinAddress& naAccountID) +SLE::pointer Ledger::getAccountRoot(LedgerStateParms& parms, const NewcoinAddress& naAccountID) { return getAccountRoot(parms, naAccountID.getAccountID()); } -SerializedLedgerEntry::pointer Ledger::getNickname(LedgerStateParms& parms, const std::string& nickname) -{ - return getNickname(parms, Serializer::getSHA512Half(nickname)); -} - -SerializedLedgerEntry::pointer Ledger::getNickname(LedgerStateParms& parms, const uint256& nickHash) -{ - ScopedLock l(mAccountStateMap->Lock()); - - return getASNode(parms, nickHash, ltNICKNAME); -} - // // Generator Map // -SerializedLedgerEntry::pointer Ledger::getGenerator(LedgerStateParms& parms, const uint160& uGeneratorID) +SLE::pointer Ledger::getGenerator(LedgerStateParms& parms, const uint160& uGeneratorID) { - uint256 nodeID=getGeneratorIndex(uGeneratorID); - ScopedLock l(mAccountStateMap->Lock()); - try - { - return getASNode(parms, nodeID, ltGENERATOR_MAP); - } - catch (...) - { - parms = lepERROR; - return SerializedLedgerEntry::pointer(); - } + return getASNode(parms, getGeneratorIndex(uGeneratorID), ltGENERATOR_MAP); +} + +// +// Nickname +// + +SLE::pointer Ledger::getNickname(LedgerStateParms& parms, const uint256& uNickname) +{ + ScopedLock l(mAccountStateMap->Lock()); + + return getASNode(parms, uNickname, ltNICKNAME); } // // Ripple State // -SerializedLedgerEntry::pointer Ledger::getRippleState(LedgerStateParms& parms, const uint256& uNode) +SLE::pointer Ledger::getRippleState(LedgerStateParms& parms, const uint256& uNode) { ScopedLock l(mAccountStateMap->Lock()); @@ -152,14 +141,14 @@ uint256 Ledger::getDirIndex(const uint256& uBase, const uint64 uNodeDir) return uNode; } -SerializedLedgerEntry::pointer Ledger::getDirRoot(LedgerStateParms& parms, const uint256& uRootIndex) +SLE::pointer Ledger::getDirRoot(LedgerStateParms& parms, const uint256& uRootIndex) { ScopedLock l(mAccountStateMap->Lock()); return getASNode(parms, uRootIndex, ltDIR_ROOT); } -SerializedLedgerEntry::pointer Ledger::getDirNode(LedgerStateParms& parms, const uint256& uNodeIndex) +SLE::pointer Ledger::getDirNode(LedgerStateParms& parms, const uint256& uNodeIndex) { ScopedLock l(mAccountStateMap->Lock()); diff --git a/src/RippleState.h b/src/RippleState.h index 0f0281a28d..8efbae945f 100644 --- a/src/RippleState.h +++ b/src/RippleState.h @@ -3,6 +3,7 @@ // // A ripple line's state. +// - Isolate ledger entry format. // #include "SerializedLedger.h" From f6e32912bb05774fb44893fa71a39caf08bc5c6c Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Tue, 5 Jun 2012 13:06:20 -0700 Subject: [PATCH 05/12] Implement transaction creation for nickname_set. --- src/Transaction.cpp | 38 ++++++++++++++++++++++++++++++++++++++ src/Transaction.h | 17 +++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/src/Transaction.cpp b/src/Transaction.cpp index 72930ef294..c2ac06c86f 100644 --- a/src/Transaction.cpp +++ b/src/Transaction.cpp @@ -259,6 +259,44 @@ Transaction::pointer Transaction::sharedCreditSet( return tResult->setCreditSet(naPrivateKey, naDstAccountID, saLimitAmount, uAcceptRate); } +// +// NicknameSet +// + +Transaction::pointer Transaction::setNicknameSet( + const NewcoinAddress& naPrivateKey, + const uint256& uNickname, + bool bSetOffer, + const STAmount& saMinimumOffer) +{ + mTransaction->setITFieldH256(sfNickname, uNickname); + + // XXX Make sure field is present even for 0! + if (bSetOffer) + mTransaction->setITFieldAmount(sfMinimumOffer, saMinimumOffer); + + sign(naPrivateKey); + + return shared_from_this(); +} + +// --> bSetOffer: true, change offer +// --> saMinimumOffer: 0 to remove. +Transaction::pointer Transaction::sharedNicknameSet( + const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey, + const NewcoinAddress& naSourceAccount, + uint32 uSeq, + const STAmount& saFee, + uint32 uSourceTag, + const uint256& uNickname, + bool bSetOffer, + const STAmount& saMinimumOffer) +{ + pointer tResult = boost::make_shared(ttNICKNAME_SET, naPublicKey, naSourceAccount, uSeq, saFee, uSourceTag); + + return tResult->setNicknameSet(naPrivateKey, uNickname, bSetOffer, saMinimumOffer); +} + // // PasswordFund // diff --git a/src/Transaction.h b/src/Transaction.h index 90cb1b934d..bd1c1136ea 100644 --- a/src/Transaction.h +++ b/src/Transaction.h @@ -71,6 +71,12 @@ private: const STAmount& saLimitAmount, uint32 uAcceptRate); + Transaction::pointer setNicknameSet( + const NewcoinAddress& naPrivateKey, + const uint256& uNickname, + bool bSetOffer, + const STAmount& saMinimumOffer); + Transaction::pointer setPasswordFund( const NewcoinAddress& naPrivateKey, const NewcoinAddress& naDstAccountID); @@ -157,6 +163,17 @@ public: const STAmount& saLimitAmount, uint32 uAcceptRate); + // Set Nickname + static Transaction::pointer sharedNicknameSet( + const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey, + const NewcoinAddress& naSourceAccount, + uint32 uSeq, + const STAmount& saFee, + uint32 uSourceTag, + const uint256& uNickname, + bool bSetOffer, + const STAmount& saMinimumOffer); + // Pre-fund password change. static Transaction::pointer sharedPasswordFund( const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey, From 3945749b6405e3c69b15dcac4de98369eb6bcd69 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Tue, 5 Jun 2012 13:06:46 -0700 Subject: [PATCH 06/12] Implement NetworkOPs stubs for nickname_set. --- src/NetworkOPs.cpp | 9 +++++++++ src/NetworkOPs.h | 7 +++++++ 2 files changed, 16 insertions(+) diff --git a/src/NetworkOPs.cpp b/src/NetworkOPs.cpp index 33838890bd..ef517b5d33 100644 --- a/src/NetworkOPs.cpp +++ b/src/NetworkOPs.cpp @@ -210,6 +210,15 @@ STVector256 NetworkOPs::getDirNode(const uint256& uLedger, const uint256& uDirLi return svIndexes; } +// +// Nickname functions +// + +NicknameState::pointer NetworkOPs::getNicknameState(const uint256& uLedger, const std::string& strNickname) +{ + return mLedgerMaster->getLedgerByHash(uLedger)->getNicknameState(strNickname); +} + // // Ripple functions // diff --git a/src/NetworkOPs.h b/src/NetworkOPs.h index be1feb1c7c..f7fd4c121b 100644 --- a/src/NetworkOPs.h +++ b/src/NetworkOPs.h @@ -4,6 +4,7 @@ #include "LedgerMaster.h" #include "AccountState.h" #include "RippleState.h" +#include "NicknameState.h" // #include @@ -82,6 +83,12 @@ public: uint256& uDirNodeFirst, uint256& uDirNodeLast); STVector256 getDirNode(const uint256& uLedger, const uint256& uDirLineNode); + // + // Nickname functions + // + + NicknameState::pointer getNicknameState(const uint256& uLedger, const std::string& strNickname); + // // Ripple functions // From ba983ccec3e2de05f7568e87929085d56e7613ea Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Tue, 5 Jun 2012 13:07:17 -0700 Subject: [PATCH 07/12] Implement RPC commands nickname_info and nickname_set. --- src/RPCServer.cpp | 75 +++++++++++++++++++++++++++++++++++++++++++++++ src/RPCServer.h | 2 ++ src/main.cpp | 2 ++ 3 files changed, 79 insertions(+) diff --git a/src/RPCServer.cpp b/src/RPCServer.cpp index 1460767f1b..56194b20dd 100644 --- a/src/RPCServer.cpp +++ b/src/RPCServer.cpp @@ -22,6 +22,7 @@ #include "Conversion.h" #include "NewcoinAddress.h" #include "AccountState.h" +#include "NicknameState.h" #include "utils.h" #define VALIDATORS_FETCH_SECONDS 30 @@ -826,6 +827,78 @@ Json::Value RPCServer::doCreditSet(Json::Value& params) } } +// nickname_info +Json::Value RPCServer::doNicknameInfo(Json::Value& params) +{ + uint256 uLedger; + + if (params.size() != 1) + { + return JSONRPCError(400, "invalid params"); + } + + std::string strNickname = params[0u].asString(); + boost::trim(strNickname); + + if (strNickname.empty()) + { + return JSONRPCError(400, "invalid nickname (zero length)"); + } + else if (!mNetOps->available()) + { + return JSONRPCError(503, "network not available"); + } + else if ((uLedger = mNetOps->getCurrentLedger()).isZero()) + { + return JSONRPCError(503, "no current ledger"); + } + + NicknameState::pointer nsSrc = mNetOps->getNicknameState(uLedger, strNickname); + if (!nsSrc) + { + return JSONRPCError(500, "nickname does not exist"); + } + + Json::Value ret(Json::objectValue); + + ret["nickname"] = strNickname; + + nsSrc->addJson(ret); + + return ret; +} + +// nickname_set [] [] +Json::Value RPCServer::doNicknameSet(Json::Value& params) +{ + uint256 uLedger; + + if (params.size() < 2 || params.size() > 3) + { + return JSONRPCError(400, "invalid params"); + } + + std::string strNickname = params[2u].asString(); + boost::trim(strNickname); + + if (strNickname.empty()) + { + return JSONRPCError(400, "invalid nickname (zero length)"); + } + else if (!mNetOps->available()) + { + return JSONRPCError(503, "network not available"); + } + else if ((uLedger = mNetOps->getCurrentLedger()).isZero()) + { + return JSONRPCError(503, "no current ledger"); + } + + NicknameState::pointer nsSrc = mNetOps->getNicknameState(uLedger, strNickname); + + return "not implemented"; +} + // password_fund [] // YYY Make making account default to first account for seed. Json::Value RPCServer::doPasswordFund(Json::Value ¶ms) @@ -1867,6 +1940,8 @@ Json::Value RPCServer::doCommand(const std::string& command, Json::Value& params if (command == "account_wallet_set") return doAccountWalletSet(params); if (command == "connect") return doConnect(params); if (command == "credit_set") return doCreditSet(params); + if (command == "nickname_info") return doNicknameInfo(params); + if (command == "nickname_set") return doNicknameSet(params); if (command == "password_fund") return doPasswordFund(params); if (command == "password_set") return doPasswordSet(params); if (command == "peers") return doPeers(params); diff --git a/src/RPCServer.h b/src/RPCServer.h index 0a2acc8443..a8358235c3 100644 --- a/src/RPCServer.h +++ b/src/RPCServer.h @@ -56,6 +56,8 @@ private: Json::Value doConnect(Json::Value& params); Json::Value doCreditSet(Json::Value& params); Json::Value doLedger(Json::Value& params); + Json::Value doNicknameInfo(Json::Value& params); + Json::Value doNicknameSet(Json::Value& params); Json::Value doPasswordFund(Json::Value& params); Json::Value doPasswordSet(Json::Value& params); Json::Value doPeers(Json::Value& params); diff --git a/src/main.cpp b/src/main.cpp index 3e05f8be9e..caa32cb01b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -46,6 +46,8 @@ void printHelp(const po::options_description& desc) cout << " connect []" << endl; cout << " credit_set []" << endl; cout << " ledger" << endl; + cout << " nickname_info " << endl; + cout << " nickname_set [] []" << endl; cout << " password_fund []" << endl; cout << " password_set []" << endl; cout << " peers" << endl; From 8e88b1cd8a1c50dc6f3aabed1714ab3b4dc0541d Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Tue, 5 Jun 2012 14:13:00 -0700 Subject: [PATCH 08/12] Add fee configuration for creating nicknames. --- src/Config.cpp | 16 +++++++++++----- src/Config.h | 5 +++-- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/Config.cpp b/src/Config.cpp index a1e767cde1..980c9812d3 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -8,7 +8,8 @@ #include // Fees are in XNS raw. -#define DEFAULT_FEE_CREATE 1000 +#define DEFAULT_FEE_ACCOUNT_CREATE 1000 +#define DEFAULT_FEE_NICKNAME_CREATE 1000 #define DEFAULT_FEE_DEFAULT 100 #define CONFIG_FILE_NAME SYSTEM_NAME "d.cfg" // newcoind.cfg @@ -24,7 +25,8 @@ #define SECTION_PEER_CONNECT_LOW_WATER "peer_connect_low_water" #define SECTION_NETWORK_QUORUM "network_quorum" #define SECTION_VALIDATION_QUORUM "validation_quorum" -#define SECTION_FEE_CREATE "fee_create" +#define SECTION_FEE_ACCOUNT_CREATE "fee_account_create" +#define SECTION_FEE_NICKNAME_CREATE "fee_nickname_create" #define SECTION_FEE_DEFAULT "fee_default" #define SECTION_ACCOUNT_PROBE_MAX "account_probe_max" @@ -59,7 +61,8 @@ Config::Config() NETWORK_QUORUM = 0; // Don't need to see other nodes VALIDATION_QUORUM = 1; // Only need one node to vouch - FEE_CREATE = DEFAULT_FEE_CREATE; + FEE_ACCOUNT_CREATE = DEFAULT_FEE_ACCOUNT_CREATE; + FEE_NICKNAME_CREATE = DEFAULT_FEE_NICKNAME_CREATE; FEE_DEFAULT = DEFAULT_FEE_DEFAULT; ACCOUNT_PROBE_MAX = 10; @@ -118,8 +121,11 @@ void Config::load() if (sectionSingleB(secConfig, SECTION_VALIDATION_QUORUM, strTemp)) VALIDATION_QUORUM = MAX(0, boost::lexical_cast(strTemp)); - if (sectionSingleB(secConfig, SECTION_FEE_CREATE, strTemp)) - FEE_CREATE = boost::lexical_cast(strTemp); + if (sectionSingleB(secConfig, SECTION_FEE_ACCOUNT_CREATE, strTemp)) + FEE_ACCOUNT_CREATE = boost::lexical_cast(strTemp); + + if (sectionSingleB(secConfig, SECTION_FEE_NICKNAME_CREATE, strTemp)) + FEE_NICKNAME_CREATE = boost::lexical_cast(strTemp); if (sectionSingleB(secConfig, SECTION_FEE_DEFAULT, strTemp)) FEE_DEFAULT = boost::lexical_cast(strTemp); diff --git a/src/Config.h b/src/Config.h index 51290f0bd8..e6f74a0c6d 100644 --- a/src/Config.h +++ b/src/Config.h @@ -75,8 +75,9 @@ public: std::string VALIDATION_KEY; // Fees - uint64 FEE_CREATE; // Fee to create an account - uint64 FEE_DEFAULT; // Default fee. + uint64 FEE_DEFAULT; // Default fee. + uint64 FEE_ACCOUNT_CREATE; // Fee to create an account. + uint64 FEE_NICKNAME_CREATE; // Fee to create a nickname. // Configuration parameters std::string DATA_DIR; From 1f7abd6a94fa255dad863f99a0e70eff50795f3e Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Tue, 5 Jun 2012 14:13:32 -0700 Subject: [PATCH 09/12] Clean up getText for SerializedLedgerEntry. --- src/SerializedLedger.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/SerializedLedger.cpp b/src/SerializedLedger.cpp index b991a25790..beeb69dee5 100644 --- a/src/SerializedLedger.cpp +++ b/src/SerializedLedger.cpp @@ -1,6 +1,7 @@ - #include "SerializedLedger.h" +#include + SerializedLedgerEntry::SerializedLedgerEntry(SerializerIterator& sit, const uint256& index) : SerializedType("LedgerEntry"), mIndex(index) { @@ -47,12 +48,10 @@ std::string SerializedLedgerEntry::getFullText() const std::string SerializedLedgerEntry::getText() const { - std::string ret = "{"; - ret += mIndex.GetHex(); - ret += mVersion.getText(); - ret += mObject.getText(); - ret += "}"; - return ret; + return str(boost::format("{ %s, %s, %s }") + % mIndex.GetHex() + % mVersion.getText() + % mObject.getText()); } Json::Value SerializedLedgerEntry::getJson(int options) const From 41c6ae939a42e59e4ef593db75c28ced9d11b248 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Tue, 5 Jun 2012 14:14:03 -0700 Subject: [PATCH 10/12] Fix NicknameSet transaction handling. --- src/TransactionEngine.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/TransactionEngine.cpp b/src/TransactionEngine.cpp index df05307b24..8748f8b336 100644 --- a/src/TransactionEngine.cpp +++ b/src/TransactionEngine.cpp @@ -364,7 +364,17 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran case ttPAYMENT: if (txn.getFlags() & tfCreateAccount) { - saCost = theConfig.FEE_CREATE; + saCost = theConfig.FEE_ACCOUNT_CREATE; + } + break; + + case ttNICKNAME_SET: + { + LedgerStateParms qry = lepNONE; + SLE::pointer sleNickname = mLedger->getNickname(qry, txn.getITFieldH256(sfNickname)); + + if (!sleNickname) + saCost = theConfig.FEE_NICKNAME_CREATE; } break; @@ -878,7 +888,7 @@ TransactionEngineResult TransactionEngine::doNicknameSet(const SerializedTransac SLE::pointer sleSrc = accounts[0].second; - uint256 uNickname = txn.getITFieldH256(sfWalletLocator); + uint256 uNickname = txn.getITFieldH256(sfNickname); bool bMinOffer = txn.getITFieldPresent(sfMinimumOffer); STAmount saMinOffer = bMinOffer ? txn.getITFieldAmount(sfAmount) : STAmount(); @@ -899,7 +909,7 @@ TransactionEngineResult TransactionEngine::doNicknameSet(const SerializedTransac sleNickname->makeIFieldAbsent(sfMinimumOffer); } - accounts.push_back(std::make_pair(taaCREATE, sleNickname)); + accounts.push_back(std::make_pair(taaMODIFY, sleNickname)); } else { From 0b02b20003a0d7f6bc9286b8ec9e6320868df810 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Tue, 5 Jun 2012 14:50:42 -0700 Subject: [PATCH 11/12] Add support for a signature when creating NicknameSet transactions. --- src/Ledger.h | 2 +- src/Transaction.cpp | 11 ++++++++--- src/Transaction.h | 6 ++++-- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/Ledger.h b/src/Ledger.h index d4976d6170..9d82641295 100644 --- a/src/Ledger.h +++ b/src/Ledger.h @@ -165,7 +165,7 @@ public: // Nickname functions // - uint256 getNicknameHash(const std::string& strNickname) + static uint256 getNicknameHash(const std::string& strNickname) { Serializer s(strNickname); return s.getSHA256(); } NicknameState::pointer getNicknameState(const uint256& uNickname); diff --git a/src/Transaction.cpp b/src/Transaction.cpp index c2ac06c86f..328a7aa6fc 100644 --- a/src/Transaction.cpp +++ b/src/Transaction.cpp @@ -267,7 +267,8 @@ Transaction::pointer Transaction::setNicknameSet( const NewcoinAddress& naPrivateKey, const uint256& uNickname, bool bSetOffer, - const STAmount& saMinimumOffer) + const STAmount& saMinimumOffer, + const std::vector& vucSignature) { mTransaction->setITFieldH256(sfNickname, uNickname); @@ -275,6 +276,9 @@ Transaction::pointer Transaction::setNicknameSet( if (bSetOffer) mTransaction->setITFieldAmount(sfMinimumOffer, saMinimumOffer); + if (!vucSignature.empty()) + mTransaction->setITFieldVL(sfSignature, vucSignature); + sign(naPrivateKey); return shared_from_this(); @@ -290,11 +294,12 @@ Transaction::pointer Transaction::sharedNicknameSet( uint32 uSourceTag, const uint256& uNickname, bool bSetOffer, - const STAmount& saMinimumOffer) + const STAmount& saMinimumOffer, + const std::vector& vucSignature) { pointer tResult = boost::make_shared(ttNICKNAME_SET, naPublicKey, naSourceAccount, uSeq, saFee, uSourceTag); - return tResult->setNicknameSet(naPrivateKey, uNickname, bSetOffer, saMinimumOffer); + return tResult->setNicknameSet(naPrivateKey, uNickname, bSetOffer, saMinimumOffer, vucSignature); } // diff --git a/src/Transaction.h b/src/Transaction.h index bd1c1136ea..2510a04e64 100644 --- a/src/Transaction.h +++ b/src/Transaction.h @@ -75,7 +75,8 @@ private: const NewcoinAddress& naPrivateKey, const uint256& uNickname, bool bSetOffer, - const STAmount& saMinimumOffer); + const STAmount& saMinimumOffer, + const std::vector& vucSignature); Transaction::pointer setPasswordFund( const NewcoinAddress& naPrivateKey, @@ -172,7 +173,8 @@ public: uint32 uSourceTag, const uint256& uNickname, bool bSetOffer, - const STAmount& saMinimumOffer); + const STAmount& saMinimumOffer, + const std::vector& vucSignature); // Pre-fund password change. static Transaction::pointer sharedPasswordFund( From 1159e71c2639304b7e94c898b5c85c294f7f3d31 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Tue, 5 Jun 2012 14:52:37 -0700 Subject: [PATCH 12/12] Implement RPC commands nickname_info and nickname_set. --- src/NicknameState.cpp | 29 +++++++++++++ src/NicknameState.h | 37 +++++++++++++++++ src/RPCServer.cpp | 94 ++++++++++++++++++++++++++++++++++++------- src/RPCServer.h | 2 +- 4 files changed, 147 insertions(+), 15 deletions(-) create mode 100644 src/NicknameState.cpp create mode 100644 src/NicknameState.h 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);