Merge pull request #403 from sipa/cbitcoinaddress
authorJeff Garzik <jgarzik@exmulti.com>
Sun, 24 Jul 2011 22:38:38 +0000 (15:38 -0700)
committerJeff Garzik <jgarzik@exmulti.com>
Sun, 24 Jul 2011 22:38:38 +0000 (15:38 -0700)
keys indexed by address + introduced CBitcoinaddress

1  2 
src/main.cpp
src/wallet.cpp

diff --combined src/main.cpp
@@@ -21,9 -21,6 +21,6 @@@ set<CWallet*> setpwalletRegistered
  
  CCriticalSection cs_main;
  
- CCriticalSection cs_mapPubKeys;
- map<uint160, vector<unsigned char> > mapPubKeys;
  map<uint256, CTransaction> mapTransactions;
  CCriticalSection cs_mapTransactions;
  unsigned int nTransactionsUpdated = 0;
@@@ -2570,7 -2567,6 +2567,7 @@@ bool SendMessages(CNode* pto, bool fSen
                      vGetData.clear();
                  }
              }
 +            mapAlreadyAskedFor[inv] = nNow;
              pto->mapAskFor.erase(pto->mapAskFor.begin());
          }
          if (!vGetData.empty())
diff --combined src/wallet.cpp
@@@ -124,7 -124,6 +124,6 @@@ public
  
  bool CWallet::EncryptWallet(const string& strWalletPassphrase)
  {
-     CRITICAL_BLOCK(cs_mapPubKeys)
      CRITICAL_BLOCK(cs_KeyStore)
      CRITICAL_BLOCK(cs_vMasterKey)
      CRITICAL_BLOCK(cs_pwalletdbEncryption)
@@@ -271,7 -270,7 +270,7 @@@ bool CWallet::AddToWallet(const CWallet
              if (txout.scriptPubKey == scriptDefaultKey)
              {
                  SetDefaultKey(GetOrReuseKeyFromPool());
-                 SetAddressBookName(PubKeyToAddress(vchDefaultKey), "");
+                 SetAddressBookName(CBitcoinAddress(vchDefaultKey), "");
              }
          }
  
@@@ -407,8 -406,8 +406,8 @@@ int CWalletTx::GetRequestCount() cons
      return nRequests;
  }
  
- void CWalletTx::GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, list<pair<string, int64> >& listReceived,
-                            list<pair<string, int64> >& listSent, int64& nFee, string& strSentAccount) const
+ void CWalletTx::GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, list<pair<CBitcoinAddress, int64> >& listReceived,
+                            list<pair<CBitcoinAddress, int64> >& listSent, int64& nFee, string& strSentAccount) const
  {
      nGeneratedImmature = nGeneratedMature = nFee = 0;
      listReceived.clear();
      // but non-standard clients might (so return a list of address/amount pairs)
      BOOST_FOREACH(const CTxOut& txout, vout)
      {
-         string address;
-         uint160 hash160;
+         CBitcoinAddress address;
          vector<unsigned char> vchPubKey;
-         if (ExtractHash160(txout.scriptPubKey, hash160))
-             address = Hash160ToAddress(hash160);
-         else if (ExtractPubKey(txout.scriptPubKey, NULL, vchPubKey))
-             address = PubKeyToAddress(vchPubKey);
-         else
+         if (!ExtractAddress(txout.scriptPubKey, pwallet, address))
          {
              printf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n",
                     this->GetHash().ToString().c_str());
@@@ -471,25 -465,25 +465,25 @@@ void CWalletTx::GetAccountAmounts(cons
      int64 allGeneratedImmature, allGeneratedMature, allFee;
      allGeneratedImmature = allGeneratedMature = allFee = 0;
      string strSentAccount;
-     list<pair<string, int64> > listReceived;
-     list<pair<string, int64> > listSent;
+     list<pair<CBitcoinAddress, int64> > listReceived;
+     list<pair<CBitcoinAddress, int64> > listSent;
      GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount);
  
      if (strAccount == "")
          nGenerated = allGeneratedMature;
      if (strAccount == strSentAccount)
      {
-         BOOST_FOREACH(const PAIRTYPE(string,int64)& s, listSent)
+         BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& s, listSent)
              nSent += s.second;
          nFee = allFee;
      }
      CRITICAL_BLOCK(pwallet->cs_mapAddressBook)
      {
-         BOOST_FOREACH(const PAIRTYPE(string,int64)& r, listReceived)
+         BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& r, listReceived)
          {
              if (pwallet->mapAddressBook.count(r.first))
              {
-                 map<string, string>::const_iterator mi = pwallet->mapAddressBook.find(r.first);
+                 map<CBitcoinAddress, string>::const_iterator mi = pwallet->mapAddressBook.find(r.first);
                  if (mi != pwallet->mapAddressBook.end() && (*mi).second == strAccount)
                      nReceived += r.second;
              }
@@@ -941,17 -935,9 +935,17 @@@ bool CWallet::CreateTransaction(const v
                      dPriority += (double)nCredit * pcoin.first->GetDepthInMainChain();
                  }
  
 -                // Fill a vout back to self with any change
 -                int64 nChange = nValueIn - nTotalValue;
 -                if (nChange >= CENT)
 +                int64 nChange = nValueIn - nValue - nFeeRet;
 +                // if sub-cent change is required, the fee must be raised to at least MIN_TX_FEE
 +                // or until nChange becomes zero
 +                if (nFeeRet < MIN_TX_FEE && nChange > 0 && nChange < CENT)
 +                {
 +                    int64 nMoveToFee = min(nChange, MIN_TX_FEE - nFeeRet);
 +                    nChange -= nMoveToFee;
 +                    nFeeRet += nMoveToFee;
 +                }
 +
 +                if (nChange > 0)
                  {
                      // Note: We use a new key here to keep it from being obvious which side is the change.
                      //  The drawback is that by not reusing a previous key, the change may be lost if a
  
                      // Fill a vout to ourself, using same address type as the payment
                      CScript scriptChange;
-                     if (vecSend[0].first.GetBitcoinAddressHash160() != 0)
+                     if (vecSend[0].first.GetBitcoinAddress().IsValid())
                          scriptChange.SetBitcoinAddress(vchPubKey);
                      else
                          scriptChange << vchPubKey << OP_CHECKSIG;
@@@ -1115,7 -1101,7 +1109,7 @@@ string CWallet::SendMoney(CScript scrip
  
  
  // requires cs_main lock
- string CWallet::SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtxNew, bool fAskFee)
+ string CWallet::SendMoneyToBitcoinAddress(const CBitcoinAddress& address, int64 nValue, CWalletTx& wtxNew, bool fAskFee)
  {
      // Check amount
      if (nValue <= 0)
  
      // Parse bitcoin address
      CScript scriptPubKey;
-     if (!scriptPubKey.SetBitcoinAddress(strAddress))
-         return _("Invalid bitcoin address");
+     scriptPubKey.SetBitcoinAddress(address);
  
      return SendMoney(scriptPubKey, nValue, wtxNew, fAskFee);
  }
@@@ -1144,13 -1129,13 +1137,13 @@@ int CWallet::LoadWallet(bool& fFirstRun
          return nLoadWalletRet;
      fFirstRunRet = vchDefaultKey.empty();
  
-     if (!HaveKey(vchDefaultKey))
+     if (!HaveKey(Hash160(vchDefaultKey)))
      {
          // Create new keyUser and set as default key
          RandAddSeedPerfmon();
  
          SetDefaultKey(GetOrReuseKeyFromPool());
-         if (!SetAddressBookName(PubKeyToAddress(vchDefaultKey), ""))
+         if (!SetAddressBookName(CBitcoinAddress(vchDefaultKey), ""))
              return DB_LOAD_FAIL;
      }
  
  }
  
  
- bool CWallet::SetAddressBookName(const string& strAddress, const string& strName)
+ bool CWallet::SetAddressBookName(const CBitcoinAddress& address, const string& strName)
  {
-     mapAddressBook[strAddress] = strName;
+     mapAddressBook[address] = strName;
      if (!fFileBacked)
          return false;
-     return CWalletDB(strWalletFile).WriteName(strAddress, strName);
+     return CWalletDB(strWalletFile).WriteName(address.ToString(), strName);
  }
  
- bool CWallet::DelAddressBookName(const string& strAddress)
+ bool CWallet::DelAddressBookName(const CBitcoinAddress& address)
  {
-     mapAddressBook.erase(strAddress);
+     mapAddressBook.erase(address);
      if (!fFileBacked)
          return false;
-     return CWalletDB(strWalletFile).EraseName(strAddress);
+     return CWalletDB(strWalletFile).EraseName(address.ToString());
  }
  
  
@@@ -1271,7 -1256,7 +1264,7 @@@ void CWallet::ReserveKeyFromKeyPool(int
          setKeyPool.erase(setKeyPool.begin());
          if (!walletdb.ReadPool(nIndex, keypool))
              throw runtime_error("ReserveKeyFromKeyPool() : read failed");
-         if (!HaveKey(keypool.vchPubKey))
+         if (!HaveKey(Hash160(keypool.vchPubKey)))
              throw runtime_error("ReserveKeyFromKeyPool() : unknown key in key pool");
          assert(!keypool.vchPubKey.empty());
          printf("keypool reserve %"PRI64d"\n", nIndex);