diff --git a/src/RPCServer.cpp b/src/RPCServer.cpp index ec8346346f..3ea55211c6 100644 --- a/src/RPCServer.cpp +++ b/src/RPCServer.cpp @@ -232,9 +232,7 @@ Json::Value RPCServer::authorize(const NewcoinAddress& naSeed, const NewcoinAddr return JSONRPCError(500, "wrong password (changed)"); } - Json::Value obj(Json::objectValue); - - return obj; + return Json::Value(Json::objectValue); } // account_info || @@ -417,18 +415,21 @@ Json::Value RPCServer::doSend(Json::Value& params) SerializedLedgerEntry::pointer sleSrc; Json::Value obj = authorize(naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate, sleSrc); + if (!obj.empty()) + { + std::cerr << "Auth Error" << std::endl; + return obj; + } + STAmount saSrcBalance = sleSrc->getIValueFieldAmount(sfBalance); - if (!obj.isNull()) - { - nothing(); - } - else if (saSrcBalance < theConfig.FEE_DEFAULT) + if (saSrcBalance < theConfig.FEE_DEFAULT) { return JSONRPCError(500, "insufficent funds"); } else { + STPath spPaths; Transaction::pointer trans = Transaction::sharedPayment( naAccountPublic, naAccountPrivate, naSrcAccountID, @@ -437,7 +438,8 @@ Json::Value RPCServer::doSend(Json::Value& params) 0, // YYY No source tag naDstAccountID, saDstAmount, - saSrcAmount); + saSrcAmount, + spPaths); (void) theApp->getOPs().processTransaction(trans); diff --git a/src/SerializedObject.cpp b/src/SerializedObject.cpp index 41443033ac..554acf4b55 100644 --- a/src/SerializedObject.cpp +++ b/src/SerializedObject.cpp @@ -564,6 +564,16 @@ void STObject::setValueFieldAmount(SOE_Field field, const STAmount &v) (*cf) = v; } +void STObject::setValueFieldPath(SOE_Field field, const STPath &v) +{ + SerializedType* rf = getPField(field); + if (!rf) throw std::runtime_error("Field not found"); + if (rf->getSType() == STI_NOTPRESENT) rf = makeFieldPresent(field); + STPath* cf = dynamic_cast(rf); + if (!cf) throw std::runtime_error("Wrong field type"); + (*cf) = v; +} + Json::Value STObject::getJson(int options) const { Json::Value ret(Json::objectValue); diff --git a/src/SerializedObject.h b/src/SerializedObject.h index 505aa63745..29881b8a69 100644 --- a/src/SerializedObject.h +++ b/src/SerializedObject.h @@ -57,8 +57,10 @@ enum SOE_Field sfNextRateLgr, sfNickname, sfOfferCurrency, + sfPaths, sfPubKey, sfRateLock, + sfSendMax, sfSequence, sfSignature, sfSigningKey, @@ -159,6 +161,7 @@ public: void setValueFieldAccount(SOE_Field field, const NewcoinAddress& addr) { setValueFieldAccount(field, addr.getAccountID()); } void setValueFieldAmount(SOE_Field field, const STAmount&); + void setValueFieldPath(SOE_Field field, const STPath&); bool isFieldPresent(SOE_Field field) const; SerializedType* makeFieldPresent(SOE_Field field); diff --git a/src/SerializedTransaction.h b/src/SerializedTransaction.h index 5becb4fe0f..ba516ecf40 100644 --- a/src/SerializedTransaction.h +++ b/src/SerializedTransaction.h @@ -101,6 +101,8 @@ public: { return mInnerTxn.setValueFieldAccount(field, v); } void setITFieldAmount(SOE_Field field, const STAmount& v) { return mInnerTxn.setValueFieldAmount(field, v); } + void setITFieldPath(SOE_Field field, const STPath& v) + { return mInnerTxn.setValueFieldPath(field, v); } // optional field functions bool getITFieldPresent(SOE_Field field) const; diff --git a/src/SerializedTypes.h b/src/SerializedTypes.h index 5a902b29de..01ad34d955 100644 --- a/src/SerializedTypes.h +++ b/src/SerializedTypes.h @@ -467,10 +467,10 @@ public: virtual Json::Value getJson(int) const; SerializedTypeID getSType() const { return STI_PATH; } - int getPathLength() const { return value.size(); } + int getPathLength() const { return value.size(); } const STPathElement& getElement(int off) const { return value[off]; } STPathElement& peekElement(int off) { return value[off]; } - void emptyPath() { value.empty(); } + bool emptyPath() const { return value.empty(); } void addPathElement(const STPathElement& e) { value.push_back(e); } }; diff --git a/src/Transaction.cpp b/src/Transaction.cpp index 96ae29f622..d2ae2f3459 100644 --- a/src/Transaction.cpp +++ b/src/Transaction.cpp @@ -53,11 +53,11 @@ Transaction::pointer Transaction::sharedTransaction(const std::vectorsetITFieldU32(sfFlags, tfCreateAccount); mTransaction->setITFieldAccount(sfDestination, naCreateAccountID); @@ -169,11 +169,11 @@ Transaction::pointer Transaction::setCreate( Transaction::pointer Transaction::sharedCreate( const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey, const NewcoinAddress& naSourceAccount, - uint32 uSeq, - STAmount saFee, - uint32 uSourceTag, - const NewcoinAddress& naCreateAccountID, - STAmount uFund) + uint32 uSeq, + const STAmount& saFee, + uint32 uSourceTag, + const NewcoinAddress& naCreateAccountID, + const STAmount& uFund) { pointer tResult = boost::make_shared(ttPAYMENT, naPublicKey, naSourceAccount, @@ -187,13 +187,27 @@ Transaction::pointer Transaction::sharedCreate( // Transaction::pointer Transaction::setPayment( - const NewcoinAddress& naPrivateKey, - const NewcoinAddress& toAccount, - STAmount saAmount) + const NewcoinAddress& naPrivateKey, + const NewcoinAddress& toAccount, + const STAmount& saAmount, + const STAmount& saSendMax, + const STPath& spPaths) { mTransaction->setITFieldAccount(sfDestination, toAccount); mTransaction->setITFieldAmount(sfAmount, saAmount); + if (saAmount != saSendMax) + { + mTransaction->makeITFieldPresent(sfSendMax); + mTransaction->setITFieldAmount(sfSendMax, saSendMax); + } + + if (!spPaths.emptyPath()) + { + mTransaction->makeITFieldPresent(sfPaths); + mTransaction->setITFieldPath(sfPaths, spPaths); + } + sign(naPrivateKey); return shared_from_this(); @@ -201,19 +215,20 @@ Transaction::pointer Transaction::setPayment( Transaction::pointer Transaction::sharedPayment( const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey, - const NewcoinAddress& naSourceAccount, - uint32 uSeq, - STAmount saFee, - uint32 uSourceTag, - const NewcoinAddress& toAccount, - STAmount saAmount, - STAmount saSendMax) + const NewcoinAddress& naSourceAccount, + uint32 uSeq, + const STAmount& saFee, + uint32 uSourceTag, + const NewcoinAddress& toAccount, + const STAmount& saAmount, + const STAmount& saSendMax, + const STPath& saPaths) { pointer tResult = boost::make_shared(ttPAYMENT, naPublicKey, naSourceAccount, uSeq, saFee, uSourceTag); - return tResult->setPayment(naPrivateKey, toAccount, saAmount); + return tResult->setPayment(naPrivateKey, toAccount, saAmount, saSendMax, saPaths); } // diff --git a/src/Transaction.h b/src/Transaction.h index e2a7d43e1e..48273aa218 100644 --- a/src/Transaction.h +++ b/src/Transaction.h @@ -47,20 +47,22 @@ private: SerializedTransaction::pointer mTransaction; Transaction::pointer setClaim( - const NewcoinAddress& naPrivateKey, - const std::vector& vucGenerator, - const std::vector& vucPubKey, - const std::vector& vucSignature); + const NewcoinAddress& naPrivateKey, + const std::vector& vucGenerator, + const std::vector& vucPubKey, + const std::vector& vucSignature); Transaction::pointer setCreate( - const NewcoinAddress& naPrivateKey, - const NewcoinAddress& naCreateAccountID, - STAmount uFund); + const NewcoinAddress& naPrivateKey, + const NewcoinAddress& naCreateAccountID, + const STAmount& uFund); Transaction::pointer setPayment( - const NewcoinAddress& naPrivateKey, - const NewcoinAddress& toAccount, - STAmount saAmount); + const NewcoinAddress& naPrivateKey, + const NewcoinAddress& toAccount, + const STAmount& saAmount, + const STAmount& saSendMax, + const STPath& spPaths); public: Transaction(const SerializedTransaction::pointer st, bool bValidate); @@ -69,41 +71,42 @@ public: Transaction( TransactionType ttKind, - const NewcoinAddress& naPublicKey, // To prove transaction is consistent and authorized. - const NewcoinAddress& naSourceAccount, // To identify the paying account. - uint32 uSeq, // To order transactions. - STAmount saFee, // Transaction fee. - uint32 uSourceTag); // User call back value. + const NewcoinAddress& naPublicKey, // To prove transaction is consistent and authorized. + const NewcoinAddress& naSourceAccount, // To identify the paying account. + uint32 uSeq, // To order transactions. + const STAmount& saFee, // Transaction fee. + uint32 uSourceTag); // User call back value. // Claim a wallet. static Transaction::pointer sharedClaim( const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey, - const NewcoinAddress& naSourceAccount, - uint32 uSourceTag, - const std::vector& vucGenerator, - const std::vector& vucPubKey, - const std::vector& vucSignature); + const NewcoinAddress& naSourceAccount, + uint32 uSourceTag, + const std::vector& vucGenerator, + const std::vector& vucPubKey, + const std::vector& vucSignature); // Create an account. static Transaction::pointer sharedCreate( const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey, - const NewcoinAddress& naSourceAccount, - uint32 uSeq, - STAmount saFee, - uint32 uSourceTag, - const NewcoinAddress& naCreateAccountID, // Account to create. - STAmount uFund); // Initial funds in XNC. + const NewcoinAddress& naSourceAccount, + uint32 uSeq, + const STAmount& saFee, + uint32 uSourceTag, + const NewcoinAddress& naCreateAccountID, // Account to create. + const STAmount& uFund); // Initial funds in XNC. // Make a payment. static Transaction::pointer sharedPayment( const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey, - const NewcoinAddress& naSourceAccount, - uint32 uSeq, - STAmount saFee, - uint32 uSourceTag, - const NewcoinAddress& toAccount, - STAmount saAmount, - STAmount saSendMax); + const NewcoinAddress& naSourceAccount, + uint32 uSeq, + const STAmount& saFee, + uint32 uSourceTag, + const NewcoinAddress& toAccount, + const STAmount& saAmount, + const STAmount& saSendMax, + const STPath& saPaths); bool sign(const NewcoinAddress& naAccountPrivate); bool checkSign() const; diff --git a/src/TransactionEngine.cpp b/src/TransactionEngine.cpp index a693b47581..ffb7f72389 100644 --- a/src/TransactionEngine.cpp +++ b/src/TransactionEngine.cpp @@ -331,6 +331,7 @@ TransactionEngineResult TransactionEngine::doPayment(const SerializedTransaction std::cerr << "doPayment: Invalid transaction: Payment destination account not specifed." << std::endl; return tenINVALID; } + // XXX Only bad if no currency conversion in between through other people's offer. else if (srcAccountID == dstAccountID) { std::cerr << "doPayment: Invalid transaction: Source account is the same as destination." << std::endl; diff --git a/src/TransactionFormats.cpp b/src/TransactionFormats.cpp index a53f898578..03c3d3dd92 100644 --- a/src/TransactionFormats.cpp +++ b/src/TransactionFormats.cpp @@ -9,8 +9,10 @@ TransactionFormat InnerTxnFormats[]= { S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 }, { S_FIELD(Destination), STI_ACCOUNT, SOE_REQUIRED, 0 }, { S_FIELD(Amount), STI_AMOUNT, SOE_REQUIRED, 0 }, - { S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 1 }, - { S_FIELD(InvoiceID), STI_HASH256, SOE_IFFLAG, 2 }, + { S_FIELD(SendMax), STI_AMOUNT, SOE_IFFLAG, 1 }, + { S_FIELD(Paths), STI_PATH, SOE_IFFLAG, 2 }, + { S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 4 }, + { S_FIELD(InvoiceID), STI_HASH256, SOE_IFFLAG, 8 }, { S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x02000000 }, { sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } } },