diff --git a/src/cpp/ripple/LedgerFormats.h b/src/cpp/ripple/LedgerFormats.h index e39e7a8945..4c2ba9c54d 100644 --- a/src/cpp/ripple/LedgerFormats.h +++ b/src/cpp/ripple/LedgerFormats.h @@ -3,6 +3,8 @@ #include "SerializedObject.h" +#define ENABLE_REQUIRE_DEST_TAG 0 + // Used as the type of a transaction or the type of a ledger entry. enum LedgerEntryType { @@ -40,6 +42,9 @@ enum LedgerSpecificFlags { // ltACCOUNT_ROOT lsfPasswordSpent = 0x00010000, // True, if password set fee is spent. +#if ENABLE_REQUIRE_DEST_TAG + lsfRequireDestTag = 0x00020000, // True, to require a DestinationTag for payments. +#endif // ltOFFER lsfPassive = 0x00010000, diff --git a/src/cpp/ripple/PaymentTransactor.cpp b/src/cpp/ripple/PaymentTransactor.cpp index e5e27a057c..9cc97309ea 100644 --- a/src/cpp/ripple/PaymentTransactor.cpp +++ b/src/cpp/ripple/PaymentTransactor.cpp @@ -99,6 +99,14 @@ TER PaymentTransactor::doApply() sleDst->setFieldAccount(sfAccount, uDstAccountID); sleDst->setFieldU32(sfSequence, 1); } +#if ENABLE_REQUIRE_DEST_TAG + else if ((sleDst->getFlags() & lsfRequireDestTag) && !mTxn.isFieldPresent(sfDestinationTag)) + { + cLog(lsINFO) << "doPayment: Malformed transaction: DestinationTag required."; + + return temINVALID; + } +#endif else { mEngine->entryModify(sleDst); diff --git a/src/cpp/ripple/SerializeProto.h b/src/cpp/ripple/SerializeProto.h index 57ef55200f..fc6ee038a6 100644 --- a/src/cpp/ripple/SerializeProto.h +++ b/src/cpp/ripple/SerializeProto.h @@ -1,6 +1,8 @@ // This is not really a header file, but it can be used as one with // appropriate #define statements. +#define ENABLE_DESTINATION_TAG 0 + // types (common) TYPE(Int16, UINT16, 1) TYPE(Int32, UINT32, 2) @@ -44,6 +46,9 @@ FIELD(TransferRate, UINT32, 11) FIELD(WalletSize, UINT32, 12) FIELD(OwnerCount, UINT32, 13) +#if ENABLE_DESTINATION_TAG + FIELD(DestinationTag, UINT32, 14) +#endif // 32-bit integers (uncommon) FIELD(HighQualityIn, UINT32, 16) diff --git a/src/cpp/ripple/Transaction.h b/src/cpp/ripple/Transaction.h index 35d33b91a5..29505f285f 100644 --- a/src/cpp/ripple/Transaction.h +++ b/src/cpp/ripple/Transaction.h @@ -84,7 +84,7 @@ public: STAmount getAmount() const { return mTransaction->getFieldU64(sfAmount); } STAmount getFee() const { return mTransaction->getTransactionFee(); } uint32 getFromAccountSeq() const { return mTransaction->getSequence(); } - uint32 getIdent() const { return mTransaction->getFieldU32(sfSourceTag); } + uint32 getSourceTag() const { return mTransaction->getFieldU32(sfSourceTag); } std::vector getSignature() const { return mTransaction->getSignature(); } uint32 getLedger() const { return mInLedger; } TransStatus getStatus() const { return mStatus; } diff --git a/src/cpp/ripple/TransactionErr.cpp b/src/cpp/ripple/TransactionErr.cpp index 131e03ad34..b02b2c50ce 100644 --- a/src/cpp/ripple/TransactionErr.cpp +++ b/src/cpp/ripple/TransactionErr.cpp @@ -53,6 +53,9 @@ bool transResultInfo(TER terCode, std::string& strToken, std::string& strHuman) { temBAD_SEQUENCE, "temBAD_SEQUENCE", "Malformed: Sequence is not in the past." }, { temDST_IS_SRC, "temDST_IS_SRC", "Destination may not be source." }, { temDST_NEEDED, "temDST_NEEDED", "Destination not specified." }, +#if ENABLE_REQUIRE_DEST_TAG + { temDST_TAG_NEEDED, "temDST_TAG_NEEDED", "Destination tag required." }, +#endif { temINVALID, "temINVALID", "The transaction is ill-formed." }, { temINVALID_FLAG, "temINVALID_FLAG", "The transaction has an invalid flag." }, { temREDUNDANT, "temREDUNDANT", "Sends same currency to self." }, diff --git a/src/cpp/ripple/TransactionErr.h b/src/cpp/ripple/TransactionErr.h index 85f8226072..676a84142b 100644 --- a/src/cpp/ripple/TransactionErr.h +++ b/src/cpp/ripple/TransactionErr.h @@ -39,6 +39,9 @@ enum TER // aka TransactionEngineResult temBAD_SEQUENCE, temDST_IS_SRC, temDST_NEEDED, +#if ENABLE_REQUIRE_DEST_TAG + temDST_TAG_NEEDED, +#endif temINVALID, temINVALID_FLAG, temREDUNDANT, diff --git a/src/cpp/ripple/TransactionFormats.cpp b/src/cpp/ripple/TransactionFormats.cpp index b428ed7640..8e77e585c2 100644 --- a/src/cpp/ripple/TransactionFormats.cpp +++ b/src/cpp/ripple/TransactionFormats.cpp @@ -55,6 +55,9 @@ static bool TFInit() << SOElement(sfSendMax, SOE_OPTIONAL) << SOElement(sfPaths, SOE_DEFAULT) << SOElement(sfInvoiceID, SOE_OPTIONAL) +#if ENABLE_DESTINATION_TAG + << SOElement(sfDestinationTag, SOE_OPTIONAL) +#endif ; DECLARE_TF(Contract, ttCONTRACT)