Remove LocalAccount from Transaction code.

This commit is contained in:
Arthur Britto
2012-05-13 15:07:12 -07:00
parent 76e8e34038
commit e16c771932
7 changed files with 74 additions and 92 deletions

View File

@@ -174,7 +174,7 @@ Transaction::pointer Ledger::getTransaction(const uint256& transID) const
Transaction::pointer txn = theApp->getMasterTransaction().fetch(transID, false); Transaction::pointer txn = theApp->getMasterTransaction().fetch(transID, false);
if (txn) return txn; if (txn) return txn;
txn = boost::make_shared<Transaction>(item->getData(), true); txn = Transaction::sharedTransaction(item->getData(), true);
if (txn->getStatus() == NEW) if (txn->getStatus() == NEW)
txn->setStatus(mClosed ? COMMITTED : INCLUDED, mLedgerSeq); txn->setStatus(mClosed ? COMMITTED : INCLUDED, mLedgerSeq);
@@ -382,7 +382,7 @@ Ledger::pointer Ledger::switchPreviousLedger(Ledger::pointer oldPrevious, Ledger
{ {
uint256 txnID = mit->getTag(); uint256 txnID = mit->getTag();
Transaction::pointer tx = theApp->getMasterTransaction().fetch(txnID, false); Transaction::pointer tx = theApp->getMasterTransaction().fetch(txnID, false);
if(!tx) tx = boost::make_shared<Transaction>(mit->peekData(), false); if(!tx) tx = Transaction::sharedTransaction(mit->peekData(), false);
txnMap.insert(std::make_pair(txnID, tx)); txnMap.insert(std::make_pair(txnID, tx));
} }

View File

@@ -18,6 +18,10 @@ bool LocalTransaction::makeTransaction()
return false; return false;
} }
std::cerr << "LocalTransaction is obsolete." << std::endl;
return false;
#if 0
mTransaction=Transaction::pointer(new Transaction(lac, mDestAcctID, mAmount, mTag, mTransaction=Transaction::pointer(new Transaction(lac, mDestAcctID, mAmount, mTag,
theApp->getOPs().getCurrentLedgerID())); theApp->getOPs().getCurrentLedgerID()));
if(mTransaction->getStatus()!=NEW) if(mTransaction->getStatus()!=NEW)
@@ -31,6 +35,7 @@ bool LocalTransaction::makeTransaction()
return false; return false;
} }
return true; return true;
#endif
} }
void LocalTransaction::performTransaction() void LocalTransaction::performTransaction()

View File

@@ -129,14 +129,14 @@ const std::vector<unsigned char>& SerializedTransaction::peekSignature() const
return mSignature.peekValue(); return mSignature.peekValue();
} }
bool SerializedTransaction::sign(CKey& key) bool SerializedTransaction::sign(const NewcoinAddress& naAccountPrivate)
{ {
return key.Sign(getSigningHash(), mSignature.peekValue()); return naAccountPrivate.accountPrivateSign(getSigningHash(), mSignature.peekValue());
} }
bool SerializedTransaction::checkSign(const CKey& key) const bool SerializedTransaction::checkSign(const NewcoinAddress& naAccountPrivate) const
{ {
return key.Verify(getSigningHash(), mSignature.getValue()); return naAccountPrivate.accountPrivateVerify(getSigningHash(), mSignature.getValue());
} }
void SerializedTransaction::setSignature(const std::vector<unsigned char>& sig) void SerializedTransaction::setSignature(const std::vector<unsigned char>& sig)

View File

@@ -111,8 +111,8 @@ public:
virtual Json::Value getJson(int options) const; virtual Json::Value getJson(int options) const;
bool sign(CKey& key); bool sign(const NewcoinAddress& naAccountPrivate);
bool checkSign(const CKey& key) const; bool checkSign(const NewcoinAddress& naAccountPrivate) const;
}; };
#endif #endif

View File

@@ -11,28 +11,22 @@
#include "Serializer.h" #include "Serializer.h"
#include "SerializedTransaction.h" #include "SerializedTransaction.h"
Transaction::Transaction(LocalAccount::pointer fromLocalAccount, const NewcoinAddress& toAccount, uint64 amount, Transaction::Transaction(const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey,
uint32 ident, uint32 ledger) : mInLedger(0), mStatus(NEW) const NewcoinAddress& naFromAccount, const NewcoinAddress& toAccount,
uint64 amount,
uint32 iSeq, uint32 ident, uint32 ledger) : mInLedger(0), mStatus(NEW)
{ {
AccountState::pointer accountState = fromLocalAccount->getAccountState(); mAccountFrom = naFromAccount;
if (!accountState) throw std::runtime_error("transaction on non-existent account");
mAccountFrom = fromLocalAccount->getAddress(); mFromPubKey = naPublicKey;
assert(mFromPubKey.isValid());
mTransaction = boost::make_shared<SerializedTransaction>(ttMAKE_PAYMENT); mTransaction = boost::make_shared<SerializedTransaction>(ttMAKE_PAYMENT);
mFromPubKey = fromLocalAccount->getPublicKey(); mTransaction->setSigningPubKey(mFromPubKey);
assert(mFromPubKey);
// XXX Temporary: We don't really have local accounts.
NewcoinAddress signPubKey;
signPubKey.setAccountPublic(mFromPubKey->GetPubKey());
mTransaction->setSigningPubKey(signPubKey);
mTransaction->setSourceAccount(mAccountFrom); mTransaction->setSourceAccount(mAccountFrom);
mTransaction->setSequence(accountState->getSeq()); mTransaction->setSequence(iSeq);
assert(mTransaction->getSequence() != 0); assert(mTransaction->getSequence() != 0);
mTransaction->setTransactionFee(100); // for now mTransaction->setTransactionFee(100); // for now
@@ -50,8 +44,7 @@ Transaction::Transaction(LocalAccount::pointer fromLocalAccount, const NewcoinAd
mTransaction->setITFieldU32(sfSourceTag, ident); mTransaction->setITFieldU32(sfSourceTag, ident);
} }
assert(mFromPubKey); if (!sign(naPrivateKey))
if (!sign(fromLocalAccount))
{ {
#ifdef DEBUG #ifdef DEBUG
std::cerr << "Unable to sign transaction" << std::endl; std::cerr << "Unable to sign transaction" << std::endl;
@@ -60,56 +53,39 @@ Transaction::Transaction(LocalAccount::pointer fromLocalAccount, const NewcoinAd
} }
} }
Transaction::Transaction(SerializedTransaction::pointer sit, bool validate) Transaction::Transaction(const SerializedTransaction::pointer sit, bool bValidate)
: mInLedger(0), mStatus(INVALID), mTransaction(sit) : mInLedger(0), mStatus(INVALID), mTransaction(sit)
{ {
std::vector<unsigned char> pubKey;
try try
{ {
pubKey = mTransaction->peekSigningPubKey(); mFromPubKey.setAccountPublic(mTransaction->peekSigningPubKey());
mTransactionID = mTransaction->getTransactionID(); mTransactionID = mTransaction->getTransactionID();
mAccountFrom = mTransaction->getSourceAccount(); mAccountFrom = mTransaction->getSourceAccount();
} }
catch(...) catch(...)
{ {
return; return;
} }
mFromPubKey = boost::make_shared<CKey>(); if (!bValidate || checkSign())
if (!mFromPubKey->SetPubKey(pubKey)) return;
mFromPubKey = theApp->getPubKeyCache().store(mAccountFrom, mFromPubKey);
if (!validate || checkSign())
mStatus = NEW; mStatus = NEW;
} }
Transaction::Transaction(const std::vector<unsigned char>& raw, bool validate) : mInLedger(0), mStatus(INVALID) Transaction::pointer Transaction::sharedTransaction(const std::vector<unsigned char>&vucTransaction, bool bValidate)
{ {
uint160 toAccountID;
uint160 fromAccountID;
std::vector<unsigned char> pubKey;
try try
{ {
Serializer s(raw); Serializer s(vucTransaction);
SerializerIterator sit(s); SerializerIterator sit(s);
mTransaction = boost::make_shared<SerializedTransaction>(boost::ref(sit), -1);
mFromPubKey = boost::make_shared<CKey>(); SerializedTransaction::pointer st = boost::make_shared<SerializedTransaction>(boost::ref(sit), -1);
if (!mFromPubKey->SetPubKey(pubKey)) return;
mAccountFrom.setAccountPublic(pubKey); return boost::make_shared<Transaction>(st, bValidate);
mFromPubKey = theApp->getPubKeyCache().store(mAccountFrom, mFromPubKey);
if (!mFromPubKey->SetPubKey(pubKey)) return;
mAccountFrom.setAccountPublic(pubKey);
mFromPubKey = theApp->getPubKeyCache().store(mAccountFrom, mFromPubKey);
} }
catch (...) catch (...)
{ {
return; return boost::shared_ptr<Transaction>();
} }
if (!validate || checkSign())
mStatus = NEW;
} }
#if 0 #if 0
@@ -140,10 +116,9 @@ Transaction::Transaction(const NewcoinAddress& fromID, const NewcoinAddress& toI
} }
#endif #endif
bool Transaction::sign(LocalAccount::pointer fromLocalAccount) bool Transaction::sign(const NewcoinAddress& naAccountPrivate)
{ {
CKey::pointer privateKey = fromLocalAccount->getPrivateKey(); if(!naAccountPrivate.isValid())
if(!privateKey)
{ {
#ifdef DEBUG #ifdef DEBUG
std::cerr << "No private key for signing" << std::endl; std::cerr << "No private key for signing" << std::endl;
@@ -151,6 +126,7 @@ bool Transaction::sign(LocalAccount::pointer fromLocalAccount)
return false; return false;
} }
#if 0
if( (mTransaction->getITFieldU64(sfAmount)==0) ) if( (mTransaction->getITFieldU64(sfAmount)==0) )
{ {
#ifdef DEBUG #ifdef DEBUG
@@ -159,17 +135,9 @@ bool Transaction::sign(LocalAccount::pointer fromLocalAccount)
assert(false); assert(false);
return false; return false;
} }
if(mAccountFrom.getAccountID()!=fromLocalAccount->getAddress().getAccountID())
{
#ifdef DEBUG
std::cerr << "Source mismatch" << std::endl;
#endif #endif
assert(false);
return false;
}
if(!getSTransaction()->sign(*privateKey)) if(!getSTransaction()->sign(naAccountPrivate))
{ {
#ifdef DEBUG #ifdef DEBUG
std::cerr << "Failed to make signature" << std::endl; std::cerr << "Failed to make signature" << std::endl;
@@ -177,14 +145,16 @@ bool Transaction::sign(LocalAccount::pointer fromLocalAccount)
assert(false); assert(false);
return false; return false;
} }
updateID(); updateID();
return true; return true;
} }
bool Transaction::checkSign() const bool Transaction::checkSign() const
{ {
assert(mFromPubKey); assert(mFromPubKey.isValid());
return mTransaction->checkSign(*mFromPubKey); return mTransaction->checkSign(mFromPubKey);
} }
void Transaction::setStatus(TransStatus ts, uint32 lseq) void Transaction::setStatus(TransStatus ts, uint32 lseq)
@@ -314,7 +284,7 @@ bool Transaction::convertToTransactions(uint32 firstLedgerSeq, uint32 secondLedg
Transaction::pointer firstTrans, secondTrans; Transaction::pointer firstTrans, secondTrans;
if (!!first) if (!!first)
{ // transaction in our table { // transaction in our table
firstTrans = boost::make_shared<Transaction>(first->getData(), checkFirstTransactions); firstTrans = sharedTransaction(first->getData(), checkFirstTransactions);
if ((firstTrans->getStatus() == INVALID) || (firstTrans->getID() != id )) if ((firstTrans->getStatus() == INVALID) || (firstTrans->getID() != id ))
{ {
firstTrans->setStatus(INVALID, firstLedgerSeq); firstTrans->setStatus(INVALID, firstLedgerSeq);
@@ -325,7 +295,7 @@ bool Transaction::convertToTransactions(uint32 firstLedgerSeq, uint32 secondLedg
if (!!second) if (!!second)
{ // transaction in other table { // transaction in other table
secondTrans = boost::make_shared<Transaction>(second->getData(), checkSecondTransactions); secondTrans = sharedTransaction(second->getData(), checkSecondTransactions);
if ((secondTrans->getStatus() == INVALID) || (secondTrans->getID() != id)) if ((secondTrans->getStatus() == INVALID) || (secondTrans->getID() != id))
{ {
secondTrans->setStatus(INVALID, secondLedgerSeq); secondTrans->setStatus(INVALID, secondLedgerSeq);

View File

@@ -15,20 +15,19 @@
#include "Hanko.h" #include "Hanko.h"
#include "Serializer.h" #include "Serializer.h"
#include "SHAMap.h" #include "SHAMap.h"
#include "LocalAccount.h"
#include "SerializedTransaction.h" #include "SerializedTransaction.h"
enum TransStatus enum TransStatus
{ {
NEW =0, // just received / generated NEW = 0, // just received / generated
INVALID =1, // no valid signature, insufficient funds INVALID = 1, // no valid signature, insufficient funds
INCLUDED =2, // added to the current ledger INCLUDED = 2, // added to the current ledger
CONFLICTED =3, // losing to a conflicting transaction CONFLICTED = 3, // losing to a conflicting transaction
COMMITTED =4, // known to be in a ledger COMMITTED = 4, // known to be in a ledger
HELD =5, // not valid now, maybe later HELD = 5, // not valid now, maybe later
REMOVED =6, // taken out of a ledger REMOVED = 6, // taken out of a ledger
OBSOLETE =7, // a compatible transaction has taken precedence OBSOLETE = 7, // a compatible transaction has taken precedence
INCOMPLETE =8 // needs more signatures INCOMPLETE = 8 // needs more signatures
}; };
class Transaction : public boost::enable_shared_from_this<Transaction> class Transaction : public boost::enable_shared_from_this<Transaction>
@@ -40,7 +39,7 @@ public:
private: private:
uint256 mTransactionID; uint256 mTransactionID;
NewcoinAddress mAccountFrom; NewcoinAddress mAccountFrom;
CKey::pointer mFromPubKey; NewcoinAddress mFromPubKey;
uint32 mInLedger; uint32 mInLedger;
TransStatus mStatus; TransStatus mStatus;
@@ -48,17 +47,22 @@ private:
SerializedTransaction::pointer mTransaction; SerializedTransaction::pointer mTransaction;
public: public:
Transaction(const std::vector<unsigned char>&, bool validate); Transaction(const SerializedTransaction::pointer st, bool bValidate);
Transaction(SerializedTransaction::pointer st, bool validate);
Transaction(LocalAccount::pointer fromLocal, const NewcoinAddress& to, uint64 amount, static Transaction::pointer sharedTransaction(const std::vector<unsigned char>&vucTransaction, bool bValidate);
uint32 ident, uint32 ledger);
Transaction(const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey,
const NewcoinAddress& naFromAccount, const NewcoinAddress& toAccount,
uint64 amount,
uint32 iSeq, uint32 ident, uint32 ledger);
#if 0
Transaction(const NewcoinAddress& fromID, const NewcoinAddress& toID, Transaction(const NewcoinAddress& fromID, const NewcoinAddress& toID,
CKey::pointer pubKey, uint64 amount, uint64 fee, uint32 fromSeq, uint32 fromLedger, CKey::pointer pubKey, uint64 amount, uint64 fee, uint32 fromSeq, uint32 fromLedger,
uint32 ident, const std::vector<unsigned char>& signature, uint32 ledgerSeq, TransStatus st); uint32 ident, const std::vector<unsigned char>& signature, uint32 ledgerSeq, TransStatus st);
#endif
bool sign(LocalAccount::pointer fromLocalAccount); bool sign(const NewcoinAddress& naAccountPrivate);
bool checkSign() const; bool checkSign() const;
void updateID() { mTransactionID=mTransaction->getTransactionID(); } void updateID() { mTransactionID=mTransaction->getTransactionID(); }

View File

@@ -15,11 +15,14 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
// Transactions contain a signing key. This allows us to trivially verify a transaction has at least been properly signed // 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 // 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. // associated with the account.
CKey acctKey; // XXX This could be a lot cleaner to prevent unnecessary copying.
if (!acctKey.SetPubKey(txn.peekSigningPubKey())) return tenINVALID; NewcoinAddress naPubKey;
naPubKey.setAccountPublic(txn.peekSigningPubKey());
// check signature // check signature
if (!txn.checkSign(acctKey)) return tenINVALID; if (!txn.checkSign(naPubKey))
return tenINVALID;
bool bPrepaid = false; bool bPrepaid = false;