TER SetRegularKey::doApply () { auto const sle = view().peek( keylet::account(account_)); if (mFeeDue == zero) sle->setFlag (lsfPasswordSpent); if (ctx_.tx.isFieldPresent (sfRegularKey)) { sle->setAccountID (sfRegularKey, ctx_.tx.getAccountID (sfRegularKey)); } else { if (sle->isFlag (lsfDisableMaster) && !view().peek (keylet::signers (account_))) // Account has disabled master key and no multi-signer signer list. return tecNO_ALTERNATIVE_KEY; sle->makeFieldAbsent (sfRegularKey); } return tesSUCCESS; }
TER SetAccount::doApply () { std::uint32_t const uTxFlags = ctx_.tx.getFlags (); auto const sle = view().peek( keylet::account(account_)); std::uint32_t const uFlagsIn = sle->getFieldU32 (sfFlags); std::uint32_t uFlagsOut = uFlagsIn; std::uint32_t const uSetFlag = ctx_.tx.getFieldU32 (sfSetFlag); std::uint32_t const uClearFlag = ctx_.tx.getFieldU32 (sfClearFlag); // legacy AccountSet flags bool bSetRequireDest = (uTxFlags & TxFlag::requireDestTag) || (uSetFlag == asfRequireDest); bool bClearRequireDest = (uTxFlags & tfOptionalDestTag) || (uClearFlag == asfRequireDest); bool bSetRequireAuth = (uTxFlags & tfRequireAuth) || (uSetFlag == asfRequireAuth); bool bClearRequireAuth = (uTxFlags & tfOptionalAuth) || (uClearFlag == asfRequireAuth); bool bSetDisallowXRP = (uTxFlags & tfDisallowXRP) || (uSetFlag == asfDisallowXRP); bool bClearDisallowXRP = (uTxFlags & tfAllowXRP) || (uClearFlag == asfDisallowXRP); bool sigWithMaster = false; { auto const blob = ctx_.tx.getSigningPubKey(); if (!blob.empty ()) { auto const signingPubKey = RippleAddress::createAccountPublic(blob); if (calcAccountID(signingPubKey) == account_) sigWithMaster = true; } } // // RequireAuth // if (bSetRequireAuth && !(uFlagsIn & lsfRequireAuth)) { j_.trace << "Set RequireAuth."; uFlagsOut |= lsfRequireAuth; } if (bClearRequireAuth && (uFlagsIn & lsfRequireAuth)) { j_.trace << "Clear RequireAuth."; uFlagsOut &= ~lsfRequireAuth; } // // RequireDestTag // if (bSetRequireDest && !(uFlagsIn & lsfRequireDestTag)) { j_.trace << "Set lsfRequireDestTag."; uFlagsOut |= lsfRequireDestTag; } if (bClearRequireDest && (uFlagsIn & lsfRequireDestTag)) { j_.trace << "Clear lsfRequireDestTag."; uFlagsOut &= ~lsfRequireDestTag; } // // DisallowXRP // if (bSetDisallowXRP && !(uFlagsIn & lsfDisallowXRP)) { j_.trace << "Set lsfDisallowXRP."; uFlagsOut |= lsfDisallowXRP; } if (bClearDisallowXRP && (uFlagsIn & lsfDisallowXRP)) { j_.trace << "Clear lsfDisallowXRP."; uFlagsOut &= ~lsfDisallowXRP; } // // DisableMaster // if ((uSetFlag == asfDisableMaster) && !(uFlagsIn & lsfDisableMaster)) { if (!sigWithMaster) { j_.trace << "Must use master key to disable master key."; return tecNEED_MASTER_KEY; } if ((!sle->isFieldPresent (sfRegularKey)) && (!view().peek (keylet::signers (account_)))) { // Account has no regular key or multi-signer signer list. // Prevent transaction changes until we're ready. if (view().rules().enabled(featureMultiSign, ctx_.app.config().features)) return tecNO_ALTERNATIVE_KEY; return tecNO_REGULAR_KEY; } j_.trace << "Set lsfDisableMaster."; uFlagsOut |= lsfDisableMaster; } if ((uClearFlag == asfDisableMaster) && (uFlagsIn & lsfDisableMaster)) { j_.trace << "Clear lsfDisableMaster."; uFlagsOut &= ~lsfDisableMaster; } // // DefaultRipple // if (uSetFlag == asfDefaultRipple) { uFlagsOut |= lsfDefaultRipple; } else if (uClearFlag == asfDefaultRipple) { uFlagsOut &= ~lsfDefaultRipple; } // // NoFreeze // if (uSetFlag == asfNoFreeze) { if (!sigWithMaster && !(uFlagsIn & lsfDisableMaster)) { j_.trace << "Can't use regular key to set NoFreeze."; return tecNEED_MASTER_KEY; } j_.trace << "Set NoFreeze flag"; uFlagsOut |= lsfNoFreeze; } // Anyone may set global freeze if (uSetFlag == asfGlobalFreeze) { j_.trace << "Set GlobalFreeze flag"; uFlagsOut |= lsfGlobalFreeze; } // If you have set NoFreeze, you may not clear GlobalFreeze // This prevents those who have set NoFreeze from using // GlobalFreeze strategically. if ((uSetFlag != asfGlobalFreeze) && (uClearFlag == asfGlobalFreeze) && ((uFlagsOut & lsfNoFreeze) == 0)) { j_.trace << "Clear GlobalFreeze flag"; uFlagsOut &= ~lsfGlobalFreeze; } // // Track transaction IDs signed by this account in its root // if ((uSetFlag == asfAccountTxnID) && !sle->isFieldPresent (sfAccountTxnID)) { j_.trace << "Set AccountTxnID"; sle->makeFieldPresent (sfAccountTxnID); } if ((uClearFlag == asfAccountTxnID) && sle->isFieldPresent (sfAccountTxnID)) { j_.trace << "Clear AccountTxnID"; sle->makeFieldAbsent (sfAccountTxnID); } // // EmailHash // if (ctx_.tx.isFieldPresent (sfEmailHash)) { uint128 const uHash = ctx_.tx.getFieldH128 (sfEmailHash); if (!uHash) { j_.trace << "unset email hash"; sle->makeFieldAbsent (sfEmailHash); } else { j_.trace << "set email hash"; sle->setFieldH128 (sfEmailHash, uHash); } } // // WalletLocator // if (ctx_.tx.isFieldPresent (sfWalletLocator)) { uint256 const uHash = ctx_.tx.getFieldH256 (sfWalletLocator); if (!uHash) { j_.trace << "unset wallet locator"; sle->makeFieldAbsent (sfWalletLocator); } else { j_.trace << "set wallet locator"; sle->setFieldH256 (sfWalletLocator, uHash); } } // // MessageKey // if (ctx_.tx.isFieldPresent (sfMessageKey)) { Blob const messageKey = ctx_.tx.getFieldVL (sfMessageKey); if (messageKey.empty ()) { j_.debug << "set message key"; sle->makeFieldAbsent (sfMessageKey); } else { j_.debug << "set message key"; sle->setFieldVL (sfMessageKey, messageKey); } } // // Domain // if (ctx_.tx.isFieldPresent (sfDomain)) { Blob const domain = ctx_.tx.getFieldVL (sfDomain); if (domain.empty ()) { j_.trace << "unset domain"; sle->makeFieldAbsent (sfDomain); } else { j_.trace << "set domain"; sle->setFieldVL (sfDomain, domain); } } // // TransferRate // if (ctx_.tx.isFieldPresent (sfTransferRate)) { std::uint32_t uRate = ctx_.tx.getFieldU32 (sfTransferRate); if (uRate == 0 || uRate == QUALITY_ONE) { j_.trace << "unset transfer rate"; sle->makeFieldAbsent (sfTransferRate); } else if (uRate > QUALITY_ONE) { j_.trace << "set transfer rate"; sle->setFieldU32 (sfTransferRate, uRate); } } if (uFlagsIn != uFlagsOut) sle->setFieldU32 (sfFlags, uFlagsOut); return tesSUCCESS; }