void STObject::setFieldAccount (SField::ref field, const uint160& v) { SerializedType* rf = getPField (field, true); if (!rf) throw std::runtime_error ("Field not found"); if (rf->getSType () == STI_NOTPRESENT) rf = makeFieldPresent (field); STAccount* cf = dynamic_cast<STAccount*> (rf); if (!cf) throw std::runtime_error ("Wrong field type"); cf->setValueH160 (v); }
void STObject::setFieldVL (SField::ref field, Blob const& v) { SerializedType* rf = getPField (field, true); if (!rf) throw std::runtime_error ("Field not found"); if (rf->getSType () == STI_NOTPRESENT) rf = makeFieldPresent (field); STVariableLength* cf = dynamic_cast<STVariableLength*> (rf); if (!cf) throw std::runtime_error ("Wrong field type"); cf->setValue (v); }
void STObject::setFieldU8 (SField::ref field, unsigned char v) { SerializedType* rf = getPField (field, true); if (!rf) throw std::runtime_error ("Field not found"); if (rf->getSType () == STI_NOTPRESENT) rf = makeFieldPresent (field); STUInt8* cf = dynamic_cast<STUInt8*> (rf); if (!cf) throw std::runtime_error ("Wrong field type"); cf->setValue (v); }
void STObject::setFieldPathSet (SField::ref field, const STPathSet& v) { SerializedType* rf = getPField (field, true); if (!rf) throw std::runtime_error ("Field not found"); if (rf->getSType () == STI_NOTPRESENT) rf = makeFieldPresent (field); STPathSet* cf = dynamic_cast<STPathSet*> (rf); if (!cf) throw std::runtime_error ("Wrong field type"); (*cf) = v; }
STObject& STObject::peekFieldObject (SField::ref field) { SerializedType* rf = getPField (field, true); if (!rf) throw std::runtime_error ("Field not found"); if (rf->getSType () == STI_NOTPRESENT) rf = makeFieldPresent (field); STObject* cf = dynamic_cast<STObject*> (rf); if (!cf) throw std::runtime_error ("Wrong field type"); return *cf; }
void STObject::setAccountID (SField const& field, AccountID const& v) { STBase* rf = getPField (field, true); if (!rf) throw std::runtime_error ("Field not found"); if (rf->getSType () == STI_NOTPRESENT) rf = makeFieldPresent (field); STAccount* cf = dynamic_cast<STAccount*> (rf); if (!cf) throw std::runtime_error ("Wrong field type"); cf->setValueH160 (v); }
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; }