Handle make payment for native currencies.

Keep a vector of affected account state nodes to make atomicity easier.
This commit is contained in:
JoelKatz
2012-04-22 19:14:06 -07:00
parent 003ec1af1e
commit a5e8ab6943
2 changed files with 95 additions and 27 deletions

View File

@@ -1,5 +1,6 @@
#include "TransactionEngine.h" #include "TransactionEngine.h"
#include "TransactionFormats.h" #include "TransactionFormats.h"
TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTransaction& txn, TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTransaction& txn,
@@ -51,7 +52,10 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
return terALREADY; return terALREADY;
return terPAST_SEQ; return terPAST_SEQ;
} }
else src->setIFieldU32(sfSequence, t_seq);
std::vector<AffectedAccount> accounts;
accounts.push_back(std::make_pair(taaMODIFY, src));
TransactionEngineResult result = terUNKNOWN; TransactionEngineResult result = terUNKNOWN;
switch(txn.getTxnType()) switch(txn.getTxnType())
{ {
@@ -60,15 +64,15 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
break; break;
case ttMAKE_PAYMENT: case ttMAKE_PAYMENT:
result = doPayment(txn, *src); result = doPayment(txn, accounts);
break; break;
case ttINVOICE: case ttINVOICE:
result = doInvoice(txn, *src); result = doInvoice(txn, accounts);
break; break;
case ttEXCHANGE_OFFER: case ttEXCHANGE_OFFER:
result = doOffer(txn, *src); result = doOffer(txn, accounts);
break; break;
default: default:
@@ -77,13 +81,21 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
} }
if (result == terSUCCESS) if (result == terSUCCESS)
{ // Write back the source account state and add the transaction to the ledger { // Write back the account states and add the transaction to the ledger
// WRITEME: Special case code for changing transaction key // WRITEME: Special case code for changing transaction key
src->setIFieldU32(sfSequence, t_seq); for(std::vector<AffectedAccount>::iterator it=accounts.begin(), end=accounts.end();
if(mLedger->writeBack(lepNONE, src) & lepERROR) it != end; ++it)
{ {
if ( (it->first==taaMODIFY) || (it->first==taaCREATE) )
{
if(mLedger->writeBack(lepNONE, it->second) & lepERROR)
assert(false); assert(false);
return terFAILED; }
else if (it->first == taaDELETE)
{
if(!mLedger->peekAccountStateMap()->delItem(it->second->getIndex()))
assert(false);
}
} }
Serializer s; Serializer s;
@@ -94,38 +106,84 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
return result; return result;
} }
TransactionEngineResult TransactionEngine::doPayment(const SerializedTransaction& txn, SerializedLedgerEntry& source) TransactionEngineResult TransactionEngine::doPayment(const SerializedTransaction& txn,
std::vector<AffectedAccount>& accounts)
{
uint32 txFlags = txn.getFlags();
uint160 destAccount = txn.getITFieldAccount(sfDestination);
// Does the destination account exist?
if (!destAccount) return terINVALID;
LedgerStateParms qry = lepNONE;
SerializedLedgerEntry::pointer dest = mLedger->getAccountRoot(qry, destAccount);
if (!dest)
{ // can this transaction create an account
if ((txFlags & 0x00010000) == 0) // no
return terNO_TARGET;
dest = boost::make_shared<SerializedLedgerEntry>(ltACCOUNT_ROOT);
dest->setIndex(Ledger::getAccountRootIndex(destAccount));
dest->setIFieldAccount(sfAccount, destAccount);
dest->setIFieldU32(sfSequence, 1);
accounts.push_back(std::make_pair(taaCREATE, dest));
}
else accounts.push_back(std::make_pair(taaMODIFY, dest));
uint64 amount = txn.getITFieldU64(sfAmount);
uint160 currency;
if(txn.getITFieldPresent(sfCurrency))
currency = txn.getITFieldH160(sfCurrency);
bool native = !!currency;
if (native)
{
uint64 balance = accounts[0].second->getIFieldU64(sfBalance);
if (balance < amount) return terUNFUNDED;
accounts[0].second->setIFieldU64(sfBalance, balance - amount);
accounts[1].second->setIFieldU64(sfBalance, accounts[1].second->getIFieldU64(sfBalance) + amount);
}
else
{
// WRITEME: Handle non-native currencies, paths
return terUNKNOWN;
}
return terUNKNOWN;
}
TransactionEngineResult TransactionEngine::doInvoice(const SerializedTransaction& txn,
std::vector<AffectedAccount>& accounts)
{ {
return terUNKNOWN; return terUNKNOWN;
} }
TransactionEngineResult TransactionEngine::doInvoice(const SerializedTransaction&, SerializedLedgerEntry& source) TransactionEngineResult TransactionEngine::doOffer(const SerializedTransaction& txn,
std::vector<AffectedAccount>& accounts)
{ {
return terUNKNOWN; return terUNKNOWN;
} }
TransactionEngineResult TransactionEngine::doOffer(const SerializedTransaction&, SerializedLedgerEntry& source) TransactionEngineResult TransactionEngine::doTake(const SerializedTransaction& txn,
std::vector<AffectedAccount>& accounts)
{ {
return terUNKNOWN; return terUNKNOWN;
} }
TransactionEngineResult TransactionEngine::doTake(const SerializedTransaction&, SerializedLedgerEntry& source) TransactionEngineResult TransactionEngine::doCancel(const SerializedTransaction& txn,
std::vector<AffectedAccount>& accounts)
{ {
return terUNKNOWN; return terUNKNOWN;
} }
TransactionEngineResult TransactionEngine::doCancel(const SerializedTransaction&, SerializedLedgerEntry& source) TransactionEngineResult TransactionEngine::doStore(const SerializedTransaction& txn,
std::vector<AffectedAccount>& accounts)
{ {
return terUNKNOWN; return terUNKNOWN;
} }
TransactionEngineResult TransactionEngine::doStore(const SerializedTransaction&, SerializedLedgerEntry& source) TransactionEngineResult TransactionEngine::doDelete(const SerializedTransaction& txn,
std::vector<AffectedAccount>& accounts)
{ {
return terUNKNOWN; return terUNKNOWN;
} }
TransactionEngineResult TransactionEngine::doDelete(const SerializedTransaction&, SerializedLedgerEntry& source)
{
return terUNKNOWN;
}

View File

@@ -36,18 +36,28 @@ enum TransactionEngineParams
tepNO_CHECK_FEE = 2, // It was voted into a ledger anyway tepNO_CHECK_FEE = 2, // It was voted into a ledger anyway
}; };
enum TransactionAccountAction
{
taaACCESS,
taaCREATE,
taaMODIFY,
taaDELETE
};
typedef std::pair<TransactionAccountAction, SerializedLedgerEntry::pointer> AffectedAccount;
class TransactionEngine class TransactionEngine
{ {
protected: protected:
Ledger::pointer mLedger; Ledger::pointer mLedger;
TransactionEngineResult doPayment(const SerializedTransaction&, SerializedLedgerEntry& source); TransactionEngineResult doPayment(const SerializedTransaction&, std::vector<AffectedAccount>&);
TransactionEngineResult doInvoice(const SerializedTransaction&, SerializedLedgerEntry& source); TransactionEngineResult doInvoice(const SerializedTransaction&, std::vector<AffectedAccount>&);
TransactionEngineResult doOffer(const SerializedTransaction&, SerializedLedgerEntry& source); TransactionEngineResult doOffer(const SerializedTransaction&, std::vector<AffectedAccount>&);
TransactionEngineResult doTake(const SerializedTransaction&, SerializedLedgerEntry& source); TransactionEngineResult doTake(const SerializedTransaction&, std::vector<AffectedAccount>&);
TransactionEngineResult doCancel(const SerializedTransaction&, SerializedLedgerEntry& source); TransactionEngineResult doCancel(const SerializedTransaction&, std::vector<AffectedAccount>&);
TransactionEngineResult doStore(const SerializedTransaction&, SerializedLedgerEntry& source); TransactionEngineResult doStore(const SerializedTransaction&, std::vector<AffectedAccount>&);
TransactionEngineResult doDelete(const SerializedTransaction&, SerializedLedgerEntry& source); TransactionEngineResult doDelete(const SerializedTransaction&, std::vector<AffectedAccount>&);
public: public:
TransactionEngine() { ; } TransactionEngine() { ; }