From 50e23112e312a23f73935b7c8837d1e74adbe851 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Fri, 20 Jan 2012 13:43:07 -0800 Subject: [PATCH] Fix applying transactions with a local destination to the wallet. --- LocalTransaction.h | 7 +++++-- NetworkOPs.cpp | 9 +++++++++ Wallet.cpp | 46 ++++++++++++++++++++++++++++++++-------------- 3 files changed, 46 insertions(+), 16 deletions(-) diff --git a/LocalTransaction.h b/LocalTransaction.h index 1d5eb7c927..0a719c415f 100644 --- a/LocalTransaction.h +++ b/LocalTransaction.h @@ -22,14 +22,14 @@ protected: uint64 mAmount; uint32 mTag; std::string mComment; - bool mPaid; + bool mPaid, mCredited; Transaction::pointer mTransaction; public: LocalTransaction(const uint160 &dest, uint64 amount, uint32 tag) : - mDestAcctID(dest), mAmount(amount), mTag(tag), mPaid(false) { ; } + mDestAcctID(dest), mAmount(amount), mTag(tag), mPaid(false), mCredited(false) { ; } void setComment(const std::string& comment) { mComment=comment; } const uint160& getDestinationAccount() const { return mDestAcctID; } @@ -43,6 +43,9 @@ public: bool isPaid() const { return mPaid; } void setPaid() { mPaid=true; } void setUnpaid() { mPaid=false; } + bool isCredited() const { return mCredited; } + void setCredited() { mCredited=true; } + void setUncredited() { mCredited=false; } void performTransaction(); // perform this transaction as if we received it from the network bool makeTransaction(); // create a transaction object according to these rules diff --git a/NetworkOPs.cpp b/NetworkOPs.cpp index deb2fbf8b2..3e080d72bd 100644 --- a/NetworkOPs.cpp +++ b/NetworkOPs.cpp @@ -43,6 +43,9 @@ Transaction::pointer NetworkOPs::processTransaction(Transaction::pointer trans, if((r==Ledger::TR_PREASEQ) || (r==Ledger::TR_BADLSEQ)) { // transaction should be held +#ifdef DEBUG + std::cerr << "Transaction should be held" << std::endl; +#endif trans->setStatus(HELD); trans->save(); theApp->getMasterLedger().addHeldTransaction(trans); @@ -50,12 +53,18 @@ Transaction::pointer NetworkOPs::processTransaction(Transaction::pointer trans, } if( (r==Ledger::TR_PASTASEQ) || (r==Ledger::TR_ALREADY) ) { // duplicate or conflict +#ifdef DEBUG + std::cerr << "Transaction is obsolete" << std::endl; +#endif trans->setStatus(OBSOLETE); return trans; } if(r==Ledger::TR_SUCCESS) { +#ifdef DEBUG + std::cerr << "Transaction is now included, synching to wallet" << std::endl; +#endif trans->setStatus(INCLUDED); theApp->getWallet().applyTransaction(trans); diff --git a/Wallet.cpp b/Wallet.cpp index bbf3dc660e..e1592546f1 100644 --- a/Wallet.cpp +++ b/Wallet.cpp @@ -819,48 +819,66 @@ void Wallet::applyTransaction(Transaction::pointer txn) { TransStatus st=txn->getStatus(); bool shouldBePaid=(st==INCLUDED) || (st==HELD) || (st==NEW); - + + LocalTransaction::pointer ltx; + boost::recursive_mutex::scoped_lock sl(mLock); - std::map::iterator lac=mAccounts.find(txn->getFromAccount()); + std::map::iterator lti=mTransactions.find(txn->getID()); + if(lti!=mTransactions.end()) ltx=lti->second; + + std::map::iterator lac=mAccounts.find(txn->getToAccount()); + if(lac!=mAccounts.end()) + { // this is to a local account + if(!ltx) + { // this is to a local account, and we don't have a local transaction for it + ltx=LocalTransaction::pointer(new + LocalTransaction(txn->getToAccount(), txn->getAmount(), txn->getIdent())); + ltx->setTransaction(txn); + mTransactions.insert(std::make_pair(txn->getID(), ltx)); + ltx->setCredited(); + lac->second->credit(txn->getAmount()-txn->getFee()); + } + } + + lac=mAccounts.find(txn->getFromAccount()); if(lac==mAccounts.end()) return; if ( (st!=INVALID) && (lac->second->getTxnSeq()==txn->getFromAccountSeq()) ) lac->second->incTxnSeq(); - std::map::iterator ltx=mTransactions.find(txn->getID()); - if(ltx==mTransactions.end()) + if(!ltx) { // we don't have this transactions if(shouldBePaid) { // we need it - LocalTransaction::pointer nlt(new + ltx=LocalTransaction::pointer(new LocalTransaction(txn->getToAccount(), txn->getAmount(), txn->getIdent())); - nlt->setTransaction(txn); - mTransactions.insert(std::make_pair(txn->getID(), nlt)); + ltx->setTransaction(txn); + mTransactions.insert(std::make_pair(txn->getID(), ltx)); lac->second->debit(txn->getAmount()); - ltx->second->setPaid(); + ltx->setPaid(); } } else { // we have this transaction in some form (ltx->second) if( (st==COMMITTED) || (st==INVALID) ) { // we need to remove it - if(ltx->second->isPaid()) + if(ltx->isPaid()) { lac->second->credit(txn->getAmount()); - ltx->second->setUnpaid(); + ltx->setUnpaid(); } mTransactions.erase(txn->getID()); } - else if(ltx->second->isPaid() && !shouldBePaid) + else if(ltx->isPaid() && !shouldBePaid) { // we paid for this transaction and it didn't happen lac->second->credit(txn->getAmount()); - ltx->second->setUnpaid(); + ltx->setUnpaid(); } - else if(!ltx->second->isPaid() && shouldBePaid) + else if(!ltx->isPaid() && shouldBePaid) { // this transaction happened, and we haven't paid locally lac->second->debit(txn->getAmount()); - ltx->second->setPaid(); + ltx->setPaid(); } } }