Work toward TransactionEngine ripple support.

This commit is contained in:
Arthur Britto
2012-06-17 20:31:05 -07:00
parent 616af57654
commit 171d2f1bf5
2 changed files with 78 additions and 31 deletions

View File

@@ -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>&)

View File

@@ -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