diff --git a/src/Ledger.cpp b/src/Ledger.cpp index f8388e45e..7e058d6bc 100644 --- a/src/Ledger.cpp +++ b/src/Ledger.cpp @@ -174,7 +174,7 @@ Transaction::pointer Ledger::getTransaction(const uint256& transID) const Transaction::pointer txn = theApp->getMasterTransaction().fetch(transID, false); if (txn) return txn; - txn = boost::make_shared(item->getData(), true); + txn = Transaction::sharedTransaction(item->getData(), true); if (txn->getStatus() == NEW) txn->setStatus(mClosed ? COMMITTED : INCLUDED, mLedgerSeq); @@ -382,7 +382,7 @@ Ledger::pointer Ledger::switchPreviousLedger(Ledger::pointer oldPrevious, Ledger { uint256 txnID = mit->getTag(); Transaction::pointer tx = theApp->getMasterTransaction().fetch(txnID, false); - if(!tx) tx = boost::make_shared(mit->peekData(), false); + if(!tx) tx = Transaction::sharedTransaction(mit->peekData(), false); txnMap.insert(std::make_pair(txnID, tx)); } diff --git a/src/LocalTransaction.cpp b/src/LocalTransaction.cpp index f184228ba..6a6439409 100644 --- a/src/LocalTransaction.cpp +++ b/src/LocalTransaction.cpp @@ -18,6 +18,10 @@ bool LocalTransaction::makeTransaction() return false; } + std::cerr << "LocalTransaction is obsolete." << std::endl; + return false; + +#if 0 mTransaction=Transaction::pointer(new Transaction(lac, mDestAcctID, mAmount, mTag, theApp->getOPs().getCurrentLedgerID())); if(mTransaction->getStatus()!=NEW) @@ -31,6 +35,7 @@ bool LocalTransaction::makeTransaction() return false; } return true; +#endif } void LocalTransaction::performTransaction() diff --git a/src/SerializedTransaction.cpp b/src/SerializedTransaction.cpp index 38f44e257..982102790 100644 --- a/src/SerializedTransaction.cpp +++ b/src/SerializedTransaction.cpp @@ -129,14 +129,14 @@ const std::vector& SerializedTransaction::peekSignature() const 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& sig) diff --git a/src/SerializedTransaction.h b/src/SerializedTransaction.h index 13a4d54f3..5ce70312e 100644 --- a/src/SerializedTransaction.h +++ b/src/SerializedTransaction.h @@ -111,8 +111,8 @@ public: virtual Json::Value getJson(int options) const; - bool sign(CKey& key); - bool checkSign(const CKey& key) const; + bool sign(const NewcoinAddress& naAccountPrivate); + bool checkSign(const NewcoinAddress& naAccountPrivate) const; }; #endif diff --git a/src/Transaction.cpp b/src/Transaction.cpp index 47ee23423..37fa0a8bf 100644 --- a/src/Transaction.cpp +++ b/src/Transaction.cpp @@ -11,28 +11,22 @@ #include "Serializer.h" #include "SerializedTransaction.h" -Transaction::Transaction(LocalAccount::pointer fromLocalAccount, const NewcoinAddress& toAccount, uint64 amount, - uint32 ident, uint32 ledger) : mInLedger(0), mStatus(NEW) +Transaction::Transaction(const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey, + const NewcoinAddress& naFromAccount, const NewcoinAddress& toAccount, + uint64 amount, + uint32 iSeq, uint32 ident, uint32 ledger) : mInLedger(0), mStatus(NEW) { - AccountState::pointer accountState = fromLocalAccount->getAccountState(); - if (!accountState) throw std::runtime_error("transaction on non-existent account"); + mAccountFrom = naFromAccount; - mAccountFrom = fromLocalAccount->getAddress(); + mFromPubKey = naPublicKey; + assert(mFromPubKey.isValid()); - mTransaction = boost::make_shared(ttMAKE_PAYMENT); + mTransaction = boost::make_shared(ttMAKE_PAYMENT); - mFromPubKey = fromLocalAccount->getPublicKey(); - assert(mFromPubKey); - - // XXX Temporary: We don't really have local accounts. - NewcoinAddress signPubKey; - - signPubKey.setAccountPublic(mFromPubKey->GetPubKey()); - - mTransaction->setSigningPubKey(signPubKey); + mTransaction->setSigningPubKey(mFromPubKey); mTransaction->setSourceAccount(mAccountFrom); - mTransaction->setSequence(accountState->getSeq()); + mTransaction->setSequence(iSeq); assert(mTransaction->getSequence() != 0); mTransaction->setTransactionFee(100); // for now @@ -50,8 +44,7 @@ Transaction::Transaction(LocalAccount::pointer fromLocalAccount, const NewcoinAd mTransaction->setITFieldU32(sfSourceTag, ident); } - assert(mFromPubKey); - if (!sign(fromLocalAccount)) + if (!sign(naPrivateKey)) { #ifdef DEBUG 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) { - std::vector pubKey; - try { - pubKey = mTransaction->peekSigningPubKey(); - mTransactionID = mTransaction->getTransactionID(); - mAccountFrom = mTransaction->getSourceAccount(); + mFromPubKey.setAccountPublic(mTransaction->peekSigningPubKey()); + mTransactionID = mTransaction->getTransactionID(); + mAccountFrom = mTransaction->getSourceAccount(); } catch(...) { return; } - mFromPubKey = boost::make_shared(); - if (!mFromPubKey->SetPubKey(pubKey)) return; - mFromPubKey = theApp->getPubKeyCache().store(mAccountFrom, mFromPubKey); - - if (!validate || checkSign()) + if (!bValidate || checkSign()) mStatus = NEW; } -Transaction::Transaction(const std::vector& raw, bool validate) : mInLedger(0), mStatus(INVALID) +Transaction::pointer Transaction::sharedTransaction(const std::vector&vucTransaction, bool bValidate) { - uint160 toAccountID; - uint160 fromAccountID; - std::vector pubKey; - try { - Serializer s(raw); - SerializerIterator sit(s); - mTransaction = boost::make_shared(boost::ref(sit), -1); + Serializer s(vucTransaction); + SerializerIterator sit(s); - mFromPubKey = boost::make_shared(); - if (!mFromPubKey->SetPubKey(pubKey)) return; - mAccountFrom.setAccountPublic(pubKey); - mFromPubKey = theApp->getPubKeyCache().store(mAccountFrom, mFromPubKey); - if (!mFromPubKey->SetPubKey(pubKey)) return; - mAccountFrom.setAccountPublic(pubKey); - mFromPubKey = theApp->getPubKeyCache().store(mAccountFrom, mFromPubKey); + SerializedTransaction::pointer st = boost::make_shared(boost::ref(sit), -1); + + return boost::make_shared(st, bValidate); } catch (...) { - return; + return boost::shared_ptr(); } - if (!validate || checkSign()) - mStatus = NEW; } #if 0 @@ -140,10 +116,9 @@ Transaction::Transaction(const NewcoinAddress& fromID, const NewcoinAddress& toI } #endif -bool Transaction::sign(LocalAccount::pointer fromLocalAccount) +bool Transaction::sign(const NewcoinAddress& naAccountPrivate) { - CKey::pointer privateKey = fromLocalAccount->getPrivateKey(); - if(!privateKey) + if(!naAccountPrivate.isValid()) { #ifdef DEBUG std::cerr << "No private key for signing" << std::endl; @@ -151,6 +126,7 @@ bool Transaction::sign(LocalAccount::pointer fromLocalAccount) return false; } +#if 0 if( (mTransaction->getITFieldU64(sfAmount)==0) ) { #ifdef DEBUG @@ -159,17 +135,9 @@ bool Transaction::sign(LocalAccount::pointer fromLocalAccount) assert(false); return false; } - - if(mAccountFrom.getAccountID()!=fromLocalAccount->getAddress().getAccountID()) - { -#ifdef DEBUG - std::cerr << "Source mismatch" << std::endl; #endif - assert(false); - return false; - } - if(!getSTransaction()->sign(*privateKey)) + if(!getSTransaction()->sign(naAccountPrivate)) { #ifdef DEBUG std::cerr << "Failed to make signature" << std::endl; @@ -177,14 +145,16 @@ bool Transaction::sign(LocalAccount::pointer fromLocalAccount) assert(false); return false; } + updateID(); + return true; } bool Transaction::checkSign() const { - assert(mFromPubKey); - return mTransaction->checkSign(*mFromPubKey); + assert(mFromPubKey.isValid()); + return mTransaction->checkSign(mFromPubKey); } void Transaction::setStatus(TransStatus ts, uint32 lseq) @@ -310,11 +280,11 @@ bool Transaction::convertToTransactions(uint32 firstLedgerSeq, uint32 secondLedg const uint256& id = it->first; const SHAMapItem::pointer& first = it->second.first; const SHAMapItem::pointer& second = it->second.second; - - Transaction::pointer firstTrans, secondTrans; + + Transaction::pointer firstTrans, secondTrans; if (!!first) { // transaction in our table - firstTrans = boost::make_shared(first->getData(), checkFirstTransactions); + firstTrans = sharedTransaction(first->getData(), checkFirstTransactions); if ((firstTrans->getStatus() == INVALID) || (firstTrans->getID() != id )) { firstTrans->setStatus(INVALID, firstLedgerSeq); @@ -325,7 +295,7 @@ bool Transaction::convertToTransactions(uint32 firstLedgerSeq, uint32 secondLedg if (!!second) { // transaction in other table - secondTrans = boost::make_shared(second->getData(), checkSecondTransactions); + secondTrans = sharedTransaction(second->getData(), checkSecondTransactions); if ((secondTrans->getStatus() == INVALID) || (secondTrans->getID() != id)) { secondTrans->setStatus(INVALID, secondLedgerSeq); diff --git a/src/Transaction.h b/src/Transaction.h index d1fbe4a89..20f068c65 100644 --- a/src/Transaction.h +++ b/src/Transaction.h @@ -15,20 +15,19 @@ #include "Hanko.h" #include "Serializer.h" #include "SHAMap.h" -#include "LocalAccount.h" #include "SerializedTransaction.h" enum TransStatus { - NEW =0, // just received / generated - INVALID =1, // no valid signature, insufficient funds - INCLUDED =2, // added to the current ledger - CONFLICTED =3, // losing to a conflicting transaction - COMMITTED =4, // known to be in a ledger - HELD =5, // not valid now, maybe later - REMOVED =6, // taken out of a ledger - OBSOLETE =7, // a compatible transaction has taken precedence - INCOMPLETE =8 // needs more signatures + NEW = 0, // just received / generated + INVALID = 1, // no valid signature, insufficient funds + INCLUDED = 2, // added to the current ledger + CONFLICTED = 3, // losing to a conflicting transaction + COMMITTED = 4, // known to be in a ledger + HELD = 5, // not valid now, maybe later + REMOVED = 6, // taken out of a ledger + OBSOLETE = 7, // a compatible transaction has taken precedence + INCOMPLETE = 8 // needs more signatures }; class Transaction : public boost::enable_shared_from_this @@ -40,7 +39,7 @@ public: private: uint256 mTransactionID; NewcoinAddress mAccountFrom; - CKey::pointer mFromPubKey; + NewcoinAddress mFromPubKey; uint32 mInLedger; TransStatus mStatus; @@ -48,17 +47,22 @@ private: SerializedTransaction::pointer mTransaction; public: - Transaction(const std::vector&, bool validate); - Transaction(SerializedTransaction::pointer st, bool validate); + Transaction(const SerializedTransaction::pointer st, bool bValidate); - Transaction(LocalAccount::pointer fromLocal, const NewcoinAddress& to, uint64 amount, - uint32 ident, uint32 ledger); + static Transaction::pointer sharedTransaction(const std::vector&vucTransaction, bool bValidate); + 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, CKey::pointer pubKey, uint64 amount, uint64 fee, uint32 fromSeq, uint32 fromLedger, uint32 ident, const std::vector& signature, uint32 ledgerSeq, TransStatus st); +#endif - bool sign(LocalAccount::pointer fromLocalAccount); + bool sign(const NewcoinAddress& naAccountPrivate); bool checkSign() const; void updateID() { mTransactionID=mTransaction->getTransactionID(); } diff --git a/src/TransactionEngine.cpp b/src/TransactionEngine.cpp index b1760f03c..a7c2dd100 100644 --- a/src/TransactionEngine.cpp +++ b/src/TransactionEngine.cpp @@ -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 // 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. - CKey acctKey; - if (!acctKey.SetPubKey(txn.peekSigningPubKey())) return tenINVALID; + // XXX This could be a lot cleaner to prevent unnecessary copying. + NewcoinAddress naPubKey; + + naPubKey.setAccountPublic(txn.peekSigningPubKey()); // check signature - if (!txn.checkSign(acctKey)) return tenINVALID; + if (!txn.checkSign(naPubKey)) + return tenINVALID; bool bPrepaid = false;