diff --git a/Application.h b/Application.h index c6dd5b0f8d..5a14abe5d5 100644 --- a/Application.h +++ b/Application.h @@ -10,6 +10,7 @@ #include "LedgerMaster.h" #include "Wallet.h" #include "Peer.h" +#include "NetworkOPs.h" #include "database/database.h" #include @@ -19,10 +20,12 @@ class PeerDoor; class Application { + NetworkOPs mNetOps; + Wallet mWallet; + TimingService mTimingService; UniqueNodeList mUNL; KnownNodeList mKnownNodes; - Wallet mWallet; PubKeyCache mPKCache; LedgerMaster mMasterLedger; Database* mDatabase; @@ -41,11 +44,12 @@ class Application public: Application(); - ConnectionPool& getConnectionPool() { return(mConnectionPool); } + ConnectionPool& getConnectionPool() { return mConnectionPool; } - UniqueNodeList& getUNL() { return(mUNL); } + UniqueNodeList& getUNL() { return mUNL; } - Wallet& getWallet() { return(mWallet); } + Wallet& getWallet() { return mWallet ; } + NetworkOPs& getOPs() { return mNetOps; } PubKeyCache& getPubKeyCache() { return mPKCache; } diff --git a/LedgerMaster.cpp b/LedgerMaster.cpp index 85b65984c8..e22bef6e29 100644 --- a/LedgerMaster.cpp +++ b/LedgerMaster.cpp @@ -24,9 +24,11 @@ uint64 LedgerMaster::getBalance(std::string& addr) return mCurrentLedger->getBalance(humanTo160(addr)); } -bool LedgerMaster::addTransaction(Transaction::pointer transaction) +bool LedgerMaster::addHeldTransaction(Transaction::pointer transaction) { - return mCurrentLedger->applyTransaction(transaction)==Ledger::TR_SUCCESS; + boost::recursive_mutex::scoped_lock ml(mLock); + if(!mHeldTransactionsByID[transaction->getID()]) + mHeldTransactionsByID[transaction->getID()]=transaction; } void LedgerMaster::pushLedger(Ledger::pointer newLedger) diff --git a/LedgerMaster.h b/LedgerMaster.h index 2f2a554618..4988fbf8fa 100644 --- a/LedgerMaster.h +++ b/LedgerMaster.h @@ -22,7 +22,6 @@ class LedgerMaster LedgerHistory mLedgerHistory; std::map mHeldTransactionsByID; - std::map mHeldTransactionsByLedger; void applyFutureTransactions(uint32 ledgerIndex); bool isValidTransaction(Transaction::pointer trans); @@ -60,7 +59,7 @@ public: AccountState::pointer getAccountState(const uint160& addr) { return mCurrentLedger->getAccountState(addr); } - bool addTransaction(Transaction::pointer trans); + bool addHeldTransaction(Transaction::pointer trans); }; #endif diff --git a/Makefile b/Makefile index 9d0ff21cf7..912e844d10 100644 --- a/Makefile +++ b/Makefile @@ -72,7 +72,7 @@ SRCS= keystore.cpp BitcoinUtil.cpp \ Application.cpp TimingService.cpp KnownNodeList.cpp ConnectionPool.cpp Peer.cpp \ PeerDoor.cpp RPCDoor.cpp RPCServer.cpp rpc.cpp Conversion.cpp RequestParser.cpp HashedObject.cpp \ UniqueNodeList.cpp PubKeyCache.cpp SHAMapDiff.cpp DeterministicKeys.cpp LedgerMaster.cpp \ - LedgerHistory.cpp + LedgerHistory.cpp NetworkOPs.cpp DBSRCS= SqliteDatabase.cpp database.cpp diff --git a/NetworkOPs.cpp b/NetworkOPs.cpp new file mode 100644 index 0000000000..864ad6494c --- /dev/null +++ b/NetworkOPs.cpp @@ -0,0 +1,101 @@ + +#include "Application.h" +#include "NetworkOPs.h" +#include "Transaction.h" + +// This is the primary interface into the "client" portion of the program. +// Code that wants to do normal operations on the network such as +// creating and monitoring accounts, creating transactions, and so on +// should use this interface. The RPC code will primarily be a light wrapper +// over this code. + +// Eventually, it will check the node's operating mode (synched, unsynched, +// etectera) and defer to the correct means of processing. The current +// code assumes this node is synched (and will continue to do so until +// there's a functional network. + +uint64 NetworkOPs::getNetworkTime() +{ + return time(NULL); +} + +uint32 NetworkOPs::getCurrentLedgerID() +{ + return theApp->getMasterLedger().getCurrentLedger()->getLedgerSeq(); +} + +Transaction::pointer NetworkOPs::processTransaction(Transaction::pointer trans) +{ + Transaction::pointer dbtx=Transaction::load(trans->getID()); + if(dbtx) return dbtx; + + if(!trans->checkSign()) + { + trans->setStatus(INVALID); + return trans; + } + + Ledger::TransResult r=theApp->getMasterLedger().getCurrentLedger()->applyTransaction(trans); + if(r==Ledger::TR_ERROR) throw Fault(IO_ERROR); + + if((r==Ledger::TR_PREASEQ) || (r==Ledger::TR_BADLSEQ)) + { // transaction should be held + trans->setStatus(HELD); + trans->save(); + theApp->getMasterLedger().addHeldTransaction(trans); + return trans; + } + if( (r==Ledger::TR_PASTASEQ) || (r==Ledger::TR_ALREADY) ) + { // duplicate or conflict + trans->setStatus(OBSOLETE); + return trans; + } + + if(r==Ledger::TR_SUCCESS) + { + // WRITEME: send to others + trans->setStatus(INCLUDED); + return trans; + } + + trans->setStatus(INVALID); + return trans; +} + +Transaction::pointer NetworkOPs::findTransactionByID(const uint256& transactionID) +{ + return Transaction::load(transactionID); +} + +int NetworkOPs::findTransactionsBySource(std::list& txns, + const uint160& sourceAccount, uint32 minSeq, uint32 maxSeq) +{ + AccountState::pointer state=getAccountState(sourceAccount); + if(!state) return 0; + if(minSeq>state->getSeq()) return 0; + if(maxSeq>state->getSeq()) maxSeq=state->getSeq(); + if(maxSeq>minSeq) return 0; + + int count=0; + for(int i=minSeq; i<=maxSeq; i++) + { + Transaction::pointer txn=Transaction::findFrom(sourceAccount, i); + if(txn) + { + txns.push_back(txn); + count++; + } + } + return count; +} + +int NetworkOPs::findTransactionsByDestination(std::list& txns, + const uint160& destinationAccount, uint32 startLedgerSeq, uint32 endLedgerSeq, int maxTransactions) +{ + // WRITEME +} + +AccountState::pointer NetworkOPs::getAccountState(const uint160& accountID) +{ + return theApp->getMasterLedger().getCurrentLedger()->getAccountState(accountID); +} diff --git a/NetworkOPs.h b/NetworkOPs.h new file mode 100644 index 0000000000..29044aeb9b --- /dev/null +++ b/NetworkOPs.h @@ -0,0 +1,49 @@ +#ifndef __NETWORK_OPS__ +#define __NETWORK_OPS__ + +#include "Transaction.h" +#include "AccountState.h" + +// Operations that clients may wish to perform against the network + +class NetworkOPs +{ + enum Fault + { + IO_ERROR=1, + NO_NETWORK=2, + }; + +public: + + // network information + uint64 getNetworkTime(); + uint32 getCurrentLedgerID(); + + // transaction operations + Transaction::pointer processTransaction(Transaction::pointer transaction); + Transaction::pointer findTransactionByID(const uint256& transactionID); + int findTransactionsBySource(std::list&, const uint160& sourceAccount, + uint32 minSeq, uint32 maxSeq); + int findTransactionsByDestination(std::list&, const uint160& destinationAccount, + uint32 startLedgerSeq, uint32 endLedgerSeq, int maxTransactions); + + // account operations + AccountState::pointer getAccountState(const uint160& accountID); + + // contact block operations + + // raw object operations + bool findRawLedger(const uint256& ledgerHash, std::vector& rawLedger); + bool findRawTransaction(const uint256& transactionHash, std::vector& rawTransaction); + bool findAccountNode(const uint256& nodeHash, std::vector& rawAccountNode); + bool findTransactionNode(const uint256& nodeHash, std::vector& rawTransactionNode); + + // tree synchronzation operations + bool getTransactionTreeNodes(uint32 ledgerSeq, const uint256& myNodeID, + const std::vector& myNode, std::list >& newNodes); + bool getAccountStateNodes(uint32 ledgerSeq, const uint256& myNodeId, + const std::vector& myNode, std::list >& newNodes); +}; + +#endif