//------------------------------------------------------------------------------ /* Copyright (c) 2011-2013, OpenCoin, Inc. */ //============================================================================== SETUP_LOG (WalletAddTransactor) TER WalletAddTransactor::doApply () { Log::out() << "WalletAdd>"; Blob const vucPubKey = mTxn.getFieldVL (sfPublicKey); Blob const vucSignature = mTxn.getFieldVL (sfSignature); const uint160 uAuthKeyID = mTxn.getFieldAccount160 (sfRegularKey); const RippleAddress naMasterPubKey = RippleAddress::createAccountPublic (vucPubKey); const uint160 uDstAccountID = naMasterPubKey.getAccountID (); const uint32 uTxFlags = mTxn.getFlags (); if (uTxFlags) { WriteLog (lsINFO, WalletAddTransactor) << "WalletAdd: Malformed transaction: Invalid flags set."; return temINVALID_FLAG; } // FIXME: This should be moved to the transaction's signature check logic and cached if (!naMasterPubKey.accountPublicVerify (Serializer::getSHA512Half (uAuthKeyID.begin (), uAuthKeyID.size ()), vucSignature)) { Log::out() << "WalletAdd: unauthorized: bad signature "; return tefBAD_ADD_AUTH; } SLE::pointer sleDst = mEngine->entryCache (ltACCOUNT_ROOT, Ledger::getAccountRootIndex (uDstAccountID)); if (sleDst) { Log::out() << "WalletAdd: account already created"; return tefCREATED; } // Direct XRP payment. STAmount saDstAmount = mTxn.getFieldAmount (sfAmount); const STAmount saSrcBalance = mTxnAccount->getFieldAmount (sfBalance); const uint32 uOwnerCount = mTxnAccount->getFieldU32 (sfOwnerCount); const uint64 uReserve = mEngine->getLedger ()->getReserve (uOwnerCount); STAmount saPaid = mTxn.getTransactionFee (); // Make sure have enough reserve to send. Allow final spend to use reserve for fee. if (saSrcBalance + saPaid < saDstAmount + uReserve) // Reserve is not scaled by fee. { // Vote no. However, transaction might succeed, if applied in a different order. WriteLog (lsINFO, WalletAddTransactor) << boost::str (boost::format ("WalletAdd: Delay transaction: Insufficient funds: %s / %s (%d)") % saSrcBalance.getText () % (saDstAmount + uReserve).getText () % uReserve); return tecUNFUNDED_ADD; } // Deduct initial balance from source account. mTxnAccount->setFieldAmount (sfBalance, saSrcBalance - saDstAmount); // Create the account. sleDst = mEngine->entryCreate (ltACCOUNT_ROOT, Ledger::getAccountRootIndex (uDstAccountID)); sleDst->setFieldAccount (sfAccount, uDstAccountID); sleDst->setFieldU32 (sfSequence, 1); sleDst->setFieldAmount (sfBalance, saDstAmount); sleDst->setFieldAccount (sfRegularKey, uAuthKeyID); Log::out() << "WalletAdd<"; return tesSUCCESS; } // vim:ts=4