mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Add PasswordFund and PasswordSet to transaction engine.
This commit is contained in:
@@ -10,10 +10,6 @@
|
||||
#include "utils.h"
|
||||
#include "Log.h"
|
||||
|
||||
typedef SerializedLedgerEntry SLE;
|
||||
|
||||
|
||||
|
||||
#define DIR_NODE_MAX 32
|
||||
|
||||
// We return the uNodeDir so that on delete we can quickly know where the element is mentioned in the directory.
|
||||
@@ -231,6 +227,62 @@ TransactionEngineResult TransactionEngine::dirDelete(
|
||||
}
|
||||
}
|
||||
|
||||
TransactionEngineResult TransactionEngine::setAuthorized(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts, bool bSet)
|
||||
{
|
||||
//
|
||||
// Verify that submitter knows the private key for the generator.
|
||||
// Otherwise, people could deny access to generators.
|
||||
//
|
||||
|
||||
std::vector<unsigned char> vucCipher = txn.getITFieldVL(sfGenerator);
|
||||
std::vector<unsigned char> vucPubKey = txn.getITFieldVL(sfPubKey);
|
||||
std::vector<unsigned char> vucSignature = txn.getITFieldVL(sfSignature);
|
||||
NewcoinAddress naAccountPublic = NewcoinAddress::createAccountPublic(vucPubKey);
|
||||
|
||||
if (!naAccountPublic.accountPublicVerify(Serializer::getSHA512Half(vucCipher), vucSignature))
|
||||
{
|
||||
std::cerr << "createGenerator: bad signature unauthorized generator claim" << std::endl;
|
||||
|
||||
return tenBAD_GEN_AUTH;
|
||||
}
|
||||
|
||||
// Create generator.
|
||||
uint160 hGeneratorID = naAccountPublic.getAccountID();
|
||||
|
||||
LedgerStateParms qry = lepNONE;
|
||||
SLE::pointer sleGen = mLedger->getGenerator(qry, hGeneratorID);
|
||||
if (!sleGen)
|
||||
{
|
||||
// Create the generator.
|
||||
sleGen = boost::make_shared<SerializedLedgerEntry>(ltGENERATOR_MAP);
|
||||
|
||||
sleGen->setIndex(Ledger::getGeneratorIndex(hGeneratorID));
|
||||
sleGen->setIFieldH160(sfGeneratorID, hGeneratorID);
|
||||
sleGen->setIFieldVL(sfGenerator, vucCipher);
|
||||
|
||||
accounts.push_back(std::make_pair(taaCREATE, sleGen));
|
||||
}
|
||||
else if (!bSet)
|
||||
{
|
||||
// Doing a claim. Must set generator.
|
||||
// Generator is already in use. Regular passphrases limited to one wallet.
|
||||
std::cerr << "createGenerator: generator already in use" << std::endl;
|
||||
|
||||
return tenGEN_IN_USE;
|
||||
}
|
||||
|
||||
// Set the public key needed to use the account.
|
||||
SLE::pointer sleDst = accounts[0].second;
|
||||
|
||||
uint160 uAuthKeyID = bSet
|
||||
? hGeneratorID
|
||||
: txn.getITFieldAccount(sfAuthorizedKey);
|
||||
|
||||
sleDst->setIFieldAccount(sfAuthorizedKey, uAuthKeyID);
|
||||
|
||||
return terSUCCESS;
|
||||
}
|
||||
|
||||
TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTransaction& txn,
|
||||
TransactionEngineParams params)
|
||||
{
|
||||
@@ -287,6 +339,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
|
||||
switch(txn.getTxnType())
|
||||
{
|
||||
case ttCLAIM:
|
||||
case ttPASSWORD_SET:
|
||||
saCost = 0;
|
||||
break;
|
||||
|
||||
@@ -301,6 +354,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
|
||||
case ttCREDIT_SET:
|
||||
case ttINVOICE:
|
||||
case ttOFFER:
|
||||
case ttPASSWORD_FUND:
|
||||
case ttTRANSIT_SET:
|
||||
case ttWALLET_ADD:
|
||||
nothing();
|
||||
@@ -363,28 +417,60 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
|
||||
return terNO_ACCOUNT;
|
||||
}
|
||||
|
||||
// Consistency: Check signature
|
||||
// Check if account cliamed.
|
||||
switch (txn.getTxnType())
|
||||
{
|
||||
case ttCLAIM:
|
||||
if (naSigningPubKey.getAccountID() != srcAccountID)
|
||||
if (sleSrc->getIFieldPresent(sfAuthorizedKey))
|
||||
{
|
||||
// Signing Pub Key must be for Source Account ID.
|
||||
std::cerr << "sourceAccountID: " << naSigningPubKey.humanAccountID() << std::endl;
|
||||
std::cerr << "txn accountID: " << txn.getSourceAccount().humanAccountID() << std::endl;
|
||||
std::cerr << "applyTransaction: Account already claimed." << std::endl;
|
||||
|
||||
return tenINVALID;
|
||||
return tenCLAIMED;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!sleSrc->getIFieldPresent(sfAuthorizedKey))
|
||||
{
|
||||
std::cerr << "applyTransaction: Can not use unclaimed account." << std::endl;
|
||||
std::cerr << "applyTransaction: Souce is an unclaimed account." << std::endl;
|
||||
|
||||
return tenUNCLAIMED;
|
||||
}
|
||||
else if (naSigningPubKey.getAccountID() != sleSrc->getIValueFieldAccount(sfAuthorizedKey).getAccountID())
|
||||
break;
|
||||
}
|
||||
|
||||
// Consistency: Check signature
|
||||
switch (txn.getTxnType())
|
||||
{
|
||||
case ttCLAIM:
|
||||
// Transaction's signing public key must be for the source account.
|
||||
// To prove the master private key made this transaction.
|
||||
if (naSigningPubKey.getAccountID() != srcAccountID)
|
||||
{
|
||||
// Signing Pub Key must be for Source Account ID.
|
||||
std::cerr << "sourceAccountID: " << naSigningPubKey.humanAccountID() << std::endl;
|
||||
std::cerr << "txn accountID: " << txn.getSourceAccount().humanAccountID() << std::endl;
|
||||
|
||||
return tenBAD_CLAIM_ID;
|
||||
}
|
||||
break;
|
||||
|
||||
case ttPASSWORD_SET:
|
||||
// Transaction's signing public key must be for the source account.
|
||||
// To prove the master private key made this transaction.
|
||||
if (naSigningPubKey.getAccountID() != srcAccountID)
|
||||
{
|
||||
// Signing Pub Key must be for Source Account ID.
|
||||
std::cerr << "sourceAccountID: " << naSigningPubKey.humanAccountID() << std::endl;
|
||||
std::cerr << "txn accountID: " << txn.getSourceAccount().humanAccountID() << std::endl;
|
||||
|
||||
return tenBAD_SET_ID;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Verify the transaction's signing public key is the key authorized for signing.
|
||||
if (naSigningPubKey.getAccountID() != sleSrc->getIValueFieldAccount(sfAuthorizedKey).getAccountID())
|
||||
{
|
||||
std::cerr << "applyTransaction: Not authorized to use account." << std::endl;
|
||||
|
||||
@@ -481,6 +567,14 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
|
||||
result = doOffer(txn, accounts);
|
||||
break;
|
||||
|
||||
case ttPASSWORD_FUND:
|
||||
result = doPasswordFund(txn, accounts, srcAccountID);
|
||||
break;
|
||||
|
||||
case ttPASSWORD_SET:
|
||||
result = doPasswordSet(txn, accounts);
|
||||
break;
|
||||
|
||||
case ttPAYMENT:
|
||||
result = doPayment(txn, accounts, srcAccountID);
|
||||
break;
|
||||
@@ -545,13 +639,13 @@ TransactionEngineResult TransactionEngine::doAccountSet(const SerializedTransact
|
||||
|
||||
if (txFlags & tfUnsetEmailHash)
|
||||
{
|
||||
std::cerr << "doClaim: unset email hash" << std::endl;
|
||||
std::cerr << "doAccountSet: unset email hash" << std::endl;
|
||||
|
||||
sleSrc->makeIFieldAbsent(sfEmailHash);
|
||||
}
|
||||
else if (txn.getITFieldPresent(sfEmailHash))
|
||||
{
|
||||
std::cerr << "doClaim: set email hash" << std::endl;
|
||||
std::cerr << "doAccountSet: set email hash" << std::endl;
|
||||
|
||||
sleSrc->setIFieldH128(sfEmailHash, txn.getITFieldH128(sfEmailHash));
|
||||
}
|
||||
@@ -562,13 +656,13 @@ TransactionEngineResult TransactionEngine::doAccountSet(const SerializedTransact
|
||||
|
||||
if (txFlags & tfUnsetWalletLocator)
|
||||
{
|
||||
std::cerr << "doClaim: unset wallet locator" << std::endl;
|
||||
std::cerr << "doAccountSet: unset wallet locator" << std::endl;
|
||||
|
||||
sleSrc->makeIFieldAbsent(sfWalletLocator);
|
||||
}
|
||||
else if (txn.getITFieldPresent(sfWalletLocator))
|
||||
{
|
||||
std::cerr << "doClaim: set wallet locator" << std::endl;
|
||||
std::cerr << "doAccountSet: set wallet locator" << std::endl;
|
||||
|
||||
sleSrc->setIFieldH256(sfWalletLocator, txn.getITFieldH256(sfWalletLocator));
|
||||
}
|
||||
@@ -584,13 +678,13 @@ TransactionEngineResult TransactionEngine::doAccountSet(const SerializedTransact
|
||||
}
|
||||
else if (sleSrc->getIFieldPresent(sfMessageKey))
|
||||
{
|
||||
std::cerr << "doClaim: can not change message key" << std::endl;
|
||||
std::cerr << "doAccountSet: can not change message key" << std::endl;
|
||||
|
||||
return tenMSG_SET;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "doClaim: set message key" << std::endl;
|
||||
std::cerr << "doAccountSet: set message key" << std::endl;
|
||||
|
||||
sleSrc->setIFieldVL(sfMessageKey, txn.getITFieldVL(sfMessageKey));
|
||||
}
|
||||
@@ -605,71 +699,11 @@ TransactionEngineResult TransactionEngine::doClaim(const SerializedTransaction&
|
||||
{
|
||||
std::cerr << "doClaim>" << std::endl;
|
||||
|
||||
SLE::pointer sleDst = accounts[0].second;
|
||||
|
||||
std::cerr << str(boost::format("doClaim: %s") % sleDst->getFullText()) << std::endl;
|
||||
|
||||
// Verify not already claimed.
|
||||
if (sleDst->getIFieldPresent(sfAuthorizedKey))
|
||||
{
|
||||
std::cerr << "doClaim: source already claimed" << std::endl;
|
||||
|
||||
return terCLAIMED;
|
||||
}
|
||||
|
||||
//
|
||||
// Generator ID is based on regular account #0 public key.
|
||||
// Verify that submitter knows the private key for the generator.
|
||||
// Otherwise, people could deny access to generators.
|
||||
//
|
||||
|
||||
std::vector<unsigned char> vucCipher = txn.getITFieldVL(sfGenerator);
|
||||
std::vector<unsigned char> vucPubKey = txn.getITFieldVL(sfPubKey);
|
||||
std::vector<unsigned char> vucSignature = txn.getITFieldVL(sfSignature);
|
||||
NewcoinAddress naAccountPublic = NewcoinAddress::createAccountPublic(vucPubKey);
|
||||
|
||||
if (!naAccountPublic.accountPublicVerify(Serializer::getSHA512Half(vucCipher), vucSignature))
|
||||
{
|
||||
std::cerr << "doClaim: bad signature unauthorized generator claim" << std::endl;
|
||||
|
||||
return tenBAD_GEN_AUTH;
|
||||
}
|
||||
|
||||
//
|
||||
// Verify generator not already in use.
|
||||
//
|
||||
|
||||
uint160 hGeneratorID = naAccountPublic.getAccountID();
|
||||
|
||||
LedgerStateParms qry = lepNONE;
|
||||
SLE::pointer sleGen = mLedger->getGenerator(qry, hGeneratorID);
|
||||
if (sleGen)
|
||||
{
|
||||
// Generator is already in use. Regular passphrases limited to one wallet.
|
||||
std::cerr << "doClaim: generator already in use" << std::endl;
|
||||
|
||||
return tenGEN_IN_USE;
|
||||
}
|
||||
|
||||
//
|
||||
// Claim the account.
|
||||
//
|
||||
|
||||
// Set the public key needed to use the account.
|
||||
sleDst->setIFieldAccount(sfAuthorizedKey, hGeneratorID);
|
||||
|
||||
// Construct a generator map entry.
|
||||
sleGen = boost::make_shared<SerializedLedgerEntry>(ltGENERATOR_MAP);
|
||||
|
||||
sleGen->setIndex(Ledger::getGeneratorIndex(hGeneratorID));
|
||||
sleGen->setIFieldH160(sfGeneratorID, hGeneratorID);
|
||||
sleGen->setIFieldVL(sfGenerator, vucCipher);
|
||||
|
||||
accounts.push_back(std::make_pair(taaCREATE, sleGen));
|
||||
TransactionEngineResult result = setAuthorized(txn, accounts, true);
|
||||
|
||||
std::cerr << "doClaim<" << std::endl;
|
||||
|
||||
return terSUCCESS;
|
||||
return result;
|
||||
}
|
||||
|
||||
TransactionEngineResult TransactionEngine::doCreditSet(const SerializedTransaction& txn,
|
||||
@@ -771,6 +805,44 @@ TransactionEngineResult TransactionEngine::doCreditSet(const SerializedTransacti
|
||||
return terResult;
|
||||
}
|
||||
|
||||
TransactionEngineResult TransactionEngine::doPasswordFund(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts, const uint160& uSrcAccountID)
|
||||
{
|
||||
std::cerr << "doPasswordFund>" << std::endl;
|
||||
uint160 uDstAccountID = txn.getITFieldAccount(sfDestination);
|
||||
LedgerStateParms qry = lepNONE;
|
||||
SLE::pointer sleDst = mLedger->getAccountRoot(qry, uDstAccountID);
|
||||
if (!sleDst)
|
||||
{
|
||||
// Destination account does not exist.
|
||||
std::cerr << "doPasswordFund: Delay transaction: Destination account does not exist." << std::endl;
|
||||
|
||||
return terSET_MISSING_DST;
|
||||
}
|
||||
|
||||
bool bSpent = !!(sleDst->getFlags() & lsfPasswordSpent);
|
||||
if (bSpent)
|
||||
{
|
||||
sleDst->clearFlag(lsfPasswordSpent);
|
||||
|
||||
if (uSrcAccountID != uDstAccountID)
|
||||
accounts.push_back(std::make_pair(taaMODIFY, sleDst));
|
||||
}
|
||||
std::cerr << "doPasswordFund<" << std::endl;
|
||||
|
||||
return terSUCCESS;
|
||||
}
|
||||
|
||||
TransactionEngineResult TransactionEngine::doPasswordSet(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts)
|
||||
{
|
||||
std::cerr << "doPasswordSet>" << std::endl;
|
||||
|
||||
TransactionEngineResult result = setAuthorized(txn, accounts, false);
|
||||
|
||||
std::cerr << "doPasswordSet<" << std::endl;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
TransactionEngineResult TransactionEngine::doPayment(const SerializedTransaction& txn,
|
||||
std::vector<AffectedAccount>& accounts,
|
||||
const uint160& srcAccountID)
|
||||
|
||||
@@ -20,9 +20,12 @@ enum TransactionEngineResult
|
||||
tenDST_IS_SRC, // Destination may not be source.
|
||||
tenBAD_GEN_AUTH, // Not authorized to claim generator.
|
||||
tenBAD_ADD_AUTH, // Not authorized to add account.
|
||||
tenBAD_CLAIM_ID, // Malformed.
|
||||
tenBAD_SET_ID, // Malformed.
|
||||
|
||||
// Invalid: Ledger won't allow.
|
||||
tenUNCLAIMED = -200, // Can not use an unclaimed account.
|
||||
tenCLAIMED, // Can not claim a previously claimed account.
|
||||
tenBAD_AUTH, // Transaction's public key is not authorized.
|
||||
tenCREATED, // Can't add an already created account.
|
||||
tenMSG_SET, // Can't change a message key.
|
||||
@@ -40,7 +43,6 @@ enum TransactionEngineResult
|
||||
// Might succeed if not conflict is not caused by transaction ordering.
|
||||
terALREADY, // The transaction was already in the ledger
|
||||
terBAD_SEQ, // This sequence number should be zero for prepaid transactions.
|
||||
terCLAIMED, // Can not claim a previously claimed account.
|
||||
terCREATED, // Can not create a previously created account.
|
||||
terDIR_FULL, // Can not add entry to full dir.
|
||||
terINSUF_FEE_B, // Account balance can't pay fee
|
||||
@@ -56,6 +58,7 @@ enum TransactionEngineResult
|
||||
terPRE_SEQ, // Missing/inapplicable prior transaction
|
||||
terUNFUNDED, // Source account had insufficient balance for transaction.
|
||||
terNO_LINE_NO_ZERO, // Can't zero non-existant line, destination might make it.
|
||||
terSET_MISSING_DST, // Can't set password, destination missing.
|
||||
};
|
||||
|
||||
enum TransactionEngineParams
|
||||
@@ -91,18 +94,23 @@ private:
|
||||
const uint256& uBase, // Key of item.
|
||||
const uint256& uLedgerIndex); // Item being deleted
|
||||
|
||||
TransactionEngineResult setAuthorized(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts, bool bSet);
|
||||
|
||||
protected:
|
||||
Ledger::pointer mLedger;
|
||||
|
||||
TransactionEngineResult doAccountSet(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts);
|
||||
TransactionEngineResult doClaim(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts);
|
||||
TransactionEngineResult doCreditSet(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts,
|
||||
const uint160& srcAccountID);
|
||||
const uint160& uSrcAccountID);
|
||||
TransactionEngineResult doDelete(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts);
|
||||
TransactionEngineResult doInvoice(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts);
|
||||
TransactionEngineResult doOffer(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts);
|
||||
TransactionEngineResult doPasswordFund(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts,
|
||||
const uint160& uSrcAccountID);
|
||||
TransactionEngineResult doPasswordSet(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts);
|
||||
TransactionEngineResult doPayment(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts,
|
||||
const uint160& srcAccountID);
|
||||
const uint160& uSrcAccountID);
|
||||
TransactionEngineResult doStore(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts);
|
||||
TransactionEngineResult doTake(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts);
|
||||
TransactionEngineResult doTransitSet(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts);
|
||||
|
||||
Reference in New Issue
Block a user