diff --git a/Application.cpp b/Application.cpp index d64fb1ee44..896687fa05 100644 --- a/Application.cpp +++ b/Application.cpp @@ -91,6 +91,7 @@ void Application::run() // temporary mWallet.load(); + mWallet.syncToLedger(true, &(*secondLedger)); // temporary mIOService.run(); // This blocks diff --git a/Conversion.cpp b/Conversion.cpp index 6f513be9f9..d151819103 100644 --- a/Conversion.cpp +++ b/Conversion.cpp @@ -38,14 +38,14 @@ bool u160ToHuman(uint160& buf, std::string& retStr) return(true); } -uint160 uint256::to160() const +base_uint160 uint256::to160() const { uint160 m; memcpy(&m, this, sizeof(uint160)); return m; } -uint256 uint160::to256() const +base_uint256 uint160::to256() const { uint256 m; memcpy(&m, this, sizeof(this)); diff --git a/Ledger.cpp b/Ledger.cpp index 63b62c8119..7f67394c75 100644 --- a/Ledger.cpp +++ b/Ledger.cpp @@ -237,14 +237,25 @@ Ledger::TransResult Ledger::removeTransaction(Transaction::pointer trans) } Ledger::TransResult Ledger::hasTransaction(Transaction::pointer trans) -{ +{ // Is this transaction in this ledger? If not, could it go in it? boost::recursive_mutex::scoped_lock sl(mLock); if(mTransactionMap==NULL) return TR_ERROR; try { Transaction::pointer t=getTransaction(trans->getID()); - if(t==NULL) return TR_NOTFOUND; - return TR_SUCCESS; + if(!!t) return TR_ALREADY; + + if(trans->getSourceLedger()>mLedgerSeq) return TR_BADLSEQ; + + AccountState::pointer fromAccount=getAccountState(trans->getFromAccount()); + if(!fromAccount) return TR_BADACCT; // cannot send from non-existent account + + // may be in a previous ledger + if(fromAccount->getSeq()>trans->getFromAccountSeq()) return TR_PASTASEQ; + + if(fromAccount->getSeq()getFromAccountSeq()) return TR_PREASEQ; + if(fromAccount->getBalance()getAmount()) return TR_INSUFF; + return TR_NOTFOUND; } catch (SHAMapException) { @@ -385,152 +396,3 @@ Ledger::pointer Ledger::loadByHash(const uint256& ledgerHash) sql.append("';"); return getSQL(sql); } - -#if 0 -// returns true if the from account has enough for the transaction and seq num is correct -bool Ledger::addTransaction(Transaction::pointer trans,bool checkDuplicate) -{ - if(checkDuplicate && hasTransaction(trans)) return(false); - - if(mParent) - { // check the lineage of the from addresses - uint160 address=protobufTo160(trans->from()); - if(mAccounts.count(address)) - { - pair account=mAccounts[address]; - if( (account.firstamount()) && - (trans->seqnum()==account.second) ) - { - account.first -= trans->amount(); - account.second++; - mAccounts[address]=account; - - - uint160 destAddress=protobufTo160(trans->dest()); - - Account destAccount=mAccounts[destAddress]; - destAccount.first += trans->amount(); - mAccounts[destAddress]=destAccount; - - - mValidSig=false; - mValidHash=false; - mTransactions.push_back(trans); - if(mChild) - { - mChild->parentAddedTransaction(trans); - } - return(true); - }else - { - mDiscardedTransactions.push_back(trans); - return false; - } - }else - { - mDiscardedTransactions.push_back(trans); - return false; - } - - }else - { // we have no way to know so just hold on to it but don't add to the accounts - mValidSig=false; - mValidHash=false; - mDiscardedTransactions.push_back(trans); - return(true); - } -} - -// Don't check the amounts. We will do this at the end. -void Ledger::addTransactionAllowNeg(Transaction::pointer trans) -{ - uint160 fromAddress=protobufTo160(trans->from()); - - if(mAccounts.count(fromAddress)) - { - Account fromAccount=mAccounts[fromAddress]; - if(trans->seqnum()==fromAccount.second) - { - fromAccount.first -= trans->amount(); - fromAccount.second++; - mAccounts[fromAddress]=fromAccount; - - uint160 destAddress=protobufTo160(trans->dest()); - - Account destAccount=mAccounts[destAddress]; - destAccount.first += trans->amount(); - mAccounts[destAddress]=destAccount; - - mTransactions.push_back(trans); - - }else - { // invalid seqnum - mDiscardedTransactions.push_back(trans); - } - }else - { - if(trans->seqnum()==0) - { - - mAccounts[fromAddress]=Account(-((int64)trans->amount()),1); - - uint160 destAddress=protobufTo160(trans->dest()); - - Account destAccount=mAccounts[destAddress]; - destAccount.first += trans->amount(); - mAccounts[destAddress]=destAccount; - - mTransactions.push_back(trans); - - }else - { - mDiscardedTransactions.push_back(trans); - } - } -} - - - -// Must look for transactions to discard to make this account positive -// When we chuck transactions it might cause other accounts to need correcting -void Ledger::correctAccount(const uint160& address) -{ - list effected; - - // do this in reverse so we take of the higher seqnum first - for( list::reverse_iterator iter=mTransactions.rbegin(); iter != mTransactions.rend(); ) - { - Transaction::pointer trans= *iter; - if(protobufTo160(trans->from()) == address) - { - Account fromAccount=mAccounts[address]; - assert(fromAccount.second==trans->seqnum()+1); - if(fromAccount.first<0) - { - fromAccount.first += trans->amount(); - fromAccount.second --; - - mAccounts[address]=fromAccount; - - uint160 destAddress=protobufTo160(trans->dest()); - Account destAccount=mAccounts[destAddress]; - destAccount.first -= trans->amount(); - mAccounts[destAddress]=destAccount; - if(destAccount.first<0) effected.push_back(destAddress); - - list::iterator temp=mTransactions.erase( --iter.base() ); - if(fromAccount.first>=0) break; - - iter=list::reverse_iterator(temp); - }else break; - }else iter--; - } - - BOOST_FOREACH(uint160& address,effected) - { - correctAccount(address); - } - -} - -#endif diff --git a/LocalAccount.h b/LocalAccount.h index c56f76d36f..3e43196272 100644 --- a/LocalAccount.h +++ b/LocalAccount.h @@ -17,8 +17,8 @@ protected: int mAccountSeq; // local usage tracking - uint64 mBalance; // The balance, from the last ledger - uint64 mBalanceLT; // The balance, after all local transactions + uint64 mLgrBalance; // The balance, from the last ledger + int64 mTxnDelta; // The balance changes from local/pending transactions uint32 mTxnSeq; // The sequence number of the next transaction public: @@ -41,9 +41,10 @@ public: uint32 getTxnSeq() const { return mTxnSeq; } uint32 incTxnSeq() { return mTxnSeq++; } - uint64 getBalance() const { return mBalance; } - void credit(uint64 amount) { mBalance+=amount; } - void debit(uint64 amount) { assert(mBalance>=amount); mBalance-=amount; } + int64 getEffectiveBalance() const { return static_cast(mLgrBalance)+mTxnDelta; } + void credit(uint64 amount) { mTxnDelta+=amount; } + void debit(uint64 amount) { mTxnDelta-=amount; } + void setLedgerBalance(uint64_t lb) { mLgrBalance=lb; } }; class LocalAccountFamily @@ -119,6 +120,7 @@ public: uint32 getAcctSeq() const; uint64 getBalance() const; + void setLedgerBalance(uint64_t ledgerBalance); void incAcctSeq(uint32 transAcctSeq); CKey::pointer getPublicKey(); diff --git a/Wallet.cpp b/Wallet.cpp index dfb26042be..98e42c765e 100644 --- a/Wallet.cpp +++ b/Wallet.cpp @@ -9,6 +9,7 @@ #include "boost/interprocess/sync/scoped_lock.hpp" #include "Wallet.h" +#include "Ledger.h" #include "NewcoinAddress.h" #include "Application.h" @@ -20,7 +21,7 @@ LocalAccountEntry::LocalAccountEntry(const uint160& accountFamily, int accountSeq, EC_POINT* rootPubKey) : mPublicKey(new CKey(accountFamily, rootPubKey, accountSeq)), mAccountFamily(accountFamily), mAccountSeq(accountSeq), - mBalance(0), mBalanceLT(0), mTxnSeq(0) + mLgrBalance(0), mTxnDelta(0), mTxnSeq(0) { mAcctID=mPublicKey->GetAddress().GetHash160(); if(theApp!=NULL) mPublicKey=theApp->getPubKeyCache().store(mAcctID, mPublicKey); @@ -401,7 +402,14 @@ uint64 LocalAccount::getBalance() const { LocalAccountEntry::pointer la(mFamily->get(mSeq)); if(!la) return 0; - return la->getBalance(); + return la->getEffectiveBalance(); +} + +void LocalAccount::setLedgerBalance(uint64_t lb) +{ + LocalAccountEntry::pointer la(mFamily->get(mSeq)); + if(!la) return ; + la->setLedgerBalance(lb); } CKey::pointer LocalAccount::getPublicKey() @@ -794,18 +802,17 @@ void Wallet::syncToLedger(bool force, Ledger* ledger) { boost::recursive_mutex::scoped_lock sl(mLock); if(!force && (mLedger>=ledger->getLedgerSeq())) return; - for(std::map::iterator it=mAccounts.begin(); it!=mAccounts.end(); ++it) - { - LocalAccount::pointer& lac=it->second; - AccountState::pointer acs=ledger->getAccountState(it->first); - if(!acs) - { // account is not in the ledger - // WRITEME - } - else - { // account is in the ledger - // WRITEME - } + for(std::map::iterator xit=mTransactions.begin(); + xit!=mTransactions.end(); ++xit) + { // check each transaction, see if it's in the ledger or allowed in the ledger + // WRITEME + } + for(std::map::iterator ait=mAccounts.begin(); ait!=mAccounts.end(); ++ait) + { // check each account, see if our ledger balance matches + LocalAccount::pointer& lac=ait->second; + AccountState::pointer acs=ledger->getAccountState(ait->first); + if(!acs) lac->setLedgerBalance(0); + else lac->setLedgerBalance(acs->getBalance()); } if(mLedgergetLedgerSeq()) mLedger=ledger->getLedgerSeq(); } diff --git a/bignum.h b/bignum.h index 72296106e2..0023861897 100644 --- a/bignum.h +++ b/bignum.h @@ -300,7 +300,7 @@ public: while (isxdigit(*psz)) { *this <<= 4; - int n = phexdigit[*psz++]; + int n = phexdigit[(int) *psz++]; *this += n; } if (fNegative) diff --git a/uint256.h b/uint256.h index f53bcee50d..4ddbb772f4 100644 --- a/uint256.h +++ b/uint256.h @@ -320,7 +320,7 @@ public: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 }; const char* pbegin = psz; - while (phexdigit[*psz] || *psz == '0') + while (phexdigit[(int) *psz] || *psz == '0') psz++; psz--; unsigned char* p1 = (unsigned char*)pn; @@ -470,7 +470,7 @@ public: *this = 0; } - uint256 to256() const; + base_uint256 to256() const; }; inline bool operator==(const uint160& a, uint64 b) { return (base_uint160)a == b; } @@ -586,7 +586,7 @@ public: *this = 0; } - uint160 to160() const; + base_uint160 to160() const; };