From 36a84484e017379f390e0933eba2b5273c09de7f Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Mon, 17 Jun 2013 12:14:03 -0700 Subject: [PATCH] Implement clearing the regular key, setting and clearing the no master flag and enforcing the no master flag. --- .../protocol/ripple_SerializedObject.cpp | 5 ++++ .../protocol/ripple_SerializedObject.h | 1 + modules/ripple_data/protocol/ripple_TER.cpp | 2 ++ modules/ripple_data/protocol/ripple_TER.h | 2 ++ .../ripple_data/protocol/ripple_TxFormat.cpp | 2 +- src/cpp/ripple/AccountSetTransactor.cpp | 28 +++++++++++++++++++ src/cpp/ripple/RegularKeySetTransactor.cpp | 13 +++++++-- src/cpp/ripple/Transactor.cpp | 9 ++++-- src/cpp/ripple/Transactor.h | 1 + 9 files changed, 57 insertions(+), 6 deletions(-) diff --git a/modules/ripple_data/protocol/ripple_SerializedObject.cpp b/modules/ripple_data/protocol/ripple_SerializedObject.cpp index be3a4cc09d..c5ccc7baa6 100644 --- a/modules/ripple_data/protocol/ripple_SerializedObject.cpp +++ b/modules/ripple_data/protocol/ripple_SerializedObject.cpp @@ -531,6 +531,11 @@ bool STObject::clearFlag (uint32 f) return true; } +bool STObject::isFlag (uint32 f) +{ + return (getFlags () & f) == f; +} + uint32 STObject::getFlags (void) const { const STUInt32* t = dynamic_cast (peekAtPField (sfFlags)); diff --git a/modules/ripple_data/protocol/ripple_SerializedObject.h b/modules/ripple_data/protocol/ripple_SerializedObject.h index 91e45731a2..a12767c168 100644 --- a/modules/ripple_data/protocol/ripple_SerializedObject.h +++ b/modules/ripple_data/protocol/ripple_SerializedObject.h @@ -136,6 +136,7 @@ public: bool setFlag (uint32); bool clearFlag (uint32); + bool isFlag(uint32); uint32 getFlags () const; uint256 getHash (uint32 prefix) const; diff --git a/modules/ripple_data/protocol/ripple_TER.cpp b/modules/ripple_data/protocol/ripple_TER.cpp index ff08562a56..a902d3379c 100644 --- a/modules/ripple_data/protocol/ripple_TER.cpp +++ b/modules/ripple_data/protocol/ripple_TER.cpp @@ -46,6 +46,8 @@ bool transResultInfo (TER terCode, std::string& strToken, std::string& strHuman) { tefNO_AUTH_REQUIRED, "tefNO_AUTH_REQUIRED", "Auth is not required." }, { 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." }, + { tefNO_REGULAR_KEY, "tefNO_REGULAR_KEY", "Regular key is not set." }, { telLOCAL_ERROR, "telLOCAL_ERROR", "Local failure." }, { telBAD_DOMAIN, "telBAD_DOMAIN", "Domain too long." }, diff --git a/modules/ripple_data/protocol/ripple_TER.h b/modules/ripple_data/protocol/ripple_TER.h index 1ca9d7f5d2..dc1bbda68f 100644 --- a/modules/ripple_data/protocol/ripple_TER.h +++ b/modules/ripple_data/protocol/ripple_TER.h @@ -94,6 +94,8 @@ enum TER // aka TransactionEngineResult tefNO_AUTH_REQUIRED, // Can't set auth if auth is not required. tefPAST_SEQ, tefWRONG_PRIOR, + tefMASTER_DISABLED, + tefNO_REGULAR_KEY, // -99 .. -1: R Retry (sequence too high, no funds for txn fee, originating account non-existent) // Causes: diff --git a/modules/ripple_data/protocol/ripple_TxFormat.cpp b/modules/ripple_data/protocol/ripple_TxFormat.cpp index f9542030ad..98e15ad46f 100644 --- a/modules/ripple_data/protocol/ripple_TxFormat.cpp +++ b/modules/ripple_data/protocol/ripple_TxFormat.cpp @@ -51,7 +51,7 @@ void TFInit () ; DECLARE_TF (SetRegularKey, ttREGULAR_KEY_SET) - << SOElement (sfRegularKey, SOE_REQUIRED) + << SOElement (sfRegularKey, SOE_OPTIONAL) ; DECLARE_TF (Payment, ttPAYMENT) diff --git a/src/cpp/ripple/AccountSetTransactor.cpp b/src/cpp/ripple/AccountSetTransactor.cpp index 8ab0a59504..34941727fe 100644 --- a/src/cpp/ripple/AccountSetTransactor.cpp +++ b/src/cpp/ripple/AccountSetTransactor.cpp @@ -105,6 +105,34 @@ TER AccountSetTransactor::doApply () uFlagsOut &= ~lsfDisallowXRP; } + // + // DisableMaster + // + + if ((tfDisableMaster | tfEnableMaster) == (uTxFlags & (tfDisableMaster | tfEnableMaster))) + { + WriteLog (lsINFO, AccountSetTransactor) << "AccountSet: Malformed transaction: Contradictory flags set."; + + return temINVALID_FLAG; + } + + if ((uTxFlags & tfDisableMaster) && !isSetBit (uFlagsIn, lsfDisableMaster)) + { + if (!mTxnAccount->isFieldPresent (sfRegularKey)) + return tefNO_REGULAR_KEY; + + WriteLog (lsINFO, AccountSetTransactor) << "AccountSet: Set lsfDisableMaster."; + + uFlagsOut |= lsfDisableMaster; + } + + if ((uTxFlags & tfEnableMaster) && isSetBit (uFlagsIn, lsfDisableMaster)) + { + WriteLog (lsINFO, AccountSetTransactor) << "AccountSet: Clear lsfDisableMaster."; + + uFlagsOut &= ~lsfDisableMaster; + } + // // EmailHash // diff --git a/src/cpp/ripple/RegularKeySetTransactor.cpp b/src/cpp/ripple/RegularKeySetTransactor.cpp index 532af4db6e..2d0b472afa 100644 --- a/src/cpp/ripple/RegularKeySetTransactor.cpp +++ b/src/cpp/ripple/RegularKeySetTransactor.cpp @@ -38,8 +38,17 @@ TER RegularKeySetTransactor::doApply () mTxnAccount->setFlag (lsfPasswordSpent); } - uint160 uAuthKeyID = mTxn.getFieldAccount160 (sfRegularKey); - mTxnAccount->setFieldAccount (sfRegularKey, uAuthKeyID); + if (mTxn.isFieldPresent (sfRegularKey)) + { + uint160 uAuthKeyID = mTxn.getFieldAccount160 (sfRegularKey); + mTxnAccount->setFieldAccount (sfRegularKey, uAuthKeyID); + } + else + { + if (mTxnAccount->isFlag (lsfDisableMaster)) + return tefMASTER_DISABLED; + mTxnAccount->makeFieldAbsent (sfRegularKey); + } std::cerr << "RegularKeySet<" << std::endl; diff --git a/src/cpp/ripple/Transactor.cpp b/src/cpp/ripple/Transactor.cpp index 08bf56936f..9d0b41795f 100644 --- a/src/cpp/ripple/Transactor.cpp +++ b/src/cpp/ripple/Transactor.cpp @@ -45,6 +45,7 @@ UPTR_T Transactor::makeTransactor (const SerializedTransaction& txn, Transactor::Transactor (const SerializedTransaction& txn, TransactionEngineParams params, TransactionEngine* engine) : mTxn (txn), mEngine (engine), mParams (params) { mHasAuthKey = false; + mSigMaster = false; } void Transactor::calculateFee () @@ -101,12 +102,14 @@ TER Transactor::checkSig () { // Consistency: Check signature // Verify the transaction's signing public key is the key authorized for signing. - if (mHasAuthKey && mSigningPubKey.getAccountID () == mTxnAccount->getFieldAccount160 (sfRegularKey)) + if (mSigningPubKey.getAccountID () == mTxnAccountID) { // Authorized to continue. - nothing (); + mSigMaster = true; + if (mTxnAccount->isFlag(lsfDisableMaster)) + return tefMASTER_DISABLED; } - else if (mSigningPubKey.getAccountID () == mTxnAccountID) + else if (mHasAuthKey && mSigningPubKey.getAccountID () == mTxnAccount->getFieldAccount160 (sfRegularKey)) { // Authorized to continue. nothing (); diff --git a/src/cpp/ripple/Transactor.h b/src/cpp/ripple/Transactor.h index 909cb9a2bc..e67b8fa981 100644 --- a/src/cpp/ripple/Transactor.h +++ b/src/cpp/ripple/Transactor.h @@ -29,6 +29,7 @@ protected: STAmount mSourceBalance; // Balance after fees. SLE::pointer mTxnAccount; bool mHasAuthKey; + bool mSigMaster; RippleAddress mSigningPubKey; virtual TER preCheck ();