From 9486fc416ca7c59b8930b734266eed4d5b714c50 Mon Sep 17 00:00:00 2001 From: David Schwartz Date: Fri, 3 Jan 2014 13:01:57 -0800 Subject: [PATCH] Support AccountTxnID and LastLedgerSequence. --- src/ripple_app/tx/AccountSetTransactor.cpp | 18 ++++++++++++++++++ src/ripple_app/tx/Transactor.cpp | 12 ++++++++++++ src/ripple_data/protocol/LedgerFormats.cpp | 1 + .../protocol/SerializeDeclarations.h | 1 + src/ripple_data/protocol/TER.cpp | 1 + src/ripple_data/protocol/TER.h | 1 + src/ripple_data/protocol/TxFlags.h | 1 + src/ripple_data/protocol/TxFormats.cpp | 4 +++- 8 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/ripple_app/tx/AccountSetTransactor.cpp b/src/ripple_app/tx/AccountSetTransactor.cpp index 9fd497fb69..876fa74436 100644 --- a/src/ripple_app/tx/AccountSetTransactor.cpp +++ b/src/ripple_app/tx/AccountSetTransactor.cpp @@ -156,6 +156,24 @@ TER AccountSetTransactor::doApply () uFlagsOut &= ~lsfDisableMaster; } + // + // Track transaction IDs signed by this account in its root + // + + if ((uSetFlag == asfAccountTxnID) && (uClearFlag != asfAccountTxnID) && !mTxnAccount->isFieldPresent (sfAccountTxnID)) + { + WriteLog (lsINFO, AccountSetTransactor) << "AccountSet: Set AccountTxnID"; + + mTxnAccount->makeFieldPresent (sfAccountTxnID); + } + + if ((uClearFlag == asfAccountTxnID) && (uSetFlag != asfAccountTxnID) && mTxnAccount->isFieldPresent (sfAccountTxnID)) + { + WriteLog (lsINFO, AccountSetTransactor) << "AccountSet: Clear AccountTxnID"; + + mTxnAccount->makeFieldAbsent (sfAccountTxnID); + } + // // EmailHash // diff --git a/src/ripple_app/tx/Transactor.cpp b/src/ripple_app/tx/Transactor.cpp index ae68a7ddcd..fc0bf0a184 100644 --- a/src/ripple_app/tx/Transactor.cpp +++ b/src/ripple_app/tx/Transactor.cpp @@ -170,12 +170,24 @@ TER Transactor::checkSeq () return tefPAST_SEQ; } + // Deprecated: Do not use if (mTxn.isFieldPresent (sfPreviousTxnID) && (mTxnAccount->getFieldH256 (sfPreviousTxnID) != mTxn.getFieldH256 (sfPreviousTxnID))) return tefWRONG_PRIOR; + if (mTxn.isFieldPresent (sfAccountTxnID) && + (mTxnAccount->getFieldH256 (sfAccountTxnID) != mTxn.getFieldH256 (sfAccountTxnID))) + return tefWRONG_PRIOR; + + if (mTxn.isFieldPresent (sfLastLedgerSequence) && + (mEngine->getLedger()->getLedgerSeq() > mTxn.getFieldU32 (sfLastLedgerSequence))) + return tefMAX_LEDGER; + mTxnAccount->setFieldU32 (sfSequence, t_seq + 1); + if (mTxnAccount->isFieldPresent (sfAccountTxnID)) + mTxnAccount->setFieldH256 (sfAccountTxnID, mTxn.getTransactionID ()); + return tesSUCCESS; } diff --git a/src/ripple_data/protocol/LedgerFormats.cpp b/src/ripple_data/protocol/LedgerFormats.cpp index 910f3dfebc..1e871686e8 100644 --- a/src/ripple_data/protocol/LedgerFormats.cpp +++ b/src/ripple_data/protocol/LedgerFormats.cpp @@ -26,6 +26,7 @@ LedgerFormats::LedgerFormats () << SOElement (sfOwnerCount, SOE_REQUIRED) << SOElement (sfPreviousTxnID, SOE_REQUIRED) << SOElement (sfPreviousTxnLgrSeq, SOE_REQUIRED) + << SOElement (sfAccountTxnID, SOE_OPTIONAL) << SOElement (sfRegularKey, SOE_OPTIONAL) << SOElement (sfEmailHash, SOE_OPTIONAL) << SOElement (sfWalletLocator, SOE_OPTIONAL) diff --git a/src/ripple_data/protocol/SerializeDeclarations.h b/src/ripple_data/protocol/SerializeDeclarations.h index dd113b5ba0..5a1008a26c 100644 --- a/src/ripple_data/protocol/SerializeDeclarations.h +++ b/src/ripple_data/protocol/SerializeDeclarations.h @@ -118,6 +118,7 @@ FIELD (PreviousTxnID, HASH256, 5) FIELD (LedgerIndex, HASH256, 6) FIELD (WalletLocator, HASH256, 7) FIELD (RootIndex, HASH256, 8) +FIELD (AccountTxnID, HASH256, 9) // 256-bit (uncommon) FIELD (BookDirectory, HASH256, 16) diff --git a/src/ripple_data/protocol/TER.cpp b/src/ripple_data/protocol/TER.cpp index 663bc8c803..e39e1979f5 100644 --- a/src/ripple_data/protocol/TER.cpp +++ b/src/ripple_data/protocol/TER.cpp @@ -63,6 +63,7 @@ bool transResultInfo (TER terCode, std::string& strToken, std::string& strHuman) { tefPAST_SEQ, "tefPAST_SEQ", "This sequence number has already past." }, { tefWRONG_PRIOR, "tefWRONG_PRIOR", "This previous transaction does not match." }, { tefMASTER_DISABLED, "tefMASTER_DISABLED", "Master key is disabled." }, + { tefMAX_LEDGER, "tefMAX_LEDGER", "Ledger sequence too high." }, { telLOCAL_ERROR, "telLOCAL_ERROR", "Local failure." }, { telBAD_DOMAIN, "telBAD_DOMAIN", "Domain too long." }, diff --git a/src/ripple_data/protocol/TER.h b/src/ripple_data/protocol/TER.h index 94384f5144..c91be322d8 100644 --- a/src/ripple_data/protocol/TER.h +++ b/src/ripple_data/protocol/TER.h @@ -108,6 +108,7 @@ enum TER // aka TransactionEngineResult tefPAST_SEQ, tefWRONG_PRIOR, tefMASTER_DISABLED, + tefMAX_LEDGER, // -99 .. -1: R Retry (sequence too high, no funds for txn fee, originating account non-existent) // Causes: diff --git a/src/ripple_data/protocol/TxFlags.h b/src/ripple_data/protocol/TxFlags.h index 7ebbf0b38c..5012b71c55 100644 --- a/src/ripple_data/protocol/TxFlags.h +++ b/src/ripple_data/protocol/TxFlags.h @@ -55,6 +55,7 @@ const uint32 asfRequireDest = 1; const uint32 asfRequireAuth = 2; const uint32 asfDisallowXRP = 3; const uint32 asfDisableMaster = 4; +const uint32 asfAccountTxnID = 5; // OfferCreate flags: const uint32 tfPassive = 0x00010000; diff --git a/src/ripple_data/protocol/TxFormats.cpp b/src/ripple_data/protocol/TxFormats.cpp index c8d75294c7..edea5cc317 100644 --- a/src/ripple_data/protocol/TxFormats.cpp +++ b/src/ripple_data/protocol/TxFormats.cpp @@ -95,7 +95,9 @@ void TxFormats::addCommonFields (Item& item) << SOElement(sfSourceTag, SOE_OPTIONAL) << SOElement(sfAccount, SOE_REQUIRED) << SOElement(sfSequence, SOE_REQUIRED) - << SOElement(sfPreviousTxnID, SOE_OPTIONAL) + << SOElement(sfPreviousTxnID, SOE_OPTIONAL) // Deprecated: Do not use + << SOElement(sfLastLedgerSequence, SOE_OPTIONAL) + << SOElement(sfAccountTxnID, SOE_OPTIONAL) << SOElement(sfFee, SOE_REQUIRED) << SOElement(sfOperationLimit, SOE_OPTIONAL) << SOElement(sfSigningPubKey, SOE_REQUIRED)