mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Work toward TransactionEngine ripple support.
This commit is contained in:
@@ -1,6 +1,11 @@
|
|||||||
|
//
|
||||||
|
// XXX Should make sure all fields and are recognized on a transactions.
|
||||||
|
// XXX Make sure fee is claimed for failed transactions.
|
||||||
|
//
|
||||||
|
|
||||||
#include "TransactionEngine.h"
|
#include "TransactionEngine.h"
|
||||||
|
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
#include <boost/format.hpp>
|
#include <boost/format.hpp>
|
||||||
|
|
||||||
#include "../json/writer.h"
|
#include "../json/writer.h"
|
||||||
@@ -1007,10 +1012,15 @@ TransactionEngineResult TransactionEngine::doPasswordSet(const SerializedTransac
|
|||||||
|
|
||||||
TransactionEngineResult TransactionEngine::doPayment(const SerializedTransaction& txn,
|
TransactionEngineResult TransactionEngine::doPayment(const SerializedTransaction& txn,
|
||||||
std::vector<AffectedAccount>& accounts,
|
std::vector<AffectedAccount>& accounts,
|
||||||
const uint160& srcAccountID)
|
const uint160& uSrcAccountID)
|
||||||
{
|
{
|
||||||
uint32 txFlags = txn.getFlags();
|
uint32 txFlags = txn.getFlags();
|
||||||
uint160 uDstAccountID = txn.getITFieldAccount(sfDestination);
|
uint160 uDstAccountID = txn.getITFieldAccount(sfDestination);
|
||||||
|
// XXX Could also be ripple if direct credit lines.
|
||||||
|
bool bRipple = txn.getITFieldPresent(sfPaths);
|
||||||
|
bool bCreate = !!(txFlags & tfCreateAccount);
|
||||||
|
STAmount saAmount = txn.getITFieldAmount(sfAmount);
|
||||||
|
STAmount saSrcBalance = accounts[0].second->getIValueFieldAmount(sfBalance);
|
||||||
|
|
||||||
if (!uDstAccountID)
|
if (!uDstAccountID)
|
||||||
{
|
{
|
||||||
@@ -1018,38 +1028,30 @@ TransactionEngineResult TransactionEngine::doPayment(const SerializedTransaction
|
|||||||
return tenINVALID;
|
return tenINVALID;
|
||||||
}
|
}
|
||||||
// XXX Only bad if no currency conversion in between through other people's offer.
|
// XXX Only bad if no currency conversion in between through other people's offer.
|
||||||
else if (srcAccountID == uDstAccountID)
|
else if (uSrcAccountID == uDstAccountID)
|
||||||
{
|
{
|
||||||
std::cerr << "doPayment: Invalid transaction: Source account is the same as destination." << std::endl;
|
std::cerr << "doPayment: Invalid transaction: Source account is the same as destination." << std::endl;
|
||||||
return tenINVALID;
|
return tenINVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bCreate = !!(txFlags & tfCreateAccount);
|
// XXX Allow ripple to create.
|
||||||
|
|
||||||
uint160 uCurrency;
|
|
||||||
if (txn.getITFieldPresent(sfCurrency))
|
|
||||||
{
|
|
||||||
uCurrency = txn.getITFieldH160(sfCurrency);
|
|
||||||
if (!uCurrency)
|
|
||||||
{
|
|
||||||
std::cerr << "doPayment: Invalid transaction: " SYSTEM_CURRENCY_CODE " explicitly specified." << std::endl;
|
|
||||||
return tenEXPLICITXNC;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LedgerStateParms qry = lepNONE;
|
LedgerStateParms qry = lepNONE;
|
||||||
SLE::pointer sleDst = mLedger->getAccountRoot(qry, uDstAccountID);
|
SLE::pointer sleDst = mLedger->getAccountRoot(qry, uDstAccountID);
|
||||||
if (!sleDst)
|
if (!sleDst)
|
||||||
{
|
{
|
||||||
// Destination account does not exist.
|
// Destination account does not exist.
|
||||||
if (bCreate && !!uCurrency)
|
// XXX Also make sure non-ripple dest if creating.
|
||||||
|
if (bCreate && !saAmount.isNative())
|
||||||
{
|
{
|
||||||
std::cerr << "doPayment: Invalid transaction: Create account may only fund XBC." << std::endl;
|
std::cerr << "doPayment: Invalid transaction: Create account may only fund XNS." << std::endl;
|
||||||
return tenCREATEXNC;
|
|
||||||
|
return tenCREATEXNS;
|
||||||
}
|
}
|
||||||
else if (!bCreate)
|
else if (!bCreate)
|
||||||
{
|
{
|
||||||
std::cerr << "doPayment: Delay transaction: Destination account does not exist." << std::endl;
|
std::cerr << "doPayment: Delay transaction: Destination account does not exist." << std::endl;
|
||||||
|
|
||||||
return terNO_DST;
|
return terNO_DST;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1066,6 +1068,7 @@ TransactionEngineResult TransactionEngine::doPayment(const SerializedTransaction
|
|||||||
else if (bCreate)
|
else if (bCreate)
|
||||||
{
|
{
|
||||||
std::cerr << "doPayment: Invalid transaction: Account already created." << std::endl;
|
std::cerr << "doPayment: Invalid transaction: Account already created." << std::endl;
|
||||||
|
|
||||||
return terCREATED;
|
return terCREATED;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1073,28 +1076,68 @@ TransactionEngineResult TransactionEngine::doPayment(const SerializedTransaction
|
|||||||
accounts.push_back(std::make_pair(taaMODIFY, sleDst));
|
accounts.push_back(std::make_pair(taaMODIFY, sleDst));
|
||||||
}
|
}
|
||||||
|
|
||||||
STAmount saAmount = txn.getITFieldAmount(sfAmount);
|
if (!bRipple)
|
||||||
|
|
||||||
if (!uCurrency)
|
|
||||||
{
|
{
|
||||||
STAmount saSrcBalance = accounts[0].second->getIValueFieldAmount(sfBalance);
|
// Direct XNS payment.
|
||||||
|
if (!saAmount.isNative())
|
||||||
|
{
|
||||||
|
std::cerr << "doPayment: Invalid transaction: direct " SYSTEM_CURRENCY_CODE " required." << std::endl;
|
||||||
|
|
||||||
|
return tenDIRECT_XNS_ONLY;
|
||||||
|
}
|
||||||
|
|
||||||
if (saSrcBalance < saAmount)
|
if (saSrcBalance < saAmount)
|
||||||
{
|
{
|
||||||
std::cerr << "doPayment: Delay transaction: Insufficent funds." << std::endl;
|
std::cerr << "doPayment: Delay transaction: Insufficent funds." << std::endl;
|
||||||
|
|
||||||
return terUNFUNDED;
|
return terUNFUNDED;
|
||||||
}
|
}
|
||||||
|
|
||||||
accounts[0].second->setIFieldAmount(sfBalance, saSrcBalance - saAmount);
|
accounts[0].second->setIFieldAmount(sfBalance, saSrcBalance - saAmount);
|
||||||
accounts[1].second->setIFieldAmount(sfBalance, accounts[1].second->getIValueFieldAmount(sfBalance) + saAmount);
|
accounts[1].second->setIFieldAmount(sfBalance, accounts[1].second->getIValueFieldAmount(sfBalance) + saAmount);
|
||||||
}
|
|
||||||
else
|
return terSUCCESS;
|
||||||
{
|
|
||||||
// WRITEME: Handle non-native currencies, paths
|
|
||||||
return tenUNKNOWN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return terSUCCESS;
|
//
|
||||||
|
// Try direct ripple first.
|
||||||
|
//
|
||||||
|
|
||||||
|
uint160 uDstCurrency = saAmount.getCurrency();
|
||||||
|
|
||||||
|
qry = lepNONE;
|
||||||
|
SLE::pointer sleRippleState = mLedger->getRippleState(qry, uSrcAccountID, uDstAccountID, uDstCurrency);
|
||||||
|
|
||||||
|
if (sleRippleState)
|
||||||
|
{
|
||||||
|
// There is a direct relationship.
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
STPathSet spsPaths = txn.getITFieldPathSet(sfPaths);
|
||||||
|
|
||||||
|
// XXX If we are parsing for determing forwarding check maximum path count.
|
||||||
|
if (!spsPaths.getPathCount())
|
||||||
|
{
|
||||||
|
std::cerr << "doPayment: Invalid transaction: No paths." << std::endl;
|
||||||
|
|
||||||
|
return tenRIPPLE_EMPTY;
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
std::vector<STPath> spPath;
|
||||||
|
|
||||||
|
BOOST_FOREACH(std::vector<STPath>& spPath, spsPaths)
|
||||||
|
{
|
||||||
|
|
||||||
|
std::cerr << "doPayment: Implementation error: Not implemented." << std::endl;
|
||||||
|
|
||||||
|
return tenUNKNOWN;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::cerr << "doPayment: Delay transaction: No ripple paths could be satisfied." << std::endl;
|
||||||
|
|
||||||
|
return terBAD_RIPPLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
TransactionEngineResult TransactionEngine::doTransitSet(const SerializedTransaction& st, std::vector<AffectedAccount>&)
|
TransactionEngineResult TransactionEngine::doTransitSet(const SerializedTransaction& st, std::vector<AffectedAccount>&)
|
||||||
|
|||||||
@@ -14,20 +14,23 @@ enum TransactionEngineResult
|
|||||||
|
|
||||||
// Malformed: Fee claimed
|
// Malformed: Fee claimed
|
||||||
tenGEN_IN_USE = -300, // Generator already in use.
|
tenGEN_IN_USE = -300, // Generator already in use.
|
||||||
tenCREATEXNC, // Can not specify non XNC for Create.
|
tenCREATEXNS, // Can not specify non XNS for Create.
|
||||||
tenEXPLICITXNC, // XNC is used by default, don't specify it.
|
tenEXPLICITXNS, // XNS is used by default, don't specify it.
|
||||||
tenDST_NEEDED, // Destination not specified.
|
tenDST_NEEDED, // Destination not specified.
|
||||||
tenDST_IS_SRC, // Destination may not be source.
|
tenDST_IS_SRC, // Destination may not be source.
|
||||||
tenBAD_GEN_AUTH, // Not authorized to claim generator.
|
tenBAD_GEN_AUTH, // Not authorized to claim generator.
|
||||||
tenBAD_ADD_AUTH, // Not authorized to add account.
|
tenBAD_ADD_AUTH, // Not authorized to add account.
|
||||||
tenBAD_CLAIM_ID, // Malformed.
|
tenBAD_CLAIM_ID, // Malformed.
|
||||||
tenBAD_SET_ID, // Malformed.
|
tenBAD_SET_ID, // Malformed.
|
||||||
|
tenDIRECT_XNS_ONLY, // Direct payments are non-ripple XNS only.
|
||||||
|
tenRIPPLE_EMPTY, // PathSet with no paths.
|
||||||
|
|
||||||
// Invalid: Ledger won't allow.
|
// Invalid: Ledger won't allow.
|
||||||
tenCLAIMED = -200, // Can not claim a previously claimed account.
|
tenCLAIMED = -200, // Can not claim a previously claimed account.
|
||||||
tenCREATED, // Can't add an already created account.
|
tenCREATED, // Can't add an already created account.
|
||||||
tenMSG_SET, // Can't change a message key.
|
tenMSG_SET, // Can't change a message key.
|
||||||
tenBAD_AUTH_MASTER, // Auth for unclaimed account needs correct master key.
|
tenBAD_AUTH_MASTER, // Auth for unclaimed account needs correct master key.
|
||||||
|
tenBAD_RIPPLE, // Ledger prevents ripple from succeeding.
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
tenFAILED = -100, // Something broke horribly
|
tenFAILED = -100, // Something broke horribly
|
||||||
@@ -61,6 +64,7 @@ enum TransactionEngineResult
|
|||||||
terFUNDS_SPENT, // Can't set password, password set funds already spent.
|
terFUNDS_SPENT, // Can't set password, password set funds already spent.
|
||||||
terUNCLAIMED, // Can not use an unclaimed account.
|
terUNCLAIMED, // Can not use an unclaimed account.
|
||||||
terBAD_AUTH, // Transaction's public key is not authorized.
|
terBAD_AUTH, // Transaction's public key is not authorized.
|
||||||
|
terBAD_RIPPLE, // No ripple path can be satisfied.
|
||||||
};
|
};
|
||||||
|
|
||||||
enum TransactionEngineParams
|
enum TransactionEngineParams
|
||||||
|
|||||||
Reference in New Issue
Block a user