mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Merge branch 'pay'
This commit is contained in:
@@ -263,17 +263,21 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
|
||||
return tenINVALID;
|
||||
}
|
||||
|
||||
//
|
||||
// Verify transaction is signed properly.
|
||||
//
|
||||
|
||||
// Extract signing key
|
||||
// Transactions contain a signing key. This allows us to trivially verify a transaction has at least been properly signed
|
||||
// without going to disk. Each transaction also notes a source account id. This is used to verify that the signing key is
|
||||
// associated with the account.
|
||||
// XXX This could be a lot cleaner to prevent unnecessary copying.
|
||||
NewcoinAddress naPubKey;
|
||||
NewcoinAddress naSigningPubKey;
|
||||
|
||||
naPubKey.setAccountPublic(txn.peekSigningPubKey());
|
||||
naSigningPubKey.setAccountPublic(txn.peekSigningPubKey());
|
||||
|
||||
// check signature
|
||||
if (!txn.checkSign(naPubKey))
|
||||
// Consistency: really signed.
|
||||
if (!txn.checkSign(naSigningPubKey))
|
||||
{
|
||||
std::cerr << "applyTransaction: Invalid transaction: bad signature" << std::endl;
|
||||
return tenINVALID;
|
||||
@@ -299,6 +303,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
|
||||
case ttOFFER:
|
||||
case ttCREDIT_SET:
|
||||
case ttTRANSIT_SET:
|
||||
case ttWALLET_ADD:
|
||||
result = terSUCCESS;
|
||||
break;
|
||||
|
||||
@@ -349,15 +354,46 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
|
||||
boost::recursive_mutex::scoped_lock sl(mLedger->mLock);
|
||||
|
||||
// find source account
|
||||
// If we are only verifying some transactions, this would be probablistic.
|
||||
// If are only forwarding, due to resource limitations, we might verifying only some transactions, this would be probablistic.
|
||||
LedgerStateParms lspRoot = lepNONE;
|
||||
SLE::pointer sleSrc = mLedger->getAccountRoot(lspRoot, srcAccountID);
|
||||
if (!sleSrc)
|
||||
{
|
||||
std::cerr << str(boost::format("applyTransaction: Delay transaction: source account does not exisit: %s") % txn.getSourceAccount().humanAccountID()) << std::endl;
|
||||
|
||||
return terNO_ACCOUNT;
|
||||
}
|
||||
|
||||
// Consistency: Check signature
|
||||
switch (txn.getTxnType())
|
||||
{
|
||||
case ttCLAIM:
|
||||
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 tenINVALID;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!sleSrc->getIFieldPresent(sfAuthorizedKey))
|
||||
{
|
||||
std::cerr << "applyTransaction: Can not use unclaimed account." << std::endl;
|
||||
|
||||
return tenUNCLAIMED;
|
||||
}
|
||||
else if (naSigningPubKey.getAccountID() != sleSrc->getIFieldH160(sfAuthorizedKey))
|
||||
{
|
||||
std::cerr << "applyTransaction: Not authorized to use account." << std::endl;
|
||||
|
||||
return tenBAD_AUTH;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// deduct the fee, so it's not available during the transaction
|
||||
// we only write the account back if the transaction succeeds
|
||||
if (!saCost.isZero())
|
||||
@@ -390,15 +426,18 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
|
||||
if (a_seq < t_seq)
|
||||
{
|
||||
std::cerr << "applyTransaction: future sequence number" << std::endl;
|
||||
|
||||
return terPRE_SEQ;
|
||||
}
|
||||
if (mLedger->hasTransaction(txID))
|
||||
{
|
||||
std::cerr << "applyTransaction: duplicate sequence number" << std::endl;
|
||||
|
||||
return terALREADY;
|
||||
}
|
||||
|
||||
std::cerr << "applyTransaction: past sequence number" << std::endl;
|
||||
|
||||
return terPAST_SEQ;
|
||||
}
|
||||
else sleSrc->setIFieldU32(sfSequence, t_seq);
|
||||
@@ -408,6 +447,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
|
||||
if (t_seq)
|
||||
{
|
||||
std::cerr << "applyTransaction: bad sequence for pre-paid transaction" << std::endl;
|
||||
|
||||
return terPAST_SEQ;
|
||||
}
|
||||
}
|
||||
@@ -446,6 +486,10 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
|
||||
result = doTransitSet(txn, accounts);
|
||||
break;
|
||||
|
||||
case ttWALLET_ADD:
|
||||
result = doWalletAdd(txn, accounts);
|
||||
break;
|
||||
|
||||
default:
|
||||
result = tenUNKNOWN;
|
||||
break;
|
||||
@@ -486,41 +530,23 @@ TransactionEngineResult TransactionEngine::doClaim(const SerializedTransaction&
|
||||
std::vector<AffectedAccount>& accounts)
|
||||
{
|
||||
std::cerr << "doClaim>" << std::endl;
|
||||
NewcoinAddress naSigningPubKey;
|
||||
|
||||
naSigningPubKey.setAccountPublic(txn.peekSigningPubKey());
|
||||
|
||||
uint160 sourceAccountID = naSigningPubKey.getAccountID();
|
||||
|
||||
if (sourceAccountID != txn.getSourceAccount().getAccountID())
|
||||
{
|
||||
// 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 tenINVALID;
|
||||
}
|
||||
|
||||
LedgerStateParms qry = lepNONE;
|
||||
SLE::pointer sleDst = accounts[0].second;
|
||||
|
||||
if (!sleDst)
|
||||
{
|
||||
// Source account does not exist. Could succeed if it was created first.
|
||||
std::cerr << str(boost::format("doClaim: no such account: %s") % txn.getSourceAccount().humanAccountID()) << std::endl;
|
||||
return terNO_ACCOUNT;
|
||||
}
|
||||
|
||||
std::cerr << str(boost::format("doClaim: %s") % sleDst->getFullText()) << std::endl;
|
||||
|
||||
// Verify not already claimed.
|
||||
if (sleDst->getIFieldPresent(sfAuthorizedKey))
|
||||
{
|
||||
// Source account already claimed.
|
||||
std::cerr << "doClaim: source already claimed" << std::endl;
|
||||
|
||||
return terCLAIMED;
|
||||
}
|
||||
|
||||
//
|
||||
// Verify claim is authorized for public key.
|
||||
// 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);
|
||||
@@ -533,22 +559,24 @@ TransactionEngineResult TransactionEngine::doClaim(const SerializedTransaction&
|
||||
|
||||
if (!naAccountPublic.accountPublicVerify(Serializer::getSHA512Half(vucCipher), vucSignature))
|
||||
{
|
||||
std::cerr << "doClaim: bad signature unauthorized claim" << std::endl;
|
||||
return tenINVALID;
|
||||
std::cerr << "doClaim: bad signature unauthorized generator claim" << std::endl;
|
||||
|
||||
return tenBAD_GEN_AUTH;
|
||||
}
|
||||
|
||||
//
|
||||
// Verify generator not already in use.
|
||||
//
|
||||
|
||||
uint160 hGeneratorID = naAccountPublic.getAccountID();
|
||||
uint160 hGeneratorID = naAccountPublic.getAccountID();
|
||||
|
||||
qry = lepNONE;
|
||||
SLE::pointer sleGen = mLedger->getGenerator(qry, hGeneratorID);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -588,6 +616,7 @@ TransactionEngineResult TransactionEngine::doCreditSet(const SerializedTransacti
|
||||
std::cerr << "doCreditSet: Invalid transaction: Payment destination account not specifed." << std::endl;
|
||||
return tenDST_NEEDED;
|
||||
}
|
||||
// XXX Might make sense for ripple.
|
||||
else if (uSrcAccountID == uDstAccountID)
|
||||
{
|
||||
std::cerr << "doCreditSet: Invalid transaction: Source account is the same as destination." << std::endl;
|
||||
@@ -882,6 +911,72 @@ TransactionEngineResult TransactionEngine::doTransitSet(const SerializedTransact
|
||||
return tenINVALID;
|
||||
}
|
||||
|
||||
TransactionEngineResult TransactionEngine::doWalletAdd(const SerializedTransaction& txn,
|
||||
std::vector<AffectedAccount>& accounts)
|
||||
{
|
||||
std::cerr << "WalletAdd>" << std::endl;
|
||||
|
||||
SLE::pointer sleDst = accounts[0].second;
|
||||
|
||||
std::cerr << str(boost::format("WalletAdd: %s") % sleDst->getFullText()) << std::endl;
|
||||
|
||||
// Verify not already claimed.
|
||||
if (sleDst->getIFieldPresent(sfAuthorizedKey))
|
||||
{
|
||||
std::cerr << "WalletAdd: 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;
|
||||
|
||||
naAccountPublic.setAccountPublic(vucPubKey);
|
||||
|
||||
if (!naAccountPublic.accountPublicVerify(Serializer::getSHA512Half(vucCipher), vucSignature))
|
||||
{
|
||||
std::cerr << "WalletAdd: 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 << "WalletAdd: generator already in use" << std::endl;
|
||||
|
||||
return tenGEN_IN_USE;
|
||||
}
|
||||
|
||||
//
|
||||
// Claim the account.
|
||||
//
|
||||
|
||||
// Set the public key needed to use the account.
|
||||
sleDst->setIFieldH160(sfAuthorizedKey, hGeneratorID);
|
||||
|
||||
std::cerr << "WalletAdd<" << std::endl;
|
||||
|
||||
return terSUCCESS;
|
||||
}
|
||||
|
||||
TransactionEngineResult TransactionEngine::doInvoice(const SerializedTransaction& txn,
|
||||
std::vector<AffectedAccount>& accounts)
|
||||
{
|
||||
@@ -900,12 +995,6 @@ TransactionEngineResult TransactionEngine::doTake(const SerializedTransaction& t
|
||||
return tenUNKNOWN;
|
||||
}
|
||||
|
||||
TransactionEngineResult TransactionEngine::doCancel(const SerializedTransaction& txn,
|
||||
std::vector<AffectedAccount>& accounts)
|
||||
{
|
||||
return tenUNKNOWN;
|
||||
}
|
||||
|
||||
TransactionEngineResult TransactionEngine::doStore(const SerializedTransaction& txn,
|
||||
std::vector<AffectedAccount>& accounts)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user